朴素贝叶斯的实现

朴素贝叶斯的实现

朴素贝叶斯使用概率论的知识进行监督学习的训练

调用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()  #贝叶斯分类
    

猜你喜欢

转载自blog.csdn.net/qq_39905917/article/details/83352703