99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁精彩閱讀機(jī)器學(xué)習(xí)之樸素貝葉斯(NB)分類算法與Python實(shí)現(xiàn)
機(jī)器學(xué)習(xí)之樸素貝葉斯(NB)分類算法與Python實(shí)現(xiàn)
2017-07-23
收藏

機(jī)器學(xué)習(xí)樸素貝葉斯(NB)分類算法與Python實(shí)現(xiàn)

樸素貝葉斯(Naive Bayesian)是最為廣泛使用的分類方法,它以概率論為基礎(chǔ),是基于貝葉斯定理和特征條件獨(dú)立假設(shè)的分類方法。

一、 概述

1.1 簡(jiǎn)介

樸素貝葉斯(Naive Bayesian)是基于貝葉斯定理和特征條件獨(dú)立假設(shè)的分類方法,它通過特征計(jì)算分類的概率,選取概率大的情況進(jìn)行分類,因此它是基于概率論的一種機(jī)器學(xué)習(xí)分類方法。因?yàn)榉诸惖哪繕?biāo)是確定的,所以也是屬于監(jiān)督學(xué)習(xí)。

Q1:什么是基于概率論的方法?
通過概率來衡量事件發(fā)生的可能性。概率論和統(tǒng)計(jì)學(xué)恰好是兩個(gè)相反的概念,統(tǒng)計(jì)學(xué)是抽取部分樣本進(jìn)行統(tǒng)計(jì)來估算總體的情況,而概率論是通過總體情況來估計(jì)單個(gè)事件或者部分事情的發(fā)生情況。因此,概率論需要已知的數(shù)據(jù)去預(yù)測(cè)未知的事件。
例如,我們看到天氣烏云密布,電閃雷鳴并陣陣狂風(fēng),在這樣的天氣特征(F)下,我們推斷下雨的概率比不下雨的概率大,也就是p(下雨)>p(不下雨),所以認(rèn)為待會(huì)兒會(huì)下雨。這個(gè)從經(jīng)驗(yàn)上看對(duì)概率進(jìn)行判斷。
而氣象局通過多年長(zhǎng)期積累的數(shù)據(jù),經(jīng)過計(jì)算,今天下雨的概率p(下雨)=85%,p(不下雨)=15%,同樣的,p(下雨)>p(不下雨),因此今天的天氣預(yù)報(bào)肯定預(yù)報(bào)下雨。這是通過一定的方法計(jì)算概率從而對(duì)下雨事件進(jìn)行判斷。

Q2:樸素貝葉斯,樸素在什么地方?
之所以叫樸素貝葉斯,因?yàn)樗?jiǎn)單、易于操作,基于特征獨(dú)立性假設(shè),假設(shè)各個(gè)特征不會(huì)相互影響,這樣就大大減小了計(jì)算概率的難度。

1.2 條件概率與貝葉斯定理

(1)概率論中幾個(gè)基本概念

事件交和并:
A和B兩個(gè)事件的交,指的是事件A和B同時(shí)出現(xiàn),記為A∩B;
A和B兩個(gè)事件的并,指的是事件A和事件B至少出現(xiàn)一次的情況,記為A∪B。

互補(bǔ)事件:事件A的補(bǔ)集,也就是事件A不發(fā)生的時(shí)候的事件,記為Ac。這個(gè)時(shí)候,要么A發(fā)生,要么Ac發(fā)生,P(A)+P(Ac)=1。

條件概率(conditional probability):
某個(gè)事件發(fā)生時(shí)另外一個(gè)事件發(fā)生的概率,如事件B發(fā)生條件下事件A發(fā)生的概率:

概率的乘法法則(multiplication rule of probability):

獨(dú)立事件交的概率:
兩個(gè)相互獨(dú)立的事件,其交的概率為:

更多概率論基本概念,參見:概率論基本概念

(2)貝葉斯定理(Bayes’s Rule):
如果有k個(gè)互斥且有窮個(gè)事件


p(A):事件A發(fā)生的概率;
p(A∩B):事件A 和事件B同時(shí)發(fā)生的概率
p(A|B):表示事件A在事件B發(fā)生的條件下發(fā)生的概率,

1.3 樸素貝葉斯分類的原理

樸素貝葉斯基于條件概率、貝葉斯定理和獨(dú)立性假設(shè)原則
(1)首先,我們來看條件概率原理:

基于概率論的方法告訴我們,當(dāng)只有兩種分類時(shí):

(2)其次,貝葉斯定理
同樣的道理,引入貝葉斯定理,有:

其中,x,y表示特征變量,ci表示分類,p(ci|x,y)即表示在特征為x,y的情況下分入類別ci的概率,因此,結(jié)合條件概率和貝葉斯定理,有:

如果p(c1|x,y)>p(c2|x,y),那么分類應(yīng)當(dāng)屬于c1;

如果p(c1|x,y)<p(c2|x,y),那么分類應(yīng)當(dāng)屬于c2;

貝葉斯定理最大的好處是可以用已知的三個(gè)概率去計(jì)算未知的概率,而如果僅僅是為了比較p(ci|x,y)和p(cj|x,y)的大小,只需要已知兩個(gè)概率即可,分母相同,比較p(x,y|ci)p(ci)和p(x,y|cj)p(cj)即可。

(3)特征條件獨(dú)立假設(shè)原則

樸素貝葉斯最常見的分類應(yīng)用是對(duì)文檔進(jìn)行分類,因此,最常見的特征條件是文檔中,出現(xiàn)詞匯的情況,通常將詞匯出現(xiàn)的特征條件用詞向量ω表示,由多個(gè)數(shù)值組成,數(shù)值的個(gè)數(shù)和訓(xùn)練樣本集中的詞匯表個(gè)數(shù)相同。
因此,上述的貝葉斯條件概率公式可表示為:

前面提到樸素貝葉斯還有一個(gè)假設(shè),就是基于特征條件獨(dú)立的假設(shè),也就是我們姑且認(rèn)為詞匯表中各個(gè)單詞獨(dú)立出現(xiàn),不會(huì)相互影響,因此,p(ω|ci)可以將ω展開成獨(dú)立事件概率相乘的形式,因此:


這樣,計(jì)算概率就簡(jiǎn)單太多了。

1.4 樸素貝葉斯分類的流程和優(yōu)缺點(diǎn)

(1)分類流程

1.數(shù)據(jù)準(zhǔn)備:收集數(shù)據(jù),并將數(shù)據(jù)預(yù)處理為數(shù)值型或者布爾型,如對(duì)文本分類,需要將文本解析為詞向量
2.訓(xùn)練數(shù)據(jù):根據(jù)訓(xùn)練樣本集計(jì)算詞項(xiàng)出現(xiàn)的概率,訓(xùn)練數(shù)據(jù)后得到各類下詞匯出現(xiàn)概率的向量
3. 測(cè)試數(shù)據(jù):用測(cè)試樣本集去測(cè)試分類的準(zhǔn)確性

(2) 優(yōu)缺點(diǎn)
1. 監(jiān)督學(xué)習(xí),需要確定分類的目標(biāo)
2. 對(duì)缺失數(shù)據(jù)不敏感,在數(shù)據(jù)較少的情況下依然可以使用該方法
3. 可以處理多個(gè)類別 的分類問題
4. 適用于標(biāo)稱型數(shù)據(jù)
5. 對(duì)輸入數(shù)據(jù)的形勢(shì)比較敏感
6. 由于用先驗(yàn)數(shù)據(jù)去預(yù)測(cè)分類,因此存在誤差

二、Python算法實(shí)現(xiàn)

以在線社區(qū)的留言板評(píng)論為例,運(yùn)用樸素貝葉斯分類方法,對(duì)文本進(jìn)行自動(dòng)分類。

構(gòu)造一些實(shí)驗(yàn)樣本,包括已經(jīng)切分詞條的文檔集合,并且已經(jīng)分類(帶有侮辱性言論,和正常言論)。為了獲取方便,在bayes.py中構(gòu)造一個(gè)loadDataSet函數(shù)來生成實(shí)驗(yàn)樣本。

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] #1表示侮辱性言論,0表示正常言論
    return postingList,classVec

2.1 根據(jù)文檔詞匯表構(gòu)建詞向量

(1)構(gòu)建詞匯表生成函數(shù)creatVocabList:

def createVocabList(dataSet):
    vocabSet=set([])
    for document in dataSet:
        vocabSet=vocabSet|set(document) #取兩個(gè)集合的并集
    return list(vocabSet)


(2)對(duì)輸入的詞匯表構(gòu)建詞向量

#詞集模型
def setOfWords2Vec(vocabList,inputSet):
    returnVec=zeros(len(vocabList)) #生成零向量的array
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)]=1 #有單詞,則該位置填充0
        else: print('the word:%s is not in my Vocabulary!'% word)
    return returnVec #返回全為0和1的向量


這種構(gòu)建詞向量的方法,只記錄了每個(gè)詞是否出現(xiàn),而沒有記錄詞出現(xiàn)的次數(shù),這樣的模型叫做詞集模型,如果在詞向量中記錄詞出現(xiàn)的次數(shù),沒出現(xiàn)一次,則多記錄一次,這樣的詞向量構(gòu)建方法,被稱為詞袋模型,下面構(gòu)建以一個(gè)詞袋模型的詞向量生成函數(shù)bagOfWord2VecMN:

#詞袋模型
def bagOfWords2VecMN(vocabList,inputSet):
    returnVec=[0]*len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)]+=1
    return returnVec #返回非負(fù)整數(shù)的詞向量
    測(cè)試,對(duì)詞向量生成函數(shù)進(jìn)行測(cè)試,在控制臺(tái)輸入如下命令:

In [105]: import bayes
     ...:
In [106]: listPosts,listClasses=bayes.loadDataSet()
     ...:
In [107]: myVocabList=bayes.createVocabList(listPosts)
     ...:
In [108]: myVocabList
     ...:
Out[108]:
['I','quit', 'him', 'licks', 'food', 'problems', 'how', 'help', 'mr', 'my', 'take', 'posting', 'stupid', 'has', 'steak', 'buying', 'dalmation', 'flea', 'cute', 'park', 'please', 'dog', 'worthless', 'to', 'garbage','love', 'is', 'so', 'maybe', 'ate', 'stop', 'not']

In [109]: bayes.setOfWords2Vec(myVocabList,listPosts[0])
     ...:
Out[109]: array([ 0.,  0.,  0., ...,  0.,  0.,  0.])

In [110]: bayes.setOfWords2Vec(myVocabList,listPosts[1])
     ...:

2.2 運(yùn)用詞向量計(jì)算概率

再看前文提到的樸素貝葉斯的原理,要計(jì)算詞向量ω=(ω0,ω1,ω2,...ωN,),落入ci類別下的概率:

因此計(jì)算出現(xiàn)概率大致有這么一些流程:

是用Python代碼實(shí)現(xiàn),創(chuàng)建函數(shù)TrainNB:

def trainNB0(trainMatrix,trainCategory):
    numTrainDocs=len(trainMatrix) #文檔數(shù)目
    numWord=len(trainMatrix[0]) #詞匯表詞數(shù)目
    pAbusive=sum(trainCategory)/len(trainCategory) #p1,出現(xiàn)侮辱性評(píng)論的概率
    p0Num=zeros(numWord);p1Num=zeros(numWord)
    p0Demon=0;p1Demon=0
    for i in range(numTrainDocs):
        if trainCategory[i]==0:
            p0Num+=trainMatrix[i] #向量相加
            p0Demon+=sum(trainMatrix[i]) #向量中1累加求和
        else:
            p1Num+=trainMatrix[i]
            p1Demon+=sum(trainMatrix[i])
    p0Vec=p0Num/p0Demon
    p1Vec=p1Num/p1Demon
    return p0Vec,p1Vec,pAbusive

解釋:
1.pAbusive=sum(trainCategory)/len(trainCategory),表示文檔集中分類為1的文檔數(shù)目,累加求和將詞向量中所有1相加,len求長(zhǎng)度函數(shù)則對(duì)所有0和1進(jìn)行計(jì)數(shù),最后得到分類為1的概率
2.p0Num+=trainMatrix[i];p0Demon+=sum(trainMatrix[i]),前者是向量相加,其結(jié)果還是向量,trainMatrix[i]中是1的位置全部加到p0Num中,后者是先求和(該詞向量中詞項(xiàng)的數(shù)目),其結(jié)果是數(shù)值,表示詞項(xiàng)總數(shù)。
3.p0Vec=p0Num/p0Demon,向量除以數(shù)值,結(jié)果是向量,向量中每個(gè)元素都除以該數(shù)值。

測(cè)試:對(duì)構(gòu)建的樸素貝葉斯分類器訓(xùn)練函數(shù)進(jìn)行測(cè)試,在python(個(gè)人使用的是ipython)提示符中輸入:

In [111]: reload(bayes)
     ...:
Out[111]: <module 'bayes' from 'G:\\Workspaces\\MachineLearning\\bayes.py'>
In [112]: listPosts,listClasses=bayes.loadDataSet()
     ...:
In [113]: myVocabList=bayes.createVocabList(listPosts)
     ...:
In [114]: trainMat=[]
     ...:
In [115]: for postinDoc in listPosts:
     ...:     trainMat.append(bayes.setOfWords2Vec(myVocabList,postinDoc))
     ...:
     ...:
In [116]: p0v,p1v,pAb=bayes.trainNB0(trainMat,listClasses)
     ...:
In [117]: pAb
     ...:
Out[117]: 0.5
In [118]: p0v
     ...:
Out[118]:
array([ 0.04166667,  0.        ,  0.08333333, ...,  0.04166667,
        0.04166667,  0.        ])
In [119]: p1v
     ...:
Out[119]:
array([ 0.        ,  0.05263158,  0.05263158, ...,  0.        ,
        0.05263158,  0.05263158])
#myVocabList中第26個(gè)詞匯是'love',即myVocabList[25]='love'
In [121]: p0v[25]
Out[121]: 0.041666666666666664
In [122]: p1v[25]
Out[122]: 0.0
##myVocabList中第13個(gè)詞匯是'stupid',即myVocabList[13]='stupid'
In [124]: p0v[12]
Out[124]: 0.0
In [125]: p1v[12]
Out[125]: 0.15789473684210525


從結(jié)果我們看到,侮辱性文檔出現(xiàn)的概率是0.5,詞項(xiàng)’love’在侮辱性文檔中出現(xiàn)的概率是0,在正常言論中出現(xiàn)的概率是0.042;詞項(xiàng)‘stupid’在正常言論中出現(xiàn)的概率是0,在侮辱性言論中出現(xiàn)的規(guī)律是0.158.

算法漏洞:

乘積為0

我們看到,當(dāng)某分類下某詞項(xiàng)出現(xiàn)頻次為0時(shí),其概率也是0,因此在計(jì)算p(w0|ci)p(w1|ci)p(w2|ci)......p(wN|ci)會(huì)因?yàn)槠渲心硞€(gè)的概率為0而全部是0。

為了避免這樣的情況發(fā)生,我們將所有詞項(xiàng)出現(xiàn)的頻次都初始化為1,某類所有詞項(xiàng)數(shù)量初始化為2。

因子太小導(dǎo)致結(jié)果溢出問題

由于p(w0|ci)p(w1|ci)p(w2|ci)......p(wN|ci)中每個(gè)因子都很小,所有因子相乘,特別是因子數(shù)量多的時(shí)候,會(huì)導(dǎo)致結(jié)果溢出,從而得到錯(cuò)誤的數(shù)據(jù)

避免溢出問題的發(fā)生,可以使用求自然對(duì)數(shù)的方法,自然對(duì)數(shù)和原本的數(shù)值同增同減,不會(huì)有任何損失,因此不會(huì)影響求得的概率結(jié)果。

因此,將樸素貝葉斯分類器函數(shù)修改為:

def trainNB1(trainMatrix,trainCategory):
    numTrainDocs=len(trainMatrix)
    numWord=len(trainMatrix[0])
    pAbusive=sum(trainCategory)/len(trainCategory)
    p0Num=ones(numWord);p1Num=ones(numWord)# 初始化為1
    p0Demon=2;p1Demon=2 #初始化為2
    for i in range(numTrainDocs):
        if trainCategory[i]==0:
            p0Num+=trainMatrix[i]
            p0Demon+=sum(trainMatrix[i])
        else:
            p1Num+=trainMatrix[i]
            p1Demon+=sum(trainMatrix[i])
    p0Vec=log(p0Num/p0Demon) #對(duì)結(jié)果求對(duì)數(shù)
    p1Vec=log(p1Num/p1Demon) #對(duì)結(jié)果求自然對(duì)數(shù)
    return p0Vec,p1Vec,pAbusive

2.3 運(yùn)用分類器函數(shù)對(duì)文檔進(jìn)行分類

前文概率論講到,計(jì)算文檔在各類中的概率,取較大者作為該文檔的分類,所以構(gòu)建分類函數(shù)classifyNB:

def testingNB():
    listPosts,listClasses=loadDataSet()
    myVocabList=createVocabList(listPosts)
    trainMat=[]
    for postinDoc in listPosts:
        trainMat.append(setOfWords2Vec(myVocabList,postinDoc))
    p0V,p1V,pAb=trainNB1(trainMat,listClasses)
    testEntry=['love','my','dalmation']
    thisDoc=setOfWords2Vec(myVocabList,testEntry)
    print(testEntry,'classified as:',classifyNB(thisDoc,p0V,p1V,pAb))
    testEntry=['stupid','garbage']
    thisDoc=array(setOfWords2Vec(myVocabList,testEntry))
    print(testEntry,'classified as:',classifyNB(thisDoc,p0V,p1V,pAb))


說明:
p1=sum(vec2Classify*p1Vec)+log(pClass1) 的數(shù)學(xué)原理是ln(a*b)=ln(a) +ln(b)

接下來構(gòu)造幾個(gè)樣本,來測(cè)試分類函數(shù):

def testingNB():
    listPosts,listClasses=loadDataSet()
    myVocabList=createVocabList(listPosts)
    trainMat=[]
    for postinDoc in listPosts:
        trainMat.append(setOfWords2Vec(myVocabList,postinDoc))
    p0V,p1V,pAb=trainNB1(trainMat,listClasses)
    testEntry=['love','my','dalmation']
    thisDoc=setOfWords2Vec(myVocabList,testEntry)
    print(testEntry,'classified as:',classifyNB(thisDoc,p0V,p1V,pAb))
    testEntry=['stupid','garbage']
    thisDoc=array(setOfWords2Vec(myVocabList,testEntry))
    print(testEntry,'classified as:',classifyNB(thisDoc,p0V,p1V,pAb))

測(cè)試,在Python命令符中輸入:In [126]: reload(bayes)

...:
Out[126]: <module 'bayes' from 'G:\\Workspaces\\MachineLearning\\bayes.py'>

In [127]: bayes.testingNB()
     ...:
['love', 'my', 'dalmation'] classified as: 0 #分類到正常言論
['stupid', 'garbage'] classified as: 1 #分類到侮辱性言論

三、 實(shí)例:使用樸素貝葉斯過濾垃圾郵件

文件夾spam和ham中各有25封txt文檔形式的郵件正文,兩個(gè)文件夾分別分類為1和0,如打開ham中2.txt文件,其內(nèi)容為:

Yay to you both doing fine!

I'm working on an MBA in Design Strategy at CCA (top art school.)  It's a new program focusing on more of a right-brained creative and strategic approach to management.  I'm an 1/8 of the way done today!

現(xiàn)在,利用這些文檔,進(jìn)行樸素貝葉斯分類算法訓(xùn)練和測(cè)試:


#切分文本函數(shù)
def textParser(bigString):
    import re #正則表達(dá)式
    listOfTokens=re.split(r'\W*',bigString) #\W表示非單詞符進(jìn)行劃分
    return [tok.lower() for tok in listOfTokens if len(tok)>2] #返回小寫且長(zhǎng)度大于2的詞項(xiàng)

#對(duì)文件夾中文件進(jìn)行自動(dòng)處理
def spanTest():
    docList=[];classList=[];fullText=[]
    for i in range(1,26):
        wordList=textParser(open('machinelearninginaction/Ch04/email/spam/%d.txt'%i).read())
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(1)
        wordList=textParser(open('machinelearninginaction/Ch04/email/ham/%d.txt'%i).read())
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(0)
    vocabList=createVocabList(docList)
    #留存交叉驗(yàn)證
    trainingSet=list(range(50));testSet=[]
    for i in range(10):
        randIndex=int(random.uniform(0,len(trainingSet)))
        testSet.append(trainingSet[randIndex])
        del(trainingSet[randIndex])
    trainMat=[];trainClasses=[]
    for docIndex in trainingSet:
        trainMat.append(setOfWords2Vec(vocabList,docList[docIndex]))
        trainClasses.append(classList[docIndex])
    p0V,p1V,pAb=trainNB1(trainMat,trainClasses)
    errorCount=0
    for docIndex in testSet:
        wordVector=setOfWords2Vec(vocabList,docList[docIndex])
        if classifyNB(wordVector,p0V,p1V,pAb) != classList[docIndex]:
            errorCount+=1
            print('classification error',docList[docIndex])
    print('the error rate is:',float(errorCount)/len(testSet))


利用該樣本集合中的數(shù)據(jù)樣本,隨機(jī)選取一部分作為訓(xùn)練樣本集,剩余部分作為測(cè)試樣本集,這樣的方法稱為留存交叉驗(yàn)證

在Python console中對(duì)函數(shù)進(jìn)行測(cè)試:

In [131]: bayes.spanTest()
     ...:
classification error ['home', 'based', 'business', 'opportunity', 'knocking', 'your', 'door', 'don抰', 'rude', 'and', 'let', 'this', 'chance', 'you', 'can', 'earn', 'great', 'income', 'and', 'find', 'your', 'financial', 'life', 'transformed', 'learn', 'more', 'here', 'your', 'success', 'work', 'from', 'home', 'finder', 'experts']
the error rate is: 0.1
D:\Tools\ANACONDA\lib\re.py:212: FutureWarning: split() requires a non-empty pattern match.
  return _compile(pattern, flags).split(string, maxsplit)

可以看到測(cè)試的錯(cuò)誤率為0.1,并且輸出了分類錯(cuò)誤的文檔中的詞項(xiàng)。多次執(zhí)行上述函數(shù)進(jìn)行測(cè)試,發(fā)現(xiàn)錯(cuò)誤率會(huì)變化。

四、實(shí)例:使用樸素貝葉斯分類器從個(gè)人廣告中獲取區(qū)域傾向

我們利用python庫(kù)中中的Universal Feed Parser來獲取數(shù)據(jù),首先需要引入包feedparser:import feedparser,如果沒有需要安裝,比較簡(jiǎn)單的方法是使用pip進(jìn)行安裝。

#獲取頻率最高的詞項(xiàng)
def calcMostFreq(vocabList,fullText):
    import operator
    freqDict={}
    for word in vocabList:
        freqDict[word]=fullText.count(word)
    sortedFreq=sorted(freqDict.items(),key=operator.itemgetter(1),reverse=True)
    return sortedFreq[:20]

#
def localWords(feed1,feed0):
    import feedparser
    docList=[];classList=[];fullText=[]
    minLen=min(len(feed1['entries']),len(feed0['entries']))
    for i in range(minLen):
        wordList=textParser(feed1['entries'][i]['summary'])
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(1)
        wordList=textParser(feed0['entries'][i]['summary'])
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(0)
    vocabList=createVocabList(docList)
    top30words=calcMostFreq(vocabList,fullText) #選取頻率最高的30個(gè)詞
    #去掉出現(xiàn)頻率最高的30個(gè)詞
    for pairW in top30words:
        if pairW[0] in vocabList:
            vocabList.remove(pairW[0])
    trainSet=list(range(2*minLen))
    testSet=[]
    for i in range(20):
        randIndex=int(random.uniform(0,len(trainSet)))
        testSet.append(trainSet[randIndex])
        del(trainSet[randIndex])
    trainMat=[];trainClasses=[]
    for docIndex in trainSet:
        trainMat.append(bagOfWords2VecMN(vocabList,docList[docIndex]))
        trainClasses.append(classList[docIndex])
    p0V,p1V,pSpam=trainNB1(trainMat,trainClasses)
    errorCount=0
    for docIndex in testSet:
        wordVector=bagOfWords2VecMN(vocabList,docList[docIndex])
        if classifyNB(wordVector,p0V,p1V,pSpam) !=classList[docIndex]:
            errorCount+=1
    print('the error rate is:',float(errorCount)/len(testSet))
    return vocabList,p0V,p1V

說明:
1.為什么要去除頻次最高的詞項(xiàng):因?yàn)槌霈F(xiàn)頻次高的詞項(xiàng)很多是沒有意義的冗余和輔助性內(nèi)容,不移除這些詞匯,使用樸素貝葉斯分類算法,其錯(cuò)誤率會(huì)顯著高一些
- 另外一個(gè)方法,是從詞表中刪除輔助詞,這個(gè)需要?jiǎng)h除的詞表被稱為停用詞表,這個(gè)網(wǎng)站列出了多門語言,如英文、中文等語言中的停用詞表。

在Python命令符中對(duì)上述函數(shù)進(jìn)行測(cè)試:

In [132]: import feedparser
     ...:
In [133]: ny=feedparser.parse('https://newyork.craigslist.org/stp/index.rss')
     ...:
In [134]: sf=feedparser.parse('https://sfbay.craigslist.org/stp/index.rss')
     ...:
In [135]: vocabList,pSF,pNY=bayes.localWords(ny,sf)
     ...:
the error rate is: 0.45
D:\Tools\ANACONDA\lib\re.py:212: FutureWarning: split() requires a non-empty pattern match.
  return _compile(pattern, flags).split(string, maxsplit)

In [136]: vocabList,pSF,pNY=bayes.localWords(ny,sf)
     ...:
the error rate is: 0.3
D:\Tools\ANACONDA\lib\re.py:212: FutureWarning: split() requires a non-empty pattern match.
  return _compile(pattern, flags).split(string, maxsplit)


(2)顯示最具表征性的詞匯

In [143]: bayes.getTopWords(ny,sf,-4.5)
the error rate is: 0.4
SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF
guy
know
talk
friendship
married
maybe
going
single
out
male
NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY
day
out
meet
chat
seeking
year
time
stocks
well
now
woman
kik
company
work
D:\Tools\ANACONDA\lib\re.py:212: FutureWarning: split() requires a non-empty pattern match.
  return _compile(pattern, flags).split(string, maxsplit)#最具表征性的詞匯表顯示函數(shù)
def getTopWords(ny,sf,t=-6.0):
    import operator
    vocabList,p0V,p1V=localWords(ny,sf)
    topNY=[];topSF=[]
    for i in range(len(p0V)):
    #選取一個(gè)閾值t
        if p0V[i]>t:topSF.append((vocabList[i],p0V[i]))
        if p1V[i]>t:topNY.append((vocabList[i],p1V[i]))
    sortedSF=sorted(topSF,key=lambda x: x[1],reverse=True)
    print('SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF')
    for item in sortedSF:
        print(item[0])        
    sortedNY=sorted(topNY,key=lambda pair: pair[1],reverse=True)
    print('NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY')
    for item in sortedNY:

print(item[0])

測(cè)試:在Python命令符中輸入命令來測(cè)試函數(shù):

In [143]: bayes.getTopWords(ny,sf,-4.5)
the error rate is: 0.4
SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF
guy
know
talk
friendship
married
maybe
going
single
out
male
NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY
day
out
meet
chat
seeking
year
time
stocks
well
now
woman
kik
company
work
D:\Tools\ANACONDA\lib\re.py:212: FutureWarning: split() requires a non-empty pattern match.
  return _compile(pattern, flags).split(string, maxsplit)

數(shù)據(jù)分析咨詢請(qǐng)掃描二維碼

若不方便掃碼,搜微信號(hào):CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個(gè)參數(shù)驗(yàn)證碼對(duì)象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個(gè)配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺(tái)檢測(cè)極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時(shí)表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請(qǐng)參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時(shí)完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請(qǐng)輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請(qǐng)輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }