1. 程式人生 > >利用sklearn 樸素貝葉斯進行評論短語的分類

利用sklearn 樸素貝葉斯進行評論短語的分類

功能:

對評論短語,比如一個文章下的評論短語進行分類通過或者刪除,也就是是垃圾 、不是垃圾。

工具:

Spyder,jieba分詞,numpy,joblib,sklearn

程式:

# -*- coding: utf-8 -*-
"""
Created on Mon May 14 10:12:38 2018
@author: Administrator
"""
import codecs
import jieba
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import CountVectorizer,TfidfVectorizer
import numpy as np
from sklearn.externals import joblib
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, auc 


"""
CountVectorizer:
      只考慮詞彙在文字中出現的頻率
      驗證檔案並計算令牌的出現次數並將其作為稀疏矩陣返回
TfidfVectorizer:
     除了考量某詞彙在文字出現的頻率,還關注包含這個詞彙的所有文字的數量
     能夠削減高頻沒有意義的詞彙出現帶來的影響, 挖掘更有意義的特徵
     相比之下,文字條目越多,Tfid的效果會越顯著
     將術語頻率逆序文件頻率歸一化為發生次數的稀疏矩陣。 
"""

#獲取停用詞表
stop_words = "E:/Python/data/totalstop.txt"
stopwords = codecs.open(stop_words,'rb',encoding='utf-8').readlines()
stopwords = [ w.strip() for w in stopwords ]

train_data_path="E:/Python/data/四萬.txt"
test_data_path="E:/Python/data/兩萬.txt"
model_save_path="E:/Python/model/NB/NB_model.m"

#獲取資料
def get_data(path):
    data=[]
    target=[]
    fileIn = codecs.open(path,'rb',encoding='utf-8')
    for line in fileIn.readlines(): 
        lineArr = line.strip().split()
        target.append(int(lineArr[0].encode('utf-8').decode('utf-8-sig')))
        data.append(lineArr[1])
    target=np.array(target)
    return data,target

#去掉停用詞
def del_stopwords(data_get):
    data=[]     
    for word in data_get:
        n=0 
        word_cut = [words for words in jieba.cut(word)]
        result=""
        for cut_word in word_cut:
            if cut_word not in stopwords:
                 result+=cut_word
                 n+=1
                 if(n<len(word_cut)):
                     result+=" "
        data.append(result)
    return data

#訓練模型
def train_NN(data,target):
     clf=Pipeline([('vect',TfidfVectorizer()),('clf',MultinomialNB(alpha=0.001)),])#alpha引數,也叫平滑引數,其預設值為1.0
     clf.fit(data,target)
     #joblib.dump(clf,model_save_path)
     return clf
#測試模型
"""
TP: 將正類預測為正類數  
FN: 將正類預測為負類數  
FP: 將負類預測為正類數  
TN: 將負類預測為負類數  
查準率TP/(TP+FP)查準率關心的是”預測出正例的正確率”即從正反例子中挑選出正例的問題。 
查全率TP/(TP+FN)查全率關心的是”預測出正例的保證性”即從正例中挑選出正例的問題。     
"""
def test(data,target,clf):
    n=0
    TP=0
    TN=0
    FP=0
    FN=0
    sore_list=[]
    for word in data:
        sore_list.append(clf.predict_proba([word])[0][1])###結果為1的得分
        label=clf.predict([word])  #預測結果
        if(label==1 and target[n]==1):
            TP+=1
        elif(label==0 and target[n]==0): 
            TN+=1
        elif(label==1 and target[n]==0):
            FP+=1
        else:
            FN+=1
        n+=1
        print("data:",word)
        print("label:",label)   
    ccuracy = (TP+TN)/(TP+FN+FP+TN)
    precision = TP/(TP+FP)
    recall = TP/(TP+FN)
    F1=2*precision*recall/(precision+recall)
    print("F1:",F1)
    print("準確率:",ccuracy)
    print("查準率:",precision)
    print("召回率:",recall)

    return sore_list


#獲取訓練資料並去除停用詞
train_data,train_target=get_data(train_data_path)   
train_data=del_stopwords(train_data)

#獲取測試資料並去除停用詞
test_data,test_target=get_data(test_data_path)
test_data=del_stopwords(test_data)

#測試
clf=train_NN(train_data,train_target)
sore_list=test(test_data,test_target,clf)

data=np.append([sore_list],[test_target],axis=0).T#把得分和原始labe 組合在一起
data=data[np.lexsort(-data[:,::-1].T)]### 把得分系數按從大到小排序

sore=data[:,0]
label=data[:,1]

false_positive_rate, true_positive_rate, thresholds = roc_curve(label, sore)  
roc_auc = auc(false_positive_rate, true_positive_rate)  

plt.title('ROC')  
plt.plot(false_positive_rate, true_positive_rate, 'b',  
label='AUC = %0.2f'% roc_auc)  
plt.legend(loc='lower right')  
plt.plot([0,1],[0,1],'r--')  
plt.xlim([-0.1,1])  
plt.ylim([0,1.1])  
plt.ylabel('True Positive Rate')  
plt.xlabel('False Positive Rate')  
plt.show() 

"""
呼叫模型進行測試
test_data,test_target=get_data(test_data_path)
test_data=del_stopwords(test_data)
clf = joblib.load("E:/Python/model/NB/NB_model.m")
test(test_data,test_target,clf)
"""




























    

結果:



解釋:

我的訓練資料是四萬條,是txt模式儲存在本地。


類別分為0,1,     0是刪除,1是通過。

測試資料是2萬條,同樣格式儲存在本地。

資料獲取之後 去掉停用詞。

模型訓練完畢之後儲存在本地,下次可以直接呼叫模型。

alpha數值預設為1,但是經過除錯 發現設定為0.001準確率最高,但是再小的話 準確率不會提高。

其餘說明見文中說明。