二 朴素贝叶斯
1.1 基础
朴素贝叶斯算法(Naive Bayes, NB) 是应用最为广泛的分类算法之一,
NaïveBayes算法,又叫朴素贝叶斯算法,
-
朴素:特征条件独立;
-
贝叶斯:基于贝叶斯定理 p ( c ∣ x ) = p ( x ∣ c ) p ( c ) p ( x ) p(c \mid x)=\frac{p(x \mid c) p(c)}{p(x)} p(c∣x)=p(x)p(x∣c)p(c)
-
k类贝叶斯推广
存在k
类( c 1 , c 2 , . . . , c k c_1, c_2, ..., c_k c1,c2,...,ck), z在实例 x = ( x ( 1 ) , x ( 2 ) , ⋯ , x ( n ) x^{(1)}, x^{(2)}, \cdots, x^{(n)} x(1),x(2),⋯,x(n))中求
---- >>>> 实例中归属于 c i c_i ci类可能性 ?
由上贝叶斯可得:
P ( Y = c i ∣ X = x ) = P ( X = x ∣ Y = c i ) ⋅ P ( Y = c i ) P ( X = x ) P\left(Y=c_{i} \mid X=x\right)=\frac{P\left(X=x \mid Y=c_{i}\right) \cdot P\left(Y=c_{i}\right)}{P(X=x)} P(Y=ci∣X=x)=P(X=x)P(X=x∣Y=ci)⋅P(Y=ci)
又由全概率公式 P ( X = x ) P(X = x) P(X=x)得:
P ( Y = c i ∣ X = x ) = P ( X = x ∣ Y = c i ) ⋅ P ( Y = c i ) ∑ i = 1 K P ( X = x ∣ Y = c i ) ⋅ P ( Y = c i ) P\left(Y=c_{i} \mid X=x\right)=\frac{P\left(X=x \mid Y=c_{i}\right) \cdot P\left(Y=c_{i}\right)}{\sum_{i=1}^{K} P\left(X=x \mid Y=c_{i}\right) \cdot P\left(Y=c_{i}\right)} P(Y=ci∣X=x)=∑i=1KP(X=x∣Y=ci)⋅P(Y=ci)P(X=x∣Y=ci)⋅P(Y=ci)需要判断是否为 c i c_i ci类别 >>>> P ( Y = c i ∣ X = x ) P\left(Y=c_{i} \mid X=x\right) P(Y=ci∣X=x)最大即最有可能 >>>> 分母所有类别相同, 分子最大即可
arg max c i P ( X = x ∣ Y = c i ) ⋅ P ( Y = c i ) \arg \max _{c_{i}} P\left(X=x \mid Y=c_{i}\right) \cdot P\left(Y=c_{i}\right) argcimaxP(X=x∣Y=ci)⋅P(Y=ci)
假设: 各实例间特征相互独立, 可进一步化简得
P
(
X
=
x
∣
Y
=
c
i
)
=
∏
j
=
1
n
P
(
X
(
j
)
=
x
(
j
)
∣
Y
=
c
i
)
⟹
P
(
X
=
x
)
=
∑
i
=
1
K
P
(
Y
=
c
i
)
∏
j
=
1
n
P
(
X
(
j
)
=
x
(
j
)
∣
Y
=
c
i
)
⟹
P
(
Y
=
c
i
∣
X
=
x
)
=
P
(
X
=
x
∣
Y
=
c
i
)
⋅
P
(
Y
=
c
i
)
∑
i
=
1
K
P
(
Y
=
c
i
)
∏
j
=
1
n
P
(
X
(
j
)
=
x
(
j
)
∣
Y
=
c
i
)
⟹
P
(
Y
=
c
i
∣
X
=
x
)
=
P
(
Y
=
c
i
)
∏
j
=
1
n
P
(
X
(
j
)
=
x
(
j
)
∣
Y
=
c
i
)
∑
i
=
1
K
P
(
Y
=
c
i
)
∏
j
=
1
n
P
(
X
(
j
)
=
x
(
j
)
∣
Y
=
c
i
)
\begin{aligned} & P\left(X=x \mid Y=c_{i}\right)=\prod_{j=1}^{n} P\left(X^{(j)}=x^{(j)} \mid Y=c_{i}\right) \\ \Longrightarrow & P(X=x)=\sum_{i=1}^{K} P\left(Y=c_{i}\right) \prod_{j=1}^{n} P\left(X^{(j)}=x^{(j)} \mid Y=c_{i}\right) \\ \Longrightarrow & P\left(Y=c_{i} \mid X=x\right)=\frac{P\left(X=x \mid Y=c_{i}\right) \cdot P\left(Y=c_{i}\right)}{\sum_{i=1}^{K} P\left(Y=c_{i}\right) \prod_{j=1}^{n} P\left(X(j)=x^{(j) \mid} Y=c_{i}\right)} \\ \Longrightarrow & P\left(Y=c_{i} \mid X=x\right)=\frac{P\left(Y=c_{i}\right) \prod_{j=1}^{n} P\left(X^{(j)}=x^{(j)} \mid Y=c_{i}\right)}{\sum_{i=1}^{K} P\left(Y=c_{i}\right) \prod_{j=1}^{n} P\left(X^{(j)}=x^{(j)} \mid Y=c_{i}\right)} \end{aligned}
⟹⟹⟹P(X=x∣Y=ci)=j=1∏nP(X(j)=x(j)∣Y=ci)P(X=x)=i=1∑KP(Y=ci)j=1∏nP(X(j)=x(j)∣Y=ci)P(Y=ci∣X=x)=∑i=1KP(Y=ci)∏j=1nP(X(j)=x(j)∣Y=ci)P(X=x∣Y=ci)⋅P(Y=ci)P(Y=ci∣X=x)=∑i=1KP(Y=ci)∏j=1nP(X(j)=x(j)∣Y=ci)P(Y=ci)∏j=1nP(X(j)=x(j)∣Y=ci)
贝叶斯后验概率 = 先验概率 * 调整因子
朴素贝叶斯算法对线性判别分析作进一步的模型简化,它将线性判别分析中的协方差矩阵中的协方差全部变成0,只保留各自特征的方差,也就是朴素贝叶斯假设各个特征之间是不相关的。在之前所看到的偏差-方差理论中,我们知道模型的简化可以带来方差的减少但是增加偏差,因此朴素贝叶斯也不例外,它比线性判别分析模型的方差小,偏差大。虽然简化了模型,实际中使用朴素贝叶斯的案例非常多,甚至多于线性判别分析.
1.2 LR/LDA/朴素贝叶斯实例
- 载入经典数据集
import pandas as pd
from sklearn import datasets
iris = datasets.load_iris()
X = iris.data
y = iris.target
feature = iris.feature_names
data = pd.DataFrame(X,columns=feature)
data['target'] = y
data.head()
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target
0 5.1 3.5 1.4 0.2 0
1 4.9 3.0 1.4 0.2 0
2 4.7 3.2 1.3 0.2 0
3 4.6 3.1 1.5 0.2 0
4 5.0 3.6 1.4 0.2 0
逻辑回归:
参数:
penalty
: {‘l1’, ‘l2’, ‘elasticnet’, ‘none’}, default=’l2’正则化方式
dual
: bool, default=False 是否使用对偶形式,当n_samples> n_features时,默认dual = False。
C
: float, default=1.0
solver
: {‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’, ‘saga’}, default=’lbfgs’
l1_ratio
: float, default=None
from sklearn.linear_model import LogisticRegression
log_iris = LogisticRegression()
log_iris.fit(X,y)
log_iris.score(X,y)
C:\ProgramData\Anaconda3\lib\site-packages\sklearn\linear_model\_logistic.py:762: ConvergenceWarning: lbfgs failed to converge (status=1):
STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.
Increase the number of iterations (max_iter) or scale the data as shown in:
https://scikit-learn.org/stable/modules/preprocessing.html
Please also refer to the documentation for alternative solver options:
https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression
n_iter_i = _check_optimize_result(
0.9733333333333334
- 线性判别分析
class sklearn.linear_model.LogisticRegression(penalty='l2', *, dual=False, tol=0.0001, C=1.0, fit_intercept=True, intercept_scaling=1, class_weight=None, random_state=None, solver='lbfgs', max_iter=100, multi_class='auto', verbose=0, warm_start=False, n_jobs=None, l1_ratio=None)
- 参数:
solver
:{'svd','lsqr','eigen'}
,默认=‘svd’
solver的使用,可能的值:
'svd'
:奇异值分解(默认)。不计算协方差矩阵,因此建议将此求解器用于具有大量特征的数据。
'lsqr'
:最小二乘解,可以与收缩结合使用。
'eigen'
:特征值分解,可以与收缩结合使用。
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
lda_iris = LinearDiscriminantAnalysis()
lda_iris.fit(X,y)
lda_iris.score(X,y)
0.98
- 朴素贝叶斯
from sklearn.naive_bayes import GaussianNB
NB_iris = GaussianNB()
NB_iris.fit(X, y)
NB_iris.score(X,y)
0.96
1.3 贝叶斯应用
- 莺尾花数据集–贝叶斯分类
- 导入数据
x, y = datasets.load_iris(return_X_y = True) # y即为target
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2, random_state = 0)
我们需要计算两个概率分别是:条件概率: P ( X ( i ) = x ( i ) ∣ Y = c k ) P(X^{(i)}=x^{(i)}|Y=c_k) P(X(i)=x(i)∣Y=ck)和类目 c k c_k ck的先验概率: P ( Y = c k ) P(Y=c_k) P(Y=ck)。
数据数值连续 >>> 假设每一个特征符合高斯分布 >>> 利用高斯朴素贝叶斯
- 训练预测
clf = GaussianNB(var_smoothing = 1e-8)
clf.fit(x_train, y_train)
y_predict = clf.predict(x_test)
accuracy = metrics.accuracy_score(y_test, y_predict) # sum(y_test == y_pred) / X_test.shape[0]
accuracy
预测概率
y_proba = clf.predict_proba(x_test)
print("预测概率及 预测结果", np.c_[y_proba, y_predict])
- 离散数据集–贝叶斯分类
X = np.random.RandomState(1).randint(5, size = (600, 100)) 随机生成600个100维的数据,每一维的特征都是[0, 4]
y = np.array([1, 2, 3, 4, 5, 6] * 100)
data = np.c_[X, y]
data
- 划分训练测试集
random.shuffle(data)
x, y = data[:, :-1], data[:, -1]
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2, random_state = 0)
- 训练预测
clf = CategoricalNB(alpha = 1)
clf.fit(x_train, y_train)
print("acc: %.3f"%clf.score(x_test, y_test))
x = np.random.RandomState(1).randint(5, size = (1, 100))
print(clf.predict_proba(x))
print(clf.predict(x))
对于离散特征,贝叶斯法:
P ( X ( j ) = x ( j ) ∣ Y = c k ) = ∑ i = 1 N I ( x i j = a j l , y i = c k ) + α ∑ i = 1 N I ( y i = c k ) + S j α P\left(X^{(j)}=x^{(j)} \mid Y=c_{k}\right)=\frac{\sum_{i=1}^{N} I\left(x_{i}^{j}=a_{j l}, y_{i}=c_{k}\right)+\alpha}{\sum_{i=1}^{N} I\left(y_{i}=c_{k}\right)+S_{j} \alpha} P(X(j)=x(j)∣Y=ck)=∑i=1NI(yi=ck)+Sjα∑i=1NI(xij=ajl,yi=ck)+α
们可以看出就是对每一个变量的多加了一个频数alpha。当alphaλ=0时,就是极大似然估计。通常取值alpha=1,这就是拉普拉斯平滑(Laplace smoothing),这有叫做贝叶斯估计,主要是因为如果使用极大似然估计,如果某个特征值在训练数据中没有出现,这时候会出现概率为0的情况,导致整个估计都为0,因为引入贝叶斯估计。
其中:
S
j
S_{j}
Sj:表示第j
个特征的个数。
x
i
j
x_{i}^{j}
xij:表示第i
个样本的第j
维元素。
y
i
y_{i}
yi:第i
个样本的label。
- 贝叶斯优点: 数据量表现好, 数据量大可进行增量计算, 具有较好的可解释性
- 缺点: 朴素贝叶斯模型与其他分类方法相比具有最小的理论误差率。但是实际上并非总是如此,这是因为朴素贝叶斯模型给定输出类别的情况下,假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比较多或者属性之间相关性较大时,分类效果不好。而在属性相关性较小时,朴素贝叶斯性能最为良好。对于这一点,有半朴素贝叶斯之类的算法通过考虑部分关联性适度改进,例如为了计算量不至于太大,我们假定每个属性只依赖另外的一个。解决特征之间的相关性,我们还可以使用数据降维(PCA)的方法,去除特征相关性,再进行朴素贝叶斯计算。