基於fastText對商品評論進行情感分析

1. 問題背景
在電商平臺中,不少用戶都會基於本身的購物體驗對商品進行評分和評論.但有些用戶只給出了評論而沒有評分,沒有了評分的量化標準,這給商家進行數據運營與選品決策帶來了困難.如何根據商品評論估計出相對應的評分,這是情感分析的問題,咱們能夠用fastText文本分類器來快速解決.
2. fastText簡介
fastText是FAIR(Facebook AI Research)於2016年開源的一個詞向量與文本分類工具,主要優勢是可以取得與深度神經網絡相媲美的分類精度,同時訓練速度比深度神經網絡快幾個數量級,節約了不小的訓練成本,果真是名副其實fastText.
3. fastText安裝html

$ git clone https://github.com/facebookresearch/fastText.git
$ cd fastText
$ sudo python setup.py install

4. 準備數據
下載Yelp商品評論數據(JSON格式)
Yelp是美國著名商戶點評網站,提供了470萬的用戶評論數據以做科學研究.Yelp採用的是五星級評分,用戶評分和評論的例子以下:
yelp.pngpython

下載解壓後會獲得數據reviews.json(大約5.3G),每行是個json對象,格式以下:git

{
  "review_id": "abc123",
  "user_id": "xyz123",
  "business_id": "1234",
  "stars": 5,
  "date":" 2019-01-01",
  "text": "This restaurant is great!",
  "useful":0,
  "funny":0,
  "cool":0
}

可是fastText要求輸入的數據須要有個標籤前綴__label__YOURLABEL,因此咱們要對reviews.json的數據進行預處理,像上面的評論要轉換爲github

__label__5 This restaurant is great!

5. 數據預處理json

import json
from pathlib import Path
import re
import random

reviews_data = Path("yelp_dataset") / "review.json"
training_data = Path("fasttext_dataset_training.txt")
test_data = Path("fasttext_dataset_test.txt")

# What percent of data to save separately as test data
percent_test_data = 0.10

def strip_formatting(string):
    string = string.lower()
    string = re.sub(r"([.!?,'/()])", r" \1 ", string)
    return string

with reviews_data.open() as input, \
     training_data.open("w") as train_output, \
     test_data.open("w") as test_output:

    for line in input:
        review_data = json.loads(line)

        rating = review_data['stars']
        text = review_data['text'].replace("\n", " ")
        text = strip_formatting(text)

        fasttext_line = "__label__{} {}".format(rating, text)

        if random.random() <= percent_test_data:
            test_output.write(fasttext_line + "\n")
        else:
            train_output.write(fasttext_line + "\n")

將上面代碼保存爲dataPre.py,運行後會獲得按照9:1比例隨機劃分的訓練數據和測試數據(fasttext_dataset_training.txt & fasttext_dataset_test.txt)
6. 訓練模型網絡

import fasttext
model = fasttext.train_supervised(input="fasttext_dataset_training.txt")
model.save_model("model_reviews.bin
")

訓練模型並保存模型爲model_reviews.bin
sentitrain.pngdom

7. 測試模型ide

import fasttext

def print_results(N, p, r):
    print("樣本數N\t" + str(N))
    print("精確率P@{}\t{:.3f}".format(1, p))
    print("召回率R@{}\t{:.3f}".format(1, r))

model = fasttext.load_model("model_reviews.bin")

print_results(*model.test('fasttext_dataset_test.txt'))

fast.png
運行後獲得測試結果精確率是69.6%,仍是有很大的提高空間的
8. 優化模型
在以前的模型訓練中是不考慮單詞的順序的,每一個單詞在句子中是獨立的,但實際情形不是這樣的,每每須要考慮上下文,這個時候咱們能夠用參數wordNgrams來進行改進,把N個單詞捆綁在一塊兒進行訓練.考慮到時間成本,咱們取wordNgrams=2.工具

import fasttext

model = fasttext.train_supervised(input="fasttext_dataset_training.txt", lr=1.0, epoch=25, wordNgrams=2)
model.save_model("model_reviews.bin")
def print_results(N, p, r):
    print("樣本數N\t" + str(N))
    print("精確率P@{}\t{:.3f}".format(1, p))
    print("召回率R@{}\t{:.3f}".format(1, r))
  
print_results(*model.test('fasttext_dataset_test.txt'))

better.png

精確率爲69.8%,只提升了0.2%,模型仍須要優化啊測試

咱們隨機找幾個評論預測一下星級評分

import fasttext



model = fasttext.load_model("model_reviews.bin")
sent = input("Please input:")

test = model.predict(sent)
s = float('%.4f' % test[1])



if test[0] =="('__label__1.0',)":
    print("Star rating:☆ \nConfidence: % s%%" % (s*100))
elif test[0] =="('__label__2.0',)":
    print("star rating:☆☆ \nConfidence: % s%%" % (s*100))
elif test[0] =="('__label__3.0',)":
    print("star rating:☆☆☆ \nConfidence: % s%%" % (s*100))
elif test[0] =="('__label__4.0',)":
    print("star rating:☆☆☆☆ \nConfidence: % s%%" % (s*100))
else:
    print("star rating:☆☆☆☆☆ \nConfidence: % s%%" % (s*100))

predict.png

參考:
  1. Text Classification is Your New Secret Weapon
  2. fastText supervised tutorial
相關文章
相關標籤/搜索