Python實(shí)現(xiàn)基于Fasttext的商品評(píng)論數(shù)據(jù)分類的操作流程
在以往的文本分類型的任務(wù)中,基本的流程主要是就是:
- 文本數(shù)據(jù)加載
- 數(shù)據(jù)清洗
- 分詞
- 向量化
- 分類模型訓(xùn)練
- 性能評(píng)估
這里面比如向量化和模型搭建是獨(dú)立的兩個(gè)節(jié)點(diǎn),可以自由地進(jìn)行設(shè)計(jì),當(dāng)然了也是一份工作量,今天使用的fasttext更像是一個(gè)集成的庫(kù),把向量化和分類一起做掉了,這個(gè)對(duì)于使用層面來講就更方便了一些,不過也并不是絕對(duì)的,一般經(jīng)驗(yàn)來說,封裝程度越高的庫(kù)對(duì)于個(gè)性化的開發(fā)越不友好,但是如果僅僅只是使用一下就行,能夠?qū)崿F(xiàn)自己的功能這樣的想法的話倒是可以使用這種類型的庫(kù)的,總之,沒有絕對(duì)的最優(yōu),只有適合自己的模型。
本文主要也是基于具體的應(yīng)用來體驗(yàn)fasttext,整體流程如下:

為了清晰展示流程,這里我用不同的顏色來標(biāo)識(shí)不同的功能部分:
綠色部分為數(shù)據(jù)采集部分,這部分由于部分原因無法開放到這里
藍(lán)色部分為數(shù)據(jù)處理部分,這部分主要完成原始數(shù)據(jù)的清洗分詞等工作
黃色部分主要是實(shí)例化調(diào)用fasttext提供的模型來完成分類評(píng)估等工作
首先看下原始數(shù)據(jù)樣例如下:
{
'_id': '4c671f75cc20b28264c30c2ef158f32b',
'guid': 'b2422b96a015b85d9a47c83e65f01987',
'content': 'iPhone13收到了,很喜歡的蘋果手機(jī),一直都是蘋果的忠實(shí)粉絲。13手機(jī)外觀真的太驚艷了,最新款的手機(jī)就是不一樣,非常的好看!午夜色也是很驚艷的,是我很喜歡的顏色。外觀設(shè)計(jì)非常的好看,小巧精致,很喜歡iPhone的產(chǎn)品。新款的相機(jī)非常好,拍攝效果強(qiáng)大,很適合愛美的女生拍照。拍視頻的電影模式也是非常驚艷,真的太棒了,濾鏡自帶美顏效果,非常特別!前置攝像頭也有亮點(diǎn),優(yōu)化升級(jí),升級(jí)后的像素真的超棒!萌萌的攝像頭,手機(jī)大小合適,握著手感很舒服。屏幕非常細(xì)膩,通透,屏幕很喜歡!新一代運(yùn)行速度快了很多,系統(tǒng)非常流暢,屏幕120hz刷新率。電池也還不錯(cuò),正常使用,續(xù)航能力還是挺久的,玩游戲也不會(huì)發(fā)燙。買了套裝一年延保的,感覺還是很不錯(cuò)的!A15速度還是很快的,加上iOS15的加持,手機(jī)很流暢,使用了一周了,手機(jī)各方面都很不錯(cuò)!',
'creationTime': '2021-11-2907: 13: 51',
'isDelete': False,
'isTop': False,
'userImageUrl': 'misc.360buyimg.com/user/myjd-2015/css/i/peisong.jpg',
'topped': 0,
'replies': [
{
'id': 946189091,
'commentId': 16739194625,
'content': '謝謝您對(duì)本店的支持,我們會(huì)不斷的努力,爭(zhēng)取做的更好,我們成長(zhǎng)的路上有您的支持,我們表示感謝,歡迎再次光臨。祝您生活愉快,合家安康!',
'pin': 'jd_oMFlwVDJJjkA',
'userClient': 98,
'userImage': 'misc.360buyimg.com/user/myjd-2015/css/i/peisong.jpg',
'ip': '115.207.85.31',
'productId': 10039695828478,
'replyList': [
],
'nickname': 'jd_oMFlwVDJJjkA',
'creationTime': '2021-11-2910: 10: 54',
'parentId': 0,
'targetId': 0,
'venderShopInfo': {
'id': 10706414,
'appName': '//mall.jd.com/index-10706414.html',
'title': '京東之家官方旗艦店',
'venderId': 10955089
}
}
],
'replyCount': 28,
'score': 5,
'imageStatus': 1,
'usefulVoteCount': 28,
'userClient': 4,
'discussionId': 1006752884,
'imageCount': 8,
'anonymousFlag': 1,
'plusAvailable': 201,
'mobileVersion': '10.2.4',
'mergeOrderStatus': 2,
'productColor': '128G午夜色',
'productSize': '套裝五:搭配店鋪延保一年',
'textIntegral': 40,
'imageIntegral': 40,
'status': 1,
'referenceId': '10039695828478',
'referenceTime': '2021-11-0802: 31: 34',
'nickname': 'z***a',
'replyCount2': 39,
'userImage': 'misc.360buyimg.com/user/myjd-2015/css/i/peisong.jpg',
'orderId': 0,
'integral': 80,
'productSales': '[
]',
'referenceImage': 'jfs/t1/124476/38/25971/146827/622b14cfEec332c92/75f5bf4417c1fd1d.jpg',
'referenceName': '【12期免息可選】Apple蘋果iPhone13(A2634)全網(wǎng)通5G手機(jī)128G綠色套裝一:搭配90天品勝碎屏保障',
'firstCategory': 9987,
'secondCategory': 653,
'thirdCategory': 655,
'aesPin': None,
'days': 21,
'afterDays': 0,
'comp_con': 'iPhone13收到了很喜歡的蘋果手機(jī)一直都是蘋果的忠實(shí)粉絲13手機(jī)外觀真的太驚艷了最新款的手機(jī)就是不一樣非常的好看午夜色也是很驚艷的是我很喜歡的顏色外觀設(shè)計(jì)非常的好看小巧精致很喜歡iPhone的產(chǎn)品新款的相機(jī)非常好拍攝效果強(qiáng)大很適合愛美的女生拍照拍視頻的電影模式也是非常驚艷真的太棒了濾鏡自帶美顏效果非常特別前置攝像頭也有亮點(diǎn)優(yōu)化升級(jí)升級(jí)后的像素真的超棒萌的攝像頭手機(jī)大小合適握著手感很舒服屏幕非常細(xì)膩通透屏幕很喜歡新一代運(yùn)行速度快了很多系統(tǒng)非常流暢屏幕120hz刷新率電池也還不錯(cuò)正常使用續(xù)航能力還是挺久的玩游戲也不會(huì)發(fā)燙買了套裝一年延保的感覺還是很不錯(cuò)的A15速度還是很快的加上iOS15的加持手機(jī)很流暢使用了一周了手機(jī)各方面都很不錯(cuò)',
'label': 1,
'cut_li': [
'iPhone',
'13',
'收到',
'喜歡',
'蘋果',
'手機(jī)',
'一直',
'蘋果',
'忠實(shí)',
'粉絲',
'13',
'手機(jī)',
'外觀',
'真的',
'太',
'驚艷',
'最新款',
'手機(jī)',
'非常',
'好看',
'午夜',
'色',
'驚艷',
'喜歡',
'顏色',
'外觀設(shè)計(jì)',
'非常',
'好看',
'小巧',
'精致',
'喜歡',
'iPhone',
'產(chǎn)品',
'新款',
'相機(jī)',
'非常',
'拍攝',
'效果',
'強(qiáng)大',
'適合',
'愛美',
'女生',
'拍照',
'拍',
'視頻',
'電影',
'模式',
'非常',
'驚艷',
'真的',
'太棒了',
'濾鏡',
'自帶',
'美顏',
'效果',
'非常',
'特別',
'前置',
'攝像頭',
'亮點(diǎn)',
'優(yōu)化',
'升級(jí)',
'升級(jí)',
'像素',
'真的',
'超棒',
'萌',
'攝像頭',
'手機(jī)',
'大小',
'合適',
'握',
'手感',
'舒服',
'屏幕',
'非常',
'細(xì)膩',
'通透',
'屏幕',
'喜歡',
'新一代',
'運(yùn)行',
'速度',
'快',
'很多',
'系統(tǒng)',
'非常',
'流暢',
'屏幕',
'120hz',
'刷新率',
'電池',
'不錯(cuò)',
'正常',
'使用',
'續(xù)航',
'能力',
'挺久',
'玩游戲',
'不會(huì)',
'發(fā)燙',
'買',
'套裝',
'一年',
'延保',
'感覺',
'不錯(cuò)',
'A15',
'速度',
'很快',
'加上',
'iOS15',
'加持',
'手機(jī)',
'流暢',
'使用',
'一周',
'手機(jī)',
'方面',
'不錯(cuò)'
],
'cut_con': 'iPhone13收到喜歡蘋果手機(jī)一直蘋果忠實(shí)粉絲13手機(jī)外觀真的太驚艷最新款手機(jī)非常好看午夜色驚艷喜歡顏色外觀設(shè)計(jì)非常好看小巧精致喜歡iPhone產(chǎn)品新款相機(jī)非常拍攝效果強(qiáng)大適合愛美女生拍照拍視頻電影模式非常驚艷真的太棒了濾鏡自帶美顏效果非常特別前置攝像頭亮點(diǎn)優(yōu)化升級(jí)升級(jí)像素真的超棒萌攝像頭手機(jī)大小合適握手感舒服屏幕非常細(xì)膩通透屏幕喜歡新一代運(yùn)行速度快很多系統(tǒng)非常流暢屏幕120hz刷新率電池不錯(cuò)正常使用續(xù)航能力挺久玩游戲不會(huì)發(fā)燙買套裝一年延保感覺不錯(cuò)A15速度很快加上iOS15加持手機(jī)流暢使用一周手機(jī)方面不錯(cuò)',
'label_con': '__label__1,
iPhone13收到喜歡蘋果手機(jī)一直蘋果忠實(shí)粉絲13手機(jī)外觀真的太驚艷最新款手機(jī)非常好看午夜色驚艷喜歡顏色外觀設(shè)計(jì)非常好看小巧精致喜歡iPhone產(chǎn)品新款相機(jī)非常拍攝效果強(qiáng)大適合愛美女生拍照拍視頻電影模式非常驚艷真的太棒了濾鏡自帶美顏效果非常特別前置攝像頭亮點(diǎn)優(yōu)化升級(jí)升級(jí)像素真的超棒萌攝像頭手機(jī)大小合適握手感舒服屏幕非常細(xì)膩通透屏幕喜歡新一代運(yùn)行速度快很多系統(tǒng)非常流暢屏幕120hz刷新率電池不錯(cuò)正常使用續(xù)航能力挺久玩游戲不會(huì)發(fā)燙買套裝一年延保感覺不錯(cuò)A15速度很快加上iOS15加持手機(jī)流暢使用一周手機(jī)方面不錯(cuò)'
}之后對(duì)原始數(shù)據(jù)進(jìn)行解析處理:
# 文本去重
con_li = []
data_clear = []
for item in data:
if item["content"] not in con_li:
con_li.append(item["content"])
data_clear.append(item)
print("文本去重過濾條數(shù):%s" % (len(data) - len(data_clear)))
print("剩余評(píng)論個(gè)數(shù):", len(con_li)) # 剩余評(píng)論個(gè)數(shù)
def clean_txt(raw):
"""
提取清洗
"""
fil = re.compile(r"[^0-9a-zA-Z\u4e00-\u9fa5]+")
return fil.sub(" ", raw)
compress_num = 0
for i, item in enumerate(data_clear):
temp_com = item["content"]
compress_com = clean_txt(temp_com)
if compress_com != temp_com:
compress_num += 1
item["comp_con"] = compress_com
data_clear[i] = item
print("data_clear_legnth: ", len(data_clear))
for one in data_clear[:3]:
print("one: ", one)接著對(duì)清洗處理好的數(shù)據(jù)記性分詞和數(shù)據(jù)組裝:
# 進(jìn)行結(jié)巴分詞
stop_words = []
with open("cn_stopwords.txt", "r", encoding="utf-8") as f:
stop_words = f.readlines()
stop_words = [sw.strip() for sw in stop_words]
stop_words.append("\n")
data_li = []
for i, item in enumerate(data_final):
cut_li = list(jieba_fast.cut(item["comp_con"]))
cut_clear_li = [c.strip() for c in cut_li if c.strip() and c not in stop_words]
item["cut_li"] = cut_clear_li
cut_con = " ".join(cut_clear_li)
item["cut_con"] = cut_con
label_con = "__label__%s , %s" % (item["label"], item["cut_con"])
item["label_con"] = label_con
data_li.append(label_con)
data_final[i] = item
print("data_final_legnth: ", len(data_final))
for one in data_final[:3]:
print("one: ", one)處理后的數(shù)據(jù)如下:

雖然說看著有些奇怪,尤其是: __label__,但是這個(gè)沒辦法,fasttext需要的標(biāo)準(zhǔn)數(shù)據(jù)格式就是這個(gè)樣子的。
之后就可以進(jìn)行模型訓(xùn)練了,核心實(shí)現(xiàn)如下:
def train_model(ipt=None, opt=None, model="", dim=100, epoch=5, lr=0.5, loss="softmax"):
np.set_printoptions(suppress=True)
classifier = fasttext.train_supervised(
ipt, label="__label__", dim=dim, epoch=epoch, lr=lr, wordNgrams=4, loss=loss
)
"""
訓(xùn)練一個(gè)監(jiān)督模型, 返回一個(gè)模型對(duì)象
@param input: 訓(xùn)練數(shù)據(jù)文件路徑
@param lr: 學(xué)習(xí)率
@param dim: 向量維度
@param ws: cbow模型時(shí)使用
@param epoch: 次數(shù)
@param minCount: 詞頻閾值, 小于該值在初始化時(shí)會(huì)過濾掉
@param minCountLabel: 類別閾值,類別小于該值初始化時(shí)會(huì)過濾掉
@param minn: 構(gòu)造subword時(shí)最小char個(gè)數(shù)
@param maxn: 構(gòu)造subword時(shí)最大char個(gè)數(shù)
@param neg: 負(fù)采樣
@param wordNgrams: n-gram個(gè)數(shù)
@param loss: 損失函數(shù)類型, softmax, ns: 負(fù)采樣, hs: 分層softmax
@param bucket: 詞擴(kuò)充大小, [A, B]: A語料中包含的詞向量, B不在語料中的詞向量
@param thread: 線程個(gè)數(shù), 每個(gè)線程處理輸入數(shù)據(jù)的一段, 0號(hào)線程負(fù)責(zé)loss輸出
@param lrUpdateRate: 學(xué)習(xí)率更新
@param t: 負(fù)采樣閾值
@param label: 類別前綴
@param verbose: ??
@param pretrainedVectors: 預(yù)訓(xùn)練的詞向量文件路徑, 如果word出現(xiàn)在文件夾中初始化不再隨機(jī)
@return model object
"""
classifier.save_model(opt)
return classifier這里同樣實(shí)現(xiàn)了對(duì)于模型結(jié)果的評(píng)估方法:
def cal_precision_and_recall(file="test.txt"):
"""
計(jì)算每個(gè)標(biāo)簽 的precision和recall
"""
precision = defaultdict(int, 1)
recall = defaultdict(int, 1)
total = defaultdict(int, 1)
with open(file, encoding="utf-8") as f:
for line in f:
label, content = line.split(",", 1)
total[label.strip().strip("__label__")] += 1
labels2 = classifier.predict([content.strip()])
pre_label, sim = labels2[0][0][0], labels2[1][0][0]
recall[pre_label.strip().strip("__label__")] += 1
if label.strip() == pre_label.strip():
precision[label.strip().strip("__label__")] += 1
print("{:<10} {:<30}".format("precision", str(precision.dict)))
print("{:<10} {:<30}".format("recall", str(recall.dict)))
print("{:<10} {:<30}".format("total", str(total.dict)))
for sub in precision.dict:
pre = precision[sub] / total[sub]
rec = precision[sub] / recall[sub]
F1 = (2 * pre * rec) / (pre + rec)
print(
f"{sub.strip('__label__')} \t precision: {str(pre)} \t recall: {str(rec)} \t F1: {str(F1)}"
)運(yùn)行結(jié)果如下所示:

到此這篇關(guān)于Python實(shí)現(xiàn)基于Fasttext的商品評(píng)論數(shù)據(jù)分類的文章就介紹到這了,更多相關(guān)Python Fasttext商品評(píng)論內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pandas string轉(zhuǎn)dataframe的方法
下面小編就為大家分享一篇pandas string轉(zhuǎn)dataframe的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-04-04
Python調(diào)用PC攝像頭實(shí)現(xiàn)掃描二維碼
PC攝像機(jī)掃描二維碼的應(yīng)用場(chǎng)景很廣泛,可以應(yīng)用于各種需要快速掃描、識(shí)別和管理的場(chǎng)景,本文就來具體講講如何用Python實(shí)現(xiàn)這一功能吧2023-05-05
在spyder IPython console中,運(yùn)行代碼加入?yún)?shù)的實(shí)例
這篇文章主要介紹了在spyder IPython console中,運(yùn)行代碼加入?yún)?shù)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-04-04
在anaconda中配置graphviz包的詳細(xì)過程
graphviz是貝爾實(shí)驗(yàn)室開發(fā)的一個(gè)開源的工具包,它使用一個(gè)特定的DSL(領(lǐng)域特定語言):dot作為腳本語言,然后使用布局引擎來解析此腳本,并完成自動(dòng)布局,這篇文章主要介紹了如何在anaconda中配置graphviz包,需要的朋友可以參考下2023-02-02
利用Python實(shí)現(xiàn)QQ實(shí)時(shí)到賬免簽支付功能
這篇文章主要介紹了利用Python實(shí)現(xiàn)QQ實(shí)時(shí)到賬免簽支付功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
Python實(shí)現(xiàn)"驗(yàn)證回文串"的幾種方法
這篇文章主要介紹了Python實(shí)現(xiàn)"驗(yàn)證回文串"的幾種方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
Python 使用 attrs 和 cattrs 實(shí)現(xiàn)面向?qū)ο缶幊痰膶?shí)踐
這篇文章主要介紹了Python 使用 attrs 和 cattrs 實(shí)現(xiàn)面向?qū)ο缶幊痰膶?shí)踐,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06

