日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于libsvm的中文文本分类原型

發布時間:2025/4/14 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于libsvm的中文文本分类原型 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

支持向量機(Support Vector Machine)是Cortes和Vapnik于1995年首先提出的,它在解決小樣本?、非線性高維模式識別?中表現出許多特有的優勢,并能夠推廣應用到函數擬合等其他機器學習問題中。支持向量機方法是建立在統計學習理論的VC 維理論和結構風險最小?原理基礎上的,根據有限的樣本信息在模型的復雜性(即對特定訓練樣本的學習精度,Accuracy)和學習能力(即無錯誤地識別任意樣本的能力)之間尋求最佳折衷,以期獲得最好的推廣能力(或稱泛化能力)。SVM理論的學習,請參考jasper的博客?。

??? LIBSVM 是臺灣大學林智仁(Chih-Jen Lin)博士等開發設計的一個操作簡單、易于使用、快速有效的通用 SVM 軟件包,可以解決分類問題(包括 C?SVC 、ν?SVC ), 回歸問題(包括 ε ? SVR 、v? SVR )? 以及分布估計(one ? class ? SVM ) 等問題,提供了線性、多項式、徑向基和 S 形函數四種常用的核函數供選擇,可以有效地解決多類問題、交叉驗證選擇參數、對不平衡樣本加權、多類問題的概率估計等。LIBSVM?是一個開源的軟件包,。他不僅提供了 LIBSVM 的 C++語言的算法源代碼,還提供了 Python、Java、R、MATLAB、Perl、Ruby、LabVIEW以及 C#.net 等各種語言的接口,可以方便的在 Windows 或 UNIX 平臺下使用,也便于科研工作者根據自己的需要進行改進(譬如設計使用符合自己特定問題需要的核函數等)。

??? 文本分類,大致分為如下幾件事情:樣本?,分詞?,特征提取?,向量計算?,分類訓練?,測試和調試?。

?

1.樣本選擇

搜狗語料?http://www.sogou.com/labs/dl/c.html?,下精簡版吧,如果實驗用用,這足夠了,你要下107M的也可以。當然,你也可以自己找語料,不過麻煩點而已,把各大門戶網站的對應頻道下的文章都爬下來。

?

2.分詞

Bamboo分詞,這是基于CRF++的分詞模塊,既然是研究統計學習,分詞也得用基于統計的不是,如果還是用一字典來分詞,那就太out啦。

http://code.google.com/p/nlpbamboo/wiki/GettingStarted?。安裝完畢bamboo,還要下載訓練好的模型(這個模型是基于人民日報1月語料)

http://code.google.com/p/nlpbamboo/downloads/list?,下載index.tar.bz2, 解壓到/opt/bamboo/index下。

因為咱主要目的是研究分類,不是分詞,就不要去搞分詞的訓練了,如果想訓練可以看我的另外一篇博客:CRF++中文分詞指南?。

nlpbamboo安裝的幾個要點

1、CRF++使用默認目錄安裝

2、編譯完nlpbamboo后執行下/opt/bamboo/bin/bamboo看看bamboo是否安裝成功

如果提示ERROR: libcrfpp.so.0: cannot open shared object file: No such file or directory需要執行以下操作

ln -s /usr/local/lib/libcrfpp.so.* /usr/lib/
ldconfig

3、安裝PHP擴展后下載index.tar.bz2這個模型,然后在php.ini中添加

bamboo.parsers = crf_seg

因為官方的 index.tar.bz2 中只包含 crf_seg 的 model,所以不加 crf_pos 那些;否則php將無法


可以試試:/opt/bamboo/bin/bamboo -p crf_seg filename,如果成功證明裝好了。

??? 稍微注意以下,搜狗的詞庫是gb2312的,所以,請轉為utf8,再分詞,這是python寫的函數:輸入一個文件名,轉為utf8,再分詞,分詞文件以.seg為后綴。

[python]?view plaincopy
  • def?seg(fn):??
  • ????if?not?os.path.isfile(fn+'.utf8'):??
  • ????cmd?=?'iconv?-f?gb2312?-t?utf8?-c?%s?>?%s.utf8'?%(fn,fn)??
  • ????print?cmd??
  • ????os.system(cmd)??
  • ????cmd?=?'/opt/bamboo/bin/bamboo?-p?crf_seg?%s.utf8?>?%s.seg'?%?(fn,fn)??
  • ????print?cmd??
  • ????os.system(cmd)???
  • 分詞結果如下:

    一 家 剛剛 成立 兩 年 的 網絡 支付 公司 , 它 的 目標 是 成為 市值 100億 美元 的 上市 公司 。
    這家 公司 叫做 快 錢 , 說 這 句 話 的 是 快錢 的 CEO 關 國光 。 他 之前 曾 任 網易 的 高級 副 總裁 , 負責 過 網易 的 上市 工作 。 對于 為什么 選擇 第三 方 支付 作為 創業 方向 , 他 曾經 對 媒體 這樣 說 : “ 我 能 看到 這個 胡同 對面 是 什么 , 別人 只能 看到 這個 胡同 。 ” 自信 與 狂妄 只 有 一 步 之 遙 ―― 這 幾乎 是 所有 創業者 的 共同 特征 , 是 自信 還是 狂妄 也許 需要 留待 時間 來 考證 。

    ?

    3.特征提取

    ??? svm不是在高維模式識別具有優勢嗎,咋還要特征提取呢,把所有詞都當成特征不就行了嗎?對于詞庫來說,十幾萬的詞是很常見的,把對類別區分度(GDP,CPI,股票對經濟類的區分度就高,其他一些高頻詞,如我們,大家,一起等就沒有區分度)高的詞挑選出來,一來可以減少計算量,二來應該是可以提高分類效果。

    ???? 據說,開方檢驗(CHI)信息增益(IG)對于挑選特征好,我選擇的是CHI。兩者的概念,請google。

    ??? 首先統計詞在文檔中的次數

    [python]?view plaincopy
  • #ingore?some?term??
  • def?ingore(s):??
  • ????return?s?==?'nbsp'?or?s?==?'?'?or?s?==?'?'?or?s?==?'/t'?or?s?==?'/n'?/??
  • ???????????or?s?==?','?or?s?==?'。'?or?s?==?'!'?or?s?==?'、'?or?s?==?'―'/??
  • ???????????or?s?==?'?'??or?s?==?'@'?or?s?==?':'?/??
  • ???????????or?s?==?'#'?or?s?==?'%'??or?s?==?'&'?/??
  • ???????????or?s?==?'('?or?s?==?')'?or?s?==?'《'?or?s?==?'》'?/??
  • ???????????or?s?==?'['?or?s?==?']'?or?s?==?'{'?or?s?==?'}'?/??
  • ???????????or?s?==?'*'?or?s?==?','?or?s?==?'.'??or?s?==?'&'?/??
  • ???????????or?s?==?'!'?or?s?==?'?'?or?s?==?':'?or?s?==?';'/??
  • ???????????or?s?==?'-'?or?s?==?'&'/??
  • ???????????or?s?==?'<'?or?s?==?'>'?or?s?==?'('?or?s?==?')'?/??
  • ???????????or?s?==?'['?or?s?==?']'?or?s?==?'{'?or?s?==?'}'????
  • ?????
  • #term?times??
  • def?getterm(fn):??
  • ????fnobj?=?open(fn,'r')??
  • ????data?=?fnobj.read()??
  • ????fnobj.close()??
  • ????arr?=?data.split('?')??
  • ????docterm?=?dict()??
  • ????for?a?in?arr:?????
  • ????a?=?a.strip('?/n/t')??
  • ????if?not?ingore(a)?and?len(?a.decode('utf-8'))?>=2:??
  • ????????times?=?docterm.get(a)??
  • ????????if?times:??
  • ????????docterm[a]?=?times?+?1??
  • ????????else:??
  • ????????docterm[a]?=?1????????
  • ????return?docte??
  • #cls_term:cls,term,artcount??
  • #term_cls:term,cls,artcount??
  • def?stat(cls,fn,cls_term,term_cls):??
  • ????docterm?=?getterm(fn)??
  • ????termdi?=?cls_term.get(cls)??
  • ????if?not?termdi:??
  • ????termdi??=?dict()??
  • ????cls_term[cls]?=?termdi??
  • ????#term,times??
  • ????for?t?in?docterm.iterkeys():??
  • ????artcount?=?termdi.get(t)??
  • ????if?not?artcount:??
  • ????????artcount?=?0??????
  • ????termdi[k]?=?artcount?+?1??
  • ????clsdi?=?term_cls.get(t)??
  • ????if?not?clsdi:??
  • ????????clsdi?=?{}??
  • ????????term_cls[k]?=?clsdi??
  • ????artcount?=?clsdi.get(cls)??
  • ????if?not?artcount:??
  • ????????artcount?=?0??
  • ????clsdi[cls]?=?artcount?+?1??
  • ?

    分別計算每個詞的a/b/c/d

    a:在這個分類下包含這個詞的文檔數量

    b:不在該分類下包含這個詞的文檔數量

    c:在這個分類下不包含這個詞的文檔數量

    d:不在該分類下,且不包含這個詞的文檔數量

    因為前面統計了每個類下,每個詞,文章數和每個詞,每個類,文章數。所以很容易得到a,b,c,d的值。

    z1 = a*d - b*c
    x2 = (z1 * z1 * float(N)) /( (a+c)*(a+b)*(b+d)*(c+d) )

    ?

    計算之后,排序,并取出前1000個詞(這里指的每個類別的特征詞)。

    li = sorted(termchi.iteritems(), key=lambda d:d[1], reverse = True)

    循環每個分類,并把每個類別的特征合并(合并成一個文件,作為特征詞典),合并后存為feature文件,第一列是序號,第二列是對應的詞,序號就是特征號。

    1?????? 逐項
    2?????? 深市
    3?????? 九寨溝
    4?????? 島內
    5?????? 期望
    6?????? 第20分鐘
    7?????? 合理
    8?????? 謝杏芳
    9?????? 賽迪
    10????? 毛澤東

    ?

    注:特征選擇的目的就是選擇在該類下,不在其他類下的特征,但是重復是避免不了的,合并的文件肯定是排重過的。先選擇每個類下的1000個詞,假如10個類,則共選擇10 * 1000個詞,然后去重,并生成特征的唯一id。

    ?

    4.訓練和測試樣本組織

    搜狐語料的1990篇中的1890作為訓練集,100篇作為測試集,分別形成train和test文件,libsvm的訓練集的格式為:

    lable1 index1:featureValue1 index2:featureValue2 index3:featureValue3 ...

    lable2 index1:featureValue1 index2:featureValue2 index3:featureValue3 ...

    對應到文本分類上就是:類別ID 特征序號(第3步計算的特征序號):特征值(TFIDF值)......

    如,我摘了一行,這是一篇文章的例子,8就是類別ID,189是特征“189 指導"的序號,0.171153是特征值:

    8 189:0.171153 253:0.081381 298:0.630345 504:0.135512 562:79.423503 578:0.072219 698:0.078896 710:0.036074 740:0.215368 868:0.263524 1336:0.114355 1365:0.076494 1372:0.085780 1555:0.572497 1563:3.932806 1598:0.114717 1685:0.129870 1972:0.193693 2282:0.061828 2865:0.026699 2897:0.099020 3040:0.039621 3041:0.258073 3191:0.091276 3377:0.125544 3454:0.062189 3623:0.139698 3653:0.128304 3932:2.990233 4353:0.202133 4394:0.312992 4420:0.356354 4424:0.482424 4522:0.447795 4675:3.618182 4767:0.065334 4848:0.270417 4875:0.213588 4941:0.407453 5004:0.070447 5125:0.717893 5214:3.222299 5250:0.052897 5251:0.281352 5310:2.010101 5357:0.203956 5474:0.034037 5504:0.193900 5861:0.859426 6120:1.320504 6129:0.107941 6364:0.184225 6373:0.287843 6379:0.080727 6385:0.712241 6847:0.209023 7007:0.147802 7121:1.320504 7547:0.248161 7636:0.108981

    采用TFIDF的算法,數據處理和特征選擇類似,計算每個類,每篇文檔,每個詞的次數,以包含這個詞的文檔數。每篇文章的每個特征項,用TF/DF的值作為特征值。(后記:用TF * IDF,然后用svm-scale縮放到0,1之間,效果比TF/DF要好,準確率能達到82%。,計算方式如下:

    ??? tf = float(times) / total
    ??? idf = math.log( N / float(term_count[term]) )
    ??? term_times[term] = tf * idf

    ?

    [python]?view plaincopy
  • #doc_term:?class?doc?term?times??
  • #term_doc:?term?doccount??
  • def?tfidf(doc_term,term_doc):??
  • ????print?'begin?compute?tf?*?idf'??
  • ????for?cls,docdi?in?doc_term.iteritems():??
  • ????for?doc,termdi?in?docdi.iteritems():??
  • ????????total?=?0??
  • ????????for?term,times?in?termdi.iteritems():??
  • ????????total?+=?times??
  • ????????for?term,times?in?termdi.iteritems():??
  • ????????tf?=?float(times)?/?total??
  • ????????df?=?float(term_doc[term])?/?N??
  • ????????termdi[term]?=?tf?/?df??
  • ?

    注意:用CHI是提取類別的特征詞,而這里用TFIDF是計算文檔的特征向量,前者是要體現類別的區分度,后者要體現文檔的區分度,兩者概念和所做的事情不一樣,所以采用的方法也不一樣。

    ?

    5.用libsvm訓練

    ??? 你看,忙活了半天,還沒有到libsvm呢,其實前面幾步很麻煩的,libsvm的資料不少,但是都是一個幾行數據的簡單例子,這不具有實際應用的價值,只有把樣本,分詞,特征提取/特征計算搞定了,分類才能做好。

    ??? 下載libsvm:http://www.csie.ntu.edu.tw/~cjlin/cgi-bin/libsvm.cgi?+http://www.csie.ntu.edu.tw/~cjlin/libsvm+zip

    ??? 解壓,make

    ??? svm-scale:特征縮放的工具??? svm-train:訓練工具? ?? svm-predict:測試工具

    ??? toos/grid.py:尋找參數的工具

    ??? 用默認參數試試:

    ?? ./svm-train train.s model.s

    ?? ./svm-predict test.s model.s result.s

    ?? 結果

    ?? Accuracy = 74.3889% (1339/1800) (classification)

    ?? 不算太理想,也不算太差。如果只是2個類,結果能到95%。我想可以從如下幾個方面改進:

    • 增加分詞的樣本數,訓練更好的分詞模型。
    • 特征提取后,用人工進行調整,因為很多詞對于類別區分度不高。
    • 用grid.py尋找合適的參數。

    ?

    參考資料:

    jasper的博客,SVM理論的學習資料:http://www.blogjava.net/zhenandaci/category/31868.html

    通俗易懂,要好好讀讀。

    ?

    libsvm的官方網站:http://www.csie.ntu.edu.tw/~cjlin/libsvm/

    看了理論性的東西,最好實踐以下,libsvm就是很好的實踐工具。

    ?

    Vapnik的兩本書,我買了第二本,發現公式太多,好晦澀。準備買第一本,據說第一本比較淺顯易懂一些

    《統計學習理論的本質》

    http://product.dangdang.com/product.aspx?product_id=20602023&ref=search-0-A

    《統計學習理論》

    http://product.dangdang.com/product.aspx?product_id=20529098&ref=search-0-A

    總結

    以上是生活随笔為你收集整理的基于libsvm的中文文本分类原型的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。