问题
朴素贝叶斯求解
- 朴素贝叶斯公式:
- 求解思想:即求先验概率与条件概率乘积的最大值
- 求解
注意:
本人求解过程中忘记了 Laplace 平滑 (⊙︿⊙),但好在预测值里面没有学历为博士的一项,所以不平滑也不影响预测,但这样是不规范的。
代码
- 分析
1 读取数据
2 数据切片,转换(将字符型数据编码)
3 划分训练集和测试集
4 导入 sklearn 贝叶斯方法,拟合
5 预测输入值
#导入数据 read_csv
import pandas as pd
import numpy as np
c=pd.read_csv('career_data.csv')
print c
# 将特征的离散数据 编码 用 LabelEncoder()对标签进行了编码
from sklearn.preprocessing import LabelEncoder
class_le = LabelEncoder()
y=class_le.fit_transform(c['enrolled'].values)
# 特征编码时直接用了 DataFrame 替换
c['985'].replace(['Yes','No'],[1,0],inplace=True)
c['education'].replace(['bachlor','master','phd'],[0,1,2],inplace=True)
c['skill'].replace(['C++','Java'],[0,1],inplace=True)
b=c.values[:,:-1]
print '\n','特征值','\n', b
print '标签值','\n',y
# 导入贝叶斯方法进行拟合
#from sklearn.cross_validation import train_test_split
from sklearn.naive_bayes import GaussianNB
#train_X,test_X, train_y, test_y = train_test_split(b,y,test_size=0.1) # test_size:测试集比例20%
clf = GaussianNB()
#clf.fit(train_X, train_y)
clf.fit(b,y)
prediction6=clf.predict(b)
print '两个类别的先验概率:',clf.class_prior_ #获取两个类别的先验概率
#print(clf.feature_prob_)
print('The accuracy of the NaiveBayes is',metrics.accuracy_score(prediction6,y))
print clf.predict([[1,1,0]])
print clf.predict_proba([[1,1,0]])
可以看到,先验概率与之前的计算相同,预测结果也是未录取,但最后的预测出的两个类别的概率与计算不同,分析主要是因为之前计算的仅仅是贝叶斯公式的分子,而程序计算的可能是是包含分母的完整的后验概率。
总结:
1 数据读取DataFrame 方法,read_csv 与read_table 还是不同的
2 标签的编码,通常都用LabelEnconder,有n类就用0~ n-1 表示出来
3 属性编码的办法太笨,我考虑过用OneHotEncoder 方法,但该方法只能进行二值转换(非0 即1 ),不适合本例,学历属性里有三类;即便可以,我还是没搞懂独热编码的原理,编完后相当于给数据扩维了,比如学历一项就会用[1,0] 与 [0,1] 来表示Yes 和 No ,那后续该如何拟合呢,维度和原来不一样了啊?还有pandas 里面的 pd.get_dummies(c[‘skill’]),结果也是一样,如何把编码后的每个属性再组合为原始数据的维度?
4 尝试了将数据划分为训练集和测试集,但是先验类别与计算的不一样了,是因为此时的先验概率是训练集的,而非原始数据集了。
5 尝试了用BonulliNB 和 MultinormialNB 方法,前者预测一致,而多项式贝叶斯方法预测相反,查了一下:多项式NB以样本出现的次数为特征值,主要用于离散特征分类,例如文本分类单词统计。
希望得到指点。