• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            chenglong7997

            教你文本聚類(轉(zhuǎn))

            教你文本聚類

            2009-08-23 18:32 189人閱讀 評(píng)論(0) 收藏 舉報(bào)

            摘 要:文本聚類是搜索引擎和語(yǔ)義web的基本技術(shù),這次本蛙和大家一起學(xué)習(xí)一下簡(jiǎn)單的文本聚類算法,可能不能直接用于實(shí)際應(yīng)用中,但對(duì)于想學(xué)搜索技術(shù)的初學(xué) 者還是有一定入門作用的。這里會(huì)用到TF/IDF權(quán)重,用余弦?jiàn)A角計(jì)算文本相似度,用方差計(jì)算兩個(gè)數(shù)據(jù)間歐式距離,用k-means進(jìn)行數(shù)據(jù)聚類等數(shù)學(xué)和 統(tǒng)計(jì)知識(shí)。關(guān)于這些概念可以去google,或者參考文本后的參考鏈接。

            思路:計(jì)算兩篇文檔的相似度,最簡(jiǎn)單的做法就是用提取文檔的TF/IDF權(quán)重,然后用余弦定理計(jì)算兩個(gè)多維向量的距離。能計(jì)算兩個(gè)文本間的距離后,用標(biāo)準(zhǔn)的k-means算法就可以實(shí)現(xiàn)文本聚類了。

            測(cè)試:首先我們準(zhǔn)備以下數(shù)據(jù)
            ===================
            奧運(yùn) 拳擊 入場(chǎng)券 基本 分罄 鄒市明 奪冠 對(duì)手 浮出 水面
            股民 要 清楚 自己 的 目的
            印花稅 之 股民 四季
            杭州 股民 放 鞭炮 慶祝 印花稅 下調(diào) 
            殘疾 女 青年 入圍 奧運(yùn) 游泳 比賽 創(chuàng) 奧運(yùn) 歷史 兩 項(xiàng) 第一
            介紹 一 個(gè) ASP.net MVC 系列 教程
            在 asp.net 中 實(shí)現(xiàn) 觀察者 模式 ,或 有 更 好 的 方法 (續(xù))
            輸 大錢 的 股民 給 我們 啟迪
            Asp.Net 頁(yè)面 執(zhí)行 流程 分析
            運(yùn)動(dòng)員 行李 將 “后 上 先 下” 奧運(yùn) 相關(guān) 人員 行李 實(shí)名制
            asp.net 控件 開發(fā) 顯示 控件 內(nèi)容
            奧運(yùn) 票務(wù) 網(wǎng)上 成功 訂票 后 應(yīng) 及時(shí) 到 銀行 代售 網(wǎng)點(diǎn) 付款
            某 心理 健康 站 開張 后 首 個(gè) 咨詢 者 是 位 新 股民
            ASP.NET 自定義 控件 復(fù)雜 屬性 聲明 持久性 淺析
            ==================
            很明顯以上數(shù)據(jù)可以分為三類:asp.net,奧運(yùn)和股民,我們就寫程序來(lái)實(shí)現(xiàn)它,各種算法的原理網(wǎng)上都有,我就大概只貼代碼,聲明一下,部分代碼是從網(wǎng) 上直接抄的,k-means代碼是我從一篇文章的java示例代碼轉(zhuǎn)換過(guò)來(lái)的,我給代碼加了不少注釋,希望能幫助大家理解。

            以下是入口函數(shù)

             static   void  Main( string [] args)
             
            {
                 
             // 1、獲取文檔輸入 
             
                 string [] docs  =  getInputDocs( " input.txt " );
                 
             if  (docs.Length  <   1 )
                 
             {
                     Console.WriteLine(
             " 沒(méi)有文檔輸入 " );
                     Console.Read();
                     
             return ;
                 }
             

             
                 
             // 2、初始化TFIDF測(cè)量器,用來(lái)生產(chǎn)每個(gè)文檔的TFIDF權(quán)重 
             
                TFIDFMeasure tf  =   new  TFIDFMeasure(docs,  new  Tokeniser());
             
                 
             int  K  =   3  // 聚成3個(gè)聚類
             
                 
             // 3、生成k-means的輸入數(shù)據(jù),是一個(gè)聯(lián)合數(shù)組,第一維表示文檔個(gè)數(shù),
                 
             // 第二維表示所有文檔分出來(lái)的所有詞 
             
                 double [][] data  =   new   double [docs.Length][];
                 
             int  docCount  =  docs.Length;  // 文檔個(gè)數(shù) 
             
                 int  dimension  =  tf.NumTerms; // 所有詞的數(shù)目 
             
                 for  ( int  i  =   0 ; i  <  docCount; i ++ )
                 
             {
                     
             for  ( int  j  =   0 ; j  <  dimension; j ++ )
                     
             {
                         data[i] 
             =  tf.GetTermVector2(i);  // 獲取第i個(gè)文檔的TFIDF權(quán)重向量 
             
                    } 

                 }
             

             
                 
             // 4、初始化k-means算法,第一個(gè)參數(shù)表示輸入數(shù)據(jù),第二個(gè)參數(shù)表示要聚成幾個(gè)類 
             
                WawaKMeans kmeans  =   new  WawaKMeans(data, K);
                 
             // 5、開始迭代 
             
                kmeans.Start();
             
                 
             // 6、獲取聚類結(jié)果并輸出 
             
                WawaCluster[] clusters  =  kmeans.Clusters;
                 
             foreach  (WawaCluster cluster  in  clusters)
                 
             {
                     List
             < int >  members  =  cluster.CurrentMembership;
                     Console.WriteLine(
             " ----------------- " );
                     
             foreach  ( int  i  in  members)
                     
             {
                         Console.WriteLine(docs[i]);
                     }
             

             
                 }
             

                 Console.Read();
             }
             

             


            以下是分詞器的主要代碼

             ///   <summary> 
             
            ///  以空白字符進(jìn)行簡(jiǎn)單分詞,并忽略大小寫,
             
            ///  實(shí)際情況中可以用其它中文分詞算法
             
            ///   </summary> 
             
            ///   <param name="input"></param> 
             
            ///   <returns></returns> 

             public  IList < string >  Partition( string  input)
             
            {
              Regex r
             = new  Regex( " ([ //t{}():;. /n]) " );  
              input
             = input.ToLower() ;
             
              String [] tokens
             = r.Split(input);          
             
              List
             < string >  filter = new   List < string > () ;
             
              
             for  ( int  i = 0 ; i  <  tokens.Length ; i ++ )
              
             {
               MatchCollection mc
             = r.Matches(tokens[i]);
               
             if  (mc.Count  <=   0   &&  tokens[i].Trim().Length  >   0        
                
             &&   ! StopWordsHandler.IsStopword (tokens[i]) )        
                filter.Add(tokens[i]) ;
                     }
             

              
              
             return  filter.ToArray();
             }
             

             


            以下是kmeans算法的基本代碼

             public   class  WawaKMeans
             
            {
                 
             ///   <summary> 
                 
             ///  數(shù)據(jù)的數(shù)量
                 
             ///   </summary> 

                  readonly   int  _coordCount;
                 
             ///   <summary> 
                 
             ///  原始數(shù)據(jù)
                 
             ///   </summary> 

                  readonly   double [][] _coordinates;
                 
             ///   <summary> 
                 
             ///  聚類的數(shù)量
                 
             ///   </summary> 

                  readonly   int  _k;
                 
             ///   <summary> 
                 
             ///  聚類
                 
             ///   </summary> 

                  private   readonly  WawaCluster[] _clusters;
             
                 
             internal  WawaCluster[] Clusters
                 
             {
                     
             get    return  _clusters; } 
                 }
             
             
             
                 
             ///   <summary> 
                 
             ///  定義一個(gè)變量用于記錄和跟蹤每個(gè)資料點(diǎn)屬于哪個(gè)群聚類
                 
             ///  _clusterAssignments[j]=i;// 表示第 j 個(gè)資料點(diǎn)對(duì)象屬于第 i 個(gè)群聚類
                 
             ///   </summary> 

                  readonly   int [] _clusterAssignments;
                 
             ///   <summary> 
                 
             ///  定義一個(gè)變量用于記錄和跟蹤每個(gè)資料點(diǎn)離聚類最近
                 
             ///   </summary> 

                  private   readonly   int [] _nearestCluster;
                 
             ///   <summary> 
                 
             ///  定義一個(gè)變量,來(lái)表示資料點(diǎn)到中心點(diǎn)的距離,
                 
             ///  其中—_distanceCache[i][j]表示第i個(gè)資料點(diǎn)到第j個(gè)群聚對(duì)象中心點(diǎn)的距離;
                 
             ///   </summary> 

                  private   readonly   double [,] _distanceCache;
                 
             ///   <summary> 
                 
             ///  用來(lái)初始化的隨機(jī)種子
                 
             ///   </summary> 

                  private   static   readonly  Random _rnd  =   new  Random( 1 );
             
                 
             public  WawaKMeans( double [][] data,  int  K)
                 
             {
                     _coordinates 
             =  data;
                     _coordCount 
             =  data.Length;
                     _k 
             =  K;
                     _clusters 
             =   new  WawaCluster[K];
                     _clusterAssignments 
             =   new   int [_coordCount];
                     _nearestCluster 
             =   new   int [_coordCount];
                     _distanceCache 
             =   new   double [_coordCount,data.Length];
                     InitRandom();
                 }
             

             
                 
             public   void  Start()
                 
             {
                     
             int  iter  =   0 ;
                     
             while  ( true )
                     
             {
                         Console.WriteLine(
             " Iteration  "   +  (iter ++  +   "  " );
                         
             // 1、重新計(jì)算每個(gè)聚類的均值 
             
                         for  ( int  i  =   0 ; i  <  _k; i ++ )
                         
             {
                             _clusters[i].UpdateMean(_coordinates);
                         }
             

             
                         
             // 2、計(jì)算每個(gè)數(shù)據(jù)和每個(gè)聚類中心的距離 
             
                         for  ( int  i  =   0 ; i  <  _coordCount; i ++ )
                         
             {
                             
             for  ( int  j  =   0 ; j  <  _k; j ++ )
                             
             {
                                 
             double  dist  =  getDistance(_coordinates[i], _clusters[j].Mean);
                                 _distanceCache[i,j] 
             =  dist;
                             }
             

                         }
             

             
                         
             // 3、計(jì)算每個(gè)數(shù)據(jù)離哪個(gè)聚類最近 
             
                         for  ( int  i  =   0 ; i  <  _coordCount; i ++ )
                         
             {
                             _nearestCluster[i] 
             =  nearestCluster(i);
                         }
             

             
                         
             // 4、比較每個(gè)數(shù)據(jù)最近的聚類是否就是它所屬的聚類
                         
             // 如果全相等表示所有的點(diǎn)已經(jīng)是最佳距離了,直接返回; 
             
                         int  k  =   0 ;
                         
             for  ( int  i  =   0 ; i  <  _coordCount; i ++ )
                         
             {
                             
             if  (_nearestCluster[i]  ==  _clusterAssignments[i])
                                 k
             ++ ;
             
                         }
             

                         
             if  (k  ==  _coordCount)
                             
             break ;
             
                         
             // 5、否則需要重新調(diào)整資料點(diǎn)和群聚類的關(guān)系,調(diào)整完畢后再重新開始循環(huán);
                         
             // 需要修改每個(gè)聚類的成員和表示某個(gè)數(shù)據(jù)屬于哪個(gè)聚類的變量 
             
                         for  ( int  j  =   0 ; j  <  _k; j ++ )
                         
             {
                             _clusters[j].CurrentMembership.Clear();
                         }
             

                         
             for  ( int  i  =   0 ; i  <  _coordCount; i ++ )
                         
             {
                             _clusters[_nearestCluster[i]].CurrentMembership.Add(i);
                             _clusterAssignments[i] 
             =  _nearestCluster[i];
                         }
             

                         
                     }
             

             
                 }
             

             
                 
             ///   <summary> 
                 
             ///  計(jì)算某個(gè)數(shù)據(jù)離哪個(gè)聚類最近
                 
             ///   </summary> 
                 
             ///   <param name="ndx"></param> 
                 
             ///   <returns></returns> 

                  int  nearestCluster( int  ndx)
                 
             {
                     
             int  nearest  =   - 1 ;
                     
             double  min  =  Double.MaxValue;
                     
             for  ( int  c  =   0 ; c  <  _k; c ++ )
                     
             {
                         
             double  d  =  _distanceCache[ndx,c];
                         
             if  (d  <  min)
                         
             {
                             min 
             =  d;
                             nearest 
             =  c;
                         }
             

                   
                     }
             

                     
             if (nearest ==- 1 )
                     
             {
                         ;
                     }
             

                     
             return  nearest;
                 }
             

                 
             ///   <summary> 
                 
             ///  計(jì)算某數(shù)據(jù)離某聚類中心的距離
                 
             ///   </summary> 
                 
             ///   <param name="coord"></param> 
                 
             ///   <param name="center"></param> 
                 
             ///   <returns></returns> 

                  static   double  getDistance( double [] coord,  double [] center)
                 
             {
                     
             // int len = coord.Length;
                     
             // double sumSquared = 0.0;
                     
             // for (int i = 0; i < len; i++)
                     
             // {
                     
             //     double v = coord[i] - center[i];
                     
             //     sumSquared += v * v;  // 平方差
                     
             // }
                     
             // return Math.Sqrt(sumSquared);
             
                     
             // 也可以用余弦?jiàn)A角來(lái)計(jì)算某數(shù)據(jù)離某聚類中心的距離 
             
                     return   1 -  TermVector.ComputeCosineSimilarity(coord, center);
             
                 }
             
             
                 
             ///   <summary> 
                 
             ///  隨機(jī)初始化k個(gè)聚類
                 
             ///   </summary> 

                  private   void  InitRandom()
                 
             {
                     
             for  ( int  i  =   0 ; i  <  _k; i ++ )
                     
             {
                         
             int  temp  =  _rnd.Next(_coordCount);
                         _clusterAssignments[temp] 
             =  i;  // 記錄第temp個(gè)資料屬于第i個(gè)聚類 
             
                        _clusters[i]  =   new  WawaCluster(temp,_coordinates[temp]);
                     }
             

                 }
             

             }
             

             


            以下是聚類實(shí)體類的定義

             internal   class  WawaCluster
             
            {
                 
             public  WawaCluster( int  dataindex, double [] data)
                 
             {
                     CurrentMembership.Add(dataindex);
                     Mean 
             =  data;
                 }
             

             
                 
             ///   <summary> 
                 
             ///  該聚類的數(shù)據(jù)成員索引
                 
             ///   </summary> 

                  internal  List < int >  CurrentMembership  =   new  List < int > ();
                 
             ///   <summary> 
                 
             ///  該聚類的中心
                 
             ///   </summary> 

                  internal   double [] Mean;
                 
             ///   <summary> 
                 
             ///  該方法計(jì)算聚類對(duì)象的均值 
                 
             ///   </summary> 
                 
             ///   <param name="coordinates"></param> 

                  public   void  UpdateMean( double [][] coordinates)
                 
             {
                     
             //  根據(jù) mCurrentMembership 取得原始資料點(diǎn)對(duì)象 coord ,該對(duì)象是 coordinates 的一個(gè)子集;
                     
             // 然后取出該子集的均值;取均值的算法很簡(jiǎn)單,可以把 coordinates 想象成一個(gè) m*n 的距陣 ,
                     
             // 每個(gè)均值就是每個(gè)縱向列的取和平均值 ,  // 該值保存在 mCenter 中 
             

                     
             for  ( int  i  =   0 ; i  <  CurrentMembership.Count; i ++ )
                     
             {
                         
             double [] coord  =  coordinates[CurrentMembership[i]];
                         
             for  ( int  j  =   0 ; j  <  coord.Length; j ++ )
                         
             {
                             Mean[j] 
             +=  coord[j];  //  得到每個(gè)縱向列的和; 
             
                        } 

                         
             for  ( int  k  =   0 ; k  <  Mean.Length; k ++ )
                         
             {
                             Mean[k] 
             /=  coord.Length;  //  對(duì)每個(gè)縱向列取平均值 
             
                        } 

                     }
             

                 }
             

             }
             

             


            計(jì)算TF/IDF和利用余弦定理計(jì)算相似度的代碼見(jiàn)完整版的代碼下載,那兩部分都是外國(guó)人寫的,里面有它的聯(lián)系方式,不懂的可以問(wèn)他,反正我差不多懂了。

            下面看看咱們的測(cè)試結(jié)果:
            Iteration 0...
            Iteration 1...
            Iteration 2...
            -----------------
            奧運(yùn) 拳擊 入場(chǎng)券 基本 分罄 鄒市明 奪冠 對(duì)手 浮出 水面
            杭州 股民 放 鞭炮 慶祝 印花稅 下調(diào)
            殘疾 女 青年 入圍 奧運(yùn) 游泳 比賽 創(chuàng) 奧運(yùn) 歷史 兩 項(xiàng) 第一
            運(yùn)動(dòng)員 行李 將 “后 上 先 下” 奧運(yùn) 相關(guān) 人員 行李 實(shí)名制
            奧運(yùn) 票務(wù) 網(wǎng)上 成功 訂票 后 應(yīng) 及時(shí) 到 銀行 代售 網(wǎng)點(diǎn) 付款
            -----------------
            股民 要 清楚 自己 的 目的
            印花稅 之 股民 四季
            輸 大錢 的 股民 給 我們 啟迪
            某 心理 健康 站 開張 后 首 個(gè) 咨詢 者 是 位 新 股民
            -----------------
            介紹 一 個(gè) ASP.net MVC 系列 教程
            在 asp.net 中 實(shí)現(xiàn) 觀察者 模式 ,或 有 更 好 的 方法 (續(xù))
            Asp.Net 頁(yè)面 執(zhí)行 流程 分析
            asp.net 控件 開發(fā) 顯示 控件 內(nèi)容
            ASP.NET 自定義 控件 復(fù)雜 屬性 聲明 持久性 淺析 
            聚 類聚的非常準(zhǔn)確,而且只迭代了3次,模型就收斂了,當(dāng)然了這是最理想的效果,其實(shí)聚類的結(jié)果受好多種因素制約,提取特征的算法,隨機(jī)初始化函 數(shù),kmeans算法的實(shí)現(xiàn)等,都有優(yōu)化的地方,不信你把輸入的數(shù)據(jù)的順序改改,聚類結(jié)果就不一樣了,或者把隨機(jī)數(shù)的種子變一下,結(jié)果也不一樣,k- means算法加入一些變異系數(shù)的調(diào)整,結(jié)果也不一樣,提取特征的地方不用TF/IDF權(quán)重算法用別的,結(jié)果肯定也不一樣。
            完整代碼里還有另一組測(cè)試數(shù)據(jù),結(jié)果也很不錯(cuò),我的意思是我的算法不是針對(duì)一組測(cè)試數(shù)據(jù),而是針對(duì)好多數(shù)據(jù)都有不錯(cuò)的結(jié)果。

            總結(jié):數(shù)學(xué)和英語(yǔ)真是寫程序之根本呀,弄這個(gè)東西遇到了好多英語(yǔ)單詞不會(huì),查還查不出來(lái),也理解不了,最后google一看,是個(gè)數(shù)學(xué)專用詞,再搜索這個(gè)數(shù)學(xué)專用詞的中文解釋,發(fā)現(xiàn)還是理解不了那數(shù)學(xué)原理。所以還是得多學(xué)習(xí)數(shù)學(xué)和英語(yǔ)。

            參考鏈接:
            K-MEANS算法
            http://beauty9235.javaeye.com/blog/161675
            什么是變異系數(shù)
            http://zhidao.baidu.com/question/15013015.html
            TF/IDF實(shí)現(xiàn)
            http://www.codeproject.com/KB/cs/tfidf.aspx

             

            源碼下載:WawaTextCluster.zip


            http://www.cnblogs.com/onlytiancai/archive/2008/05/10/1191557.html 《來(lái)源》

            posted on 2012-04-01 07:57 Snape 閱讀(564) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C++ 轉(zhuǎn)載

            導(dǎo)航

            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            統(tǒng)計(jì)

            常用鏈接

            留言簿

            隨筆分類

            隨筆檔案

            文章分類

            文章檔案

            my

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            国内精品久久久久影院网站 | 2022年国产精品久久久久| 狠狠色婷婷久久一区二区| 久久er99热精品一区二区| 亚洲国产二区三区久久| 久久人妻少妇嫩草AV无码蜜桃 | 亚洲第一永久AV网站久久精品男人的天堂AV | 精品无码久久久久国产| 国产亚洲精品美女久久久| 国产精品欧美亚洲韩国日本久久| 久久99精品久久久久久噜噜| 97久久国产露脸精品国产| 国产精品久久国产精品99盘| 久久人妻少妇嫩草AV蜜桃| 无码久久精品国产亚洲Av影片| 久久不射电影网| 久久亚洲sm情趣捆绑调教 | 国内精品久久久久久99蜜桃 | 久久久久久亚洲精品成人| 国产高潮国产高潮久久久91 | jizzjizz国产精品久久| 久久精品国产国产精品四凭| 99久久国产综合精品女同图片| 日本三级久久网| 蜜臀av性久久久久蜜臀aⅴ| 精品久久人人妻人人做精品| 久久久久亚洲AV片无码下载蜜桃 | 精品综合久久久久久88小说| 亚洲精品无码久久久久去q| 久久久久久极精品久久久| 国产亚洲综合久久系列| 区亚洲欧美一级久久精品亚洲精品成人网久久久久| 狠狠综合久久AV一区二区三区| 精品乱码久久久久久夜夜嗨 | 色综合久久天天综线观看| 亚洲国产成人久久精品动漫| 亚洲午夜久久久久妓女影院| 色诱久久av| 久久久久亚洲精品男人的天堂| 久久大香香蕉国产| 久久久久亚洲AV片无码下载蜜桃 |