- 自然語言工具包教程
- 自然語言工具包 - 首頁
- 自然語言工具包 - 簡介
- 自然語言工具包 - 入門
- 自然語言工具包 - 文字分詞
- 訓練分詞器 & 過濾停用詞
- 在Wordnet中查詢單詞
- 詞幹提取 & 詞形還原
- 自然語言工具包 - 單詞替換
- 同義詞 & 反義詞替換
- 語料庫讀取器和自定義語料庫
- 詞性標註基礎
- 自然語言工具包 - 一元標註器
- 自然語言工具包 - 組合標註器
- 自然語言工具包 - 更多NLTK標註器
- 自然語言工具包 - 語法分析
- 組塊 & 資訊提取
- 自然語言工具包 - 轉換組塊
- 自然語言工具包 - 轉換樹
- 自然語言工具包 - 文字分類
- 自然語言工具包資源
- 自然語言工具包 - 快速指南
- 自然語言工具包 - 有用資源
- 自然語言工具包 - 討論
自然語言工具包 - 文字分類
什麼是文字分類?
文字分類,顧名思義,就是對文字或文件進行分類的方法。但這裡出現了一個問題,為什麼我們需要使用文字分類器?一旦檢查了文件或文字中單詞的使用情況,分類器就能確定應該為其分配什麼類別標籤。
二元分類器
顧名思義,二元分類器將在兩個標籤之間做出決策。例如,正面或負面。在這種情況下,文字或文件要麼是一個標籤,要麼是另一個標籤,但不能同時是兩個標籤。
多標籤分類器
與二元分類器相反,多標籤分類器可以為文字或文件分配一個或多個標籤。
帶標籤與無標籤特徵集
特徵名稱到特徵值的鍵值對映稱為特徵集。帶標籤的特徵集或訓練資料對於分類訓練非常重要,以便它以後可以對無標籤的特徵集進行分類。
| 帶標籤的特徵集 | 無標籤的特徵集 |
|---|---|
| 它是一個看起來像 (feat, label) 的元組。 | 它本身就是一個特徵。 |
| 它是一個具有已知類別標籤的例項。 | 如果沒有關聯的標籤,我們可以稱之為例項。 |
| 用於訓練分類演算法。 | 訓練完成後,分類演算法可以對無標籤的特徵集進行分類。 |
文字特徵提取
文字特徵提取,顧名思義,就是將單詞列表轉換為分類器可用的特徵集的過程。我們必須將我們的文字轉換為“dict”風格的特徵集,因為自然語言工具包 (NLTK) 期望“dict”風格的特徵集。
詞袋 (BoW) 模型
BoW,是NLP中最簡單的模型之一,用於從文字或文件中提取特徵,以便在建模中使用,例如在機器學習演算法中。它基本上從例項的所有單詞構建一個單詞存在特徵集。這種方法背後的概念是,它不關心一個單詞出現的次數或單詞的順序,它只關心該單詞是否存在於單詞列表中。
示例
對於此示例,我們將定義一個名為 bow() 的函式 -
def bow(words): return dict([(word, True) for word in words])
現在,讓我們在單詞上呼叫bow()函式。我們將這些函式儲存在名為 bagwords.py 的檔案中。
from bagwords import bow bow(['we', 'are', 'using', 'tutorialspoint'])
輸出
{'we': True, 'are': True, 'using': True, 'tutorialspoint': True}
訓練分類器
在前面的部分中,我們學習瞭如何從文字中提取特徵。因此,現在我們可以訓練分類器了。第一個也是最簡單的分類器是NaiveBayesClassifier類。
樸素貝葉斯分類器
為了預測給定特徵集屬於特定標籤的機率,它使用貝葉斯定理。貝葉斯定理的公式如下。
$$P(A|B)=\frac{P(B|A)P(A)}{P(B)}$$這裡,
P(A|B) - 它也稱為後驗機率,即在第二個事件(即B)發生的情況下,第一個事件(即A)發生的機率。
P(B|A) - 它是第一個事件(即A)發生後第二個事件(即B)發生的機率。
P(A), P(B) - 它也稱為先驗機率,即第一個事件(即A)或第二個事件(即B)發生的機率。
為了訓練樸素貝葉斯分類器,我們將使用NLTK中的movie_reviews語料庫。此語料庫有兩個類別的文字,即:pos和neg。這些類別使在它們上面訓練的分類器成為二元分類器。語料庫中的每個檔案都由兩個組成,一個是正面影評,另一個是負面影評。在我們的示例中,我們將使用每個檔案作為訓練和測試分類器的單個例項。
示例
為了訓練分類器,我們需要一個帶標籤的特徵集列表,它將採用[(featureset, label)]的形式。這裡的featureset變數是一個dict,標籤是featureset的已知類別標籤。我們將建立一個名為label_corpus()的函式,它將獲取一個名為movie_reviews的語料庫,以及一個名為feature_detector的函式,預設為詞袋。它將構建並返回一個{label: [featureset]}形式的對映。之後,我們將使用此對映來建立帶標籤的訓練例項和測試例項列表。
import collections
def label_corpus(corp, feature_detector=bow):
label_feats = collections.defaultdict(list)
for label in corp.categories():
for fileid in corp.fileids(categories=[label]):
feats = feature_detector(corp.words(fileids=[fileid]))
label_feats[label].append(feats)
return label_feats
藉助上述函式,我們將獲得一個{label:fetaureset}對映。現在,我們將定義另一個名為split的函式,它將獲取label_corpus()函式返回的對映,並將每個特徵集列表拆分為帶標籤的訓練例項和測試例項。
def split(lfeats, split=0.75):
train_feats = []
test_feats = []
for label, feats in lfeats.items():
cutoff = int(len(feats) * split)
train_feats.extend([(feat, label) for feat in feats[:cutoff]])
test_feats.extend([(feat, label) for feat in feats[cutoff:]])
return train_feats, test_feats
現在,讓我們在我們的語料庫(即movie_reviews)上使用這些函式 -
from nltk.corpus import movie_reviews from featx import label_feats_from_corpus, split_label_feats movie_reviews.categories()
輸出
['neg', 'pos']
示例
lfeats = label_feats_from_corpus(movie_reviews) lfeats.keys()
輸出
dict_keys(['neg', 'pos'])
示例
train_feats, test_feats = split_label_feats(lfeats, split = 0.75) len(train_feats)
輸出
1500
示例
len(test_feats)
輸出
500
我們已經看到,在movie_reviews語料庫中,有1000個pos檔案和1000個neg檔案。我們最終也得到了1500個帶標籤的訓練例項和500個帶標籤的測試例項。
現在讓我們使用其train()類方法訓練NaïveBayesClassifier -
from nltk.classify import NaiveBayesClassifier NBC = NaiveBayesClassifier.train(train_feats) NBC.labels()
輸出
['neg', 'pos']
決策樹分類器
另一個重要的分類器是決策樹分類器。在這裡,為了訓練它,DecisionTreeClassifier類將建立一個樹結構。在此樹結構中,每個節點對應一個特徵名稱,分支對應特徵值。向下沿著分支,我們將到達樹的葉子,即分類標籤。
為了訓練決策樹分類器,我們將使用相同的訓練和測試特徵,即train_feats和test_feats變數,這些變數是我們從movie_reviews語料庫中建立的。
示例
為了訓練此分類器,我們將呼叫DecisionTreeClassifier.train()類方法,如下所示 -
from nltk.classify import DecisionTreeClassifier decisiont_classifier = DecisionTreeClassifier.train( train_feats, binary = True, entropy_cutoff = 0.8, depth_cutoff = 5, support_cutoff = 30 ) accuracy(decisiont_classifier, test_feats)
輸出
0.725
最大熵分類器
另一個重要的分類器是MaxentClassifier,它也稱為條件指數分類器或邏輯迴歸分類器。在這裡,為了訓練它,MaxentClassifier類將使用編碼將帶標籤的特徵集轉換為向量。
為了訓練決策樹分類器,我們將使用相同的訓練和測試特徵,即train_feats和test_feats變數,這些變數是我們從movie_reviews語料庫中建立的。
示例
為了訓練此分類器,我們將呼叫MaxentClassifier.train()類方法,如下所示 -
from nltk.classify import MaxentClassifier maxent_classifier = MaxentClassifier .train(train_feats,algorithm = 'gis', trace = 0, max_iter = 10, min_lldelta = 0.5) accuracy(maxent_classifier, test_feats)
輸出
0.786
Scikit-learn分類器
Scikit-learn是最好的機器學習 (ML) 庫之一。它實際上包含各種用途的各種ML演算法,但它們都具有以下相同的擬合設計模式 -
- 將模型擬合到資料
- 並使用該模型進行預測
這裡,我們不會直接訪問scikit-learn模型,而是將使用NLTK的SklearnClassifier類。此類是scikit-learn模型的包裝類,使其符合NLTK的Classifier介面。
我們將按照以下步驟訓練SklearnClassifier類 -
步驟1 - 首先,我們將像在以前的配方中一樣建立訓練特徵。
步驟2 - 現在,選擇並匯入Scikit-learn演算法。
步驟3 - 接下來,我們需要使用所選演算法構建SklearnClassifier類。
步驟4 - 最後,我們將使用我們的訓練特徵訓練SklearnClassifier類。
讓我們在下面的Python配方中實現這些步驟 -
from nltk.classify.scikitlearn import SklearnClassifier from sklearn.naive_bayes import MultinomialNB sklearn_classifier = SklearnClassifier(MultinomialNB()) sklearn_classifier.train(train_feats) <SklearnClassifier(MultinomialNB(alpha = 1.0,class_prior = None,fit_prior = True))> accuracy(sk_classifier, test_feats)
輸出
0.885
測量精確率和召回率
在訓練各種分類器時,我們也測量了它們的準確率。但是除了準確率之外,還有許多其他指標用於評估分類器。這兩個指標是精確率和召回率。
示例
在此示例中,我們將計算之前訓練的NaiveBayesClassifier類的精確率和召回率。為了實現這一點,我們將建立一個名為metrics_PR()的函式,它將有兩個引數,一個是訓練好的分類器,另一個是帶標籤的測試特徵。這兩個引數與我們在計算分類器準確率時傳遞的引數相同 -
import collections
from nltk import metrics
def metrics_PR(classifier, testfeats):
refsets = collections.defaultdict(set)
testsets = collections.defaultdict(set)
for i, (feats, label) in enumerate(testfeats):
refsets[label].add(i)
observed = classifier.classify(feats)
testsets[observed].add(i)
precisions = {}
recalls = {}
for label in classifier.labels():
precisions[label] = metrics.precision(refsets[label],testsets[label])
recalls[label] = metrics.recall(refsets[label], testsets[label])
return precisions, recalls
讓我們呼叫此函式以查詢精確率和召回率 -
from metrics_classification import metrics_PR nb_precisions, nb_recalls = metrics_PR(nb_classifier,test_feats) nb_precisions['pos']
輸出
0.6713532466435213
示例
nb_precisions['neg']
輸出
0.9676271186440678
示例
nb_recalls['pos']
輸出
0.96
示例
nb_recalls['neg']
輸出
0.478
分類器組合和投票
組合分類器是提高分類效能的最佳方法之一。投票是組合多個分類器的最佳方法之一。對於投票,我們需要有奇數個分類器。在下面的Python配方中,我們將組合三個分類器,即NaiveBayesClassifier類、DecisionTreeClassifier類和MaxentClassifier類。
為了實現這一點,我們將定義一個名為voting_classifiers()的函式,如下所示。
import itertools
from nltk.classify import ClassifierI
from nltk.probability import FreqDist
class Voting_classifiers(ClassifierI):
def __init__(self, *classifiers):
self._classifiers = classifiers
self._labels = sorted(set(itertools.chain(*[c.labels() for c in classifiers])))
def labels(self):
return self._labels
def classify(self, feats):
counts = FreqDist()
for classifier in self._classifiers:
counts[classifier.classify(feats)] += 1
return counts.max()
讓我們呼叫此函式以組合三個分類器並找到準確率 -
from vote_classification import Voting_classifiers combined_classifier = Voting_classifiers(NBC, decisiont_classifier, maxent_classifier) combined_classifier.labels()
輸出
['neg', 'pos']
示例
accuracy(combined_classifier, test_feats)
輸出
0.948
從上面的輸出中,我們可以看到組合分類器的準確率高於單個分類器。