zoukankan      html  css  js  c++  java
  • .net 自动分类算法【原创】

    目前自动分类算法是参考网上的思路和想法个人自主研发的。

    当然互联网上有很多人采用不同的方式去解决自动分类问题,也有不同的算法和论文支持去做,但纵观自动分类这块工作是属于机器学习这块工作内容,总结出来比较简单的实现方式就是本文档采用的方式(如果有其他方式,欢迎交流)。

    自动分类算法主要分为样本训练和余弦算法判别两块内容。

    1) 采用已经做好归类的高质量的文档(理论上文档要越多,分类的精准度更会更加趋向精准),使用自动分类算法进行训练归类的学习, 产生分类数据模型。

    2)输入一篇文章,使用余弦算法,采用分类数据模型进行自动判别。


    样本训练

    1)采用中文分词(或者其他分词方式,IK,庖丁,盘古等都可以)对文档进行分词处理,产生分词数据字典。(词典频率统计)

    所产生的数据字典,即为分类数据模型。(不断保存分类数据模型)


    余弦算法

    1)新的一篇文章采用相同的分词方式,进行分词数据字典生成。根据该数据字典和分类的数据字典进行相似度判别(余弦算法),从而自动判定文章的归类。


    自动分类算法的效果

    个人认为效果取决于:分词的效果 ,训练文本的质量,算法本身的效果;未充分验证!!!

    分词的效果:如果采用特定行业的词和一些行业相关的词,可能会对自动分类的效果产生影响。

    训练文本:如果训练的文本的质量足够高,文本数量足够多,应该会对自动分类的效果产生影响。

    算法效果:目前采用余弦进行相似度判别,从而自动区别分类。如果有更好的算法,效果会更加。


    影响优先级:算法>训练文本>分词效果

    【限定字典:是指行业特定的字典;在分词的结果基础上对行业特定字典进行过滤。】


    限于目前的时间这块,没有深入研究和验证,以及优化算法和一些其他的改进。仅仅根据理论,用C#进行编写。

     /// <summary>
        /// 自动分类算法 欢迎交流 by 车江毅 开源QQ群: .net 开源基础服务  238543768
        /// </summary>
        public class AutoCategoryAlgorithm
        {
            /// <summary>
            /// 限定字典
            /// </summary>
            public List<string> Words = new List<string>();
            /// <summary>
            /// 获取样本训练结果
            /// </summary>
            public Dictionary<string, Dictionary<string, int>> CategorySampleDic { get { return categorySampleDic; } }
    
            /// <summary>
            /// 样本分类训练集
            /// </summary>
            private Dictionary<string, Dictionary<string, int>> categorySampleDic = new Dictionary<string, Dictionary<string, int>>();
            public AutoCategoryAlgorithm(Dictionary<string, Dictionary<string, int>> categorysampledic)
            {
                categorySampleDic = categorysampledic;
            }
            public AutoCategoryAlgorithm()
            { }
            /// <summary>
            /// 自动分类
            /// </summary>
            /// <param name="text"></param>
            /// <returns></returns>
            public string AutoCategory(string text)
            {
                var dic = Token(text);
                Dictionary<string, double> scores = new Dictionary<string, double>();
               
                foreach (var c in categorySampleDic)
                {
                   var s= CosineSimilar(dic,c.Value);
                    scores.Add(c.Key, s);
                }
                var max = scores.OrderByDescending(c => c.Value).FirstOrDefault();
                return max.Key; 
            }
            /// <summary>
            /// 自动分类
            /// </summary>
            /// <param name="text"></param>
            /// <returns></returns>
            public Dictionary<string, double> AutoCategoryScores(string text)
            {
                var dic = Token(text);
                Dictionary<string, double> scores = new Dictionary<string, double>();
    
                foreach (var c in categorySampleDic)
                {
                    var s = CosineSimilar(dic, c.Value);
                    scores.Add(c.Key, s);
                }
                return scores;
            }
            /// <summary>
            /// 样本训练
            /// </summary>
            public void Train(string category,List<string> samples)
            {
                if (categorySampleDic.ContainsKey(category))
                {
                    if (categorySampleDic[category] == null)
                        categorySampleDic[category] = new Dictionary<string, int>();
                }
                else
                    categorySampleDic.Add(category,new Dictionary<string, int>());
                var cdic = categorySampleDic[category];//上次样本训练集
                foreach (var s in samples)
                {
                    var dic= Token(s);
                    foreach (var kv in dic)
                    {
                        if (cdic.ContainsKey(kv.Key))
                            cdic[kv.Key] += kv.Value;
                        else
                            cdic.Add(kv.Key, kv.Value);
                    }
                }
            }
    
            private Dictionary<string, int> Token(string text)
            {
                ChineseAnalyer ca = new ChineseAnalyer();
                var dic = ca.Token(text);
                if (Words.Count > 0)
                {
                    var r = new Dictionary<string, int>();
                    foreach (var w in Words)
                    {
                        if (dic.ContainsKey(w))
                        {
                            r.Add(w,dic[w]);
                        }
                    }
                    return r;
                }
                return dic;
            }
            /// <summary>
            /// 余弦算法
            /// </summary>
            /// <param name="map1"></param>
            /// <param name="map2"></param>
            /// <returns></returns>
            private double CosineSimilar(Dictionary<string, int> map1, Dictionary<string, int> map2)
            {
                var AlgorithmMap = new Dictionary<int, int[]>();
                foreach (var m in map1)
                {
                    int key = m.Key.GetHashCode();
                    AlgorithmMap.Add(key,new int[] { m.Value,0});
                }
                foreach (var m in map2)
                {
                    int key = m.Key.GetHashCode();
                    if (AlgorithmMap.ContainsKey(key))
                        AlgorithmMap[key][1] = m.Value;
                    else
                        AlgorithmMap.Add(key, new int[] {  0,m.Value });
                }
    
                double sqdoc1 = 0;
                double sqdoc2 = 0;
                double denominator = 0;
                foreach (var kv in AlgorithmMap)
                {
                    int[] c = kv.Value;
                    denominator += c[0] * c[1];
                    sqdoc1 += c[0] * c[0];
                    sqdoc2 += c[1] * c[1];
                }
    
                return denominator / Math.Sqrt(sqdoc1 * sqdoc2);
            }
        }

     by 车江毅

  • 相关阅读:
    实参和形参
    location对象
    区别 apply,call
    窗体之间的交互(window.opener)
    我的升级脚本总结
    Create elements
    history 对象
    函数参数的属性:callee
    发布app store流程
    【转】如何生成静态页面的五种方案
  • 原文地址:https://www.cnblogs.com/chejiangyi/p/7248476.html
Copyright © 2011-2022 走看看