由于自己太懒,不想看太长的代码,所以我就调用的sklearn库的朴素贝叶斯类,数据集选择的是这个博客中自己构造的数据集,该博客自己实现了朴素贝叶斯类,想自己编写一个朴素贝叶斯函数的读者可以参考这个博客。
下面是用sklearn库实现朴素贝叶斯分类:
from functools import reduce
import numpy as np
from sklearn.naive_bayes import GaussianNB
def loadDataSet():
"""构造数据集"""
wordsList = [['周六', '公司', '一起', '聚餐', '时间'],
['优惠', '返利', '打折', '优惠', '金融', '理财'],
['喜欢', '机器学习', '一起', '研究', '欢迎', '贝叶斯', '算法', '公式'],
['公司', '发票', '税点', '优惠', '增值税', '打折'],
['北京', '今天', '雾霾', '不宜', '外出', '时间', '在家', '讨论', '学习'],
['招聘', '兼职', '日薪', '保险', '返利']]
classVec = [0, 1, 0, 1, 0, 1]
return wordsList, classVec
def doc2VecList(docList):
"""将数据集合并"""
a = list(reduce(lambda x, y: set(x) | set(y), docList)) # 相同的词合并成为一个词,最终的结果是一个列表,里面没有重复的词
# reduce()方法:以本题为例,函数是set(x)|set(y),则要迭代的从docList中取出两个词进行函数计算
return a
allWordsVec = doc2VecList(docList) # 形成一个没有重复的词的词汇表
print(allWordsVec)
# ['研究', '增值税', '在家', '不宜', '兼职', '外出', '贝叶斯', '喜欢', '周六', '发票', '今天', '税点', '公司', '一起', '保险', '算法', '日薪', '公式', '北京', '理财', '打折', '雾霾', '招聘', '金融', '时间', '欢迎', '讨论', '返利', '机器学习', '聚餐', '优惠', '学习']
def word2Vec(vecList, inputWords):
"""词袋模型"""
resultVec = [0] * len(vecList)
for word in inputWords:
if word in vecList:
resultVec[vecList.index(word)] += 1
else:
print('没有发现此单词')
return np.array(resultVec)
# 将上面形成的词汇表转换成数字,以第一个数据为例,['周六', '公司', '一起', '聚餐', '时间'],
#‘周六’出现在词汇表的第9个位置,所以词汇表的第9个位置记为1,
#同理,‘公司’,‘一起’,‘聚餐’,‘时间’出现的位置都记为1,其余位置记为0,
#最终形式是[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 1, 0, 0, 0, 0, 1, 0, 0]
trainMat = list(map(lambda x: word2Vec(allWordsVec, x), docList))
print(trainMat)
# [array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
#0, 0, 1, 0, 0, 0, 0, 1, 0, 0]), array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
#0, 1, 0, 0, 0, 1, 0, 0, 2, 0]), array([1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0,
#0, 0, 0, 1, 0, 0, 1, 0, 0, 0]), array([0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
# 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]), array([0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
#0, 0, 1, 0, 1, 0, 0, 0, 0, 1]), array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
#1, 0, 0, 0, 0, 1, 0, 0, 0, 0])]
# 由于特征都是列表形式,所以要转换成矩阵的形式
classVec = np.array(classVec)
print(classVec.shape) # (6,) 标签是一维
trainMat = np.array(trainMat)
print(trainMat.shape) # (6, 32) 特征是二维
clf = GaussianNB()
clf.fit(trainMat, classVec) # 训练模型
testWords = ['公司', '聚餐', '讨论', '贝叶斯'] # 测试数据
testVec = word2Vec(allWordsVec, testWords) # 转换成词袋模型
testVec = np.array(testVec)
testVec = np.expand_dims(testVec, axis=0) # 把特征转换为二维,shape=(1,32)
clf.predict(testVec) # 输出0,分类正确