【火爐煉AI】機(jī)器學(xué)習(xí)041-NLP句子情感分析

【火爐煉AI】機(jī)器學(xué)習(xí)041-NLP句子情感分析

(本文所使用的Python庫(kù)和版本號(hào): Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )

在NLP中有一個(gè)非常實(shí)用的應(yīng)用領(lǐng)域--情感分析,情感分析是用NLP技術(shù)分析一段給定文本的情感類型,是積極的還是消極的,是樂(lè)觀的還是悲觀的等。比如在股市中,我們知道,往往大眾最悲觀的時(shí)候往往是股市的大底,而最樂(lè)觀的時(shí)候卻是股市的頂部,所以,如果我們能夠掌握大眾的心里情感狀況,那么也就能大概知道股市的底和頂,換言之,也就能夠在股市上掙得大把大把的銀子了。


1. 準(zhǔn)備數(shù)據(jù)集

本項(xiàng)目所使用的數(shù)據(jù)集也是由nltk內(nèi)部提供,其中的corpus模塊中有movies_reviews,可以給我們提供“積極”和“消極”的語(yǔ)句文本。

# 1, 準(zhǔn)備數(shù)據(jù)集
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

# 如果想要查看某個(gè)文本文件的內(nèi)容,可以使用
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', ...]

--------------------------------------------完-------------------------------------

雖然上面把文本文件的名稱提取出來(lái),但是我們還需要從這些txt文件中提取出所需要的特征,使用這些特征才能進(jìn)行后續(xù)的分類器建模。

# 2, 處理數(shù)據(jù)集
def extract_features(word_list):
    '''專門(mén)一個(gè)函數(shù)來(lái)提取特征'''
    return dict([(word,True) for word in word_list]) # 此處加True的作用是構(gòu)成dict,實(shí)質(zhì)意義不大

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]) # 打印下看看內(nèi)容是否正確

dataset=pos_features+neg_features # 將兩部分結(jié)合起來(lái)作為一個(gè)dataset

打印出來(lái)的結(jié)果很長(zhǎng),可以參考我的github里面的代碼。


2. 建立模型,訓(xùn)練特征

# 構(gòu)建模型,訓(xùn)練模型
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上的表現(xiàn)
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%

--------------------------------------------完-------------------------------------

由此可以看出該模型在測(cè)試集上的表現(xiàn)為:準(zhǔn)確率70.75%

# 查看模型內(nèi)部信息
# 該分類器是分析某段文本中哪些單詞與“積極”的關(guān)聯(lián)最大,
# 哪些與“消極”的關(guān)聯(lián)最大,進(jìn)而分析這些關(guān)鍵詞的出現(xiàn)來(lái)判斷某句話是積極或消極

# 打印這些關(guān)鍵詞
for key_word in clf.most_informative_features()[:10]:
    print(key_word[0])

-------------------------------------輸---------出--------------------------------

outstanding
insulting
ludicrous
affecting
magnificent
breathtaking
avoids
strongest
fascination
slip

--------------------------------------------完-------------------------------------

可以看出,這些關(guān)鍵詞對(duì)于區(qū)分一個(gè)句子是積極還是消極有著至關(guān)重要的作用,或者說(shuō),如果某個(gè)句子中有了這些關(guān)鍵詞,就可以區(qū)分這個(gè)句子的情感是積極還是消極,這些單詞越多,模型預(yù)測(cè)的準(zhǔn)確率就越高。


3. 用成熟模型預(yù)測(cè)新樣本

# 用該模型來(lái)預(yù)測(cè)新樣本,查看新句子的情感是積極還是消極
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%

--------------------------------------------完-------------------------------------

########################小**********結(jié)###############################

1,NLTK中所使用的分類器需要用dict類型的數(shù)據(jù)作為features來(lái)數(shù)據(jù),故而我們需要自定義一個(gè)extract_features函數(shù),來(lái)將單詞轉(zhuǎn)變?yōu)閐ict類型。

2,NLTK中已經(jīng)集成了很多分類器,比如NaiveBayesClassifier,這些分類器已經(jīng)集成了字符串處理方面的各種細(xì)節(jié),使用起來(lái)很方便。

#################################################################


注:本部分代碼已經(jīng)全部上傳到(我的github)上,歡迎下載。

參考資料:

1, Python機(jī)器學(xué)習(xí)經(jīng)典實(shí)例,Prateek Joshi著,陶俊杰,陳小莉譯

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容