1.朴素贝叶斯概率统计概念
1.1数学公式
P(B|A)· P(A)
P(A|B) = ——————————
P(B)
注:P(A|B):B已经成真,A发生的概率。
比如:
A事件:天要下暴雨,概率,P(A):60%
B事件:小明不来我家,概率,P(B):80%
天已经下暴雨,小明不来我家的概率,P(B|A):90%
那么,小明已经告知他不来我家,下暴雨的概率P(A|B) = 90%*60%/80%=67.5%
1.2实际案例
一周天气预报数据
刮风 | 闷热 | 多云 | 预报有雨 | |
---|---|---|---|---|
周一 | 是 | 是 | 否 | 是 |
周二 | 否 | 是 | 是 | 否 |
周三 | 是 | 否 | 否 | 是 |
周四 | 否 | 是 | 否 | 否 |
周五 | 是 | 否 | 是 | 否 |
周六 | 否 | 是 | 否 | 否 |
周日 | 否 | 否 | 是 | 否 |
这周过去了,实际情况本周3天下雨,4天不下雨,对应向量为y= [1,0,0,1,0,1,0],对应矩阵为X=[[1,1,0,1],[0,1,1,0],[1,0,0,1],[0,1,0,0],[1,0,1,0],[0,1,0,0],[0,0,1,0]]。
def my_BernoulliNB(): X = np.array([[1,1,0,1],[0,1,1,0],[1,0,0,1],[0,1,0,0],[1,0,1,0],[0,1,0,0],[0,0,1,0]]) y = np.array([1,1,0,0,1,0,1]) counts={}for label in np.unique(y): counts[label] = X[y==label].sum(axis=0) print("特性统计:\n{}".format(counts))
输出
特性统计:{0: array([1, 2, 0, 1]), 1: array([2, 2, 3, 1])}
表示:
简单就可以看出来,下雨好像与多云有关,多云就下雨,不多云就不下雨,让我们用程序来看一下贝叶斯算法出来的结果。
clf = BernoulliNB()clf.fit(X,y) #明天多云Next_Day = [[0,0,1,0]]pre1 = clf.predict(Next_Day)print(pre1)
输出
[1] |
---|
多云,果然下雨。
print(clf.predict_proba(Next_Day))
输出
[[0.16275954 0.83724046]]
Next_Day的没雨的概率为16.28%,有雨的概率为83.72%。
接下来再看一个数据,另一天刮风、闷热、预报有雨,但不多云。
Another_Day = [[1,1,0,1]] pre2 = clf.predict(Another_Day) print(pre2)
输出
[0] |
---|
意料之中,没有雨。
print(clf.predict_proba(Another_Day))
输出
[[0.67464862 0.32535138]]
Another_Day的没雨的概率为67.46%,有雨的概率为32.54%。
1.3朴素贝叶斯分类
朴素贝叶斯包括:贝努利贝叶斯(BernoulliNB)、高斯贝叶斯(GaussianNB)和多项式贝叶斯(MultinomailNB)。在sklearn 中分别用sklearn.naive_bayes.BernoulliNB、sklearn.naive_bayes.GaussianNB、sklearn.naive_bayes.MultinomialNB类来分别实现贝努利贝叶斯(BernoulliNB)、高斯贝叶斯(GaussianNB)和多项式贝叶斯(MultinomailNB)。下面我们来一一进行介绍。
2. 贝叶斯的实现
2.1贝努利贝叶斯(BernoulliNB)
from sklearn.datasets import make_blobsdef bernoulliNB(): X,y = make_blobs(n_samples=500,random_state=8,centers=8) X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=8) nb = BernoulliNB() nb.fit(X_train,y_train) print('训练集得分: {:.2%}'.format(nb.score(X_train,y_train))) print('测试集得分: {:.2%}'.format(nb.score(X_test,y_test)))#分别将样本的两个特征值创建图像的横轴和纵轴 x_min,x_max = X_train[:,0].min()-0.5,X_train[:,0].max()+0.5 y_min,y_max = X_train[:,1].min()-0.5,X_train[:,1].max()+0.5 xx, yy = np.meshgrid(np.arange(x_min, x_max, .02),np.arange(y_min, y_max, .02))#给每个样本分配不同的颜色 Z = nb.predict(np.c_[xx.ravel(),yy.ravel()]).reshape(xx.shape) plt.pcolormesh(xx,yy,Z,cmap=plt.cm.summer,shading='auto')#用散点把样本表示出来 plt.scatter(X_train[:,0],X_train[:,1],c=y_train,cmap=plt.cm.cool,s=20,edgecolors='k') plt.scatter(X_test[:,0],X_test[:,1],c=y_test,cmap=plt.cm.cool,s=20,marker='*') plt.xlim(xx.min(),xx.max()) plt.ylim(yy.min(),yy.max()) plt.rcParams['font.family'] = ['sans-serif'] plt.rcParams['font.sans-serif'] = ['SimHei'] plt.title(u"贝努利贝叶斯") plt.show()
输出
训练集得分: 38.13%测试集得分: 37.60%
看来贝努利贝叶斯效果不太好。
def gaussianNB(): X,y = make_blobs(n_samples=500,random_state=8,centers=8) X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=8) gnb = GaussianNB() gnb.fit(X_train,y_train) print('训练集得分: {:.2%}'.format(gnb.score(X_train,y_train))) print('测试集得分: {:.2%}'.format(gnb.score(X_test,y_test)))#分别将样本的两个特征值创建图像的横轴和纵轴 x_min,x_max = X_train[:,0].min()-0.5,X_train[:,0].max()+0.5 y_min,y_max = X_train[:,1].min()-0.5,X_train[:,1].max()+0.5 xx, yy = np.meshgrid(np.arange(x_min, x_max, .02),np.arange(y_min, y_max, .02))#给每个样本分配不同的颜色 Z = gnb.predict(np.c_[xx.ravel(),yy.ravel()]).reshape(xx.shape) plt.pcolormesh(xx,yy,Z,cmap=plt.cm.summer,shading='auto')#用散点把样本表示出来 plt.scatter(X_train[:,0],X_train[:,1],c=y_train,cmap=plt.cm.cool,s=20,edgecolors='k') plt.scatter(X_test[:,0],X_test[:,1],c=y_test,cmap=plt.cm.cool,s=20,marker='*')plt.xlim(xx.min(),xx.max()) plt.ylim(yy.min(),yy.max()) plt.rcParams['font.family'] = ['sans-serif'] plt.rcParams['font.sans-serif'] = ['SimHei'] plt.title(u"高斯贝叶斯") plt.show()
输出
训练集得分: 85.60%测试集得分: 91.20%
这个效果还是非常好的。
from sklearn.preprocessing import MinMaxScalerdef multinomialNB(): X,y = make_blobs(n_samples=500,random_state=8,centers=8) X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=8) scaler = MinMaxScaler() scaler.fit(X_train) X_train = scaler.transform(X_train) X_test = scaler.transform(X_test) mnb = MultinomialNB() mnb.fit(X_train,y_train) print('训练集得分: {:.2%}'.format(mnb.score(X_train,y_train))) print('测试集得分: {:.2%}'.format(mnb.score(X_test,y_test)))#分别将样本的两个特征值创建图像的横轴和纵轴 x_min,x_max = X_train[:,0].min()-0.5,X_train[:,0].max()+0.5 y_min,y_max = X_train[:,1].min()-0.5,X_train[:,1].max()+0.5 xx, yy = np.meshgrid(np.arange(x_min, x_max, .02),np.arange(y_min, y_max, .02))#给每个样本分配不同的颜色Z = mnb.predict(np.c_[xx.ravel(),yy.ravel()]).reshape(xx.shape) plt.pcolormesh(xx,yy,Z,cmap=plt.cm.summer,shading='auto')#用散点把样本表示出来 plt.scatter(X_train[:,0],X_train[:,1],c=y_train,cmap=plt.cm.cool,s=20,edgecolors='k') plt.scatter(X_test[:,0],X_test[:,1],c=y_test,cmap=plt.cm.cool,s=20,marker='*') plt.xlim(xx.min(),xx.max()) plt.ylim(yy.min(),yy.max()) plt.rcParams['font.family'] = ['sans-serif'] plt.rcParams['font.sans-serif'] = ['SimHei'] plt.title(u"多项式叶斯") plt.show()
注意,由于MultinomailNB要求数据集必须为非负,所有我们需要对make_blobs产生的数据进行MinMaxScaler()处理,注意红色字部分。
输出
训练集得分: 13.33%测试集得分: 9.60%
可以看出,多项式贝叶斯效果比贝努利贝叶斯更差。
3 示例
我们现在用乳腺癌数据来用高斯贝叶斯分析下第310个数据是良性还是恶性。
from sklearn.datasets import load_breast_cancerdef gaussianNB_for_breast_cancer(): cancer = load_breast_cancer() X , y = cancer.data,cancer.target X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=38) gnb = GaussianNB() gnb.fit(X_train,y_train) print('训练集得分: {:.2%}'.format(gnb.score(X_train,y_train))) print('测试集得分: {:.2%}'.format(gnb.score(X_test,y_test))) print('第310个样本预测结果: {}'.format(gnb.predict([X[310]])))
输出
训练集得分: 94.84%测试集得分: 94.41%第310个样本预测结果: [1]
因此,第310个数据是良性的。
最后我们来看一下高斯贝叶斯的学习曲线
from sklearn.model_selection import learning_curve,ShuffleSplit#定义一个绘制学习曲线的函数def plot_learning_curve(estimator, title,X, y,ylim=None,cv=None,n_jobs=2,train_sizes=np.linspace(.1,1.0,5)): plt.figure() plt.title(title)if ylim is not None: plt.ylim(*ylim) plt.rcParams['font.family'] = ['sans-serif'] plt.rcParams['font.sans-serif'] = ['SimHei'] plt.xlabel(u"训练样本") plt.ylabel(u"得分") plt.ylim(0,1.1) tarining_sizes,train_scores,test_scores = learning_curve(estimator,X,y,cv=cv,n_jobs=n_jobs,train_sizes=train_sizes) train_scores_mean = np.mean(train_scores,axis=1) test_scores_mean = np.mean(test_scores,axis=1) plt.grid() plt.plot(tarining_sizes,train_scores_mean,'o-',label=u"训练得分",c='r')plt.plot(tarining_sizes,test_scores_mean,'o-',label=u"交叉验证得分",c='g') plt.legend(loc='lower right')return plt
def learning_curve_for_gaussianNB(): cancer = load_breast_cancer() X , y = cancer.data,cancer.target title =u"学习曲线" cv = ShuffleSplit(n_splits=100,test_size=0.2,random_state=0) estimator = GaussianNB() plot_learning_curve(estimator,title,X, y,ylim=(0.9,1.01),cv=cv) plt.show()
训练集的数据随着样本从开始到150左右得分逐渐降低,然后持续持平,测试集得分一值保持不变,并且与训练集最后得分持平。
—————————————————————————————