由於近期學業繁重QAQ,所以我就不說廢話了,直接上代碼~
用樸素貝葉斯進行詞彙分類
代碼
from numpy import *
#詞表到向量的轉換
#創建實驗樣本,返回的是進行詞條切分後的文檔集合,
#還有一個類別標籤——侮辱性的or非侮辱性的
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']]
#1 代表侮辱性文字 0代表正常言論
classVec = [0,1,0,1,0,1]
return postingList,classVec
#創建一個包含在所有文檔中出現的不重複的詞的列表
def createVocabList(dataSet):
vocabSet=set([])
#document:['my', 'dog', 'has', 'flea', 'problems', 'help', 'please']
for document in dataSet:
#求並集
vocabSet=vocabSet|set(document)
#print(vocabSet)
return list(vocabSet)
#參數爲詞彙表以及某個文檔,輸出的是文檔向量
#輸出的向量的每一個元素爲1或0,表示詞彙表中
#的單詞在輸入文檔中是否出現
def setOfWords2Vec(vocabList,inputSet):
#創建一個所含元素都爲0的向量
returnVec=[0]*len(vocabList)
#遍歷文檔中的所有單詞,如果出現了詞彙表中的單詞,
#則將輸出文檔的對應值設爲1
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)]=1
else:
print("the word: %s is not in my Vocabulary!"%word)
return returnVec
#輸入的參數:文檔矩陣trainMatrix
#由每篇文檔類別標籤構成的向量trainCategory
#樸素貝葉斯分類器訓練函數
#trainMatrix:每個詞向量中的詞,在詞彙表中出現的就是1
#trainMatrix:[[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0],
#[0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0],
#[1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0],
#[0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
#[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0]]
#該詞向量中帶有侮辱性的詞的就是1
#trainCategory:[0, 1, 0, 1, 0, 1]
def trainNBO(trainMatrix,trainCategory):
#一共有幾個詞向量
numTrainDocs=len(trainMatrix)
#詞彙表的長度
numWords=len(trainMatrix[0])
#3/6 表示6個詞向量中,3個帶侮辱詞
pAbusive=sum(trainCategory)/float(numTrainDocs)
#初始化概率
p0Num=ones(numWords)
p1Num=ones(numWords)
p0Denom=2.0;p1Denom=2.0
#遍歷訓練集trainMatrix中的所有文檔
#一旦某個詞在某一文檔中出現
#該文檔的總詞數加1
#兩個類別都要進行同樣的處理
#i:012345
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)
p0Vect=log(p0Num/p0Denom)
return p0Vect,p1Vect,pAbusive
#樸素貝葉斯分類函數
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):
#元素相乘
p1=sum(vec2Classify*p1Vec)+log(pClass1)
p0=sum(vec2Classify*p0Vec)+log(1.0-pClass1)
if p1>p0:
return 1
else:
return 0
def testingNB():
listOPosts,listClasses=loadDataSet()
myVocabList=createVocabList(listOPosts)
trainMat=[]
#使用詞向量填充trainMat列表
for postinDoc in listOPosts:
Vec01=setOfWords2Vec(myVocabList,postinDoc)
trainMat.append(Vec01)
p0V,p1V,pAb=trainNBO(trainMat,listClasses)
#測試集
testEntry=['love','my','dalmation']
thisDoc=array(setOfWords2Vec(myVocabList,testEntry))
#print(thisDoc)
print(testEntry,' classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))
testEntry=['stupid','garbage']
thisDoc=array(setOfWords2Vec(myVocabList,testEntry))
#print(thisDoc)
print(testEntry,' classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))
def main():
testingNB()
#創建數據
#listOPosts,listClasses=loadDataSet()
#print(listOPosts)
#構建一個包含所有詞的列表
#myVocabList=createVocabList(listOPosts)
#print(myVocabList)
#returnVec=setOfWords2Vec(myVocabList,listOPosts[0])
#print(returnVec)
#trainMat=[]
#使用詞向量填充trainMat列表
#for postinDoc in listOPosts:
#傳入詞彙表 以及每一行詞向量
#返回的是一個與詞彙表同樣size的向量
#1表示這個詞在詞向量中出現過
#Vec01=setOfWords2Vec(myVocabList,postinDoc)
#print(Vec01)
#將01list填充trainMat
#trainMat.append(Vec01)
#print(trainMat)
#print(listClasses)
#p0V,p1V,pAB=trainNBO(trainMat,listClasses)
#print(p0V)
#print(p1V)
#print(pAB)
if __name__=='__main__':
main()