Compare with MultinomialNB / SVM / Decision tree(CART)

栏目: R语言 · 发布时间: 7年前

Source: Deep Learning on Medium

Compare MultinomialNB、SVM、Decision tree(CART) with f1-scrore、precision、recall

  • Using TFIDF( term frequency–inverse document frequency) for vectorized.
  • Using 10-fold for cross validation to get the better split.

首先import要用到的package,接著就可以開始我們的分析

import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import KFold
from sklearn import metrics

1. Data preprocessing

今天的目標是要從新聞報導中,正確的分類至相對應的文章類別,有三種類別分別是Sports, Politics, Health,接著我會用三種不同的分類器,來看看三者的效能差異。

首先,先來看看資料長怎樣呢

Compare with MultinomialNB / SVM / Decision tree(CART)
Raw data

可以看得出來是直接爬下來的data,每段的開頭是他的分類,那我們把它存成excel格式並分成categorize和content兩類。

colnames = ['categorize', 'content']
news = pd.read_csv('news_files.csv',names=colnames,encoding = 'utf8')

現在我們的資料存進去news的dataframe了,為了方便我們分類,將三種類別標示為0, 1, 2 並存到target的column

news['target'] = pd.Series(0, index=news.index)
news_data =news.iloc[:6000]

如果直接做slicing存過去,可能會遇到error — SettingWithCopyWarning,所以我們用.at填值

for i in range(len(news_data)+1):
 if news_data.iloc[i]['categorize']=='sports':
 news_data.at[i,'target'] = 0
 elif news_data.iloc[i]['categorize']=='politics':
 news_data.at[i,'target'] = 1
 else:
 news_data.at[i,'target'] = 2

2. KFold

怎麼分training和validation的data是個很重要的議題,分得好不好會影響到我們模型效能,我們這邊用KFold來分,但同時我也寫了Random分類後的結果,這邊是random分類的function,需要的也可以測試看看。

def Separate_TrainAndTest(data_raw):
 n=int(data_raw.shape[0])
 tmp_train=(np.random.rand(n)>=0.5)
 return data_raw.iloc[np.where(tmp_train==True)[0]],data_raw.iloc[np.where(tmp_train==False)[0]]

他的效能如下

Compare with MultinomialNB / SVM / Decision tree(CART)
Randomly separate

接著我們繼續本文的部分,這邊希望用KFold就是為了避免依賴某一特定的訓練和測試資料產生偏差,那我們快速看一下KFold是怎麼做

Compare with MultinomialNB / SVM / Decision tree(CART)
KFold

我們將資料分成 10 等份,從Round 1開始先拿第 1 等分用來做Validation,其餘拿來training,下一輪我們繼續拿第 2 等分做Validation,其餘 9 份一樣拿來訓練,總共做 10 次,如果想要取不同的fold也可以,但是10次是比較普遍的用法,也不會訓練太久。

接著將10次的Accuracy平均,所得到平均值,我們可以自信的說這個數值就是我們的準確度,相對隨機來的沒有偏差。

實作 Time.

這邊用sklearn裡面的KFold,裡面的參數設定是KFold(n_splits=’warn’, shuffle=False, random_state=None),想知道更詳細的話,詳見: https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.KFold.html

from sklearn.naive_bayes import MultinomialNB
kfold = KFold(10, True)
predicted = []
expected = []
for train, test in kfold.split(np.arange(len(news_data))+1):
 # train、test為index
 news_train = news_data.iloc[train]
 news_test = news_data.iloc[test]

上面我們用predicted和expected分別存10次的結果給後面做評分用

3. Vectorized

接下來是向量化(vectorized)的部分,這邊用的是TF-IDF,此演算法包含了兩個部分: 詞頻 (term frequency,TF)跟 逆向文件頻率 (inverse document frequency,IDF)。

詞頻指的是某一個給定的詞語在該文件中出現的頻率,第t個詞出現在第d篇文件的頻率記做

Compare with MultinomialNB / SVM / Decision tree(CART)

舉例來說,如果文件 1 總共有100個字,而第 1 個字在文件 1 出現的次數是12次,因此

Compare with MultinomialNB / SVM / Decision tree(CART)

而逆向文件頻率則是用來處理常用字的問題。假設詞彙t總共在第d篇文章中出現過,則詞彙t的 IDF 定義成

Compare with MultinomialNB / SVM / Decision tree(CART)

舉例來說,假設文字 1 總共出現在 25 篇不同的文件,則

Compare with MultinomialNB / SVM / Decision tree(CART)

所以如果詞彙t在非常多篇文章中都出現過,代表dt很大,此時idf就會比較小。

接著,我們將第t個詞彙對於第d篇文件的TF-IDF權重定義為

Compare with MultinomialNB / SVM / Decision tree(CART)

如此一來, 當詞彙t很常出現在文件d時,他的tf項就會比較大,而如果詞彙t也很少出現在其他篇文章,則idf項也會比較大,使Wtd整體來說更大,代表詞彙t對於文件d來說是很重要的 。

實作 Time.

這邊用sklearn.feature_extraction.text的TfidfVectorizer()直接計算,要注意的是需要將格式轉換成unicode,以下我以astype轉換

vectorizer = TfidfVectorizer()
 vectors_training = vectorizer.fit_transform(news_train['content'].values.astype('U'))
 vectors_test = vectorizer.transform(news_test['content'].values.astype('U'))

4. Classification

終於到了最後分類的階段,這邊會接續從MultinomialNB、SVM、CART分別進行training,並直接使用metric來計算三個分數,再分別列出,詳細的公式先不在這篇文章討論~

model = MultinomialNB(alpha=.01)
 model.fit(vectors_training,news_train.target)

 expected.extend(news_test.target)
 predicted.extend(model.predict(vectors_test))
print("---------Naive Bayes---------") 
print("Macro-average: {0}".format(metrics.f1_score(expected,predicted,average='macro')))
print("Micro-average: {0}".format(metrics.f1_score(expected,predicted,average='micro')))
print(metrics.classification_report(expected,predicted))
print(metrics.confusion_matrix(expected, predicted))
Compare with MultinomialNB / SVM / Decision tree(CART)
Multinomial NB score
from sklearn import svm
predicted = []
expected = []
for train, test in kfold.split(np.arange(len(news_data))+1):
 news_train = news_data.iloc[train]
 news_test = news_data.iloc[test]

 vectorizer = TfidfVectorizer()
 vectors_training = vectorizer.fit_transform(news_train['content'].values.astype('U'))
 vectors_test = vectorizer.transform(news_test['content'].values.astype('U'))

 model = svm.SVC(kernel = 'linear')
 model.fit(vectors_training,news_train.target)
 #test process
 #SVM
 expected.extend(news_test.target)
 predicted.extend(model.predict(vectors_test))
print("---------SVM---------") 
print("Macro-average: {0}".format(metrics.f1_score(expected,predicted,average='macro')))
print("Micro-average: {0}".format(metrics.f1_score(expected,predicted,average='micro')))
print(metrics.classification_report(expected,predicted,target_names = ['sports','politics','health'] ))
Compare with MultinomialNB / SVM / Decision tree(CART)
SVM score
from sklearn import tree
predicted = []
expected = []
for train, test in kfold.split(np.arange(len(news_data))+1):
 news_train = news_data.iloc[train]
 news_test = news_data.iloc[test]
 vectorizer = TfidfVectorizer()

 vectors_training = vectorizer.fit_transform(news_train['content'].values.astype('U'))
 vectors_test = vectorizer.transform(news_test['content'].values.astype('U'))

 model = tree.DecisionTreeClassifier() #不調參數 default = CART
 model.fit(vectors_training,news_train.target)

 # predict
 expected.extend(news_test.target)
 predicted.extend(model.predict(vectors_test))

#Decision Tree
print("---------Decision Tree---------")
print("Macro-average: {0}".format(metrics.f1_score(expected,predicted,average='macro')))
print("Micro-average: {0}".format(metrics.f1_score(expected,predicted,average='micro')))
print(metrics.classification_report(expected,predicted,target_names = ['sports','politics','health'] ))
print("-----------------------------")
Compare with MultinomialNB / SVM / Decision tree(CART)
CART score

Conclusion

很明顯的可以看到用10-fold所得到的結果比Random好很多,其中Accuracy又以SVM>NB>Decision Tree,但是SVM需要的時間也相對多很多,所以就看怎麼取決了,本文為第一個NLP的小實驗,有甚麼建議可以留言哦~


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。

Making Things See

Making Things See

Greg Borenstein / Make / 2012-2-3 / USD 39.99

Welcome to the Vision Revolution. With Microsoft's Kinect leading the way, you can now use 3D computer vision technology to build digital 3D models of people and objects that you can manipulate with g......一起来看看 《Making Things See》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具