贝叶斯用于文档分类
from numpy import *def loadDataSet():# 詞條切分后的文檔集合,列表每一行代表一個文檔postingList = [['my', 'dog', 'has', 'flea', 'please'],['not', 'take', 'him', 'to', 'dog', 'stupid'],['my', 'is', 'cute', 'love', 'him'],['stop', 'posting', 'stupid', 'worthless', 'garbage'],['my', 'licks', 'my', 'to', 'stop', 'him'],['quit', 'worthless', 'dog', 'stupid']]# 由人工標注的每篇文檔的類標簽classVec = [0, 1, 0, 1, 0, 1]return postingList, classVec# 統計所有文檔中出現的詞條列表
def createVocabList(dataSet):# 新建一個存放詞條的集合vocabSet = set([])# 遍歷文檔集合中的每一篇文檔for document in dataSet:# 將文檔列表轉為集合的形式,保證每個詞條的唯一性# 然后與vocabSet取并集,向vocabSet中添加沒有出現# 的新的詞條vocabSet = vocabSet | set(document)# 再將集合轉化為列表,便于接下來的處理return list(vocabSet)# 根據詞條列表中的詞條是否在文檔中出現(出現1,未出現0),將文檔轉化為詞條向量
def setOfWords2Vec(vocabSet, inputSet):# 新建一個長度為vocabSet的列表,并且各維度元素初始化為0returnVec = [0] * len(vocabSet)# 遍歷文檔中的每一個詞條for word in inputSet:# 如果詞條在詞條列表中出現if word in vocabSet:# 通過列表獲取當前word的索引(下標)# 將詞條向量中的對應下標的項由0改為1returnVec[vocabSet.index(word)] += 1else:print('the word: %s is not in my vocabulary! ' % 'word')# 返回inputet轉化后的詞條向量return returnVec# 訓練算法,從詞向量計算概率p(w0|ci)...及p(ci)
# @trainMatrix:由每篇文檔的詞條向量組成的文檔矩陣
# @trainCategory:每篇文檔的類標簽組成的向量
def trainNB0(trainMatrix, trainCategory):# 獲取文檔矩陣中文檔的數目numTrainDocs = len(trainMatrix) # 6# 獲取詞條向量的長度numWords = len(trainMatrix[0]) # 19# 所有文檔中屬于類1所占的比例p(c=1)pAbusive = sum(trainCategory) / float(numTrainDocs) # 3/6=0.5,先驗# 創建一個長度為詞條向量等長的列表p0Num = zeros(numWords)p1Num = zeros(numWords)p0Denom = 0.0p1Denom = 0.0# 遍歷每一篇文檔的詞條向量for i in range(numTrainDocs):# 如果該詞條向量對應的標簽為1if trainCategory[i] == 1:# 統計所有類別為1的詞條向量中各個詞條出現的次數p1Num += trainMatrix[i]# 統計類別為1的詞條向量中出現的所有詞條的總數# 即統計類1所有文檔中出現單詞的數目p1Denom += sum(trainMatrix[i])else:# 統計所有類別為0的詞條向量中各個詞條出現的次數p0Num += trainMatrix[i]# 統計類別為0的詞條向量中出現的所有詞條的總數# 即統計類0所有文檔中出現單詞的數目p0Denom += sum(trainMatrix[i])# 利用NumPy數組計算p(wi|c1)p1Vect = p1Num / p1Denom # 為避免下溢出問題,后面會改為log()# 利用NumPy數組計算p(wi|c0)p0Vect = p0Num / p0Denom # 為避免下溢出問題,后面會改為log()return p0Vect, p1Vect, pAbusive# 樸素貝葉斯分類函數
# @vec2Classify:待測試分類的詞條向量
# @p0Vec:類別0所有文檔中各個詞條出現的頻數p(wi|c0)
# @p0Vec:類別1所有文檔中各個詞條出現的頻數p(wi|c1)
# @pClass1:類別為1的文檔占文檔總數比例
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):# 根據樸素貝葉斯分類函數分別計算待分類文檔屬于類1和類0的概率print(vec2Classify)p1 = sum(vec2Classify * p1Vec) + log(pClass1)p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)if p1 > p0:return 1else:return 0# 分類測試整體函數
# 由數據集獲取文檔矩陣和類標簽向量
allfile, fileClasses = loadDataSet()
# 統計所有文檔中出現的詞條,存入詞條列表
VocabSet = createVocabList(allfile)
# 創建新的列表
trainMat = []
for singlefile in allfile:# 將每篇文檔利用words2Vec函數轉為詞條向量,存入文檔矩陣中trainMat.append(setOfWords2Vec(VocabSet, singlefile))# 將文檔矩陣和類標簽向量轉為NumPy的數組形式,方便接下來的概率計算
# 調用訓練函數,得到相應概率值
p0V, p1V, pAb = trainNB0(array(trainMat), array(fileClasses))
# 測試文檔
testEntry = ['love', 'my', 'cute']
# 將測試文檔轉為詞條向量,并轉為NumPy數組的形式
thisDoc = array(setOfWords2Vec(VocabSet, testEntry))
# 利用貝葉斯分類函數對測試文檔進行分類并打印
print(testEntry, 'classified as:', classifyNB(thisDoc, p0V, p1V, pAb))
# 第二個測試文檔
testEntry1 = ['stupid', 'garbage']
# 同樣轉為詞條向量,并轉為NumPy數組的形式
thisDoc1 = array(setOfWords2Vec(VocabSet, testEntry1))
print(testEntry1, 'classified as:', classifyNB(thisDoc1, p0V, p1V, pAb))
?
總結
- 上一篇: OpenCV中文路径问题、matplot
- 下一篇: OpenCV的数据类型——辅助对象