【NLP基础理论】03 文本分类
注:
Unimelb Comp90042 NLP筆記
相關tutorial代碼鏈接
Text Classification(文本分類)
目錄
- Text Classification(文本分類)
- 1 分類類型
- 1.1 主題分類(Topic Classification)
- 1.2 情感分析(Sentiment Analysis)
- 1.3 母語辨別
- 1.4 自然語言推論(natural language inference)
- 1.5 其他文本分類
- 2 分類算法
- 2.1 文本分類器搭建步驟
- 2.2 如何選擇分類模型
- 2.3 樸素貝葉斯(Na?ve Bayes)
- 2.4 邏輯回歸(Logistic Regression)
- 2.5 支持向量機(Support Vector Machines)
- 2.6 K 近鄰(KNN)
- 2.7 決策樹(Decision Tree)
- 2.8 隨機森林(Random Forests)
- 2.9 神經網絡(Neural Networks)
- 3 評估(Evaluation)
- 3.1 準確性(Accuracy)
- 3.2 精度和召回率(Precision & Recall)
- 3.3 F1 - score
- 4 sklearn簡單例子
分類定義:
- Input
- 一個文本,通常以向量的形式展示文本的特征
- 一組固定的輸出類型 C= {c1, c2, … , ck},非連續(continuous),非有序(ordinal),是分類型(categorical)
- Output
- 文本預測的類型 c∈Cc \in Cc∈C
文本分類包括哪些任務
1 分類類型
1.1 主題分類(Topic Classification)
這段文字是關于收購還是收益?由于文章中出現了“shareholders”,“subsidiary”還有“share stock”,所以可以判斷這是關于收購相關的主題。
Motivation:通常用于圖書館學、信息檢索
Classes:主題類別有“工作”、“國際新聞”等等
Features:
1)詞袋模型(BOW)
2)更長的N-grams用于詞組(phrases)
Corpora例子:
1)Reuters news corpus(RCV1,路透社新聞語料庫可參閱NLTK);
2)Pubmed abstracts(一個提供生物醫學方面的論文搜索和摘要的數據庫);
3)Tweets with hashtags(帶有話題標簽的推文)
1.2 情感分析(Sentiment Analysis)
這個tweet的感情是什么?
Motivation:Opinion mining(意見挖掘),Business Analytics(商業分析)
Classes:正向、負向、中立
Features:
1)N-grams:之前的主題分類會使用BOW(將一句話變成一個向量)是因為我們并不在意語句的順序。但是情感分析中,單詞順序非常重要。
2)極性詞典(Polarity lexicons):本質上包含了一堆正面極性和負面極性的單詞的字典。通常是由人們手工創建,精度高,但覆蓋范圍小,適合用bootstrap的方式提升算法。
Corpora的例子:Movie review dataset(影評數據)、SEMEVAL Twitter polarity dataset(基于推特的情感極性分析數據集)
1.3 母語辨別
以下是什么母語的作者寫的文章?
Motivation:司法語言學(forensic linguistics),教育應用(educational application)。前者應用于網絡罪犯證據收集,后者幫助縮小有不同文化背景的教師和學生。
Classes:作者的第一語種(比如印度尼西亞語)
Features:
1)詞級n-grams(word n-grams)
2)句法模式(syntactic patterns):POS(詞性), parse trees(解析樹), abstract syntax tree(抽象語法樹1)
3)語音特征(phonological features):通過用戶的口音來判斷
Corpora例子:
托福、雅思短文語料庫
1.4 自然語言推論(natural language inference)
這兩句話的關系是牽連的還是矛盾的?
AKA Textual Entailment(文本蘊含)
Motivation:語言理解(language understanding)
Classes:Entailment(牽連),contradiction(矛盾),netural(中立)
Features:
1)Word overlap:檢查兩個短語或句子之間重疊的單詞數
2)Length difference between the sentences:橘子們的長度差別
3)N-grams
Corpora例子:
SNLI(斯坦福自然語言推理語料庫),MNLI(多類型自然語言推理語料庫)
1.5 其他文本分類
自動核對事實(automatic fact-checking)
解釋(Paraphrase)
2 分類算法
2.1 文本分類器搭建步驟
2.2 如何選擇分類模型
偏差:我們在模型中做出的假設
方差:對訓練集的敏感程度
從Overfit和Underfit的角度來記這兩個名詞。Overfit(過擬合)就是得到的模型在某一數據集上表現太好了,基本百分百貼近,但是放到別的數據集上表現就極差,這個現象就可以說是偏差低,方差高;Underfit(欠擬合)就是這個模型怎么訓練都爛,放在其他數據集也爛,那就是偏差高,方差低,本質原因就是模型就沒選好。
然而我們希望模型在訓練集上表現良好在別的數據也表現良好,就需要一個偏差低方差低的模型,但通常不會有這么完美的模型,所以就需要我們在兩者之間權衡:偏差-方差權衡(Bias-Variance Tradeoff) 。
2.3 樸素貝葉斯(Na?ve Bayes)
貝葉斯公式:
P(y∣x)=P(x∣y)P(y)P(x)P(y|x)=\frac{P(x|y)P(y)}{P(x)}P(y∣x)=P(x)P(x∣y)P(y)?
其中我們可以把 xxx看作待分類的對象,yyy看作類別,理解為當待分類對象xxx出現后,它是類別yyy的概率有多少?
然后找出一個y^\hat{y}y^?使得概率最高,那么這個y^\hat{y}y^?就是分類結果。
y^=argmaxy∈YP(y∣x)=argmaxy∈YP(x∣y)P(y)P(x)=argmaxy∈YP(x∣y)P(y)(P(x)不影響最大值可省略)\begin{aligned} \hat{y} =& argmax_{y \in Y}P(y|x)\\ =& argmax_{y \in Y}\frac{P(x|y)P(y)}{P(x)} \\ =& argmax_{y \in Y}P(x|y)P(y) & (P(x)不影響最大值可省略) \end{aligned}y^?===?argmaxy∈Y?P(y∣x)argmaxy∈Y?P(x)P(x∣y)P(y)?argmaxy∈Y?P(x∣y)P(y)?(P(x)不影響最大值可省略)?
但一件事情、一個物品或者一句話它通常會被提取出很多特征,比如判斷一臺電腦是否適合做nlp,我們可能會去看電腦是否是獨顯、內存是否大、價格是否貴等等,從而判斷電腦是否合適。所以把對象xxx變成x1,x2,...,xmx_1,x_2,...,x_mx1?,x2?,...,xm?個特征。
y^=argmaxy∈YP(x1,x2,...,xm∣y)P(y)\hat{y} = argmax_{y \in Y}P(x_1,x_2,...,x_m|y)P(y) y^?=argmaxy∈Y?P(x1?,x2?,...,xm?∣y)P(y)
為了簡單地得到這個式子的結果,我們做一個樸素的假設,假設特征之間毫無聯系。
P(x1,x2,...,xm∣y)P(y)≈P(x1∣y)P(x2∣y)...P(xM∣y)=P(y)∏m=1MP(xm∣y)P(x_1,x_2,...,x_m|y)P(y) \approx P(x_1|y)P(x_2|y)...P(x_M|y) = P(y)\prod_{m=1}^MP(x_m|y) P(x1?,x2?,...,xm?∣y)P(y)≈P(x1?∣y)P(x2?∣y)...P(xM?∣y)=P(y)m=1∏M?P(xm?∣y)
優點:
缺點:
2.4 邏輯回歸(Logistic Regression)
一個線性模型,通過softmax函數將輸出“壓縮到”(0, 1)之間,這樣才能得到一個有效概率。
P(cn∣f1…fm)=1Z×exp(∑i=0mwifi)P(c_n|f_1\dots f_m) = \frac{1}{Z}\times exp(\sum_{i=0}^mw_if_i) P(cn?∣f1?…fm?)=Z1?×exp(i=0∑m?wi?fi?)
邏輯回歸模型在訓練過程中會最大化所有訓練數據的概率,因此適合擬合數據,但同時也就會存在過擬合的風險。所以需要邏輯回歸總會包含一個正則項(或者說懲罰項)使得權重降低或者稀疏。
優點:
不會像樸素貝葉斯那樣被不同的、相關的特征所迷惑,在這種情況下邏輯回歸會有更好的性能。
缺點:
2.5 支持向量機(Support Vector Machines)
找到一個超平面(hyperplane)可以將訓練數據根據最大邊際劃分。
H3H_3H3?是比較好的hyperplane,相比H1H_1H1?來說它分開了黑白點,相比H2H_2H2?來說它和兩個類別的距離更大更合理。
優點:
缺點:
相比deep learning,為什么SVM在NLP中更受歡迎?
2.6 K 近鄰(KNN)
根據最近的k個訓練集樣本特征中的多數來分類。
上圖中綠點當看最近的三點,那么就會被分成紅三角,當看最近的五點,則會被分成藍正方。
距離定義公式可以不同:
一般會有歐拉距離(Euclidean distance)、余弦距離(Cosine distance)
優點:
缺點:
2.7 決策樹(Decision Tree)
構建以可樹,樹上的每個節點(node)都對應一個獨立的特點。
樹葉(Leaves)是最終的決定。
基于相互信息(mutual information)的貪婪最大化(greedy maximization)
關于怎么選取哪個節點應該是什么特征,到時候會在其他文章講到,大致意思會通過計算信息增益(information gain),得到這個特征區分樣本的能力如何,IG越大能力就越強,就可以最先放入樹。
優點:
缺點:
2.8 隨機森林(Random Forests)
一種基于決策樹的集合型分類器,它包含了很多決策樹模型。這些決策樹都是通過子集和子特征集訓練出來的。
最終的類型是由這些子分類器通過眾數投票決定的。
優點:
缺點:
2.9 神經網絡(Neural Networks)
一組相互連接的節點,被分配在不同的層。
輸入層(特征),輸出層(一個類別的概率),還有至少一層隱藏層。
每個節點對其來自上一層的輸入進行線性加權,通過激活函數將結果傳遞給下一層的節點。
優點:
缺點:
調參:
- Development set(驗證集)
- 訓練集和測試集不需要
- k 折交叉驗證(k-fold cross-vallidation),適用于較少數據量的情況
3 評估(Evaluation)
3.1 準確性(Accuracy)
準確性 = 完全正確的分類 / 所有的分類
acc=(79+10)/(79+13+8+10)=0.81acc =(79+10) / (79+13+8+10) = 0.81acc=(79+10)/(79+13+8+10)=0.81
通常我們在做預測的時候會有一個簡單的baseline,就是把所有的類都預測成一個,比如說這里我們簡單的就把所有預測見過設為A,因為原本這個數據集中就有 79 + 13 個A,那baseline的準確率就有79+13/79+13+8+10=0.8479 + 13 / 79+13+8+10 = 0.8479+13/79+13+8+10=0.84。
所以說當訓練集存在不平衡問題的時候,準確率就不是很好的評估指標。
3.2 精度和召回率(Precision & Recall)
假設分類B是Positive類別。
False Positive:本身不是B但是預測成了B(positive)
False Negative:本身是B但是預測成了A(Negative)。
True Positive:本身是B預測也是B
Precision=TPTP+FP=1010+13=0.43Precision = \frac{TP}{TP+FP} = \frac{10}{10+13} = 0.43Precision=TP+FPTP?=10+1310?=0.43
Recall=TPTP+FN=1010+8=0.56Recall = \frac{TP}{TP+FN} = \frac{10}{10+8}=0.56Recall=TP+FNTP?=10+810?=0.56
我們希望Recall和Precision的值都提高。
Recall:拿現在疫情為例,我們不希望一個小陽人核酸檢測結果是陰性的吧,就是希望FN少一點,那這樣Recall就高了。
Precision:以癌癥為例子,如果說得了癌癥是positive,那我們肯定不希望說我原本是健康的,但是醫院給我檢測出癌癥,所以希望FP少一點,那Precision就高了。
3.3 F1 - score
將精度和召回率結合成一個指標:
F1=2×precision×recallprecision+recallF1 = \frac{2 \times precision \times recall}{precision + recall}F1=precision+recall2×precision×recall?
通過分別計算類別A與類別B的F1,然后計算平均,這樣可以平等地看待兩個類別。
當類別A、B的重要程度不一樣時(根據出現的數量決定的),那我們可以采用此方法。
雖然講了這么多算法,但是如果能有一個標注很好的、類別豐富的大型數據集還是最重要的。
4 sklearn簡單例子
以sklearn中路透社語料庫(reuters corpus)為數據,調用現成的包來完成簡單的文本分類。后期準備在機器學習部分手撕基本的代碼。
路透社語料庫:
簡單介紹一下,它是新聞類的語料庫,總共分了 90 個topics,數據集里面分為train和test兩類。
reuter主要有三個屬性 reuter.fileid,reuter.category,reuter.words。
reuters有意思的是一篇新聞中往往會有多個主題,所以可能同一篇數據新聞會被標記在多個topic下。
導入語料庫
import nltk nltk.download("reuters") # if necessary from nltk.corpus import reuters假設我們現在把數據根據acq類來劃分,分成是acq類和不是acq類。
from sklearn.feature_extraction import DictVectorizerdef get_BOW(text):# 先得到一個文本的詞袋,即這個文本中每個詞的詞頻BOW = {}# 通常這里會用stemm或者lemma來統計,但這里沒有for word in text:BOW[word] = BOW.get(word,0) + 1return BOW# 根據topic來找數據,并存下每個數據的bow,用于后期來預測某一個text是acq還是不是acq,做一個二值分類 def prepare_reuters_data(topic,feature_extractor):training_set = []training_classifications = []test_set = []test_classifications = []# 遍歷所有數據集file,里面有train 有testfor file_id in reuters.fileids():# 得到這個數據集下的bowfeature_dict = feature_extractor(reuters.words(file_id)) if file_id.startswith("train"):# 有多少train文件就有多少元素,每個元素是一個bowtraining_set.append(feature_dict)# 看看這個數據屬不屬于topic,標注是和不是if topic in reuters.categories(file_id):training_classifications.append(topic)else:training_classifications.append("not " + topic)else:# 區分測試集test_set.append(feature_dict)if topic in reuters.categories(file_id):test_classifications.append(topic)else:test_classifications.append("not " + topic) # 向量化,所有bow的長度為向量的長度,text中有這個詞出現則為1,沒有則為0,整個訓練集是一個很稀疏的矩陣。vectorizer = DictVectorizer()# 保證訓練集和測試集的向量長度相同,主要是通過忽略那些沒有在training data中出現卻在test中出現的單詞。training_data = vectorizer.fit_transform(training_set)test_data = vectorizer.transform(test_set)return training_data,training_classifications,test_data,test_classificationstrn_data,trn_classes,test_data,test_classes = prepare_reuters_data("acq",get_BOW)然后通過不同分類模型進行10-fold cross validation得出每個模型的準確率如何。
from sklearn import model_selection #from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, classification_reportfrom sklearn.neighbors import KNeighborsClassifier from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import RandomForestClassifier from sklearn.naive_bayes import MultinomialNB from sklearn.svm import LinearSVC from sklearn.linear_model import LogisticRegression# 這里包含了6個沒有調超參的模型 clfs = [KNeighborsClassifier(),DecisionTreeClassifier(),RandomForestClassifier(),MultinomialNB(),LinearSVC(),LogisticRegression()]# 普通的validation:將數據等類別比例的拆分成train和test,但這個會造成每次train和test數據不同,可能造成結果有偏差 # loocv,遍歷整個數據,每次就留下一個作為test,其他都是train,但這樣會很慢 # k-fold cv,把數據先分成k份,遍歷k次,每次用其中一份作為test,剩下的k-1作為trian# 關于k-fold的一些內容 """ 1、在訓練模型時,如果已經預先指定好超參數了,這時候k交叉驗證訓練出來的模型只是不同數據訓練出來的參數(權重)不同的相同結構的模型。 一些文章中預先指定了超參數,再用k交叉驗證只能單單說明在這組超參數下,模型的準確率是這樣的,并不能說明當下的這組超參數是比其他的好。 2、k交叉驗證的用法是分別對自己想要嘗試的n組超參數進行k交叉驗證訓練模型,然后比較n組超參數下用k交叉驗證方法得到的n個平均誤差,然后選出誤差較小的那組超參數。 3、在做實驗時,比如要比較不同學習算法的效果,要先分別對不同算法用k交叉驗證方法確定一組較好的超參數,然后在測試集上比較他們的準確率 """ # 簡而言之就是用我給model的一組超參數,在不停變化的數據集上(不同的train、test組合方法)進行驗證,每一次預測完都會有一個結果,然后對這些結果的值進行平均。 # 然后看這個平均值怎么樣,如果好的話說明我的超參選的好。 def do_multiple_10foldcrossvalidation(clfs,data,classifications):for clf in clfs:predictions = model_selection.cross_val_predict(clf, data,classifications, cv=10)print (clf)print ("accuracy")# 準確率是原數據的和預測的print (accuracy_score(classifications,predictions))print (classification_report(classifications,predictions))do_multiple_10foldcrossvalidation(clfs,trn_data,trn_classes)其實上述代碼出來的結果中,KNN的結果是最差的,這是因為它特別容易受到具有與任務無關的維度的噪聲特征空間的影響。所以我們剛剛的數據處理并不完整,需要對 BOW 先小寫化,再進行lemmatize或者stemm,然后再過濾一遍停用詞,這樣才算最基礎的預處理。
from nltk.corpus import stopwords nltk.download('stopwords') stopwords = stopwords.words('english')def get_BOW_lowered_no_stopwords(text):# 通常這個在一開始bow那邊就要做的,把字母lower,避免大小字母還分不同單詞。去除停用詞BOW = {}for word in text:word = word.lower()if word not in stopwords:BOW[word] = BOW.get(word,0) + 1return BOWtrn_data,trn_classes,test_data,test_classes = prepare_reuters_data("acq",get_BOW_lowered_no_stopwords)do_multiple_10foldcrossvalidation(clfs,trn_data,trn_classes)解析樹與抽象語法樹:https://blog.csdn.net/qq_36097393/article/details/88866898 ??
總結
以上是生活随笔為你收集整理的【NLP基础理论】03 文本分类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: alpha测试和beta测试
- 下一篇: 学编程会拉低数学成绩,巴黎大学跟踪150