C# NN算法实现

NN算法的核心是,欧式距离(Euclid),在分类的数据中,找到与目标数据欧式距离最近的点,把目标点分类到其类,算法很简单,下面是C#代码的实现:

namespace LocationService.Math
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    public class NN
    {
        public List<Tuple<string, double[]>> FingerPrintsTable;
        public NN()
        {
            FingerPrintsTable = new List<Tuple<string, double[]>>();
        }

        public void AddFingerPrint(string key,double[] attributes)
        {
            var finger = Tuple.Create(key,attributes);
            AddFingerPrint(finger);
        }
        public void AddFingerPrint(Tuple<string,double[]> fingerprint)
        {
            FingerPrintsTable.Add(fingerprint);
        }

        public void AddFingerPrint(IEnumerable<Tuple<string, double[]>> fingers)
        {
            FingerPrintsTable.AddRange(fingers);
        }
        public void RemoveFingerPrint(string key)
        {
            FingerPrintsTable.RemoveAll(fi => fi.Item1 == key);
        }

        public void RemoveFingerPrint(Tuple<string, double[]> fingerprint)
        {
            FingerPrintsTable.Remove(fingerprint);
        }

        public double EuclideanDistance(double[] x1, double[] x2,int scale=1)
        {
            double sum=0;
            for (int i = 0; i < x1.Length; i++)
            {
                sum += Math.Pow(x1[i] - x2[i], 2);
            }
            sum = Math.Sqrt(sum) / x1.Length*scale;
            return sum;
        }

        public List<Tuple<string, double>> FingerEuclideanList(Tuple<string, double[]> target)
        {
            List<Tuple<string, double>> list = new List<Tuple<string, double>>(); 

            foreach (var finger in FingerPrintsTable)
            {
                list.Add(Tuple.Create(finger.Item1, EuclideanDistance(finger.Item2, target.Item2)));
            }
            return list;
        }

        /// <summary>
        /// Apply the Euclidean distance
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        public Tuple<string,double> ApplyEuclideanFilter(Tuple<string, double[]> target)
        {
            var list = FingerEuclideanList(target);
            list.Sort((x, y) => (int)((x.Item2 - y.Item2) * 100));
            foreach (var item in list)
            {
                this.log("[Label:{0} Distance:{1}]", item.Item1, item.Item2);
            }
            return list[0];
        }

    }
}

用其他的案例,分类影片类型:

 

分类使用

NN nN = new NN();
            nN.AddFingerPrint("爱情",new double[] {3,104});
            nN.AddFingerPrint("爱情", new double[] {2,100 });
            nN.AddFingerPrint("爱情", new double[] {1,81});
            nN.AddFingerPrint("动作", new double[] {101,10 });
            nN.AddFingerPrint("动作", new double[] {99,5});
            nN.AddFingerPrint("动作", new double[] {98,2});

            Tuple<string, double[]> target = Tuple.Create("未知",new double[] {81,80});
            Tuple<string, double> result=null;
            this.MeasureTime(()=> {
                result = nN.ApplyEuclideanFilter(target);
                
            },time=> {
                this.log("===================================");
                this.log("分类类型:{0}   欧式距离为:{1}", result.Item1, result.Item2);
                this.log("total time:{0}ms", time);
                this.log("===================================");
            });

 

分类结果如下:

 

posted @ 2018-07-10 11:16  bdcliang  阅读(626)  评论(0编辑  收藏  举报

bdcliang