機器學習之主題詞分類【以點評信息為例】

使用到的是機器學習中的一個方向:分類。分類結果是離散的。

每個人每天都會有很多分類的意識,比如,看到一個人的背影不由地會根據衣著、發型、步態來判斷這個人的性別,判別完性別后,你還會根據身材的高低胖瘦來判斷是不是個美女或者帥哥。當然也有很多非主流,影響了我們的判斷。所以分類不能達到百分之百的正確性。

1.

最初形態是由之前同事實現的一版

使用的算法:TextCNN, 全名 卷積神經網絡。比較早的文本分類算法。

這一個版本效果一般、訓練時間比較長。部署的這個版本,對系統要求較高,必須是Fedora,還要部署cuda架構來滿足gpu的計算。

這個版本效果不好的原因,并不是算法的選取,而是文本的預處理以及最后的生成tag的處理過程需要更多的精力。

2.

使用了R語言里的knn驗證性地實現了一個版本,這個版本的效果也一般,后來為了以后維護起來方便,放棄使用r語言的方案。

這個方案有點是各種算法使用起來簡單、方便,缺點是使用的人比較少,占用資源比較大。

3.

回歸到Python實現的版本,接受建華的建議,我跟楊sir同時調研了Python里的一個算法庫sklearn,這個庫使用的人比較多維護的也很好,包含的算法也都能滿足本次分類。

初期方案是我調研nbc,樸素貝葉斯算法;楊sir調研決策樹。在準確率上來看,這兩個算法都有比較優秀的表現,決策樹的準確率略高于nbc。
以下是遇到的一些問題及解決方法:

3.1

最初的識別分類是對一整段評論做分類,一個點評只出一個標簽。這顯然不能應對那種喜歡長篇大論的點評人,比如:

之前看了很多攻略,心里有了準備,很小,不過本人不是大款,國內基本都是如家,所以這里的房間面積額我都可以接受,洗手間確實小了點但是夠用,房間2個人也基本夠用,地理位置絕b嘎嘎的,呆了三天完全沒有打車,除了去圣淘沙以外,小印度,克拉克碼頭,和獅子魚以及摩天輪,都是從酒店步行的,第一天步行了20公里,第二天步行了10公里左右,對于我這種暴走族來說不算什么,還能體驗鄉土人情,周圍居民區吃的很多,尤其酒店后方,還有北京人家,東北菜,和超級大的大排檔,步行10分鐘吧,樓下就是一個小排檔,味道不錯,有一個檔口的廚師是個東北來的,很搞笑,酒店在地鐵站上面,出地鐵下雨不被淋這個無敵了

這個點評里出現的評論項包括房間大小、洗手間、位置、周圍環境。如果這條點評只出一個標簽的話,就太對不起評論人了。明明提供了這么長豐富的內容卻用不到。

3.2

要想出多個標簽,就需要對點評內容分割。如何分割也成了一個問題。

按照標點符號(,。!?,.)來分割,比如上邊的那段點評就能分出來很多比較有意義的段落,比如:洗手間確實小了點但是夠用、味道不錯。同時也分出來了一些完全沒有意義的段落,比如:小印度、很小。

如果看到點評的原始數據,大家會發現點評中文本的復雜組合遠遠超出想象。如果出現7.20-7.24入住的點評片段,那就會被剛才的規則分成了7、20、7、24這種完全沒有意義的段落。

有的人喜歡用~符號來代替自己的,。全文的標點符號只有~ 。還有很多意想不到的點評。

針對各種規則詭異的點評數據,目前使用的預處理方案是:

  • 1、按照(,.!?,。!?~()、;……)分割點評文本;
  • 2.去掉(0123456789-)這些字符;
  • 3.如果一個片段只有1、2個漢字,就直接丟掉,如果小于7個漢字會和下一個片段結合為一組片段。

根據這些規則處理后,點評數據就被分成了很多的小片段。

3.3

進入分類階段

3.3.1

處理訓練集,首先要進行切詞,每個點評會對應一批詞語,會把出現次數最少的top5%當成停用詞。防止一些詞語產生較大的噪點。

3.3.2

生成詞語向量并訓練的參數調節。Max_df/min_df/alpha等參數的調節。Alpha是平滑參數。

3.3.3

識別分類。相當于把每一條的點評片段分詞后,放到訓練數據集生成的大坐標系中,計算被分到每一個tag類別的概率,直接能得到所屬最大概率的tag就是本次被分到的類別。這就完成了識別分類的過程。
在分類階段,有一個中間結果很重要,就是該片段到每一個tag的概率,記做X。

3.4

后期處理階段

該階段會把分類結果跟點評內容、所屬酒店 對起來,同時會對每個點評片段分類結果進行打分。

打分方式:

  • 1.根據X中給出的各個概率值,計算出一個方差fc,fc就表征了點評片段屬于各個tag的區分度,區分度越高,分類效果越好。
  • 2.根據最高的概率值x,x值越大越好,但是x是負值,所以絕對值是越小越好。

一個簡單的公式 Score=abs(fc/x) 就表示了剛才所屬的fc越大越好,|x|越小越好的意圖。這個就可以叫做“可信度

再有一些處理操作就是根據pm的需求,對酒店、點評粒度做一些額外的處理。

去重:pm要求每個點評出現的標簽,不能重復,取score較高的。

取酒店的tag:取出好評標簽前20條,差評標簽前10條。

解決同質化問題:目前還在調研階段,有多種方案,1.強行去掉最多的top4個tag,剩下的tag按照點評數競爭展示;2.純粹的tfidf算法計算得分;3.只有點評數大于5,才帶入tfidf算法,參與展示競爭。
cc

這個圖片中,越平滑、x軸覆蓋率越高 越好。黑色曲線是純tfidf,紅色曲線是有閾值tfidf,綠色曲線是去除top4的tag曲線,黃色的全部的tag展示曲線。

后續還有很多其他的各種問題,未完待續。

遇到的問題:

標注數據不夠:前期的標注數據去重后只有幾萬條,為了得到更多的標注數據,采用了多次迭代取出可信度極高的點評片段和tag,當成標注數據,再次進行訓練分類。

標注數據不準:后來使用國內已分類的點評數據來作為國際酒店點評的標注數據。由于國內的點評分類是使用第三方分類公司給出的結果,本身就有誤差,而我們再次使用包含誤差的數據作為我們的標準數據來用,會把誤差放大很多倍,導致有部分標簽的識別完全沒法使用。

4.

和其他已成熟團隊效果對比

他們的優勢在于數據積累較深,有很多優秀的標注數據以及人工團隊來做數據的清洗,而我們的優勢在于專注于自己內容的特點,可以制定出更合理、更有針對性的方案來完善分類效果。
接下來要做的就是清洗標注數據,可以用增加數據量來沖淡有誤差的數據,也可以人工去除臟數據。

5.

總結:

各個環節重要度:預處理50%、分類算法10%、后期處理30%,其他10%。

這也是精力分配的比例、難度比例。

標注數據、標注數據、標注數據。

6.

簡單介紹knn、nbc

6.1

knn:跟預測點距離最近的k個點,對類別進行投票,來區分預測點所屬的類別。

看一個二分類的例子圖片
aa

在使用時需要做兩個調優:1.距離計算公式;2.k值。
距離計算一般要注意的事項是,維度的選擇、每個維度坐標值的歸一化處理。在一個二維坐標系中計算兩個點的距離公式大家都知道:√(〖(x_1-x_2)〗^2+(〖y_1-y_2)〗^2 )
bb

k值的選擇,要根據分類效果來做微調。

6.2

nbc:樸素貝葉斯

首先舉個貝葉斯公式的例子:

一所學校里面有 60% 的男生,40% 的女生。男生總是穿長褲,女生則一半穿長褲一半穿裙子。有了這些信息之后我們可以容易地計算“隨機選取一個學生,他(她)穿長褲的概率和穿裙子的概率是多大”,這個就是前面說的“正向概率”的計算。然而,假設你走在校園中,迎面走來一個穿長褲的學生(很不幸的是你高度近似,你只看得見他(她)穿的是否長褲,而無法確定他(她)的性別),你能夠推斷出他(她)是男生的概率是多大嗎?

擴展到文本分類中,可以看到,某一個單詞屬于某一個類別的概率是多少,是由前期的訓練數據訓練出來的。這時候就有一個問題,每個詞語都是有一定的前后文關系的,比如 很贊吧但是浴室很小 切詞后是由【很贊、浴室、但是、很小】這些詞組成,由于沒有前后文關系,可能會被識別成浴室很贊。這種問題怎么辦。這就要使用樸素貝葉斯的思想,不解決。我們假設詞語沒有前后文關系。那么這個問題就變的簡單多了,我們就看每個詞語的單獨概率。前邊訓練出詞語屬于某個類別的概率后,分類時就可以帶入計算得到屬于這個類別的概率值。

參考帖子:

knn:http://coolshell.cn/articles/8052.html

nbc: http://blog.csdn.net/pongba/article/details/2958094

nbc:http://www.cnblogs.com/leoo2sk/archive/2010/09/17/naive-bayesian-classifier.html

shi.qi

發表評論

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: