Python實(shí)現(xiàn)基于Fasttext的商品評論數(shù)據(jù)分類的操作流程
在以往的文本分類型的任務(wù)中,基本的流程主要是就是:
- 文本數(shù)據(jù)加載
- 數(shù)據(jù)清洗
- 分詞
- 向量化
- 分類模型訓(xùn)練
- 性能評估
這里面比如向量化和模型搭建是獨(dú)立的兩個節(jié)點(diǎn),可以自由地進(jìn)行設(shè)計(jì),當(dāng)然了也是一份工作量,今天使用的fasttext更像是一個集成的庫,把向量化和分類一起做掉了,這個對于使用層面來講就更方便了一些,不過也并不是絕對的,一般經(jīng)驗(yàn)來說,封裝程度越高的庫對于個性化的開發(fā)越不友好,但是如果僅僅只是使用一下就行,能夠?qū)崿F(xiàn)自己的功能這樣的想法的話倒是可以使用這種類型的庫的,總之,沒有絕對的最優(yōu),只有適合自己的模型。
本文主要也是基于具體的應(yīng)用來體驗(yàn)fasttext,整體流程如下:
為了清晰展示流程,這里我用不同的顏色來標(biāo)識不同的功能部分:
綠色部分為數(shù)據(jù)采集部分,這部分由于部分原因無法開放到這里
藍(lán)色部分為數(shù)據(jù)處理部分,這部分主要完成原始數(shù)據(jù)的清洗分詞等工作
黃色部分主要是實(shí)例化調(diào)用fasttext提供的模型來完成分類評估等工作
首先看下原始數(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ī)大小合適,握著手感很舒服。屏幕非常細(xì)膩,通透,屏幕很喜歡!新一代運(yùn)行速度快了很多,系統(tǒng)非常流暢,屏幕120hz刷新率。電池也還不錯,正常使用,續(xù)航能力還是挺久的,玩游戲也不會發(fā)燙。買了套裝一年延保的,感覺還是很不錯的!A15速度還是很快的,加上iOS15的加持,手機(jī)很流暢,使用了一周了,手機(jī)各方面都很不錯!', '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': '謝謝您對本店的支持,我們會不斷的努力,爭取做的更好,我們成長的路上有您的支持,我們表示感謝,歡迎再次光臨。祝您生活愉快,合家安康!', '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ī)大小合適握著手感很舒服屏幕非常細(xì)膩通透屏幕很喜歡新一代運(yùn)行速度快了很多系統(tǒng)非常流暢屏幕120hz刷新率電池也還不錯正常使用續(xù)航能力還是挺久的玩游戲也不會發(fā)燙買了套裝一年延保的感覺還是很不錯的A15速度還是很快的加上iOS15的加持手機(jī)很流暢使用了一周了手機(jī)各方面都很不錯', 'label': 1, 'cut_li': [ 'iPhone', '13', '收到', '喜歡', '蘋果', '手機(jī)', '一直', '蘋果', '忠實(shí)', '粉絲', '13', '手機(jī)', '外觀', '真的', '太', '驚艷', '最新款', '手機(jī)', '非常', '好看', '午夜', '色', '驚艷', '喜歡', '顏色', '外觀設(shè)計(jì)', '非常', '好看', '小巧', '精致', '喜歡', 'iPhone', '產(chǎn)品', '新款', '相機(jī)', '非常', '拍攝', '效果', '強(qiáng)大', '適合', '愛美', '女生', '拍照', '拍', '視頻', '電影', '模式', '非常', '驚艷', '真的', '太棒了', '濾鏡', '自帶', '美顏', '效果', '非常', '特別', '前置', '攝像頭', '亮點(diǎn)', '優(yōu)化', '升級', '升級', '像素', '真的', '超棒', '萌', '攝像頭', '手機(jī)', '大小', '合適', '握', '手感', '舒服', '屏幕', '非常', '細(xì)膩', '通透', '屏幕', '喜歡', '新一代', '運(yùn)行', '速度', '快', '很多', '系統(tǒng)', '非常', '流暢', '屏幕', '120hz', '刷新率', '電池', '不錯', '正常', '使用', '續(xù)航', '能力', '挺久', '玩游戲', '不會', '發(fā)燙', '買', '套裝', '一年', '延保', '感覺', '不錯', 'A15', '速度', '很快', '加上', 'iOS15', '加持', '手機(jī)', '流暢', '使用', '一周', '手機(jī)', '方面', '不錯' ], 'cut_con': 'iPhone13收到喜歡蘋果手機(jī)一直蘋果忠實(shí)粉絲13手機(jī)外觀真的太驚艷最新款手機(jī)非常好看午夜色驚艷喜歡顏色外觀設(shè)計(jì)非常好看小巧精致喜歡iPhone產(chǎn)品新款相機(jī)非常拍攝效果強(qiáng)大適合愛美女生拍照拍視頻電影模式非常驚艷真的太棒了濾鏡自帶美顏效果非常特別前置攝像頭亮點(diǎn)優(yōu)化升級升級像素真的超棒萌攝像頭手機(jī)大小合適握手感舒服屏幕非常細(xì)膩通透屏幕喜歡新一代運(yùn)行速度快很多系統(tǒng)非常流暢屏幕120hz刷新率電池不錯正常使用續(xù)航能力挺久玩游戲不會發(fā)燙買套裝一年延保感覺不錯A15速度很快加上iOS15加持手機(jī)流暢使用一周手機(jī)方面不錯', 'label_con': '__label__1, iPhone13收到喜歡蘋果手機(jī)一直蘋果忠實(shí)粉絲13手機(jī)外觀真的太驚艷最新款手機(jī)非常好看午夜色驚艷喜歡顏色外觀設(shè)計(jì)非常好看小巧精致喜歡iPhone產(chǎn)品新款相機(jī)非常拍攝效果強(qiáng)大適合愛美女生拍照拍視頻電影模式非常驚艷真的太棒了濾鏡自帶美顏效果非常特別前置攝像頭亮點(diǎn)優(yōu)化升級升級像素真的超棒萌攝像頭手機(jī)大小合適握手感舒服屏幕非常細(xì)膩通透屏幕喜歡新一代運(yùn)行速度快很多系統(tǒng)非常流暢屏幕120hz刷新率電池不錯正常使用續(xù)航能力挺久玩游戲不會發(fā)燙買套裝一年延保感覺不錯A15速度很快加上iOS15加持手機(jī)流暢使用一周手機(jī)方面不錯' }
之后對原始數(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("剩余評論個數(shù):", len(con_li)) # 剩余評論個數(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)
接著對清洗處理好的數(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__,但是這個沒辦法,fasttext需要的標(biāo)準(zhǔn)數(shù)據(jù)格式就是這個樣子的。
之后就可以進(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)練一個監(jiān)督模型, 返回一個模型對象 @param input: 訓(xùn)練數(shù)據(jù)文件路徑 @param lr: 學(xué)習(xí)率 @param dim: 向量維度 @param ws: cbow模型時使用 @param epoch: 次數(shù) @param minCount: 詞頻閾值, 小于該值在初始化時會過濾掉 @param minCountLabel: 類別閾值,類別小于該值初始化時會過濾掉 @param minn: 構(gòu)造subword時最小char個數(shù) @param maxn: 構(gòu)造subword時最大char個數(shù) @param neg: 負(fù)采樣 @param wordNgrams: n-gram個數(shù) @param loss: 損失函數(shù)類型, softmax, ns: 負(fù)采樣, hs: 分層softmax @param bucket: 詞擴(kuò)充大小, [A, B]: A語料中包含的詞向量, B不在語料中的詞向量 @param thread: 線程個數(shù), 每個線程處理輸入數(shù)據(jù)的一段, 0號線程負(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)了對于模型結(jié)果的評估方法:
def cal_precision_and_recall(file="test.txt"): """ 計(jì)算每個標(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的商品評論數(shù)據(jù)分類的文章就介紹到這了,更多相關(guān)Python Fasttext商品評論內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pandas string轉(zhuǎn)dataframe的方法
下面小編就為大家分享一篇pandas string轉(zhuǎn)dataframe的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04Python調(diào)用PC攝像頭實(shí)現(xiàn)掃描二維碼
PC攝像機(jī)掃描二維碼的應(yīng)用場景很廣泛,可以應(yī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í)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04在anaconda中配置graphviz包的詳細(xì)過程
graphviz是貝爾實(shí)驗(yàn)室開發(fā)的一個開源的工具包,它使用一個特定的DSL(領(lǐng)域特定語言):dot作為腳本語言,然后使用布局引擎來解析此腳本,并完成自動布局,這篇文章主要介紹了如何在anaconda中配置graphviz包,需要的朋友可以參考下2023-02-02利用Python實(shí)現(xiàn)QQ實(shí)時到賬免簽支付功能
這篇文章主要介紹了利用Python實(shí)現(xiàn)QQ實(shí)時到賬免簽支付功能,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03Python實(shí)現(xiàn)"驗(yàn)證回文串"的幾種方法
這篇文章主要介紹了Python實(shí)現(xiàn)"驗(yàn)證回文串"的幾種方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03Python 使用 attrs 和 cattrs 實(shí)現(xiàn)面向?qū)ο缶幊痰膶?shí)踐
這篇文章主要介紹了Python 使用 attrs 和 cattrs 實(shí)現(xiàn)面向?qū)ο缶幊痰膶?shí)踐,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-06-06