一、贝叶斯公式
先验概率(prior probability) P(cj):还没有训练模型之前,根据历史数据/经验估算cj拥有的初始概率。比如买西瓜前根据自己购买西瓜的经验,好瓜的概率是p(好瓜)=0.6,坏瓜概率是p(坏瓜)=0.4。
后验概率(posterior probability):已知某些观测数据或先验信息的条件下,对于某一事件或假设成立的概率。大部分机器学习模型尝试得到后验概率。
贝叶斯定理(Bayes' theorem)是概率论中的一个重要定理,它描述了在已知一些先验信息的情况下,如何通过新的观测数据来更新对事件发生概率的估计。
贝叶斯定理可以表达为:P(A|B) = P(B|A) * P(A) / P(B),其中:
- P(A|B) 是事件A在给定事件B发生的条件下的概率,称为后验概率(posterior probability)。
- P(B|A) 是事件B在给定事件A发生的条件下的概率,称为似然函数(likelihood)。
- P(A) 是事件A的先验概率(prior probability)。
- P(B) 是事件B的边缘概率(marginal probability)。
二、贝叶斯分类器
朴素贝叶斯分类器(Naïve Bayes Classifier)采用了“属性条件独立性假设”,即每个属性独立地对分类结果发生影响。
朴素贝叶斯分类器的训练器的训练过程就是基于训练集D估计类先验概率P(c),并为每个属性估计条件概率 P(x_i│c)。 令Dc表示训练集D中第c类样本组合的集合,则类先验概率:
对离散属性,令D_c,x_i表示D_c中在第 i 个属性上取值为x_i的样本组成的集合,则条件概率P(x_i│c)可估计为:p(x_i│c)=|D_c, x_i|/|D_c|
对连续属性,可考虑概率密度函数,假定p(x_i│c)~N(μ_c,i,σ_c,i^2),其中μ_c,i和σ_c,i^2分别是第 c类样本在第i个属性上取值的均值和方差,则有:
三、实现垃圾邮件分类
1.数据集目录
2.导入相关包
#导入sklearn中的线性模型类和模型验证类
import pandas as pd
import numpy as np
from sklearn import linear_model, model_selection
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
from sklearn import tree
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
from sklearn.pipeline import make_pipeline
3.数据预处理
# 读取数据并用空字符串替换空值
data = pd.read_table('/home/aistudio/data/data227246/spambase.data') # 加载本地数据
data.to_csv('data/data227246/spambase.csv',sep='|',index=False) # data转成csv
spam = pd.read_csv("/home/aistudio/data/data227246/spambase.data") #df1
#print(df1.head(15)) # 打印前15行
spam = spam.where((pd.notnull(spam)), '') #df df1
data = spam.iloc[:,0:57]
print(data.shape)
target = spam.iloc[:,57]
print(target.shape)
4.划分训练集和测试集
#使用train_test_split函数自动随机划分训练集和测试集
#test_size为测试集所占比例
#random_state为随机数种子,相同的种子值在每次运算中的划分结果相同
x_train, x_test, y_train, y_test = model_selection.train_test_split(data,target,
test_size=0.3,random_state=1)
feature_name = spam.columns[0:57] #数据集中的列名
target_name = spam.columns[57] #数据集中的标签名字
print(feature_name,target_name)
dt = tree.DecisionTreeClassifier(criterion='gini',max_depth=4,random_state= 0) #模型初始化
dt = dt.fit(x_train, y_train) #利用数据集进行训练,需要指定样本及其标签
y_pred2 = dt.predict(x_train)
y_pred = dt.predict(x_test)
y_pred
训练误差: 0.9108695652173913 测试误差: 0.9028985507246376
5.模型训练
result = dt.score(x_test,y_test) #用模型进行分类,从接口中调用需要的信息
print(result)
result = dt.score(x_train,y_train)
print(result)
#0.9028985507246376
#0.9108695652173913
#构建一个criterion='entropy'决策树模型,树深设置为4
dt = tree.DecisionTreeClassifier(criterion='entropy',max_depth=4,random_state= 0) #模型初始化
dt = dt.fit(x_train, y_train) #利用数据集进行训练,需要指定样本及其标签
y_pred2 = dt.predict(x_train)
y_pred = dt.predict(x_test)
y_pred
test = []
test2 = [] #保存每一次测试的结果
for i in range(3,31):
clf = tree.DecisionTreeClassifier(max_depth=i+1
,random_state=30
,splitter="random"
)
clf = clf.fit(x_train, y_train)
#训练误差
score = clf.score(x_train, y_train)
test.append(score)
score = clf.score(x_test,y_test)
test2.append(score)
plt.plot(range(3,31),test,color="red",label="训练误差") #红线
plt.plot(range(3,31),test2,color="blue",label="测试误差") #蓝线
plt.xlabel("树深")
plt.ylabel("误差")
plt.legend()
plt.show()
训练误差: 0.8993788819875776 测试误差: 0.9014492753623189
6.分类预测
朴素贝叶斯有3个常用模型
1.高斯模型:处理特征是连续型变量的情况
#高斯朴素贝叶斯
data = spambase.iloc[:,0:57]
print(data.shape)
target = spambase.iloc[:,57]
print(target.shape)
X_train, X_test, y_train, y_test = train_test_split(data,target,
test_size=0.3,random_state=107)
(4600, 57)
(4600,)
In [31]
from sklearn.naive_bayes import GaussianNB
model=GaussianNB()
model.fit(X_train,y_train)
GaussianNB(priors=None, var_smoothing=1e-09)
In [32]
#模型预测
y_test_pred= model.predict(X_test)
#分类正确率
print(model.score(X_test,y_test))
from sklearn import metrics
metrics.confusion_matrix(y_test, y_test_pred)
print (metrics.classification_report(y_test,y_test_pred))
准确率:
2.多项式模型:主要用于离散特征分类,例如文本分类单词统计以出现的次数作为特征值
#多项式朴素贝叶斯
from sklearn.naive_bayes import MultinomialNB
data = spambase.iloc[:,0:57]
print(data.shape)
target = spambase.iloc[:,57]
print(target.shape)
X_train1, X_test1, y_train1, y_test1 = train_test_split(data,target,
test_size=0.3,random_state=107)
from sklearn.preprocessing import MinMaxScaler
scaler=MinMaxScaler(feature_range=(0,1))
MinMaxScaler = MinMaxScaler()
MinMaxScaler.fit(X_train1)
X_train1 = MinMaxScaler.transform(X_train1)
X_test1 = MinMaxScaler.transform(X_test1)
print(X_train1)
mnb = MultinomialNB(alpha=1.0)
mnb.fit(X_train1, y_train1)
(4600, 57)
(4600,)
[[0.07709251 0. 0. ... 0.0010059 0.00230276 0.02107146]
[0. 0. 0.14313725 ... 0.00253019 0.00570685 0.03528476]
[0.030837 0.01960784 0.16470588 ... 0.00120018 0.00140168 0.02136965]
...
[0. 0. 0. ... 0.00020699 0.00040048 0.00417454]
[0. 0. 0. ... 0.00020427 0.00020024 0.00367757]
[0. 0. 0. ... 0. 0. 0.00039757]]
MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)
In [34]
#模型预测
y_test_pred1= mnb.predict(X_test1)
#分类正确率
print("准确率为:")
print(mnb.score(X_test1,y_test1))
from sklearn import metrics
metrics.confusion_matrix(y_test1, y_test_pred1)
print (metrics.classification_report(y_test1,y_test_pred1))
3.伯努利模型:要求特征是离散的,且为布尔类型,即true和false,或者1和0
四、总结
贝叶斯分类是一种简单且有效的方法来实现垃圾邮件分类。通过准备数据、提取特征、训练模型和进行分类预测,可以实现对未知邮件的自动分类。数据集可以参考百度飞浆平台。