目前自动分类算法是参考网上的思路和想法我的自主研发的。算法
固然互联网上有不少人采用不一样的方式去解决自动分类问题,也有不一样的算法和论文支持去作,但纵观自动分类这块工做是属于机器学习这块工做内容,总结出来比较简单的实现方式就是本文档采用的方式(若是有其余方式,欢迎交流)。机器学习
自动分类算法主要分为样本训练和余弦算法判别两块内容。学习
1) 采用已经作好归类的高质量的文档(理论上文档要越多,分类的精准度更会更加趋向精准),使用自动分类算法进行训练归类的学习, 产生分类数据模型。优化
2)输入一篇文章,使用余弦算法,采用分类数据模型进行自动判别。spa
样本训练 .net
1)采用中文分词(或者其余分词方式,IK,庖丁,盘古等均可以)对文档进行分词处理,产生分词数据字典。(词典频率统计) code
所产生的数据字典,即为分类数据模型。(不断保存分类数据模型) blog
余弦算法 文档
1)新的一篇文章采用相同的分词方式,进行分词数据字典生成。根据该数据字典和分类的数据字典进行类似度判别(余弦算法),从而自动断定文章的归类。 get
自动分类算法的效果
我的认为效果取决于:分词的效果 ,训练文本的质量,算法自己的效果;未充分验证!!!
分词的效果:若是采用特定行业的词和一些行业相关的词,可能会对自动分类的效果产生影响。
训练文本:若是训练的文本的质量足够高,文本数量足够多,应该会对自动分类的效果产生影响。
算法效果:目前采用余弦进行类似度判别,从而自动区别分类。若是有更好的算法,效果会更加。
影响优先级:算法>训练文本>分词效果
【限定字典:是指行业特定的字典;在分词的结果基础上对行业特定字典进行过滤。】
限于目前的时间这块,没有深刻研究和验证,以及优化算法和一些其余的改进。仅仅根据理论,用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 车江毅