朴素贝叶斯
朴素贝叶斯模型是一组非常简单快速的分类方法啊,通常适用于维度非常高的数据集。因为运行速度快,而且可调参数少,因此非常适合为分类问题提供快速粗糙的基本方案。之所以成为“朴素”或“朴素贝叶斯”,是因为如果对每一种标签的生成模型(用于计算每个标签的P(特征|Li)P(特征|Li)进行非常简单的假设,就能找到每种类型生成模型的近似解,然后就可以使用贝叶斯分类。
高斯朴素贝叶斯
高斯朴素贝叶斯分类器假设每个标签的数据都服从简单的高斯分布,且变量无协方差(即线性无关)。只要找到每个标签的所有的所有样本点均值和标准差,在定义一个高斯分布,就可以拟合模型了。
#生成实验数据
from sklearn.datasets import make_blobs
X, y = make_blobs(100, 2, centers=2, random_state=2, cluster_std=1.5)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='RdBu')
#使用高斯朴素贝叶斯进行分类
from sklearn.naive_bayes import GaussianNB
model = GaussianNB()
model.fit(X, y)
rng = np.random.RandomState(0)
Xnew = [-6, -14] + [14, 18]* rng.rand(2000, 2)
ynew = model.predict(Xnew)
#将这些新数据画出来,看看决策边界的位置
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='RdBu')
lim = plt.axis()
plt.scatter(Xnew[:, 0], Xnew[:, 1], c=ynew, s=20, cmap='RdBu', alpha=0.2)
plt.axis(lim)
多项式朴素贝叶斯
另外一种常用的假设是多项式朴素贝叶斯,它假设特征是由一个简单的多项式分布生成的。多项式分布可以描述各种类型样本出现的次数,因此多项式朴素贝叶斯非常适合描述出现次数或者出现次数比例的特征。下面使用多项式朴素贝叶斯进行文本分类。
import seaborn as sns;sns.set()
#应用多项式朴素贝叶斯进行文本分类
#下载数据
from sklearn.datasets import fetch_20newsgroups
data = fetch_20newsgroups()
# data.target_names
#为了简化演示过程,只选择四类新闻,下载训练集合测试集
categories = ['talk.religion.misc', 'soc.religion.christian', 'sci.space',
'comp.graphics']
train = fetch_20newsgroups(subset = 'train', categories=categories)
test = fetch_20newsgroups(subset='test', categories=categories)
# print(train.data[5])
#为了能让这些数据用于机器学习,需要将每个字符串的内容转换成数值向量。可以创建一个管道,
#将TF-IDF(term frequency-inverse document frequency)向量化方法与多项式朴素贝叶斯分类器组合在一起
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import make_pipeline
model = make_pipeline(TfidfVectorizer(), MultinomialNB())
#通过这个管道,就可以将模型应用到训练数据上,预测出每个测试数据的标签
model.fit(train.data, train.target)
labels = model.predict(test.data)
#这样就得到了每个测试数据的预测标签,可以进一步的评估评估器的性能了。
#用混淆矩阵统计测试数据的真实标签与预测标签的结果
from sklearn.metrics import confusion_matrix
mat = confusion_matrix(test.target, labels)
sns.heatmap(mat.T, square=True, annot=True, fmt='d', cbar=False,
xticklabels=train.target_names, yticklabels=train.target_names)
plt.xlabel('true label')
plt.ylabel('predict label')
#定义函数,快速返回字符串的预测结果
def predict_category(s, train=train, model=model):
pred = model.predict([s])
return train.target_names[pred[0]]
#测试模型的预测效果
print(predict_category('sending a payload to the ISS'))
print(predict_category('discussing islam vs atheism'))
print(predict_category('determing the screen resolution'))
#输出结果:
sci.space
soc.religion.christian
comp.graphics
虽然这个分类器不会比直接用字符内单词(加权的)频次构建的简易概率模型更加复杂,但它的分类效果却非常好。由此可见,即使是一个非常简单的算法,只要能合理利用并进行大量高维的数据训练,就可以获得意想不到的效果。