机器学习--朴素贝叶斯实践

机器学习 | 朴素贝叶斯实践

老规矩,我们分两种方法来实现朴素贝叶斯算法。

首先,我们要手动实现朴素贝叶斯。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import pandas as pd
import numpy as np

class NaiveBayes(object):
def getTrainSet(self):
dataSet = pd.read_csv('D://test.csv')
dataSetNP = np.array(dataSet) #将数据由dataframe类型转换为数组类型
trainData = dataSetNP[:,0:dataSetNP.shape[1]-1] #训练数据x1,x2
labels = dataSetNP[:,dataSetNP.shape[1]-1] #训练数据所对应的所属类型Y
return trainData, labels

def classify(self, trainData, labels, features):
#求labels中每个label的先验概率
labels = list(labels) #转换为list类型
labelset = set(labels)
P_y = {} #存入label的概率
for label in labelset:
P_y[label] = labels.count(label)/float(len(labels)) # p = count(y) / count(Y)
print(label,P_y[label])

#求label与feature同时发生的概率
P_xy = {}
for y in P_y.keys():
y_index = [i for i, label in enumerate(labels) if label == y] # labels中出现y值的所有数值的下标索引
for j in range(len(features)): # features[0] 在trainData[:,0]中出现的值的所有下标索引
x_index = [i for i, feature in enumerate(trainData[:,j]) if feature == features[j]]
xy_count = len(set(x_index) & set(y_index)) # set(x_index)&set(y_index)列出两个表相同的元素
pkey = str(features[j]) + '*' + str(y)
P_xy[pkey] = xy_count / float(len(labels))
print(pkey,P_xy[pkey])

#求条件概率
P = {}
for y in P_y.keys():
for x in features:
pkey = str(x) + '|' + str(y)
P[pkey] = P_xy[str(x)+'*'+str(y)] / float(P_y[y]) #P[X1/Y] = P[X1Y]/P[Y]
print(pkey,P[pkey])

#求[2,'S']所属类别
F = {} #[2,'S']属于各个类别的概率
for y in P_y:
F[y] = P_y[y]
for x in features:
F[y] = F[y]*P[str(x)+'|'+str(y)] #P[y/X] = P[X/y]*P[y]/P[X],分母相等,比较分子即可,所以有F=P[X/y]*P[y]=P[x1/Y]*P[x2/Y]*P[y]
print(str(x),str(y),F[y])

features_label = max(F, key=F.get) #概率最大值对应的类别
return features_label


if __name__ == '__main__':
nb = NaiveBayes()
# 训练数据
trainData, labels = nb.getTrainSet()
# x1,x2
features = [8]
# 该特征应属于哪一类
result = nb.classify(trainData, labels, features)
print(features,'属于',result)

然后,我们再使用sklearn库来实现朴素贝叶斯算法。

sklearn中关于朴素贝叶斯算法的实现有三种:分别是GaussianNB,MultinomialNB和BernoulliNB。

其中GaussianNB就是先验为高斯分布的朴素贝叶斯,MultinomialNB就是先验为多项式分布的平朴素贝叶斯,而BernoulliNB就是先验为伯努利分布的朴素贝叶斯。我们以高斯朴素贝叶斯为例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import numpy as np
from sklearn.naive_bayes import GaussianNB

X=np.array([[-1,-1],[-2,-1],[-3,-2],[1,1],[2,1],[3,2]])
Y=np.array([1,1,1,2,2,2])

clf=GaussianNB()
clf.fit(X,Y)
'''
在使用GaussianNB的fit方法拟合数据后,我们可以进行预测。此时预测有三种方法,
包括predict,predict_log_proba和predict_proba。
    predict方法就是我们最常用的预测方法,直接给出测试集的预测类别输出。
    predict_proba则不同,它会给出测试集样本在各个类别上预测的概率。
容易理解,predict_proba预测出的各个类别概率里的最大值对应的类别,也就是predict方法得到类别。
    predict_log_proba和predict_proba类似,它会给出测试集样本在各个类别上预测的概率的一个对数转化。
转化后predict_log_proba预测出的各个类别对数概率里的最大值对应的类别,也就是predict方法得到类别。
'''
print(clf.predict([[-0.8,-1]]))
print(clf.predict_proba([[-0.8,-1]]))
print(clf.predict_log_proba([[-0.8,-1]]))
'''
GaussianNB一个重要的功能是有 partial_fit方法,这个方法的一般用在如果训练集数据量非常大,一次不能全部载入内存的时候。
这时我们可以把训练集分成若干等分,重复调用partial_fit来一步步的学习训练集,非常方便。
'''
clf_pf = GaussianNB()
clf_pf.partial_fit(X, Y, np.unique(Y))
print(clf_pf.predict([[-0.8, -1]]))

大家也可以一起实践实践,谢谢大家的观看!