
機器學(xué)習(xí)之樸素貝葉斯(NB)分類算法與Python實現(xiàn)
樸素貝葉斯(Naive Bayesian)是最為廣泛使用的分類方法,它以概率論為基礎(chǔ),是基于貝葉斯定理和特征條件獨立假設(shè)的分類方法。
一、 概述
1.1 簡介
樸素貝葉斯(Naive Bayesian)是基于貝葉斯定理和特征條件獨立假設(shè)的分類方法,它通過特征計算分類的概率,選取概率大的情況進行分類,因此它是基于概率論的一種機器學(xué)習(xí)分類方法。因為分類的目標(biāo)是確定的,所以也是屬于監(jiān)督學(xué)習(xí)。
Q1:什么是基于概率論的方法?
通過概率來衡量事件發(fā)生的可能性。概率論和統(tǒng)計學(xué)恰好是兩個相反的概念,統(tǒng)計學(xué)是抽取部分樣本進行統(tǒng)計來估算總體的情況,而概率論是通過總體情況來估計單個事件或者部分事情的發(fā)生情況。因此,概率論需要已知的數(shù)據(jù)去預(yù)測未知的事件。
例如,我們看到天氣烏云密布,電閃雷鳴并陣陣狂風(fēng),在這樣的天氣特征(F)下,我們推斷下雨的概率比不下雨的概率大,也就是p(下雨)>p(不下雨),所以認(rèn)為待會兒會下雨。這個從經(jīng)驗上看對概率進行判斷。
而氣象局通過多年長期積累的數(shù)據(jù),經(jīng)過計算,今天下雨的概率p(下雨)=85%,p(不下雨)=15%,同樣的,p(下雨)>p(不下雨),因此今天的天氣預(yù)報肯定預(yù)報下雨。這是通過一定的方法計算概率從而對下雨事件進行判斷。
Q2:樸素貝葉斯,樸素在什么地方?
之所以叫樸素貝葉斯,因為它簡單、易于操作,基于特征獨立性假設(shè),假設(shè)各個特征不會相互影響,這樣就大大減小了計算概率的難度。
1.2 條件概率與貝葉斯定理
(1)概率論中幾個基本概念
事件交和并:
A和B兩個事件的交,指的是事件A和B同時出現(xiàn),記為A∩B;
A和B兩個事件的并,指的是事件A和事件B至少出現(xiàn)一次的情況,記為A∪B。
互補事件:事件A的補集,也就是事件A不發(fā)生的時候的事件,記為Ac。這個時候,要么A發(fā)生,要么Ac發(fā)生,P(A)+P(Ac)=1。
條件概率(conditional probability):
某個事件發(fā)生時另外一個事件發(fā)生的概率,如事件B發(fā)生條件下事件A發(fā)生的概率:
概率的乘法法則(multiplication rule of probability):
獨立事件交的概率:
兩個相互獨立的事件,其交的概率為:
更多概率論基本概念,參見:概率論基本概念
(2)貝葉斯定理(Bayes’s Rule):
如果有k個互斥且有窮個事件
p(A):事件A發(fā)生的概率;
p(A∩B):事件A 和事件B同時發(fā)生的概率
p(A|B):表示事件A在事件B發(fā)生的條件下發(fā)生的概率,
1.3 樸素貝葉斯分類的原理
樸素貝葉斯基于條件概率、貝葉斯定理和獨立性假設(shè)原則
(1)首先,我們來看條件概率原理:
基于概率論的方法告訴我們,當(dāng)只有兩種分類時:
(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;
貝葉斯定理最大的好處是可以用已知的三個概率去計算未知的概率,而如果僅僅是為了比較p(ci|x,y)和p(cj|x,y)的大小,只需要已知兩個概率即可,分母相同,比較p(x,y|ci)p(ci)和p(x,y|cj)p(cj)即可。
(3)特征條件獨立假設(shè)原則
樸素貝葉斯最常見的分類應(yīng)用是對文檔進行分類,因此,最常見的特征條件是文檔中,出現(xiàn)詞匯的情況,通常將詞匯出現(xiàn)的特征條件用詞向量ω表示,由多個數(shù)值組成,數(shù)值的個數(shù)和訓(xùn)練樣本集中的詞匯表個數(shù)相同。
因此,上述的貝葉斯條件概率公式可表示為:
前面提到樸素貝葉斯還有一個假設(shè),就是基于特征條件獨立的假設(shè),也就是我們姑且認(rèn)為詞匯表中各個單詞獨立出現(xiàn),不會相互影響,因此,p(ω|ci)可以將ω展開成獨立事件概率相乘的形式,因此:
這樣,計算概率就簡單太多了。
1.4 樸素貝葉斯分類的流程和優(yōu)缺點
(1)分類流程
1.數(shù)據(jù)準(zhǔn)備:收集數(shù)據(jù),并將數(shù)據(jù)預(yù)處理為數(shù)值型或者布爾型,如對文本分類,需要將文本解析為詞向量
2.訓(xùn)練數(shù)據(jù):根據(jù)訓(xùn)練樣本集計算詞項出現(xiàn)的概率,訓(xùn)練數(shù)據(jù)后得到各類下詞匯出現(xiàn)概率的向量
3. 測試數(shù)據(jù):用測試樣本集去測試分類的準(zhǔn)確性
(2) 優(yōu)缺點
1. 監(jiān)督學(xué)習(xí),需要確定分類的目標(biāo)
2. 對缺失數(shù)據(jù)不敏感,在數(shù)據(jù)較少的情況下依然可以使用該方法
3. 可以處理多個類別 的分類問題
4. 適用于標(biāo)稱型數(shù)據(jù)
5. 對輸入數(shù)據(jù)的形勢比較敏感
6. 由于用先驗數(shù)據(jù)去預(yù)測分類,因此存在誤差
二、Python算法實現(xiàn)
以在線社區(qū)的留言板評論為例,運用樸素貝葉斯分類方法,對文本進行自動分類。
構(gòu)造一些實驗樣本,包括已經(jīng)切分詞條的文檔集合,并且已經(jīng)分類(帶有侮辱性言論,和正常言論)。為了獲取方便,在bayes.py中構(gòu)造一個loadDataSet函數(shù)來生成實驗樣本。
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) #取兩個集合的并集
return list(vocabSet)
(2)對輸入的詞匯表構(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)建詞向量的方法,只記錄了每個詞是否出現(xiàn),而沒有記錄詞出現(xiàn)的次數(shù),這樣的模型叫做詞集模型,如果在詞向量中記錄詞出現(xiàn)的次數(shù),沒出現(xiàn)一次,則多記錄一次,這樣的詞向量構(gòu)建方法,被稱為詞袋模型,下面構(gòu)建以一個詞袋模型的詞向量生成函數(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ù)的詞向量
測試,對詞向量生成函數(shù)進行測試,在控制臺輸入如下命令:
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 運用詞向量計算概率
再看前文提到的樸素貝葉斯的原理,要計算詞向量ω=(ω0,ω1,ω2,...ωN,),落入ci類別下的概率:
因此計算出現(xiàn)概率大致有這么一些流程:
是用Python代碼實現(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)侮辱性評論的概率
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求長度函數(shù)則對所有0和1進行計數(shù),最后得到分類為1的概率
2.p0Num+=trainMatrix[i];p0Demon+=sum(trainMatrix[i]),前者是向量相加,其結(jié)果還是向量,trainMatrix[i]中是1的位置全部加到p0Num中,后者是先求和(該詞向量中詞項的數(shù)目),其結(jié)果是數(shù)值,表示詞項總數(shù)。
3.p0Vec=p0Num/p0Demon,向量除以數(shù)值,結(jié)果是向量,向量中每個元素都除以該數(shù)值。
測試:對構(gòu)建的樸素貝葉斯分類器訓(xùn)練函數(shù)進行測試,在python(個人使用的是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個詞匯是'love',即myVocabList[25]='love'
In [121]: p0v[25]
Out[121]: 0.041666666666666664
In [122]: p1v[25]
Out[122]: 0.0
##myVocabList中第13個詞匯是'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,詞項’love’在侮辱性文檔中出現(xiàn)的概率是0,在正常言論中出現(xiàn)的概率是0.042;詞項‘stupid’在正常言論中出現(xiàn)的概率是0,在侮辱性言論中出現(xiàn)的規(guī)律是0.158.
算法漏洞:
乘積為0
我們看到,當(dāng)某分類下某詞項出現(xiàn)頻次為0時,其概率也是0,因此在計算p(w0|ci)p(w1|ci)p(w2|ci)......p(wN|ci)會因為其中某個的概率為0而全部是0。
為了避免這樣的情況發(fā)生,我們將所有詞項出現(xiàn)的頻次都初始化為1,某類所有詞項數(shù)量初始化為2。
因子太小導(dǎo)致結(jié)果溢出問題
由于p(w0|ci)p(w1|ci)p(w2|ci)......p(wN|ci)中每個因子都很小,所有因子相乘,特別是因子數(shù)量多的時候,會導(dǎo)致結(jié)果溢出,從而得到錯誤的數(shù)據(jù)
避免溢出問題的發(fā)生,可以使用求自然對數(shù)的方法,自然對數(shù)和原本的數(shù)值同增同減,不會有任何損失,因此不會影響求得的概率結(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) #對結(jié)果求對數(shù)
p1Vec=log(p1Num/p1Demon) #對結(jié)果求自然對數(shù)
return p0Vec,p1Vec,pAbusive
2.3 運用分類器函數(shù)對文檔進行分類
前文概率論講到,計算文檔在各類中的概率,取較大者作為該文檔的分類,所以構(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)造幾個樣本,來測試分類函數(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))
測試,在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 #分類到侮辱性言論
三、 實例:使用樸素貝葉斯過濾垃圾郵件
文件夾spam和ham中各有25封txt文檔形式的郵件正文,兩個文件夾分別分類為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)在,利用這些文檔,進行樸素貝葉斯分類算法訓(xùn)練和測試:
#切分文本函數(shù) def textParser(bigString): import re #正則表達式 listOfTokens=re.split(r'\W*',bigString) #\W表示非單詞符進行劃分 return [tok.lower() for tok in listOfTokens if len(tok)>2] #返回小寫且長度大于2的詞項 #對文件夾中文件進行自動處理 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) #留存交叉驗證 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ù)樣本,隨機選取一部分作為訓(xùn)練樣本集,剩余部分作為測試樣本集,這樣的方法稱為留存交叉驗證
在Python console中對函數(shù)進行測試:
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)
可以看到測試的錯誤率為0.1,并且輸出了分類錯誤的文檔中的詞項。多次執(zhí)行上述函數(shù)進行測試,發(fā)現(xiàn)錯誤率會變化。
四、實例:使用樸素貝葉斯分類器從個人廣告中獲取區(qū)域傾向
我們利用python庫中中的Universal Feed Parser來獲取數(shù)據(jù),首先需要引入包feedparser:import feedparser,如果沒有需要安裝,比較簡單的方法是使用pip進行安裝。
#獲取頻率最高的詞項
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個詞
#去掉出現(xiàn)頻率最高的30個詞
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àn)頻次高的詞項很多是沒有意義的冗余和輔助性內(nèi)容,不移除這些詞匯,使用樸素貝葉斯分類算法,其錯誤率會顯著高一些
- 另外一個方法,是從詞表中刪除輔助詞,這個需要刪除的詞表被稱為停用詞表,這個網(wǎng)站列出了多門語言,如英文、中文等語言中的停用詞表。
在Python命令符中對上述函數(shù)進行測試:
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)):
#選取一個閾值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])
測試:在Python命令符中輸入命令來測試函數(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ù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
SQL Server 中 CONVERT 函數(shù)的日期轉(zhuǎn)換:從基礎(chǔ)用法到實戰(zhàn)優(yōu)化 在 SQL Server 的數(shù)據(jù)處理中,日期格式轉(zhuǎn)換是高頻需求 —— 無論 ...
2025-09-18MySQL 大表拆分與關(guān)聯(lián)查詢效率:打破 “拆分必慢” 的認(rèn)知誤區(qū) 在 MySQL 數(shù)據(jù)庫管理中,“大表” 始終是性能優(yōu)化繞不開的話題。 ...
2025-09-18CDA 數(shù)據(jù)分析師:表結(jié)構(gòu)數(shù)據(jù) “獲取 - 加工 - 使用” 全流程的賦能者 表結(jié)構(gòu)數(shù)據(jù)(如數(shù)據(jù)庫表、Excel 表、CSV 文件)是企業(yè)數(shù)字 ...
2025-09-18DSGE 模型中的 Et:理性預(yù)期算子的內(nèi)涵、作用與應(yīng)用解析 動態(tài)隨機一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明確:TIF 中的地名有哪兩種存在形式? 在開始提取前,需先判斷 TIF 文件的類型 —— ...
2025-09-17CDA 數(shù)據(jù)分析師:解鎖表結(jié)構(gòu)數(shù)據(jù)特征價值的專業(yè)核心 表結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 規(guī)范存儲的結(jié)構(gòu)化數(shù)據(jù),如數(shù)據(jù)庫表、Excel 表、 ...
2025-09-17Excel 導(dǎo)入數(shù)據(jù)含缺失值?詳解 dropna 函數(shù)的功能與實戰(zhàn)應(yīng)用 在用 Python(如 pandas 庫)處理 Excel 數(shù)據(jù)時,“缺失值” 是高頻 ...
2025-09-16深入解析卡方檢驗與 t 檢驗:差異、適用場景與實踐應(yīng)用 在數(shù)據(jù)分析與統(tǒng)計學(xué)領(lǐng)域,假設(shè)檢驗是驗證研究假設(shè)、判斷數(shù)據(jù)差異是否 “ ...
2025-09-16CDA 數(shù)據(jù)分析師:掌控表格結(jié)構(gòu)數(shù)據(jù)全功能周期的專業(yè)操盤手 表格結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 存儲的結(jié)構(gòu)化數(shù)據(jù),如 Excel 表、數(shù)據(jù) ...
2025-09-16MySQL 執(zhí)行計劃中 rows 數(shù)量的準(zhǔn)確性解析:原理、影響因素與優(yōu)化 在 MySQL SQL 調(diào)優(yōu)中,EXPLAIN執(zhí)行計劃是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 對象的 text 與 content:區(qū)別、場景與實踐指南 在 Python 進行 HTTP 網(wǎng)絡(luò)請求開發(fā)時(如使用requests ...
2025-09-15CDA 數(shù)據(jù)分析師:激活表格結(jié)構(gòu)數(shù)據(jù)價值的核心操盤手 表格結(jié)構(gòu)數(shù)據(jù)(如 Excel 表格、數(shù)據(jù)庫表)是企業(yè)最基礎(chǔ)、最核心的數(shù)據(jù)形態(tài) ...
2025-09-15Python HTTP 請求工具對比:urllib.request 與 requests 的核心差異與選擇指南 在 Python 處理 HTTP 請求(如接口調(diào)用、數(shù)據(jù)爬取 ...
2025-09-12解決 pd.read_csv 讀取長浮點數(shù)據(jù)的科學(xué)計數(shù)法問題 為幫助 Python 數(shù)據(jù)從業(yè)者解決pd.read_csv讀取長浮點數(shù)據(jù)時的科學(xué)計數(shù)法問題 ...
2025-09-12CDA 數(shù)據(jù)分析師:業(yè)務(wù)數(shù)據(jù)分析步驟的落地者與價值優(yōu)化者 業(yè)務(wù)數(shù)據(jù)分析是企業(yè)解決日常運營問題、提升執(zhí)行效率的核心手段,其價值 ...
2025-09-12用 SQL 驗證業(yè)務(wù)邏輯:從規(guī)則拆解到數(shù)據(jù)把關(guān)的實戰(zhàn)指南 在業(yè)務(wù)系統(tǒng)落地過程中,“業(yè)務(wù)邏輯” 是連接 “需求設(shè)計” 與 “用戶體驗 ...
2025-09-11塔吉特百貨孕婦營銷案例:數(shù)據(jù)驅(qū)動下的精準(zhǔn)零售革命與啟示 在零售行業(yè) “流量紅利見頂” 的當(dāng)下,精準(zhǔn)營銷成為企業(yè)突圍的核心方 ...
2025-09-11CDA 數(shù)據(jù)分析師與戰(zhàn)略 / 業(yè)務(wù)數(shù)據(jù)分析:概念辨析與協(xié)同價值 在數(shù)據(jù)驅(qū)動決策的體系中,“戰(zhàn)略數(shù)據(jù)分析”“業(yè)務(wù)數(shù)據(jù)分析” 是企業(yè) ...
2025-09-11Excel 數(shù)據(jù)聚類分析:從操作實踐到業(yè)務(wù)價值挖掘 在數(shù)據(jù)分析場景中,聚類分析作為 “無監(jiān)督分組” 的核心工具,能從雜亂數(shù)據(jù)中挖 ...
2025-09-10統(tǒng)計模型的核心目的:從數(shù)據(jù)解讀到?jīng)Q策支撐的價值導(dǎo)向 統(tǒng)計模型作為數(shù)據(jù)分析的核心工具,并非簡單的 “公式堆砌”,而是圍繞特定 ...
2025-09-10