朴素贝叶斯分类(python实现)

算法优劣

  • 参考刘建平老师的博客:朴素贝叶斯算法原理小结

优点:

  1. 朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率。

  2. 对小规模的数据表现很好,能个处理多分类任务,适合增量式训练,尤其是数据量超出内存时,我们可以一批批的去增量训练。

  3. 对缺失数据不太敏感,算法也比较简单,常用于文本分类。

缺点

  1. 理论上,朴素贝叶斯模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为朴素贝叶斯模型给定输出类别的情况下,假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比较多或者属性之间相关性较大时,分类效果不好。而在属性相关性较小时,朴素贝叶斯性能最为良好。对于这一点,有半朴素贝叶斯之类的算法通过考虑部分关联性适度改进。

  2. 需要知道先验概率,且先验概率很多时候取决于假设,假设的模型可以有很多种,因此在某些时候会由于假设的先验模型的原因导致预测效果不佳。

  3. 由于我们是通过先验和数据来决定后验的概率从而决定分类,所以分类决策存在一定的错误率。

  4. 对输入数据的表达形式很敏感。

算法实现

说明

  • scikit-learn中,一共有3个朴素贝叶斯的分类算法类。分别是GaussianNBMultinomialNBBernoulliNB
  • GaussianNB:先验为高斯分布的朴素贝叶斯
  • MultinomialNB:先验为多项式分布的朴素贝叶斯
  • BernoulliNB:先验为伯努利分布的朴素贝叶斯。

数据准备

import pandas as pd
import numpy as np
X = np.array([[1.14, 1.78],[1.18, 1.96],[1.20, 1.86],[1.26, 2.00],[1.28, 2.00],
             [1.30, 1.96],[1.24, 1.72],[1.36, 1.74],[1.38, 1.64],[1.38, 1.82],
             [1.38, 1.90],[1.40, 1.70],[1.48, 1.82],[1.54, 1.82],[1.56, 2.08]])
Y = np.hstack((np.ones(6), np.ones(9)*2)) #数组合并

GaussianNB预测

from sklearn.naive_bayes import GaussianNB
clf_Ga = GaussianNB()
clf_Ga.fit(X, Y)
print("预测结果")
print(clf_Ga.predict([[1.24, 1.80]]))
print("样本为1类的概率")
print(clf_Ga.predict_proba([[1.24, 1.80]]))
print("样本为2类的概率")
print(clf_Ga.predict_log_proba([[1.24, 1.80]]))

输出:

预测结果
[1.]
样本为1类的概率
[[0.7236103 0.2763897]]
样本为2类的概率
[[-0.3235023  -1.28594344]]
  • 样本为1的概率大于样本为2的概率,所以认为该样本为1类
print("预测结果")
print(clf_Ga.predict([[1.29, 1.81],[1.43,2.03]]))

输出:

预测结果
[2. 2.]

MultinomialNB预测

  • 这里使用GridSearchCV函数进行网格搜索交叉检验调参,评估模型的分数为accuracy即准确率。
  • 调整的参数分别为:alpha(常数 λ \lambda λ),fit_prior(是否考虑先验概率)
from sklearn.naive_bayes import MultinomialNB
clf_Mu = MultinomialNB()
from sklearn.model_selection import GridSearchCV
param_grid = [{'alpha':np.arange(0.9,1.1,0.1),
              'fit_prior':['True','False']}]
grid_search = GridSearchCV(clf_Mu, param_grid, cv = 3,
                          scoring = 'accuracy',
                          return_train_score = True)
grid_search.fit(X,Y)

输出最优参

grid_search.best_params_

输出:

{'alpha': 0.9, 'fit_prior': 'True'}

查看网格搜索模型分数

cvres = grid_search.cv_results_
for accuracy,params in zip(cvres["mean_test_score"],cvres["params"]):
    print("{:.2}".format(accuracy),params)

输出:

0.6 {'alpha': 0.9, 'fit_prior': 'True'}
0.6 {'alpha': 0.9, 'fit_prior': 'False'}
0.6 {'alpha': 1.0, 'fit_prior': 'True'}
0.6 {'alpha': 1.0, 'fit_prior': 'False'}
0.6 {'alpha': 1.1, 'fit_prior': 'True'}
0.6 {'alpha': 1.1, 'fit_prior': 'False'}
  • 这里可能是因为样本只有15个,导致参数不管如何变化对准确率都没有太大影响。

预测结果

final_model = grid_search.best_estimator_

X_test = np.array([[1.24, 1.80],[1.29, 1.81],[1.43,2.03]])
X_test_prepared = final_model.predict(X_test)
print("预测结果")
print(X_test_prepared)

输出:

预测结果
[2. 2. 2.]

结语

  • 两种方法在对第1个样本的预测上有不同,这里因为样本数量太少,不做深究。

你可能感兴趣的:(python,分类,机器学习)