基於TextBlob簡單文字情感分析
如果已經安裝TextBlob,需要更新則需要執行:
$ pip install -U textblob nltk
如果第一次安裝TextBlob,你可能需要下載必要的NLTK語料庫。命令:
$ curl https://raw.github.com/sloria/TextBlob/master/download_corpora.py | python
使用此命令下載語料庫:
$ >python -m textblob.download_corpora
第1部分:一個Tweet情感分析器(簡單分類)
我們的第一個分類器將是一個簡單的情感分析器訓練的一個小資料集的假tweet。
首先,我們將匯入textblob.classifiers並建立一些訓練和測試資料。
from textblob.classifiers import NaiveBayesClassifier
train = [
('I love this sandwich.', 'pos'),
('This is an amazing place!', 'pos'),
('I feel very good about these beers.', 'pos'),
('This is my best work.', 'pos'),
("What an awesome view" , 'pos'),
('I do not like this restaurant', 'neg'),
('I am tired of this stuff.', 'neg'),
("I can't deal with this", 'neg'),
('He is my sworn enemy!', 'neg'),
('My boss is horrible.', 'neg')
]
test = [
('The beer was good.', 'pos'),
('I do not enjoy my job', 'neg'),
("I ain't feeling dandy today." , 'neg'),
("I feel amazing!", 'pos'),
('Gary is a friend of mine.', 'pos'),
("I can't believe I'm doing this.", 'neg')
]
我們通過將訓練資料傳遞給NaiveBayesClassifier的建構函式來建立一個新的分類器。
cl = NaiveBayesClassifier(train)
我們現在可以使用NaiveBayesClassifier.classify(text)方法對任意文字進行分類。
cl.classify("Their burgers are amazing") # "pos"
cl.classify("I don't like their pizza.") # "neg"
分類文字字串的另一種方法是使用TextBlob物件。 您可以將分類器傳遞到TextBlob的建構函式中。
from textblob import TextBlob
blob = TextBlob("The beer was amazing. "
"But the hangover was horrible. My boss was not happy.",
classifier=cl)
然後,可以在blob上呼叫classify()方法。
blob.classify() # "neg"
還可以利用TextBlob句子標記化和單獨分類每個句子。
for sentence in blob.sentences:
print(sentence)
print(sentence.classify())
"pos", "neg", "neg"
檢查測試集的準確性。
cl.accuracy(test)
# 0.83
我們還可以找到最豐富的功能:
cl.show_informative_features(5)
# Most Informative Features
# contains(my) = True neg : pos = 1.7 : 1.0
# contains(an) = False neg : pos = 1.6 : 1.0
# contains(my) = False pos : neg = 1.3 : 1.0
# contains(place) = False neg : pos = 1.2 : 1.0
# contains(of) = False pos : neg = 1.2 : 1.0
第2部分:從NLTK新增更多資料
我們可以通過新增更多的訓練和測試資料來改進我們的分類器。 在這裡,我們將新增從NLTK下載的電影評論語料庫的資料。
import random
from nltk.corpus import movie_reviews
reviews = [(list(movie_reviews.words(fileid)), category)
for category in movie_reviews.categories()
for fileid in movie_reviews.fileids(category)]
new_train, new_test = reviews[0:100], reviews[101:200]
現在看看這些文件中的各個部分是什麼含義。
print(new_train[0])
輸出:
(['kolya', 'is', 'one', 'of', 'the', 'richest', 'films', 'i', "'", 've', 'seen', 'in', 'some', 'time'
, '.', 'zdenek', 'sverak', 'plays', 'a', 'confirmed', 'old', 'bachelor', '(', 'who', "'", 's', 'likel
y', 'to', 'remain', 'so', ')', ',', 'who', 'finds', 'his', 'life', 'as', 'a', 'czech', 'cellist', 'in
creasingly', 'impacted', 'by', 'the', 'five', '-', 'year', 'old', 'boy', 'that', 'he', "'", 's', 'tak
ing', 'care', 'of', '.', 'though', 'it', 'ends', 'rather', 'abruptly', '--', 'and', 'i', "'", 'm', 'w
hining', ',', "'", 'cause', 'i', 'wanted', 'to', 'spend', 'more', 'time', 'with', 'these', 'character
s', '--', 'the', 'acting', ',', 'writing', ',', 'and', 'production', 'values', 'are', 'as', 'high', '
as', ',', 'if', 'not', 'higher', 'than', ',', 'comparable', 'american', 'dramas', '.', 'this', 'fathe
r', '-', 'and', '-', 'son', 'delight', '--', 'sverak', 'also', 'wrote', 'the', 'script', ',', 'while'
, 'his', 'son', ',', 'jan', ',', 'directed', '--', 'won', 'a', 'golden', 'globe', 'for', 'best', 'for
eign', 'language', 'film', 'and', ',', 'a', 'couple', 'days', 'after', 'i', 'saw', 'it', ',', 'walked
', 'away', 'an', 'oscar', '.', 'in', 'czech', 'and', 'russian', ',', 'with', 'english', 'subtitles',
'.'], 'pos')
請注意,與第1部分中的資料不同,文字以單詞列表的形式出現,而不是單個字串。 TextBlob是非常好的; 它將按預期處理這兩種形式的資料。
我們現在可以使用update(new_data)方法使用新的訓練資料更新我們的分類器,以及使用更大的測試資料集進行測試。
cl.update(new_train)
accuracy = cl.accuracy(test + new_test)
第3部分:語言檢測器(自定義特徵提取)
我還沒有提到的一個重要方面是如何從文字中提取要素。
對於給定的文件和訓練集訓練,TextBlob的預設行為是計算列車中存在哪些單詞。 例如,句子“這只是一個肉體的傷口。 可能有功能contains(flesh):True,contains(wound):True,並且包含(knight):False。
當然,這個簡單的特徵提取器可能不適合於所有問題。 在這裡,我們將為語言檢測器建立一個自定義特徵提取器。
這裡是訓練和測試資料。
train = [
("amor", "spanish"),
("perro", "spanish"),
("playa", "spanish"),
("sal", "spanish"),
("oceano", "spanish"),
("love", "english"),
("dog", "english"),
("beach", "english"),
("salt", "english"),
("ocean", "english")
]
test = [
("ropa", "spanish"),
("comprar", "spanish"),
("camisa", "spanish"),
("agua", "spanish"),
("telefono", "spanish"),
("clothes", "english"),
("buy", "english"),
("shirt", "english"),
("water", "english"),
("telephone", "english")
]
243/5000
特徵提取器只是一個函式,它接受引數文字(從中提取特徵的文字)並返回特徵字典。
讓我們建立一個非常簡單的提取器,它使用給定單詞的最後一個字母作為其唯一的特徵。
def extractor(word):
feats = {}
last_letter = word[-1]
feats["last_letter({0})".format(last_letter)] = True
return feats
print(extractor("python")) # {'last_letter(n)': True}
我們可以將此特徵提取器作為NaiveBayesClassifier的建構函式的第二個引數。
lang_detector = NaiveBayesClassifier(train, feature_extractor=extractor)
計算結果:
lang_detector.accuracy(test) # 0.7
lang_detector.show_informative_features(5)
# Most Informative Features
# last_letter(o) = None englis : spanis = 1.6 : 1.0
# last_letter(l) = None englis : spanis = 1.2 : 1.0
# last_letter(n) = None spanis : englis = 1.2 : 1.0
# last_letter(h) = None spanis : englis = 1.2 : 1.0
# last_letter(e) = None spanis : englis = 1.2 : 1.0
毫無疑問,不以字母“o”結尾的單詞往往是英語。
結論
TextBlob使得建立自己的自定義文字分類器變得容易。 永遠記住,機器學習不是那麼容易,每一個問題都需要大量的實驗。