.net 自動分類算法【原創】

目前自動分類算法是參考網上的思路和想法我的自主研發的。算法

固然互聯網上有不少人採用不一樣的方式去解決自動分類問題,也有不一樣的算法和論文支持去作,但縱觀自動分類這塊工做是屬於機器學習這塊工做內容,總結出來比較簡單的實現方式就是本文檔採用的方式(若是有其餘方式,歡迎交流)。機器學習

自動分類算法主要分爲樣本訓練和餘弦算法判別兩塊內容。學習

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 車江毅

相關文章
相關標籤/搜索