俯视机器学习
我想我还是不习惯,从看不懂数学公式到轻松推导整个算法!
第8章 Logistic回归(Logistic Regression)
1. Logistic 函数
f ( x ) = 1 1 + e − x f(x) = \frac{1}{1+e^{-x}} f(x)=1+e−x1
2. Logistic回归
考虑二分类任务,对给定的样本
x
x
x,输出类别
f
(
x
)
∈
0
,
1
f(x)\in {0,1}
f(x)∈0,1,构造函数
f
(
x
)
=
1
1
+
e
−
(
w
T
x
+
b
)
f(x) = \frac{1}{1+e^{-(w^Tx + b)}}
f(x)=1+e−(wTx+b)1
为了方便讨论,把
x
x
x 改为扩展形式,即最后增加一个元素
1
1
1,
w
,
x
w, x
w,x 采用同样的记号
f
(
x
)
=
1
1
+
e
−
w
T
x
(2)
f(x) = \frac{1}{1 + e^{-w^T x}} \tag{2}
f(x)=1+e−wTx1(2)
通过学习获得权重
w
w
w,当
x
x
x 真实类别为
0
0
0(或
1
1
1) 时,希望输出
f
(
x
)
f(x)
f(x) 也接近
0
0
0(或
1
1
1)。
给定
x
∈
R
n
x\in R^n
x∈Rn,定义期望函数
p
(
x
;
w
)
=
y
f
(
x
)
+
(
1
−
y
)
(
1
−
f
(
x
)
)
(3)
p(x;w) = yf(x) + (1-y)(1-f(x)) \tag{3}
p(x;w)=yf(x)+(1−y)(1−f(x))(3)
其中
y
y
y 为
x
x
x 的真实类别,
p
(
x
;
w
)
p(x;w)
p(x;w) 可以看成是样本的预测概率。则希望所有样本的预测概率之积最大(最大似然估计),即最大化
Π
x
p
(
x
;
w
)
\mathop{\Pi}_x p(x;w)
Πxp(x;w)
其中
m
m
m 表示样本数。通常乘积结果很小,通过取对数,不改变最优解。取对数后的期望记为
P
(
w
)
P(w)
P(w) ,有
P
(
w
)
=
∑
x
ln
p
(
x
;
w
)
(4)
P(w) = \sum_x \ln p(x;w) \tag{4}
P(w)=x∑lnp(x;w)(4)
其中
∑
x
\sum_x
∑x 表式遍历所有样本
x
x
x 求和。
把
(
2
)
,
(
3
)
(2),(3)
(2),(3) 式代入式
(
4
)
(4)
(4) ,可得
P
(
w
)
=
∑
x
[
y
w
T
x
−
ln
(
1
+
e
w
T
x
)
]
(5)
P(w) = \sum_x \left[y w^T x - \ln (1+e^{w^T x})\right] \tag{5}
P(w)=x∑[ywTx−ln(1+ewTx)](5)
通常要处理的式最小化问题,定义
l
(
w
)
=
−
P
(
w
)
l(w)=-P(w)
l(w)=−P(w)。最大化
P
(
w
)
P(w)
P(w),相当于最小化
l
(
w
)
l(w)
l(w)。
可解得
l
(
w
)
=
∑
x
[
−
y
w
T
x
+
ln
(
1
+
e
w
T
x
)
]
(5)
l(w) = \sum_x \left[-y w^T x + \ln (1+e^{w^T x})\right] \tag{5}
l(w)=x∑[−ywTx+ln(1+ewTx)](5)
这里
x
,
y
x, y
x,y 分别代表扩展的样本及其真实类别,两者均随样本不同而不同。
3. 牛顿法求解最优化目标
根据式
(
1
)
(1)
(1),第
(
t
+
1
)
(t+1)
(t+1) 轮迭代解的更新公式为
w
t
+
1
=
w
t
−
(
∂
2
l
(
w
)
∂
w
∂
w
T
)
−
1
∂
l
(
w
)
∂
w
w^{t+1} = w^t - \left(\frac{\partial^2 l(w)}{\partial w \partial w^T} \right)^{-1}\frac{\partial l(w)}{\partial w}
wt+1=wt−(∂w∂wT∂2l(w))−1∂w∂l(w)
或写为
w
t
+
1
=
w
t
−
[
∇
2
l
(
w
)
]
−
1
∇
l
(
w
)
(6)
w^{t+1} = w^t - \left[\nabla^2 l(w) \right]^{-1}\nabla l(w) \tag{6}
wt+1=wt−[∇2l(w)]−1∇l(w)(6)
计算可得
∇
l
(
w
)
=
∑
x
(
−
y
x
+
e
w
T
x
1
+
e
w
T
x
x
)
[
∇
2
l
(
w
)
]
i
j
=
∑
x
x
i
x
j
e
−
w
T
x
(
1
+
e
−
w
T
x
)
2
(7)
\nabla l(w) = \sum_x \left(-y x + \frac{e^{w^T x}}{1+e^{w^T x}}x \right) \\ [\nabla^2 l(w)]_{ij} = \sum_x \frac{x_i x_j e^{-w^T x}}{(1+ e^{-w^T x})^2} \tag{7}
∇l(w)=x∑(−yx+1+ewTxewTxx)[∇2l(w)]ij=x∑(1+e−wTx)2xixje−wTx(7)
∇
2
l
(
w
)
=
∑
x
x
x
T
e
−
w
T
x
(
1
+
e
−
w
T
x
)
2
(8)
\nabla^2 l(w) = \sum_x \frac{xx^T e^{-w^T x}}{(1+ e^{-w^T x})^2} \tag{8}
∇2l(w)=x∑(1+e−wTx)2xxTe−wTx(8)
这里 x i x_i xi(或 x j x_j xj) 分别代表 x x x 的第 i i i或( j j j) 个属性。
4. 实战:鸢尾花分类
对鸢尾花数据集的类别进行分类。
数据集介绍:
-
数据来源:R.A. Fisher
-
150 个样本点,3 类鸢尾花,每类 50 个样本点。
-
4 个属性,分别为花萼长度、花萼宽度、花瓣长度、花瓣宽度。
-
目的:根据属性判断鸢尾花类别。
编程实现
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
# 数据准备
X, y = load_iris(return_X_y=True)
X = X[(y==0) | (y==1)] # / X.max(axis=0)
X = X[:, [0,1]] # 只取前两个属性
X = np.c_[X, np.ones((len(X), 1))]
yy = y[(y==0) | (y==1)]
y = y[(y==0) | (y==1)].reshape((-1, 1))
# 牛顿法求解 logistic 回归
def get_loss(X, y, w):
return np.sum(-y * (X @ w) + np.log(1 + np.exp(X @ w)))
def get_grad(X, y, w):
G = np.zeros(X.shape[1]).reshape(-1, 1)
for i in range(len(X)):
x = X[i, :].reshape(-1,1)
G += -y[i] * x + np.exp(w.T @ x)/(1 + np.exp(w.T @ x)) * x
return G
def get_hessian(X, y, w):
H = np.zeros((X.shape[1], X.shape[1]))
for x in X:
x = x.reshape(-1, 1)
H += x @ x.T * (np.exp(-w.T @ x)) / (1 + np.exp(-w.T @x))**2
return H
# 牛顿法求解
it = 0 # 迭代次数
maxIt = 20
w = np.zeros((X.shape[1], 1))
ep = 1e-5
G = 1000.
loss = []
while np.linalg.norm(G) > ep and it < maxIt:
G = get_grad(X, y, w)
H = get_hessian(X, y, w)
w = w - (np.linalg.inv(H) @ G).reshape(-1,1)
loss.append(get_loss(X, y, w))
it += 1
print(f'iter = {it}')
print(f'w = \n{w}')
# 可视化
x1min, x1max = X[:,0].min()-.5, X[:,0].max()+.5
x2min, x2max = X[:,1].min()-.5, X[:,1].max()+.5
xx1, xx2 = np.meshgrid(np.linspace(x1min, x1max, 100),
np.linspace(x2min, x2max, 100))
X2 = np.c_[xx1.ravel(), xx2.ravel(), np.ones(len(xx1.ravel()))]
y2 = 1. / (1 + np.exp(-X2 @ w))
y2[y2 > 0.5] = 1
y2[y2 <= 0.5] = 0
Z = y2.reshape(xx1.shape)
plt.pcolormesh(xx1, xx2, Z, shading='auto', cmap=plt.cm.binary_r)
plt.scatter(X[yy==0][:,0], X[yy==0][:,1], c='r', marker='o')
plt.scatter(X[yy==1][:,0], X[yy==1][:,1], c='g', marker='+')
plt.show()
5. 实战:Sklearn中的Logistic回归
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)
- 参数
penalty [{‘l1’, ‘l2’, ‘elasticnet’, ‘none’}, default=’l2’]
惩罚dual [bool, default=False]
对偶问题或是原问题形式tol [float, default=1e-4]
提前停止的阈值C [float, default=1.0]
正则化系数,越小正则化能力越强!
- 属性
classes_
coef_
intercept_
- 方法
fit(X, y[, sample_weight])
predict(X)
score(X, y[, sample_weight])
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
X, y = load_iris(return_X_y=True)
X = X[:, :2] # 取前两个特征
X = X[(y==0) | (y==1)]
y = y[(y==0) | (y==1)]
lr = LogisticRegression()
lr.fit(X, y)
ypred = lr.predict(X)
acc = np.sum(ypred == y) / len(y)
print(f"Accurancy = {acc}")
版权申明:本教程版权归创作人所有,未经许可,谢绝转载!
交流讨论QQ群:784117704
部分视频观看地址:b站搜索“火力教育”
课件下载地址:QQ群文件(有最新更新) or 百度网盘PDF课件及代码
链接:https://pan.baidu.com/s/1lc8c7yDc30KY1L_ehJAfDg
提取码:u3ls