樸素貝葉斯分類是一種經(jīng)典的機器學(xué)習(xí)算法军浆,本主題從貝葉斯的應(yīng)用場景棕洋,到其數(shù)學(xué)基礎(chǔ),并到最終的實現(xiàn)與應(yīng)用做了介紹乒融。主要內(nèi)容包含:
??1. Naive Bayes的分類思想酬屉;
??2. Naive Bayes分類的數(shù)學(xué)基礎(chǔ)炬守;
??3. Naive Bayes分類算法實現(xiàn);
??4. Naive Bayes算法的sklearn調(diào)用;
??5. 文本特征處理方面;
??6. Naive Bayes算法的簡歷薪資預(yù)測實現(xiàn)兔综;
樸素貝葉斯算法說明
樸素貝葉斯算法的概要說明
- 樸素貝葉斯是一種分類算法颂碧;
- 屬于監(jiān)督學(xué)習(xí)始锚;
- 使用貝葉斯定理作為數(shù)學(xué)理論基礎(chǔ)。
- 大量樣本下會有較好的分類效果撒遣,不適用于數(shù)據(jù)特征有關(guān)聯(lián)的訓(xùn)練樣本邮偎。
應(yīng)用場景
- 文本分類
- 垃圾郵件過濾
- 病人分類
- 拼寫檢查
貝葉斯算法的優(yōu)缺點
-
樸素貝葉斯的主要優(yōu)點有:
- 樸素貝葉斯模型發(fā)源于古典數(shù)學(xué)理論,有穩(wěn)定的分類效率义黎。
- 對小規(guī)模的數(shù)據(jù)表現(xiàn)很好禾进,能個處理多分類任務(wù),適合增量式訓(xùn)練廉涕,尤其是數(shù)據(jù)量超出內(nèi)存時泻云,我們可以一批批的去增量訓(xùn)練艇拍。
- 對缺失數(shù)據(jù)不太敏感,算法也比較簡單宠纯,常用于文本分類卸夕。
-
樸素貝葉斯的主要缺點有:
- 理論上,樸素貝葉斯模型與其他分類方法相比具有最小的誤差率婆瓜。但是實際上并非總是如此快集,這是因為樸素貝葉斯模型給定輸出類別的情況下,假設(shè)屬性之間相互獨立,這個假設(shè)在實際應(yīng)用中往往是不成立的勃救,在屬性個數(shù)比較多或者屬性之間相關(guān)性較大時碍讨,分類效果不好治力。而在屬性相關(guān)性較小時蒙秒,樸素貝葉斯性能最為良好。對于這一點宵统,有半樸素貝葉斯之類的算法通過考慮部分關(guān)聯(lián)性適度改進晕讲。
- 需要知道先驗概率,且先驗概率很多時候取決于假設(shè)马澈,假設(shè)的模型可以有很多種瓢省,因此在某些時候會由于假設(shè)的先驗?zāi)P偷脑驅(qū)е骂A(yù)測效果不佳。
- 由于我們是通過先驗和數(shù)據(jù)來決定后驗的概率從而決定分類痊班,所以分類決策存在一定的錯誤率勤婚。
- 對輸入數(shù)據(jù)的表達(dá)形式很敏感。
樸素貝葉斯算法的分類思想
- 使用病人分類作為例子:
- 已知病例:
癥狀 | 職業(yè) | 疾病 |
---|---|---|
打噴嚏 | 護士 | 感冒 |
打噴嚏 | 農(nóng)夫 | 過敏 |
頭痛 | 建筑工人 | 腦震蕩 |
頭痛 | 建筑工人 | 感冒 |
打噴嚏 | 教師 | 感冒 |
頭痛 | 教師 | 腦震蕩 |
-
假設(shè)需要對一個新的病人的病情做判定涤伐,該病人信息如下:
打噴嚏
建筑工人
請判定病人最可能是什么猜ā:感冒?過敏凝果?腦震蕩祝迂?
-
診斷過程:
- 計算三種病狀的可能性:
- 計算感冒的可能性
- 計算過敏的可能性
- 計算腦震蕩的可能性
- 可能性最大的病狀就是最終診斷
- 計算三種病狀的可能性:
-
如果使用概率表示可能性,則某個病狀的概率計算為:
-
P(感冒|打噴嚏x建筑工人) = P(打噴嚏x建筑工人|感冒) x P(感冒) / P(打噴嚏x建筑工人)
P(打噴嚏x建筑工人|感冒) = P(打噴嚏|感冒) x P(建筑工人|感冒) =
P(感冒) =
P(打噴嚏x建筑工人) = P(打噴嚏) x P(建筑工人) =
P(感冒|打噴嚏x建筑工人) =
-
腦震蕩的概率:
- P(腦震蕩|打噴嚏x建筑工人) = P(打噴嚏x建筑工人|腦震蕩) x P(腦震蕩) / P(打噴嚏x建筑工人)
- P(打噴嚏x建筑工人|腦震蕩) = P(打噴嚏|腦震蕩) x P(建筑工人|腦震蕩) = 0
-
過敏的概率
- P(過敏|打噴嚏x建筑工人) = P(打噴嚏x建筑工人|過敏) x P(過敏) / P(打噴嚏x建筑工人)
- P(打噴嚏x建筑工人|過敏) = P(打噴嚏|過敏) x P(建筑工人|過敏) = 0
-
-
結(jié)論:
- 打噴嚏的建筑工人有66.6666%的概率是感冒器净,0%的概率是過敏與腦震蕩型雳。
sklearn的貝葉斯應(yīng)用體驗
- sklearn的貝葉斯實現(xiàn)是四個類:
- 伯努利貝葉斯
- 高斯貝葉斯
- 多項式貝葉斯
- The Complement Naive Bayes(補充貝葉斯)
- sklearn的貝葉斯算法實現(xiàn)
import numpy as np
from sklearn.naive_bayes import GaussianNB, BernoulliNB, MultinomialNB, ComplementNB
from sklearn.model_selection import train_test_split
import sklearn.datasets as ds
data,target = ds.load_iris(return_X_y=True)
# 切分?jǐn)?shù)據(jù)集
data_train, data_test, target_train, target_test = train_test_split(
data, # 數(shù)據(jù)集
target, # 數(shù)據(jù)集標(biāo)簽
test_size=0.2)
print('--------GaussianNB')
classifier1 = GaussianNB()
classifier1.fit(data_train, target_train)
pre = classifier1.predict(data_test)
print((pre == target_test).sum())
print('--------BernoulliNB')
classifier2= BernoulliNB()
classifier2.fit(data_train, target_train)
pre = classifier2.predict(data_test)
print((pre == target_test).sum())
print('--------MultinomialNB')
classifier3 = MultinomialNB()
classifier3.fit(data_train, target_train)
pre = classifier3.predict(data_test)
print((pre == target_test).sum())
print('--------ComplementNB')
classifier4 = ComplementNB()
classifier4.fit(data_train, target_train)
pre = classifier4.predict(data_test)
print((pre == target_test).sum())
--------GaussianNB
29
--------BernoulliNB
7
--------MultinomialNB
25
--------ComplementNB
20
樸素貝葉斯算法的數(shù)學(xué)基礎(chǔ)
條件概率
-
理解條件貝葉斯公式從條件概率開始:
-
假設(shè)有兩個事件
,
山害,事件
同時發(fā)生的概率(聯(lián)合概率)可以表示如下:
-
事件
同時發(fā)生,還可以表示為
已經(jīng)發(fā)生浪慌,然后
再發(fā)生的概率:
-
發(fā)生的概率(先驗概率冤荆,也稱邊緣概率)表示為:
- 在
已經(jīng)發(fā)生的條件,
發(fā)生的概率就是條件概率眷射,表示為:
-
-
-
兩個事件同時發(fā)生的概率(聯(lián)合概率)表示為:
-
從上式可以推導(dǎo)出條件概率表示::
-
從條件概率可以進一步推導(dǎo):
-
如果
是兩個獨立的特征匙赞,則其概率計算為:
-
則條件概率滿足:
全概率:
- 全概率是對一復(fù)雜事件X的概率求解問題轉(zhuǎn)化為了在不同情況下發(fā)生的簡單事件的概率的求和問題佛掖。
- 全概率公式:
- 假設(shè)
是一個完備事件組:
-
構(gòu)成整個樣本空間。
-
- 則對于任意一個事件
的概率使用全概率公式表示:
- 假設(shè)
貝葉斯定理(公式)
-
條件概率:
-
后驗概率(貝葉斯公式):
-
全概率下的貝葉斯公式
后驗概率
-
后驗概率在表現(xiàn)形式上與條件概率一樣芥被,但在理解上存在一些因果的區(qū)別:
- 如果我們出門之前我們聽到新聞?wù)f今天路上出了個交通事故,那么我們想算一下堵車的概率坐榆,這個就叫做條件概率 拴魄。也就是P(堵車|交通事故)。這是有因求果席镀。
- 如果我們已經(jīng)出了門匹中,然后遇到了堵車,那么我們想算一下堵車時由交通事故引起的概率有多大豪诲,那這個就叫做后驗概率 (其實也是條件概率顶捷,但是通常習(xí)慣這么說) 。也就是P(交通事故|堵車)屎篱。這是有果求因服赎。
-
后驗概率的概念理解:
-
后驗概率:
- 歸一化因子:
- 先驗概率:
- 似然概率:
- 標(biāo)準(zhǔn)似然概率:
- 歸一化因子:
后驗概率:標(biāo)準(zhǔn)似然概率 * 先驗概率
貝葉斯公式就是用先驗概率求后驗概率。
-
多特征的情況
-
假設(shè)
交播,則貝葉斯公式為:
-
假設(shè)
樸素貝葉斯算法的推導(dǎo)
- 條件假設(shè):
- 存在訓(xùn)練集
重虑,其分類標(biāo)簽是
-
,一共
個樣本秦士。
-
- 分類樣本為
:
- 貝葉斯算法是找出在已知訓(xùn)練集的情況缺厉,找出概率最大的那個類別。
- 存在訓(xùn)練集
-
求解問題表述:
-
假設(shè)
是完備特征集:
上述概率在離散情況下隧土,使用頻次與頻率表示提针。
貝葉斯算法中的概率計算問題
離散值的情況
-
采用多項式分布:
-
-
表示類別C_k出現(xiàn)的次數(shù)
-
表示在類別
中,
出現(xiàn)的次數(shù)次洼。
-
-
-
離散值的問題:
- 某些時候关贵,可能某些類別在樣本中沒有出現(xiàn),這樣可能導(dǎo)致
- 某些時候关贵,可能某些類別在樣本中沒有出現(xiàn),這樣可能導(dǎo)致
-
離散值問題解決:
- 引入拉普拉斯平滑卖毁,概率計算公式為:
- 其中
為一個大于0的常數(shù)揖曾,通常取為1。
- 其中
為第
個特征的取值個數(shù)(實際上亥啦,這個取值在不同場合中可以根據(jù)需要確定炭剪,因為主要用來做平滑,防止概率為0翔脱,所以取得值是多少奴拦,與最終結(jié)果關(guān)系不大)。
- 其中
- 引入拉普拉斯平滑卖毁,概率計算公式為:
稀疏離散值
- 如果我們我們的
是非常稀疏的離散值届吁,即各個特征出現(xiàn)概率很低错妖,這時我們可以假設(shè)
符合伯努利分布:
- 即特征
出現(xiàn)記為1绿鸣,不出現(xiàn)記為0。即只要
出現(xiàn)即可暂氯,我們不關(guān)注
的次數(shù)潮模。
-
- 等式前的
還是表示特征值。
- 等式后的
表示取值為0或者1(就是出現(xiàn)或者不出現(xiàn))
- 等式前的
- 即特征
連續(xù)值
- 如果我們我們的
是連續(xù)值痴施,我們通常取
的先驗概率為正態(tài)分布擎厢,即在樣本類別
的值符合正態(tài)分布。這樣
的概率分布是:
-
- 其中
為在樣本類別
中辣吃,所有
的平均值动遭。
為在樣本類別
中,所有
的方差神得。
- 其中
-
各種算法的測試效果
- 對鳶尾花這種連續(xù)數(shù)據(jù)厘惦,使用高斯貝葉斯算法無疑是合適的。
- 下面看看離散的情況
- 手工計算:
-
['打噴嚏','建筑工人']
: -
['頭痛', '護士']
:
-
- 手工計算:
- 下面看看離散的情況
離散的測試效果
import numpy as np
from sklearn.naive_bayes import GaussianNB, BernoulliNB, MultinomialNB, ComplementNB
from sklearn.preprocessing import LabelEncoder
# 數(shù)據(jù)
data = np.array([
['打噴嚏','護士','感冒'],
['打噴嚏','農(nóng)夫','過敏'],
['頭痛','建筑工人','腦震蕩'],
['頭痛','建筑工人','感冒',],
['打噴嚏','教師','感冒',],
['頭痛','教師','腦震蕩']
])
# 訓(xùn)練集
data_train = np.zeros(shape=(data.shape[0], data.shape[1]-1),dtype=np.int32)
encoder = LabelEncoder()
encoder.fit(data[:,0])
# print(encoder.classes_)
# print(encoder.transform(data[:,0]))
data_train[:,0] = encoder.transform(data[:,0])
encoder.fit(data[:,1])
# print(encoder.classes_)
data_train[:,1] = encoder.transform(data[:,1])
encoder.fit(target)
# print(encoder.classes_)
target_train = encoder.transform(data[:,2])
# 測試集
test = np.array([
['打噴嚏','建筑工人'],
['頭痛', '護士']
])
data_test = np.zeros(test.shape,dtype=np.int32)
encoder.fit(test[:,0])
data_test[:,0] = encoder.transform(test[:,0])
encoder.fit(test[:,1])
# print(encoder.classes_)
data_test[:,1] = encoder.transform(test[:,1])
print('--------GaussianNB')
classifier1 = GaussianNB()
classifier1.fit(data_train, target_train)
pre = classifier1.predict(data_test)
print(pre)
print('--------BernoulliNB')
classifier2= BernoulliNB()
classifier2.fit(data_train, target_train)
pre = classifier2.predict(data_test)
print(pre)
print('--------MultinomialNB')
classifier3 = MultinomialNB()
classifier3.fit(data_train, target_train)
pre = classifier3.predict(data_test)
print(pre)
print('--------ComplementNB')
classifier4 = ComplementNB()
classifier4.fit(data_train, target_train)
pre = classifier4.predict(data_test)
print(pre)
--------GaussianNB
[2 1]
--------BernoulliNB
[2 1]
--------MultinomialNB
[0 0]
--------ComplementNB
[2 1]
連續(xù)的測試效果
% matplotlib inline
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import numpy as np
from sklearn.naive_bayes import GaussianNB, BernoulliNB, MultinomialNB, ComplementNB
from sklearn.model_selection import train_test_split
import sklearn.datasets as ds
data,target = ds.load_iris(return_X_y=True)
# 切分?jǐn)?shù)據(jù)集
data_train, data_test, target_train, target_test = train_test_split(
data, # 數(shù)據(jù)集
target, # 數(shù)據(jù)集標(biāo)簽
test_size=0.2)
classifier = GaussianNB()
classifier.fit(data_train[:,[0, 2]], target_train)
# 可視化
figure = plt.figure('貝葉斯分類', figsize=(8, 6))
ax = figure.add_axes([0.1, 0.1, 0.8, 0.8])
x_min, x_max = data[:, 0].min(), data[:, 0].max()
y_min, y_max = data[:, 2].min(), data[:, 2].max()
x_min -= 0.25
x_max += 0.25
y_min -= 0.25
y_max += 0.25
ax.set_xlim(x_min, x_max)
ax.set_ylim(y_min, y_max)
x, y = np.mgrid[x_min: x_max:500j, y_min: y_max:500j] # 生成網(wǎng)格
x_y_plane = np.c_[x.flat, y.flat] # 按照列合并
pre = classifier.predict(x_y_plane)
colors = ListedColormap([(0.5, 0.8, 0.8, 1),(0.8, 0.5, 0.8, 1),(0.8, 0.8, 0.5, 1)])
colors_pure = ListedColormap([(1, 0, 0, 1),(0, 1, 0, 1),(0, 0, 1, 1)])
ax.scatter (x.flat, y.flat, c=pre, cmap=colors, s=2**2, marker='.')
ax.scatter (data[:, 0], data[:, 2], c=target, cmap=colors_pure, s=3**2, marker='.')
plt.show()
貝葉斯算法的應(yīng)用案例
- 簡歷分類
一個簡單的詞向量的例子
- 借鑒的文本分類的一個例子
#!/usr/bin/python
# coding=utf-8
from numpy import *
# 過濾網(wǎng)站的惡意留言 侮辱性:1 非侮辱性:0
# 創(chuàng)建一個實驗樣本
def loadDataSet():
postingList = [['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
['maybe', 'not', 'take', 'him', 'to','dog', 'park', 'stupid'],
['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
['stop', 'posting', 'stupid', 'worthless', 'garbage'],
['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
classVec = [0, 1, 0, 1, 0, 1]
return postingList, classVec
# 創(chuàng)建一個包含在所有文檔中出現(xiàn)的不重復(fù)詞的列表
def createVocabList(dataSet):
vocabSet = set([]) # 創(chuàng)建一個空集
for document in dataSet:
vocabSet = vocabSet | set(document) # 創(chuàng)建兩個集合的并集
return list(vocabSet)
# 將文檔詞條轉(zhuǎn)換成詞向量
def setOfWords2Vec(vocabList, inputSet):
returnVec = [0]*len(vocabList) # 創(chuàng)建一個其中所含元素都為0的向量
for word in inputSet:
if word in vocabList:
# returnVec[vocabList.index(word)] = 1 # index函數(shù)在字符串里找到字符第一次出現(xiàn)的位置 詞集模型
returnVec[vocabList.index(word)] += 1 # 文檔的詞袋模型 每個單詞可以出現(xiàn)多次
else:
print("the word: %s is not in my Vocabulary!" % word)
return returnVec
# 樸素貝葉斯分類器訓(xùn)練函數(shù) 從詞向量計算概率
def trainNB0(trainMatrix, trainCategory):
# trainMatrix 是詞向量矩陣
# trainCategory 是每個詞向量對應(yīng)的分類標(biāo)簽
numTrainDocs = len(trainMatrix) # 文檔數(shù)量
numWords = len(trainMatrix[0]) # 詞向量特征數(shù)
pAbusive = sum(trainCategory)/numTrainDocs # 負(fù)面的概率
# p0Num = zeros(numWords); p1Num = zeros(numWords)
# p0Denom = 0.0; p1Denom = 0.0
p0Num = ones(numWords); # 避免一個概率值為0,最后的乘積也為0
p1Num = ones(numWords); # 用來統(tǒng)計兩類數(shù)據(jù)中循头,各詞的詞頻
p0Denom = 2.0; # 用于統(tǒng)計0類中的總數(shù)
p1Denom = 2.0 # 用于統(tǒng)計1類中的總數(shù)
# p1Num = trainMatrix[trainCategory == 1].sum(axis=0).astype(float) + 1
# p0Num = trainMatrix[trainCategory == 0].sum(axis=0).astype(float) + 1
# p1Denom = trainMatrix[trainCategory == 1].sum()+ 2
# p0Denom = trainMatrix[trainCategory == 0].sum()+ 2
# 下面的計算可以使用上面4個語句替代绵估。
for i in range(numTrainDocs):
if trainCategory[i] == 1:
p1Num += trainMatrix[I]
p1Denom += sum(trainMatrix[I])
else:
p0Num += trainMatrix[I]
p0Denom += sum(trainMatrix[I])
# p1Vect = log(p1Num / p1Denom) # 在類1中,每個詞的發(fā)生概率
# p0Vect = log(p0Num / p0Denom) # 避免下溢出或者浮點數(shù)舍入導(dǎo)致的錯誤 下溢出是由太多很小的數(shù)相乘得到的
p1Vect = p1Num / p1Denom # 負(fù)面:每個詞發(fā)生的頻率(不重復(fù)詞的列表卡骂,一共32個詞,對應(yīng)不同下標(biāo))
p0Vect = p0Num / p0Denom # 正面
return p0Vect, p1Vect, pAbusive
# 樸素貝葉斯分類器
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
p1 = sum(vec2Classify*p1Vec) * pClass1 # 由于分母都一樣形入,這里省略了分母
p0 = sum(vec2Classify*p0Vec) * (1.0-pClass1) # 由于分母都一樣全跨,這里省略了分母
# print(p1, p0)
if p1 > p0:
return 1
else:
return 0
def testingNB():
listOPosts, listClasses = loadDataSet()
myVocabList = createVocabList(listOPosts)
trainMat = []
for postinDoc in listOPosts:
trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
p0V, p1V, pAb = trainNB0(array(trainMat), array(listClasses))
testEntry = ['love','my','dalmation']
thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
print(testEntry, '分類是: ', classifyNB(thisDoc, p0V, p1V, pAb))
testEntry = ['stupid','garbage']
thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
print(testEntry, '分類是: ', classifyNB(thisDoc, p0V, p1V, pAb))
# 測試調(diào)用
testingNB()
['love', 'my', 'dalmation'] 分類是: 0
['stupid', 'garbage'] 分類是: 1
sklearn中文本特征處理-特征抽取
很多時候,用戶數(shù)據(jù)是不適合機器學(xué)習(xí)算法的亿遂,需要做特殊的處理才能交給算法訓(xùn)練浓若。比如文本數(shù)據(jù)。
-
這些不能直接處理的數(shù)據(jù)蛇数,需要轉(zhuǎn)換成計算能直接處理的數(shù)值型數(shù)據(jù)挪钓,或者數(shù)值向量,或者矩陣耳舅。我們上面采用的方法就是其中的一種方式碌上,當(dāng)然這種方式根據(jù)不同的數(shù)據(jù),處理方式也不同浦徊,但不過我們常用的數(shù)據(jù)除了數(shù)值型數(shù)據(jù)馏予,一般還包含:
- 文本數(shù)據(jù);
- 日期與時間數(shù)據(jù)盔性;
- 圖像數(shù)據(jù)霞丧;
- 音頻與視頻數(shù)據(jù);
- 其他數(shù)據(jù)冕香。
-
在這個主題內(nèi)蛹尝,我由于貝葉斯的主要場景是用于的場景:
- 文本分類
- 垃圾郵件過濾
- 病人分類
- 拼寫檢查
都與文本有關(guān)后豫,所以這里我們專門講解下文本特征化相關(guān)的技能。
-
sklearn對文本的特征抽韧荒恰(Feature Extraction)函數(shù)包含:
-
feature_extraction.text.CountVectorizer([…])
- 把文檔集合轉(zhuǎn)換為計數(shù)矩陣硬贯;
-
feature_extraction.text.HashingVectorizer([…])
- 把文檔集合轉(zhuǎn)換為頻次矩陣;
-
feature_extraction.text.TfidfTransformer([…])
- 把計數(shù)矩陣轉(zhuǎn)換為tf(Term frequency) 或者 tf-idf表示陨收;
-
feature_extraction.text.TfidfVectorizer([…])
- 把原生文檔集合轉(zhuǎn)換為TF-IDF特征矩陣.
-
CountVectorizer與HashingVectorizer類
- CountVectorizer
-
注意CountVectorizer中使用的正則表達(dá)式饭豹。
-
’(?u)\b\w\w+\b’
:(?u)用來支持unicode,還有其他修飾:- (?i)不區(qū)分大小寫
- (?m)多行
- (?s)單行
- (?J)不允許出現(xiàn)重復(fù)的名字等务漩。
-
類構(gòu)造器定義
class sklearn.feature_extraction.text.CountVectorizer(
input=’content’,
encoding=’utf-8’,
decode_error=’strict’,
strip_accents=None,
lowercase=True, # 大小寫
preprocessor=None,
tokenizer=None,
stop_words=None, # 禁止統(tǒng)計的詞
token_pattern=’(?u)\b\w\w+\b’, # 切分詞的正則表達(dá)式
ngram_range=(1, 1),
analyzer=’word’,
max_df=1.0,
min_df=1,
max_features=None,
vocabulary=None,
binary=False,
dtype=<class ‘numpy.int64’>)
-
屬性:
- vocabulary_ : dict
-
重要函數(shù):
- get_feature_names(self)
# 從上面正則表達(dá)式可以知道拄衰,只有一個字母的單詞不抽取。
from sklearn.feature_extraction.text import CountVectorizer
content = ["Convert a collection of text documents to a matrix of token counts",
"This implementation produces a sparse representation of the counts using scipy.sparse.csr_matrix."]
vectorizer = CountVectorizer(lowercase=False)
re = vectorizer.fit_transform(content)
# content的行數(shù)饵骨,**詞典中索引為3的元素**翘悉, 詞頻
# (0, 3) 1 表示:第一行中,詞表中下標(biāo)為3的詞居触,出現(xiàn)頻次是1.(就是counts出現(xiàn)1次)
print(re)
# 返回類型 scipy.sparse.csr.csr_matrix
# 獲取數(shù)據(jù)
names = vectorizer.get_feature_names() # 返回特征名妖混,結(jié)果是排序的
print(names)
ve = re.toarray() # 返回content對應(yīng)的特征名統(tǒng)計(計數(shù))
ve
(0, 3) 1
(0, 16) 1
(0, 7) 1
(0, 15) 1
(0, 5) 1
(0, 13) 1
(0, 8) 2
(0, 2) 1
(0, 0) 1
(1, 4) 1
(1, 11) 1
(1, 17) 1
(1, 14) 1
(1, 10) 1
(1, 12) 2
(1, 9) 1
(1, 6) 1
(1, 1) 1
(1, 3) 1
(1, 8) 1
['Convert', 'This', 'collection', 'counts', 'csr_matrix', 'documents', 'implementation', 'matrix', 'of', 'produces', 'representation', 'scipy', 'sparse', 'text', 'the', 'to', 'token', 'using']
array([[1, 0, 1, 1, 0, 1, 0, 1, 2, 0, 0, 0, 0, 1, 0, 1, 1, 0],
[0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 2, 0, 1, 0, 0, 1]],
dtype=int64)
- HashingVectorizer
# 把字符串轉(zhuǎn)換為hash化的特征表示。
# This text vectorizer implementation uses the hashing trick
# to find the token string name to feature integer index mapping.
from sklearn.feature_extraction.text import HashingVectorizer
content = ["Convert a collection of text documents to a matrix of token counts",
"This implementation produces a sparse representation of the counts using scipy.sparse.csr_matrix."]
vectorizer = HashingVectorizer(n_features=2**16)
re = vectorizer.fit_transform(content)
# 返回類型 scipy.sparse.csr.csr_matrix
# 獲取數(shù)據(jù)
ve = re.toarray() # 返回content對應(yīng)的字符串
ve
array([[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]])
TfidfTransformer與TfidfVectorizer類
-
TF:表示詞頻率(Term Frequency)
- 計算公式 :
- 計算公式 :
-
IDF:表示逆文件頻率(Inverse Document Frequency)
- 計算公式 :
- 分母+1的目的是防止除數(shù)為0
- 計算公式 :
-
TF-IDF:
- 計算公式 :
- 計算公式 :
TF轮洋,IDF與TF-IDF的例子
import numpy as np
# 假設(shè)爬蟲爬取一篇網(wǎng)絡(luò)文章總字?jǐn)?shù)1000: Python制市,數(shù)據(jù)挖掘的出現(xiàn)的次數(shù)個30,20詞弊予。
# TF=
tf1 = 30/100
tf2 = 20/100
print(tf1, tf2)
# 假設(shè)從網(wǎng)絡(luò)爬取的網(wǎng)頁是100萬祥楣,其中包含python的60萬,包含數(shù)據(jù)挖掘的0.4萬汉柒,
# IDF=
idf1 = np.log10(100/(62)) #然對數(shù)還是常用對數(shù)误褪,在這里意義不大
idf2 =np.log10(100/(0.4))
print(idf1, idf2)
# TF-IDF=
tf_idf1 = tf1 * idf1
tf_idf2 = tf2 * idf2
print(tf_idf1, tf_idf2)
0.3 0.2
0.2076083105017461 2.3979400086720375
0.06228249315052383 0.4795880017344075
- TfidfTransformer
- TfidfTransformer構(gòu)造器定義
class sklearn.feature_extraction.text.TfidfTransformer(
norm=’l2’,
use_idf=True,
smooth_idf=True,
sublinear_tf=False) # 使用 1 + log(tf)替代tf
-
TfidfTransformer的作用:
- 轉(zhuǎn)換計數(shù)矩陣為規(guī)范化tf 或者 tf-idf 表示,由參數(shù)決定:use_idf碾褂,默認(rèn)是 tf-idf
-
屬性:
- idf_ : array, shape (n_features)
# 把字符串轉(zhuǎn)換為hash化的特征表示兽间。
# This text vectorizer implementation uses the hashing trick
# to find the token string name to feature integer index mapping.
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
content = ["Convert a collection of text documents to a matrix of token counts",
"This implementation produces a sparse representation of the counts using scipy.sparse.csr_matrix."]
count_vectorizer = CountVectorizer(lowercase=False)
re_count = count_vectorizer.fit_transform(content)
print(count_vectorizer.get_feature_names())
print(re_count)
tfidf_transformer = TfidfTransformer(use_idf=False) # 修改use_idf為True觀察結(jié)果
re_tfidf = tfidf_transformer.fit_transform(re_count)
print(re_tfidf) # tf_idf計算
# (0, 16) 0.3239110443766146 表示:在第一行中, 詞表中下標(biāo)為16的詞(token)的tf-idf為3239110443766146
print(re_tfidf.toarray()) # 矩陣形式的結(jié)果
['Convert', 'This', 'collection', 'counts', 'csr_matrix', 'documents', 'implementation', 'matrix', 'of', 'produces', 'representation', 'scipy', 'sparse', 'text', 'the', 'to', 'token', 'using']
(0, 3) 1
(0, 16) 1
(0, 7) 1
(0, 15) 1
(0, 5) 1
(0, 13) 1
(0, 8) 2
(0, 2) 1
(0, 0) 1
(1, 4) 1
(1, 11) 1
(1, 17) 1
(1, 14) 1
(1, 10) 1
(1, 12) 2
(1, 9) 1
(1, 6) 1
(1, 1) 1
(1, 3) 1
(1, 8) 1
(0, 0) 0.2886751345948129
(0, 2) 0.2886751345948129
(0, 3) 0.2886751345948129
(0, 5) 0.2886751345948129
(0, 7) 0.2886751345948129
(0, 8) 0.5773502691896258
(0, 13) 0.2886751345948129
(0, 15) 0.2886751345948129
(0, 16) 0.2886751345948129
(1, 1) 0.2672612419124244
(1, 3) 0.2672612419124244
(1, 4) 0.2672612419124244
(1, 6) 0.2672612419124244
(1, 8) 0.2672612419124244
(1, 9) 0.2672612419124244
(1, 10) 0.2672612419124244
(1, 11) 0.2672612419124244
(1, 12) 0.5345224838248488
(1, 14) 0.2672612419124244
(1, 17) 0.2672612419124244
[[0.28867513 0. 0.28867513 0.28867513 0. 0.28867513
0. 0.28867513 0.57735027 0. 0. 0.
0. 0.28867513 0. 0.28867513 0.28867513 0. ]
[0. 0.26726124 0. 0.26726124 0.26726124 0.
0.26726124 0. 0.26726124 0.26726124 0.26726124 0.26726124
0.53452248 0. 0.26726124 0. 0. 0.26726124]]
- TfidfVectorizer
- 構(gòu)造器定義:
lass sklearn.feature_extraction.text.TfidfVectorizer(
input=’content’,
encoding=’utf-8’,
decode_error=’strict’,
strip_accents=None,
lowercase=True,
preprocessor=None,
tokenizer=None,
analyzer=’word’,
stop_words=None,
token_pattern=’(?u)\b\w\w+\b’,
ngram_range=(1, 1),
max_df=1.0,
min_df=1,
max_features=None,
vocabulary=None,
binary=False,
dtype=<class ‘numpy.float64’>,
norm=’l2’,
use_idf=True,
smooth_idf=True,
sublinear_tf=False)[source]
- TfidfVectorizer的作用:
- 直接把文檔轉(zhuǎn)換為tf或者tf-idf矩陣正塌;
# 把字符串轉(zhuǎn)換為hash化的特征表示嘀略。
# This text vectorizer implementation uses the hashing trick
# to find the token string name to feature integer index mapping.
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer, TfidfVectorizer
content = ["Convert a collection of text documents to a matrix of token counts",
"This implementation produces a sparse representation of the counts using scipy.sparse.csr_matrix."]
tf_idf_vectorizer = TfidfVectorizer(lowercase=False,use_idf=True)
re_tf_idf = tf_idf_vectorizer.fit_transform(content)
print(tf_idf_vectorizer.get_feature_names())
print(re_tf_idf)
print(re_tf_idf.toarray())
['Convert', 'This', 'collection', 'counts', 'csr_matrix', 'documents', 'implementation', 'matrix', 'of', 'produces', 'representation', 'scipy', 'sparse', 'text', 'the', 'to', 'token', 'using']
(0, 0) 0.3239110443766146
(0, 2) 0.3239110443766146
(0, 8) 0.46093075168919306
(0, 13) 0.3239110443766146
(0, 5) 0.3239110443766146
(0, 15) 0.3239110443766146
(0, 7) 0.3239110443766146
(0, 16) 0.3239110443766146
(0, 3) 0.23046537584459653
(1, 8) 0.19724216536132688
(1, 3) 0.19724216536132688
(1, 1) 0.2772169812630457
(1, 6) 0.2772169812630457
(1, 9) 0.2772169812630457
(1, 12) 0.5544339625260915
(1, 10) 0.2772169812630457
(1, 14) 0.2772169812630457
(1, 17) 0.2772169812630457
(1, 11) 0.2772169812630457
(1, 4) 0.2772169812630457
[[0.32391104 0. 0.32391104 0.23046538 0. 0.32391104
0. 0.32391104 0.46093075 0. 0. 0.
0. 0.32391104 0. 0.32391104 0.32391104 0. ]
[0. 0.27721698 0. 0.19724217 0.27721698 0.
0.27721698 0. 0.19724217 0.27721698 0.27721698 0.27721698
0.55443396 0. 0.27721698 0. 0. 0.27721698]]
sklearn中好用的數(shù)據(jù)結(jié)構(gòu)Bunch類
-
使用對象屬性來管理字典的數(shù)據(jù)結(jié)構(gòu)。
- 需要在構(gòu)造器定義類似字典的key传货。
使用Bunch的好處是序列化非常方便屎鳍。
from sklearn.datasets.base import Bunch
bunch = Bunch(filed1=[], filed2=[])
print(bunch)
{'filed1': [], 'filed2': []}
關(guān)于分詞
- Python的分詞模塊有很多,比較出名的是jieba问裕。最新版本是0.39逮壁,安裝指令:
pip install jieba
- 安裝過程截圖
- 關(guān)于其他分詞工具
- 百度直接搜索關(guān)鍵字:python分詞模塊,常見的有:
- jieba(百度:
https://github.com/fxsjy/jieba
) - THULAC(清華大學(xué)自然語言處理與社會人文計算實驗室)
- SnowNLP(MIT)
- pynlpir(大數(shù)據(jù)搜索挖掘?qū)嶒炇遥ū本┦泻A空Z言信息處理與云計算應(yīng)用工程技術(shù)研究中心))
- CoreNLP
- pyLTP
- 盤古分詞
- Yaha分詞
- jieba(百度:
- 百度直接搜索關(guān)鍵字:python分詞模塊,常見的有:
jieba分詞功能
import jieba
words = """
支持三種分詞模式:
1.精確模式粮宛,試圖將句子最精確地切開窥淆,適合文本分析卖宠;
2.全模式,把句子中所有的可以成詞的詞語都掃描出來, 速度非秤欠梗快扛伍,但是不能解決歧義;
3.搜索引擎模式词裤,在精確模式的基礎(chǔ)上刺洒,對長詞再次切分,提高召回率吼砂,適合用于搜索引擎分詞逆航。
乖乖隆地咚
"""
re_jieba = jieba.cut(words)
print(re_jieba)
print(list(re_jieba))
<generator object Tokenizer.cut at 0x11d448258>
['\n', '支持', '三種', '分', '詞模式', ':', '\n', '1', '.', '精確', '模式', ',', '試圖', '將', '句子', '最', '精確', '地', '切開', '渔肩,', '適合', '文本', '分析', '因俐;', '\n', '2', '.', '全', '模式', ',', '把', '句子', '中', '所有', '的', '可以', '成詞', '的', '詞語', '都', '掃描', '出來', ',', ' ', '速度', '非常', '快', '周偎,', '但是', '不能', '解決', '歧義', '抹剩;', '\n', '3', '.', '搜索引擎', '模式', ',', '在', '精確', '模式', '的', '基礎(chǔ)', '上', '蓉坎,', '對長', '詞', '再次', '切分', '澳眷,', '提高', '召回', '率', ',', '適合', '用于', '搜索引擎', '分詞', '袍嬉。', '\n', '乖乖隆地咚', '\n']
添加自定義詞典
- 字典格式:
- 一個詞占一行境蔼;
- 每一行分三部分,每個部分使用一個空格分隔伺通,按照下列順序。
- 詞語
- 詞頻(可省略)
- 詞性(可省略)
import jieba
words = """
支持三種分詞模式:
1.精確模式逢享,試圖將句子最精確地切開罐监,適合文本分析;
2.全模式瞒爬,把句子中所有的可以成詞的詞語都掃描出來, 速度非彻快,但是不能解決歧義侧但;
3.搜索引擎模式矢空,在精確模式的基礎(chǔ)上,對長詞再次切分禀横,提高召回率屁药,適合用于搜索引擎分詞。
乖乖隆地咚
"""
jieba.load_userdict('jieba/dict.txt')
re_jieba = jieba.cut(words)
print(re_jieba)
print(list(re_jieba))
help(jieba.cut)
<generator object Tokenizer.cut at 0x11b952f10>
['\n', '支持', '三種', '分', '詞模式', ':', '\n', '1', '.', '精確', '模式', '柏锄,', '試圖', '將', '句子', '最', '精確', '地', '切開', '酿箭,', '適合', '文本', '分析', '复亏;', '\n', '2', '.', '全', '模式', ',', '把', '句子', '中', '所有', '的', '可以', '成詞', '的', '詞語', '都', '掃描', '出來', ',', ' ', '速度', '非常', '快', '缭嫡,', '但是', '不能', '解決', '歧義', '缔御;', '\n', '3', '.', '搜索引擎', '模式', ',', '在', '精確', '模式', '的', '基礎(chǔ)', '上', '妇蛀,', '對長', '詞', '再次', '切分', '耕突,', '提高', '召回', '率', ',', '適合', '用于', '搜索引擎', '分詞', '评架。', '\n', '乖乖隆地咚', '\n']
Help on method cut in module jieba:
cut(sentence, cut_all=False, HMM=True) method of jieba.Tokenizer instance
The main function that segments an entire sentence that contains
Chinese characters into seperated words.
Parameter:
- sentence: The str(unicode) to be segmented.
- cut_all: Model type. True for full pattern, False for accurate pattern.
- HMM: Whether to use the Hidden Markov Model.
分詞中符號的處理
import jieba
import re
words = """
支持三種分詞模式:
1.精確模式眷茁,試圖將句子最精確地切開,適合文本分析古程;
2.全模式蔼卡,把句子中所有的可以成詞的詞語都掃描出來, 速度非常快挣磨,但是不能解決歧義雇逞;
3.搜索引擎模式,在精確模式的基礎(chǔ)上茁裙,對長詞再次切分塘砸,提高召回率,適合用于搜索引擎分詞晤锥。
乖乖隆地咚
"""
# 替換符號
words_no_punctuation = re.sub(r"[0-9\s+\.\!\/_,$%^*()?;掉蔬;:-【】+\"\']+|[+——!矾瘾,;:女轿。?壕翩、~@#¥%……&*()]+", "", words) #去標(biāo)點符號
# print(words_no_punctuation)
jieba.load_userdict('jieba/dict.txt')
re_jieba = jieba.cut(words_no_punctuation)
print(re_jieba)
print(list(re_jieba))
# help(jieba.cut)
<generator object Tokenizer.cut at 0x11d425048>
['支持', '三種', '分', '詞模式', ':', '精確', '模式', '試圖', '將', '句子', '最', '精確', '地', '切開', '適合', '文本', '分析', '全', '模式', '把', '句子', '中', '所有', '的', '可以', '成詞', '的', '詞語', '都', '掃描', '出來', '速度', '非常', '快', '但是', '不能', '解決', '歧義', '搜索引擎', '模式', '在', '精確', '模式', '的', '基礎(chǔ)', '上', '對', '長詞', '再次', '切分', '提高', '召回', '率', '適合', '用于', '搜索引擎', '分詞', '乖乖隆地咚']
簡歷分類實現(xiàn)代碼
#coding=utf-8
import jieba
import os
import pickle
from numpy import *
from sklearn import feature_extraction
from sklearn.feature_extraction.text import TfidfTransformer # TF-IDF向量轉(zhuǎn)換類
from sklearn.feature_extraction.text import TfidfVectorizer # TF_IDF向量生成類
from sklearn.datasets.base import Bunch
from sklearn.naive_bayes import MultinomialNB # 多項式貝葉斯算法
def readFile(path):
with open(path, 'r', errors='ignore') as file: #忽略編碼錯誤
content = file.read()
return content
def saveFile(path, result):
with open(path, 'w', errors='ignore') as file:
file.write(result)
def segText(inputPath, resultPath):
fatherLists = os.listdir(inputPath) # 主目錄
for eachDir in fatherLists: # 遍歷主目錄中各個文件夾
if eachDir.startswith('.'):
continue
eachPath = inputPath + eachDir + "/" # 保存主目錄中每個文件夾目錄蛉迹,便于遍歷二級文件
each_resultPath = resultPath + eachDir + "/" # 分詞結(jié)果文件存入的目錄
if not os.path.exists(each_resultPath):
os.makedirs(each_resultPath)
childLists = os.listdir(eachPath) # 獲取每個文件夾中的各個文件
for eachFile in childLists: # 遍歷每個文件夾中的子文件
eachPathFile = eachPath + eachFile # 獲得每個文件路徑
content = readFile(eachPathFile) # 調(diào)用上面函數(shù)讀取內(nèi)容
result = (str(content)).replace("\r\n", "").strip() # 刪除多余空行與空格
cutResult = jieba.cut(result) # 默認(rèn)方式分詞,分詞結(jié)果用空格隔開
saveFile(each_resultPath + eachFile, " ".join(cutResult)) # 調(diào)用上面函數(shù)保存文件
def bunchSave(inputFile, outputFile):
catelist = os.listdir(inputFile)
bunch = Bunch(target_name=[], label=[], filenames=[], contents=[])
bunch.target_name.extend(catelist) # 將類別保存到Bunch對象中
for eachDir in catelist:
if eachDir.startswith('.'):
continue
eachPath = inputFile + eachDir + "/"
fileList = os.listdir(eachPath)
for eachFile in fileList: # 二級目錄中的每個子文件
fullName = eachPath + eachFile # 二級目錄子文件全路徑
bunch.label.append(eachDir) # 當(dāng)前分類標(biāo)簽
bunch.filenames.append(fullName) # 保存當(dāng)前文件的路徑
bunch.contents.append(readFile(fullName).strip()) # 保存文件詞向量
with open(outputFile, 'wb') as file_obj: # 持久化必須用二進制訪問模式打開
pickle.dump(bunch, file_obj)
#pickle.dump(obj, file, [,protocol])函數(shù)的功能:將obj對象序列化存入已經(jīng)打開的file中放妈。
#obj:想要序列化的obj對象北救。
#file:文件名稱。
#protocol:序列化使用的協(xié)議芜抒。如果該項省略珍策,則默認(rèn)為0。如果為負(fù)值或HIGHEST_PROTOCOL宅倒,則使用最高的協(xié)議版本
def readBunch(path):
with open(path, 'rb') as file:
bunch = pickle.load(file)
#pickle.load(file)
#函數(shù)的功能:將file中的對象序列化讀出攘宙。
return bunch
def writeBunch(path, bunchFile):
with open(path, 'wb') as file:
pickle.dump(bunchFile, file)
def getStopWord(inputFile):
stopWordList = readFile(inputFile).splitlines()
return stopWordList
def getTFIDFMat(inputPath, stopWordList, outputPath): # 求得TF-IDF向量
bunch = readBunch(inputPath)
tfidfspace = Bunch(target_name=bunch.target_name,label=bunch.label, filenames=bunch.filenames, tdm=[],
vocabulary={})
# 初始化向量空間
vectorizer = TfidfVectorizer(stop_words=stopWordList, sublinear_tf=True, max_df=0.5)
# transformer = TfidfTransformer() # 該類會統(tǒng)計每個詞語的TF-IDF權(quán)值
# 文本轉(zhuǎn)化為詞頻矩陣,單獨保存字典文件
tfidfspace.tdm = vectorizer.fit_transform(bunch.contents)
tfidfspace.vocabulary = vectorizer.vocabulary_ #獲取詞匯
writeBunch(outputPath, tfidfspace)
def getTestSpace(testSetPath, trainSpacePath, stopWordList, testSpacePath):
bunch = readBunch(testSetPath)
# 構(gòu)建測試集TF-IDF向量空間
testSpace = Bunch(target_name=bunch.target_name, label=bunch.label, filenames=bunch.filenames, tdm=[],
vocabulary={})
# 導(dǎo)入訓(xùn)練集的詞袋
trainbunch = readBunch(trainSpacePath)
# 使用TfidfVectorizer初始化向量空間模型 使用訓(xùn)練集詞袋向量
vectorizer = TfidfVectorizer(stop_words=stopWordList, sublinear_tf=True, max_df=0.5,
vocabulary=trainbunch.vocabulary)
# transformer = TfidfTransformer()
testSpace.tdm = vectorizer.fit_transform(bunch.contents)
testSpace.vocabulary = trainbunch.vocabulary
# 持久化
writeBunch(testSpacePath, testSpace)
def bayesAlgorithm(trainPath, testPath):
trainSet = readBunch(trainPath)
testSet = readBunch(testPath)
clf = MultinomialNB(alpha=0.001).fit(trainSet.tdm, trainSet.label)
#alpha:0.001 alpha 越小,迭代次數(shù)越多,精度越高
#print(shape(trainSet.tdm)) #輸出單詞矩陣的類型
#print(shape(testSet.tdm))
predicted = clf.predict(testSet.tdm)
total = len(predicted)
rate = 0
for flabel, fileName, expct_cate in zip(testSet.label, testSet.filenames, predicted):
if flabel != expct_cate:
rate += 1
print(fileName, ":實際類別:", flabel, "-->預(yù)測類別:", expct_cate)
print("erroe rate:", float(rate) * 100 / float(total), "%")
# 分詞,第一個是分詞輸入跷车,第二個參數(shù)是結(jié)果保存的路徑
segText("./dataset/data/", "./dataset/segResult/") # 分詞
bunchSave("./dataset/segResult/", "./dataset/train_set.dat") # 輸入分詞,輸出分詞向量
stopWordList = getStopWord("./dataset/stop/stopword.txt") # 獲取停用詞
getTFIDFMat("./dataset/train_set.dat", stopWordList, "./dataset/tfidfspace.dat") # 輸入詞向量持痰,輸出特征空間
# 訓(xùn)練集
segText("./dataset/test1/", "./dataset/test_segResult/") # 分詞
bunchSave("./dataset/test_segResult/", "./dataset/test_set.dat")
getTestSpace("./dataset/test_set.dat", "./dataset/tfidfspace.dat", stopWordList, "./dataset/testspace.dat")
bayesAlgorithm("./dataset/tfidfspace.dat", "./dataset/testspace.dat")
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sklearn/feature_extraction/text.py:300: UserWarning: Your stop_words may be inconsistent with your preprocessing. Tokenizing the stop words generated tokens ['ain', 'aren', 'couldn', 'didn', 'doesn', 'don', 'hadn', 'hasn', 'haven', 'isn', 'll', 'mon', 'shouldn', 've', 'wasn', 'weren', 'won', 'wouldn'] not in stop_words.
'stop_words.' % sorted(inconsistent))
./dataset/test_segResult/10k-18k/3496172.txt :實際類別: 10k-18k -->預(yù)測類別: 10k-20k
./dataset/test_segResult/10k-18k/4543973.txt :實際類別: 10k-18k -->預(yù)測類別: 7k-9k
./dataset/test_segResult/10k-18k/4751316.txt :實際類別: 10k-18k -->預(yù)測類別: 15k-30k
./dataset/test_segResult/10k-20k/326941.txt :實際類別: 10k-20k -->預(yù)測類別: 10k-16k
./dataset/test_segResult/10k-20k/3770831.txt :實際類別: 10k-20k -->預(yù)測類別: 15k-20k
./dataset/test_segResult/10k-20k/3867925.txt :實際類別: 10k-20k -->預(yù)測類別: 15k-25k
./dataset/test_segResult/10k-20k/4072821.txt :實際類別: 10k-20k -->預(yù)測類別: 20k-40k
./dataset/test_segResult/10k-20k/4498906.txt :實際類別: 10k-20k -->預(yù)測類別: 7k-14k
./dataset/test_segResult/10k-20k/4580091.txt :實際類別: 10k-20k -->預(yù)測類別: 15k-25k
./dataset/test_segResult/10k-20k/4715977.txt :實際類別: 10k-20k -->預(yù)測類別: 20k-40k
./dataset/test_segResult/10k-20k/4772554.txt :實際類別: 10k-20k -->預(yù)測類別: 20k-40k
./dataset/test_segResult/10k-20k/4838990.txt :實際類別: 10k-20k -->預(yù)測類別: 25k-50k
./dataset/test_segResult/10k-20k/4875752.txt :實際類別: 10k-20k -->預(yù)測類別: 15k-30k
./dataset/test_segResult/10k-20k/4932878.txt :實際類別: 10k-20k -->預(yù)測類別: 3k-6k
./dataset/test_segResult/10k-20k/4961212.txt :實際類別: 10k-20k -->預(yù)測類別: 13k-26k
./dataset/test_segResult/10k-20k/4967915.txt :實際類別: 10k-20k -->預(yù)測類別: 25k-50k
./dataset/test_segResult/10k-20k/5020579.txt :實際類別: 10k-20k -->預(yù)測類別: 8k-12k
./dataset/test_segResult/10k-20k/5062668.txt :實際類別: 10k-20k -->預(yù)測類別: 15k-30k
./dataset/test_segResult/10k-20k/5083284.txt :實際類別: 10k-20k -->預(yù)測類別: 8k-14k
./dataset/test_segResult/10k-20k/5107023.txt :實際類別: 10k-20k -->預(yù)測類別: 20k-30k
./dataset/test_segResult/10k-20k/5124617.txt :實際類別: 10k-20k -->預(yù)測類別: 12k-24k
./dataset/test_segResult/10k-20k/5143794.txt :實際類別: 10k-20k -->預(yù)測類別: 8k-14k
./dataset/test_segResult/10k-20k/5155415.txt :實際類別: 10k-20k -->預(yù)測類別: 15k-30k
./dataset/test_segResult/10k-20k/5158775.txt :實際類別: 10k-20k -->預(yù)測類別: 15k-30k
./dataset/test_segResult/10k-20k/5179499.txt :實際類別: 10k-20k -->預(yù)測類別: 13k-15k
./dataset/test_segResult/10k-20k/5185464.txt :實際類別: 10k-20k -->預(yù)測類別: 20k-40k
./dataset/test_segResult/10k-20k/5188881.txt :實際類別: 10k-20k -->預(yù)測類別: 17k-25k
./dataset/test_segResult/10k-20k/5209220.txt :實際類別: 10k-20k -->預(yù)測類別: 18k-30k
./dataset/test_segResult/10k-20k/5266604.txt :實際類別: 10k-20k -->預(yù)測類別: 6k-10k
./dataset/test_segResult/10k-20k/5267640.txt :實際類別: 10k-20k -->預(yù)測類別: 15k-25k
./dataset/test_segResult/10k-20k/5268311.txt :實際類別: 10k-20k -->預(yù)測類別: 20k-40k
./dataset/test_segResult/10k-20k/5278296.txt :實際類別: 10k-20k -->預(yù)測類別: 12k-20k
./dataset/test_segResult/10k-20k/5296243.txt :實際類別: 10k-20k -->預(yù)測類別: 15k-30k
./dataset/test_segResult/10k-20k/5297948.txt :實際類別: 10k-20k -->預(yù)測類別: 13k-15k
./dataset/test_segResult/10k-20k/5304000.txt :實際類別: 10k-20k -->預(yù)測類別: 20k-30k
./dataset/test_segResult/小強/4897063.txt :實際類別: 小強 -->預(yù)測類別: 11k-20k
erroe rate: 12.203389830508474 %