【火爐煉AI】機器學習041-NLP句子情感分析
【火爐煉AI】機器學習041-NLP句子情感分析
(本文所使用的Python庫和版本號: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )
在NLP中有一個非常實用的應用領域--情感分析,情感分析是用NLP技術分析一段給定文字的情感型別,是積極的還是消極的,是樂觀的還是悲觀的等。比如在股市中,我們知道,往往大眾最悲觀的時候往往是股市的大底,而最樂觀的時候卻是股市的頂部,所以,如果我們能夠掌握大眾的心裡情感狀況,那麼也就能大概知道股市的底和頂,換言之,也就能夠在股市上掙得大把大把的銀子了。
1. 準備資料集
本專案所使用的資料集也是由nltk內部提供,其中的corpus模組中有movies_reviews,可以給我們提供“積極”和“消極”的語句文字。
# 1, 準備資料集 from nltk.corpus import movie_reviews pos_fileIds=movie_reviews.fileids('pos') # 載入積極文字檔案 neg_fileIds=movie_reviews.fileids('neg') # 消極文字檔案 print(len(pos_fileIds)) # 1000 print(len(neg_fileIds)) # 1000 print(pos_fileIds[:5]) print(neg_fileIds[:5]) # 由此可看出,movie_reviews.fileids是載入各種類別文字的檔案, # 並返回該檔名組成的list # 如果想要檢視某個文字檔案的內容,可以使用 print(movie_reviews.words(fileids=['pos/cv000_29590.txt']))
-------------------------------------輸---------出--------------------------------
1000
1000
['pos/cv000_29590.txt', 'pos/cv001_18431.txt', 'pos/cv002_15918.txt', 'pos/cv003_11664.txt', 'pos/cv004_11636.txt']
['neg/cv000_29416.txt', 'neg/cv001_19502.txt', 'neg/cv002_17424.txt', 'neg/cv003_12683.txt', 'neg/cv004_12641.txt']
['films', 'adapted', 'from', 'comic', 'books', 'have', ...]
--------------------------------------------完-------------------------------------
雖然上面把文字檔案的名稱提取出來,但是我們還需要從這些txt檔案中提取出所需要的特徵,使用這些特徵才能進行後續的分類器建模。
# 2, 處理資料集
def extract_features(word_list):
'''專門一個函式來提取特徵'''
return dict([(word,True) for word in word_list]) # 此處加True的作用是構成dict,實質意義不大
pos_features=[(extract_features(movie_reviews.words(fileids=[f])),'Pos')
for f in pos_fileIds]
neg_features=[(extract_features(movie_reviews.words(fileids=[f])),'Neg')
for f in neg_fileIds]
print(pos_features[:3]) # 列印下看看內容是否正確
dataset=pos_features+neg_features # 將兩部分結合起來作為一個dataset
打印出來的結果很長,可以參考我的github裡面的程式碼。
2. 建立模型,訓練特徵
# 構建模型,訓練模型
from nltk import NaiveBayesClassifier
from nltk.classify import accuracy as nltk_accuracy
np.random.shuffle(dataset)
rows=int(len(dataset)*0.8) # 80%為train set
train_set,test_set=dataset[:rows],dataset[rows:]
print('Num of train_set: ',len(train_set),
'/nNum of test_set: ',len(test_set))
clf=NaiveBayesClassifier.train(train_set)
# 檢視該模型在test set上的表現
acc=nltk_accuracy(clf,test_set)
print('Accuracy: {:.2f}%'.format(acc*100))
-------------------------------------輸---------出--------------------------------
Num of train_set: 1600
Num of test_set: 400
Accuracy: 70.75%
--------------------------------------------完-------------------------------------
由此可以看出該模型在測試集上的表現為:準確率70.75%
# 檢視模型內部資訊
# 該分類器是分析某段文字中哪些單詞與“積極”的關聯最大,
# 哪些與“消極”的關聯最大,進而分析這些關鍵詞的出現來判斷某句話是積極或消極
# 列印這些關鍵詞
for key_word in clf.most_informative_features()[:10]:
print(key_word[0])
-------------------------------------輸---------出--------------------------------
outstanding
insulting
ludicrous
affecting
magnificent
breathtaking
avoids
strongest
fascination
slip
--------------------------------------------完-------------------------------------
可以看出,這些關鍵詞對於區分一個句子是積極還是消極有著至關重要的作用,或者說,如果某個句子中有了這些關鍵詞,就可以區分這個句子的情感是積極還是消極,這些單詞越多,模型預測的準確率就越高。
3. 用成熟模型預測新樣本
# 用該模型來預測新樣本,檢視新句子的情感是積極還是消極
new_samples = [
"It is an amazing movie",
"This is a dull movie. I would never recommend it to anyone.",
"The cinematography is pretty great in this movie",
"The direction was terrible and the story was all over the place"
]
for sample in new_samples:
predict_P=clf.prob_classify(extract_features(sample.split()))
pred_sentiment=predict_P.max()
print('Sample: {}, Type: {}, Probability: {:.2f}%'.format(
sample,pred_sentiment,predict_P.prob(pred_sentiment)*100))
-------------------------------------輸---------出--------------------------------
Sample: It is an amazing movie, Type: Pos, Probability: 61.45%
Sample: This is a dull movie. I would never recommend it to anyone., Type: Neg, Probability: 80.12%
Sample: The cinematography is pretty great in this movie, Type: Pos, Probability: 63.63%
Sample: The direction was terrible and the story was all over the place, Type: Neg, Probability: 63.89%
--------------------------------------------完-------------------------------------
########################小**********結###############################
1,NLTK中所使用的分類器需要用dict型別的資料作為features來資料,故而我們需要自定義一個extract_features函式,來將單詞轉變為dict型別。
2,NLTK中已經集成了很多分類器,比如NaiveBayesClassifier,這些分類器已經集成了字串處理方面的各種細節,使用起來很方便。
#################################################################
注:本部分程式碼已經全部上傳到(我的github)上,歡迎下載。
參考資料:
1, Python機器學習經典例項,Prateek Joshi著,陶俊傑,陳小莉譯