# 用 0 代表没有下雨,而1代表下雨。
import numpy as np
# 过去7天是否下雨可以用数组表示
y=np.array( [0,1,1,0,1,0,0] )
# 其他气象信息: 北风、闷热、多云、天气预报是否下雨
X=np.array([
[0, 1, 0, 1],
[1, 1, 1, 0],
[0, 1, 1, 0],
[0, 0, 0, 1],
[0, 1, 1, 0],
[0, 1, 0, 1],
[1, 0, 0, 1],
])
# 分析下雨、不下雨时每个气象条件的频数
counts={}
for label in np.unique(y):
counts[label]=X[ y==label ].sum(axis=0)
print("Feature counts:\n{}".format(counts))
# 没下雨时(y=0), 4天天气预报都说下雨,1天北风,2天闷热,0天多云。
# 下雨时(y=1),天气预报都说没有下雨,1天北风,3天闷热,3天多云。
from sklearn.naive_bayes import BernoulliNB
# 拟合数据
clf=BernoulliNB()
clf.fit(X,y)
# 预测一下训练集
print( clf.predict(X) )
# 打分
print( clf.score(X, y) )
# 如果天气预报说没有下雨,且出现多云,倾向于归类到“下雨”
print(clf.predict( [[0,0,1,0]] ))
clf.predict_proba( [[0,0,1,0]] )
# 如果天气预报说下雨,且北风,闷热,无云,倾向于归类到“不下雨”
print(clf.predict( [[1,1,0,1]] ))
clf.predict_proba( [[1,1,0,1]] )
from sklearn.datasets import make_blobs
from sklearn.model_selection import train_test_split
# 生成样本,数量500,分类数5
X,y=make_blobs(n_samples=500, centers=5, random_state=8)
# 拆分数据
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=8)
# 使用伯努利贝叶斯拟合数据
from sklearn.naive_bayes import BernoulliNB
nb=BernoulliNB()
nb.fit(X_train, y_train)
# 打分
print("trainning score: {:0.3f}".format( nb.score(X_train, y_train) ) )
print("testing score: {:0.3f}".format( nb.score(X_test, y_test) ) )
# 只有一半分类是正确的,很糟糕!
# 可视化,为什么这么糟糕
import numpy as np
import matplotlib.pyplot as plt
x_min, x_max = X[:,0].min()-0.5, X[:,0].max()+0.5
y_min, y_max = X[:,1].min()-0.5, X[:,1].max()+0.5
# 用不同背景色表示不同分类
xx, yy=np.meshgrid(np.arange(x_min, x_max, 0.02),
np.arange(y_min, y_max, 0.02))
z=nb.predict(np.c_[(xx.ravel(), yy.ravel())]).reshape(xx.shape)
plt.pcolormesh(xx, yy, z, cmap=plt.cm.Pastel1, shading='auto')
# 画训练集和测试集散点图
plt.scatter(X_train[:,0], X_train[:,1], c=y_train, cmap=plt.cm.cool, edgecolor='k')
plt.scatter(X_test[:,0], X_test[:,1], c=y_test, cmap=plt.cm.cool, edgecolors='k', marker='*')
plt.xlim( xx.min(), xx.max())
plt.ylim( yy.min(), yy.max())
plt.title("Classifier: BernoulliNB")
plt.show()
# 这就是简单把2条线,分为4个象限,注意有3个颜色。 # 因为使用了伯努利朴素贝叶斯的默认参数 binarize=0.0,所以模型对于数据的判断是 # 如果特征1大于或等于0,且特征2大于或等于0,归为一类; # 如果特征1小于0,且特征2小于0,归为一类; # 其余归为一类。 # 所以分类效果很烂。 # 对于多分类,不能使用伯努利朴素贝叶斯模型了。可以使用高斯朴素贝叶斯模型。
# 就是假设样本的特征符合高斯分布/正态分布。
from sklearn.naive_bayes import GaussianNB
gnb=GaussianNB()
gnb.fit(X_train, y_train)
# 打分
print("trainning score: {:0.3f}".format( gnb.score(X_train, y_train) ) )
print("testing score: {:0.3f}".format( gnb.score(X_test, y_test) ) )
# 可视化,为什么分类效果这么好
# 用不同背景色表示不同分类
xx, yy=np.meshgrid(np.arange(x_min, x_max, 0.02),
np.arange(y_min, y_max, 0.02))
z=gnb.predict(np.c_[(xx.ravel(), yy.ravel())]).reshape(xx.shape)
plt.pcolormesh(xx, yy, z, cmap=plt.cm.Pastel1, shading='auto')
# 画训练集和测试集散点图
plt.scatter(X_train[:,0], X_train[:,1], c=y_train, cmap=plt.cm.cool, edgecolor='k')
plt.scatter(X_test[:,0], X_test[:,1], c=y_test, cmap=plt.cm.cool, edgecolors='k', marker='*')
plt.xlim( xx.min(), xx.max())
plt.ylim( yy.min(), yy.max())
plt.title("Classifier: GaussianNB")
plt.show()
from sklearn.naive_bayes import MultinomialNB
mnb=MultinomialNB()
#mnb.fit(X_train, y_train) # 报错 ValueError: Negative values in data passed to MultinomialNB (input X)
#mnb.score(X_test, y_test)
# 只能传入非负数
# 导入数据预处理工具 MinMaxScaler,作用是把特征值全部转为0-1之间。
from sklearn.preprocessing import MinMaxScaler
scaler=MinMaxScaler()
scaler.fit(X_train)
X_train_scaled=scaler.transform(X_train)
X_test_scaled=scaler.transform(X_test)
# 使用多项式朴素贝叶斯拟合经过预处理的数据
mnb.fit(X_train_scaled, y_train)
mnb.score(X_test_scaled, y_test)
# 这个打分很糟糕,比伯努利NB还差。可视化
# 用不同背景色表示不同分类
xx, yy=np.meshgrid(np.arange(x_min, x_max, 0.02),
np.arange(y_min, y_max, 0.02))
z=mnb.predict(np.c_[(xx.ravel(), yy.ravel())]).reshape(xx.shape)
plt.pcolormesh(xx, yy, z, cmap=plt.cm.Pastel1, shading='auto')
# 画训练集和测试集散点图
plt.scatter(X_train[:,0], X_train[:,1], c=y_train, cmap=plt.cm.cool, edgecolor='k')
plt.scatter(X_test[:,0], X_test[:,1], c=y_test, cmap=plt.cm.cool, edgecolors='k', marker='*')
plt.xlim( xx.min(), xx.max())
plt.ylim( yy.min(), yy.max())
plt.title("Classifier: MultinomialNB")
plt.show()
# 大部分数据放到了错误的分类中。 # 多项式NB只适合对非负离散数值特征进行分类。典型例子是转化为向量后的文本数据进行分类。
from sklearn.datasets import load_breast_cancer
cancer=load_breast_cancer()
print( cancer.keys() )
# print(cancer.DESCR)
print( cancer.target_names)
print( cancer["feature_names"])
X, y=cancer.data, cancer.target
# 拆分数据
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=38)
print("train set size:", X_train.shape)
print("test set size:", X_test.shape)
# 建模
from sklearn.naive_bayes import GaussianNB
gnb=GaussianNB()
gnb.fit(X_train, y_train)
# 打分
print("trainning score: {:0.3f}".format( gnb.score(X_train, y_train) ) )
print("testing score: {:0.3f}".format( gnb.score(X_test, y_test) ) )
# 随便预测一个
print("predict:", gnb.predict( [X[312]] ))
print("real:", y[312])
import numpy as np
import matplotlib.pyplot as plt
# 导入学习曲线库
from sklearn.model_selection import learning_curve
# 导入随机拆分工具
from sklearn.model_selection import ShuffleSplit
# 定义一个函数绘制学习曲线
def plot_learning_curve(estimator, title, X, y, ylim=None, cv=None,
n_jobs=1, train_sizes=np.linspace(0.1, 1.0, 5)):
plt.figure()
plt.title(title)
if ylim is not None:
plt.ylim(*ylim)
# xlab
plt.xlabel("Traning examples")
# ylab
plt.ylabel("Score")
train_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(train_sizes, train_scores_mean, 'o-', color='r', label="Training score")
plt.plot(train_sizes, test_scores_mean, 'o-', color='g', label="Cross-validation score")
plt.legend(loc="lower right")
return plt
# setting
title="Learning Curves (Naive Bayes)"
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, n_jobs=4)
plt.show()
# 可见,随着样本量的增大,训练集打分逐渐降低,因为要拟合的信息越来越多。 # 而测试集打分基本不变,说明高斯NB在预测方面,对样本量的要求没那么苛刻。如果样本量少,可以考虑NB建模。