pyhanlp 文本分类与情感分析
這一次我們需要利用HanLP進(jìn)行文本分類(lèi)與情感分析。同時(shí)這也是pyhanlp用戶指南的倒數(shù)第二篇關(guān)于接口和Python實(shí)現(xiàn)的文章了,再之后就是導(dǎo)論,使用技巧匯總和幾個(gè)實(shí)例落。真是可喜可賀啊。
文本分類(lèi)
在HanLP中,文本分類(lèi)與情感分析都是使用一個(gè)分類(lèi)器,樸素貝葉斯分類(lèi)器。或許這個(gè)分類(lèi)器還算是比較一般,不過(guò)從最終結(jié)果來(lái)看效果還是很可以的。
因?yàn)榈讓硬捎迷~袋模式,所以當(dāng)文本較大時(shí)可能會(huì)是內(nèi)存開(kāi)效果大,不過(guò)沒(méi)關(guān)系,作者預(yù)先寫(xiě)了一個(gè)特征檢測(cè)的方法。使用卡方檢測(cè),利用閾值來(lái)過(guò)濾特征,減少內(nèi)存的開(kāi)銷(xiāo)。
原作者只給了文本分類(lèi)的例子,這里我們對(duì)原來(lái)的例子稍加改造,使其更適用分類(lèi)任務(wù)。
語(yǔ)料庫(kù)
本文語(yǔ)料庫(kù)特指文本分類(lèi)語(yǔ)料庫(kù),對(duì)應(yīng)IDataSet接口。而文本分類(lèi)語(yǔ)料庫(kù)包含兩個(gè)概念:文檔和類(lèi)目。一個(gè)文檔只屬于一個(gè)類(lèi)目,一個(gè)類(lèi)目可能含有多個(gè)文檔。比如搜狗文本分類(lèi)語(yǔ)料庫(kù)迷你版.zip,下載前請(qǐng)先閱讀搜狗實(shí)驗(yàn)室數(shù)據(jù)使用許可協(xié)議。
數(shù)據(jù)格式
分類(lèi)語(yǔ)料的根目錄.目錄必須滿足如下結(jié)構(gòu):
文件不一定需要用數(shù)字命名,也不需要以txt作為后綴名,但一定需要是文本文件.
分詞
目前,本系統(tǒng)中的分詞器接口一共有兩種實(shí)現(xiàn): BigramTokenizer and HanLPTokenizer。
但文本分類(lèi)是否一定需要分詞?答案是否定的。 我們可以順序選取文中相鄰的兩個(gè)字,作為一個(gè)“詞”(術(shù)語(yǔ)叫bigram)。這兩個(gè)字在數(shù)量很多的時(shí)候可以反映文章的主題(參考清華大學(xué)2016年的一篇論文《Zhipeng Guo, Yu Zhao, Yabin Zheng, Xiance Si, Zhiyuan Liu, Maosong Sun. THUCTC: An Efficient Chinese Text Classifier. 2016》)。這在代碼中對(duì)應(yīng)BigramTokenizer. 當(dāng)然,也可以采用傳統(tǒng)的分詞器,如HanLPTokenizer。 另外,用戶也可以通過(guò)實(shí)現(xiàn)ITokenizer來(lái)實(shí)現(xiàn)自己的分詞器,并通過(guò)IDataSet#setTokenizer來(lái)使其生效
特征提取
特征提取指的是從所有詞中,選取最有助于分類(lèi)決策的詞語(yǔ)。理想狀態(tài)下所有詞語(yǔ)都有助于分類(lèi)決策,但現(xiàn)實(shí)情況是,如果將所有詞語(yǔ)都納入計(jì)算,則訓(xùn)練速度將非常慢,內(nèi)存開(kāi)銷(xiāo)非常大且最終模型的體積非常大。
本系統(tǒng)采取的是卡方檢測(cè),通過(guò)卡方檢測(cè)去掉卡方值低于一個(gè)閾值的特征,并且限定最終特征數(shù)不超過(guò)100萬(wàn)。
預(yù)測(cè)
classify方法直接返回最可能的類(lèi)別的String形式,而predict方法返回所有類(lèi)別的得分(是一個(gè)Map形式,鍵是類(lèi)目,值是分?jǐn)?shù)或概率),categorize方法返回所有類(lèi)目的得分(是一個(gè)double數(shù)組,分類(lèi)得分按照分類(lèi)名稱(chēng)的字典序排列),label方法返回最可能類(lèi)目的字典序。
線程安全性
類(lèi)似于HanLP的設(shè)計(jì),以效率至上,本系統(tǒng)內(nèi)部實(shí)現(xiàn)沒(méi)有使用任何線程鎖,但任何預(yù)測(cè)接口都是線程安全的(被設(shè)計(jì)為不儲(chǔ)存中間結(jié)果,將所有中間結(jié)果放入?yún)?shù)棧中)。
from pyhanlp import SafeJClass import zipfile import os from pyhanlp.static import download, remove_file, HANLP_DATA_PATH# 設(shè)置路徑,否則會(huì)從配置文件中尋找 HANLP_DATA_PATH = "/home/fonttian/Data/CNLP"""" 獲取測(cè)試數(shù)據(jù)路徑,位于$root/data/textClassification/sogou-mini, 根目錄由配置文件指定,或者等于我們前面手動(dòng)設(shè)置的HANLP_DATA_PATH。 """ DATA_FILES_PATH = "textClassification/sogou-mini"def test_data_path():data_path = os.path.join(HANLP_DATA_PATH, DATA_FILES_PATH)if not os.path.isdir(data_path):os.mkdir(data_path)return data_pathdef ensure_data(data_name, data_url):root_path = test_data_path()dest_path = os.path.join(root_path, data_name)if os.path.exists(dest_path):return dest_pathif data_url.endswith('.zip'):dest_path += '.zip'download(data_url, dest_path)if data_url.endswith('.zip'):with zipfile.ZipFile(dest_path, "r") as archive:archive.extractall(root_path)remove_file(dest_path)dest_path = dest_path[:-len('.zip')]return dest_pathNaiveBayesClassifier = SafeJClass('com.hankcs.hanlp.classification.classifiers.NaiveBayesClassifier') IOUtil = SafeJClass('com.hankcs.hanlp.corpus.io.IOUtil') sogou_corpus_path = ensure_data('搜狗文本分類(lèi)語(yǔ)料庫(kù)迷你版','http://hanlp.linrunsoft.com/release/corpus/sogou-text-classification-corpus-mini.zip')def train_or_load_classifier(path):model_path = path + '.ser'if os.path.isfile(model_path):return NaiveBayesClassifier(IOUtil.readObjectFrom(model_path))classifier = NaiveBayesClassifier()classifier.train(sogou_corpus_path)model = classifier.getModel()IOUtil.saveObjectTo(model, model_path)return NaiveBayesClassifier(model)def predict(classifier, text):print("《%16s》\t屬于分類(lèi)\t【%s】" % (text, classifier.classify(text)))# 如需獲取離散型隨機(jī)變量的分布,請(qǐng)使用predict接口# print("《%16s》\t屬于分類(lèi)\t【%s】" % (text, classifier.predict(text)))if __name__ == '__main__':classifier = train_or_load_classifier(sogou_corpus_path)predict(classifier, "C羅壓梅西內(nèi)馬爾蟬聯(lián)金球獎(jiǎng) 2017=C羅年")predict(classifier, "英國(guó)造航母耗時(shí)8年仍未服役 被中國(guó)速度遠(yuǎn)遠(yuǎn)甩在身后")predict(classifier, "研究生考錄模式亟待進(jìn)一步專(zhuān)業(yè)化")predict(classifier, "如果真想用食物解壓,建議可以食用燕麥")predict(classifier, "通用及其部分競(jìng)爭(zhēng)對(duì)手目前正在考慮解決庫(kù)存問(wèn)題")print("\n 我們這里再用訓(xùn)練好的模型連測(cè)試一下新的隨便從網(wǎng)上找來(lái)的幾個(gè)新聞標(biāo)題 \n")predict(classifier, "今年考研壓力進(jìn)一步增大,或許考研正在變成第二次高考")predict(classifier, "張繼科被劉國(guó)梁連珠炮喊醒:醒醒!奧運(yùn)會(huì)開(kāi)始了。")predict(classifier, "福特終于開(kāi)竅了!新車(chē)1.5T懟出184馬力,不足11萬(wàn),思域自愧不如") 《C羅壓梅西內(nèi)馬爾蟬聯(lián)金球獎(jiǎng) 2017=C羅年》 屬于分類(lèi) 【體育】 《英國(guó)造航母耗時(shí)8年仍未服役 被中國(guó)速度遠(yuǎn)遠(yuǎn)甩在身后》 屬于分類(lèi) 【軍事】 《 研究生考錄模式亟待進(jìn)一步專(zhuān)業(yè)化》 屬于分類(lèi) 【教育】 《如果真想用食物解壓,建議可以食用燕麥》 屬于分類(lèi) 【健康】 《通用及其部分競(jìng)爭(zhēng)對(duì)手目前正在考慮解決庫(kù)存問(wèn)題》 屬于分類(lèi) 【汽車(chē)】我們這里再用訓(xùn)練好的模型連測(cè)試一下新的隨便從網(wǎng)上找來(lái)的幾個(gè)新聞標(biāo)題 《今年考研壓力進(jìn)一步增大,或許考研正在變成第二次高考》 屬于分類(lèi) 【教育】 《張繼科被劉國(guó)梁連珠炮喊醒:醒醒!奧運(yùn)會(huì)開(kāi)始了。》 屬于分類(lèi) 【體育】 《福特終于開(kāi)竅了!新車(chē)1.5T懟出184馬力,不足11萬(wàn),思域自愧不如》 屬于分類(lèi) 【汽車(chē)】從我們最后自己增加的幾個(gè)新聞標(biāo)題來(lái)看,分類(lèi)器的效果相當(dāng)?shù)暮谩_@多虧了word2vec。
情感分析
我們對(duì)于情感分析的實(shí)現(xiàn)與之前的文本分類(lèi)具有高度的相似性,同時(shí)剛剛也提到了,實(shí)際上他們就是用的一個(gè)分類(lèi)器。而在python的實(shí)現(xiàn)中,他們則幾乎一模一樣。
也正是因?yàn)槿绱?#xff0c;所以只要我們擁有同樣格式的語(yǔ)料,那么我們可以使用這個(gè)分類(lèi)器做任何我們需要的文本分類(lèi)
語(yǔ)料來(lái)源
可以利用文本分類(lèi)在情感極性語(yǔ)料上訓(xùn)練的模型做淺層情感分析。目前公開(kāi)的情感分析語(yǔ)料庫(kù)有:中文情感挖掘語(yǔ)料-ChnSentiCorp,語(yǔ)料發(fā)布者為譚松波。
""" 獲取測(cè)試數(shù)據(jù)路徑,位于$root/data/textClassification/sogou-mini, 根目錄由配置文件指定,或者等于我們前面手動(dòng)設(shè)置的HANLP_DATA_PATH。 ChnSentiCorp評(píng)論酒店情感分析 """ DATA_FILES_PATH = "sentimentAnalysis/ChnSentiCorp"if __name__ == '__main__':ChnSentiCorp_path = ensure_data('酒店評(píng)論情感分析', \'http://hanlp.linrunsoft.com/release/corpus/ChnSentiCorp.zip')# 此處感謝網(wǎng)友給出的下載鏈接# 本文示例中,如果需要使用本地資料,請(qǐng)通過(guò)上面的DATA_FILES_PATH變量控制classifier = train_or_load_classifier(ChnSentiCorp_path)predict(classifier, '距離川沙公路較近,但是公交指示不對(duì),如果是"蔡陸線"的話,會(huì)非常麻煩.建議用別的路線.房間較為簡(jiǎn)單.')predict(classifier, "商務(wù)大床房,房間很大,床有2M寬,整體感覺(jué)經(jīng)濟(jì)實(shí)惠不錯(cuò)!")predict(classifier, "標(biāo)準(zhǔn)間太差 房間還不如3星的 而且設(shè)施非常陳舊.建議酒店把老的標(biāo)準(zhǔn)間從新改善.")predict(classifier, "服務(wù)態(tài)度極其差,前臺(tái)接待好象沒(méi)有受過(guò)培訓(xùn),連基本的禮貌都不懂,竟然同時(shí)接待幾個(gè)客人")print("\n 我們這里再用訓(xùn)練好的模型連測(cè)試一下我自己編的‘新的’的文本 \n")predict(classifier, "服務(wù)態(tài)度很好,認(rèn)真的接待了我們,態(tài)度可以的!")predict(classifier, "有點(diǎn)不太衛(wèi)生,感覺(jué)不怎么樣。") 《距離川沙公路較近,但是公交指示不對(duì),如果是"蔡陸線"的話,會(huì)非常麻煩.建議用別的路線.房間較為簡(jiǎn)單.》 屬于分類(lèi) 【正面】 《商務(wù)大床房,房間很大,床有2M寬,整體感覺(jué)經(jīng)濟(jì)實(shí)惠不錯(cuò)!》 屬于分類(lèi) 【正面】 《標(biāo)準(zhǔn)間太差 房間還不如3星的 而且設(shè)施非常陳舊.建議酒店把老的標(biāo)準(zhǔn)間從新改善.》 屬于分類(lèi) 【負(fù)面】 《服務(wù)態(tài)度極其差,前臺(tái)接待好象沒(méi)有受過(guò)培訓(xùn),連基本的禮貌都不懂,竟然同時(shí)接待幾個(gè)客人》 屬于分類(lèi) 【負(fù)面】我們這里再用訓(xùn)練好的模型連測(cè)試一下我自己編的‘新的’的文本 《服務(wù)態(tài)度很好,認(rèn)真的接待了我們,態(tài)度可以的!》 屬于分類(lèi) 【正面】 《 有點(diǎn)不太衛(wèi)生,感覺(jué)不怎么樣。》 屬于分類(lèi) 【負(fù)面】參考
HanLP文本分類(lèi)與情感分析-wiki
總結(jié)
以上是生活随笔為你收集整理的pyhanlp 文本分类与情感分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: pyhanlp 两种依存句法分类器
- 下一篇: pyhanlp 文本聚类