朴素贝叶斯的实现
朴素贝叶斯使用概率论的知识进行监督学习的训练
调用sklearn库的NaiveBayes实现朴素贝叶斯
import numpy as np
from sklearn.naive_bayes import GaussianNB # 引入高斯朴素贝叶斯
features_train = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]]) #测试数据的输入
labels_train = np.array([1, 1, 1, 2, 2, 2]) #测试数据的标记
clf = GaussianNB() # 实例化
clf.fit(features_train, labels_train) # 训练数据
testdata = np.array([[-0.8, -1]]) #测试数据
testlabels = np.array([1]) #实际结果
pred = clf.predict(testdata) #预测结果
print(pred) #输出预测结果
# 准确度评估 评估正确/总数
# 方法1
accuracy = clf.score(testdata, testlabels)
print(accuracy)
# 方法2
from sklearn.metrics import accuracy_score
accuracy1 = accuracy_score(pred, testlabels)
print(accuracy1)
朴素贝叶斯的手动实现
以《统计学习方法》中的函数实现英文垃圾邮件的分类
from numpy import *
def createVocabList(dataSet): #创建一个包含所有文档的不重复词的列表
vocabSet=set([]) #创建空的集合
for docment in dataSet: #循环测试数据集
vocabSet=vocabSet| set(docment) #取两个集合的并集
return list(vocabSet) #返回不重复词的列表
def bagOfWords2Vec(vocabList,inputSet): #词袋模型
returnVec=[0]*len(vocabList)
for word in inputSet:
if word in vocabList: #如果该次在此词表中
returnVec[vocabList.index(word)]+=1 #统计出现次数
else: print ("the word is not in my vocabulry")
return returnVec
# 训练算法
# the p1Num is mean claclualte in 1 class evrey word contain weight
def train(trainMat,trainGategory): #文档矩阵,每篇文档类别标签所构成的向量
numTrain=len(trainMat)
numWords=len(trainMat[0]) #is vocabulry length
pAbusive=sum(trainGategory)/float(numTrain)
p0Num=ones(numWords);p1Num=ones(numWords) #初始化概率
p0Denom=2.0;p1Denom=2.0
for i in range(numTrain):
if trainGategory[i] == 1:
p1Num += trainMat[i] #统计类1中每个单词的总数
p1Denom += sum(trainMat[i]) #统计类1的总数
else:
p0Num += trainMat[i] #向量相加
p0Denom +=sum(trainMat[i])
p1Vec=log(p1Num/p1Denom) #类1中每个单词的概率
p0Vec=log(p0Num/p0Denom)
return p0Vec,p1Vec,pAbusive
# classfy funtion
def classfy(vec2classfy,p0Vec,p1Vec,pClass1): #进行判断
p1=sum(vec2classfy*p1Vec)+log(pClass1)
p0=sum(vec2classfy*p0Vec)+log(1-pClass1)
if p1 > p0: #判断概率的大小
return 1; #垃圾邮件
else:
return 0 #非垃圾邮件
# split the big string
def textParse(bigString):
import re #引用正则表达式
listOfTokens=re.split(r'\W*',bigString) #分隔符是除单词、数字外的字符串
return [tok.lower() for tok in listOfTokens if len(tok)>2] #单词全部转换为小写,去除一些无用的词汇(即长度小于3的词汇)
#spam email classfy
def spamTest():
fullTest=[];docList=[];classList=[]
for i in range(1,26): #垃圾邮件和非垃圾文件都是25个
wordList=textParse(open('email/spam/%d.txt' % i).read()) #读取垃圾邮件内容
docList.append(wordList)
fullTest.extend(wordList)
classList.append(1) #添加垃圾邮件标签
wordList=textParse(open('email/ham/%d.txt' % i).read()) #读取非垃圾邮件内容
docList.append(wordList)
fullTest.extend(wordList)
classList.append(0) #添加非垃圾邮寄标签
vocabList=createVocabList(docList) # 返回一个包含所有文档的不重复词的列表
trainSet=range(50);testSet=[]
#留存交叉验证法
for i in range(10): #取十份作为验证集
randIndex=int(random.uniform(0,len(trainSet)))
testSet.append(trainSet[randIndex])
del(trainSet[randIndex])
trainMat=[];trainClass=[]
for docIndex in trainSet:
trainMat.append(bagOfWords2Vec(vocabList,docList[docIndex]))
trainClass.append(classList[docIndex])
p0,p1,pSpam=train(array(trainMat),array(trainClass))
errCount=0
for docIndex in testSet:
wordVec=bagOfWords2Vec(vocabList,docList[docIndex])
if classfy(array(wordVec),p0,p1,pSpam) != classList[docIndex]:
errCount +=1
print ("classfication error"), docList[docIndex]
print ("the error rate is ") , float(errCount)/len(testSet)
if __name__ == '__main__': #主函数
spamTest() #贝叶斯分类