此篇延续上一篇博客https://blog.csdn.net/qq_31769869/article/details/105933342
logistic函数的定义
h ( X ) = 1 1 + e − z h(X) = \frac{1}{1 + e^{-z}} h(X)=1+e−z1
函数图像如下
从图像中我们可以看出x的取值范围在负无穷到正无穷,y取值在0到1之间。当 x = 0时,y = 0.5
logistic回归
估计函数:
h
(
x
(
i
)
)
=
1
1
+
e
−
x
(
i
)
θ
h(x^{(i)}) = \frac{1}{1+e^{-x^{(i)}\theta}}
h(x(i))=1+e−x(i)θ1
当
0
<
h
(
x
(
i
)
)
<
0.5
0 < h(x^{(i)}) < 0.5
0<h(x(i))<0.5,取0
当
0.5
≤
h
(
x
(
i
)
)
<
1
0.5 \le h(x^{(i)}) < 1
0.5≤h(x(i))<1,取1
代价函数:
J
(
θ
)
=
−
y
(
i
)
l
n
(
h
(
x
(
i
)
)
)
−
(
1
−
y
(
i
)
)
l
n
(
1
−
h
(
x
(
i
)
)
)
J(\theta)=-y^{(i)}ln(h(x^{(i)}))-(1-y^{(i)})ln(1 - h(x^{(i)}))
J(θ)=−y(i)ln(h(x(i)))−(1−y(i))ln(1−h(x(i)))
这个式子看起来比较复杂,可以简单的理解一下。(不太清楚这些数学的朋友可以直接去看推出的迭代公式,不理解这个代价函数对最后的代码实现影响不是特别大)
因为y的取值只有1、0,所以当
y
(
i
)
y^{(i)}
y(i) = 1,
J
(
θ
)
=
−
l
n
(
h
(
x
(
i
)
)
)
J(\theta)=-ln(h(x^{(i)}))
J(θ)=−ln(h(x(i))),所以当预测值
h
(
x
(
i
)
)
h(x^{(i)})
h(x(i))越接近1,代价函数值越小,函数图形如下,符合我们的想法。
同理,当
y
(
i
)
y^{(i)}
y(i) = 0,
J
(
θ
)
=
−
l
n
(
h
(
1
−
x
(
i
)
)
)
J(\theta)=-ln(h(1- x^{(i)}))
J(θ)=−ln(h(1−x(i))),所以当预测值
h
(
x
(
i
)
)
h(x^{(i)})
h(x(i))越接近0,代价函数值越小,函数图像如下:
求解的目标:求 θ \theta θ使得J( θ \theta θ)最小,得到的 θ \theta θ代回h(x)中即可得到分类模型。
求解方法:
梯度下降法:
我们同样按照求解线性回归的思路去求解这个代价函数,(不清楚的朋友可以去看开头的文章),
下面给出迭代的公式:
θ
=
θ
−
α
m
(
h
(
X
)
−
y
)
X
\theta = \theta - \frac{\alpha}{m}(h(X) - y)X
θ=θ−mα(h(X)−y)X
这个公式和线性回归的公式在形式上一致! 不过注意这里的 h ( X ) = 1 1 + e − x ( i ) θ h(X)=\frac{1}{1+e^{-x^{(i)}\theta}} h(X)=1+e−x(i)θ1而线性回归中h(X) = X θ \theta θ.
下面给出算法实现,求解的问题是2个特征的分类问题。
import numpy as np
import matplotlib.pyplot as plt
#2个特征值
x1 = np.array([1,2,3,4,5,6,7,8])
x2 = np.array([2,4,5,6,3,6,7,9])
X = np.column_stack((np.array([1,1,1,1,1,1,1,1]),x1,x2))
#分类的标签
y = np.array([0,0,0,0,1,1,1,1])
#初始化theta
theta = [0, 0, 0]
#学习效率
alpha = 0.03
#m个样本
m = x1.shape[0]
#更新theta
newTheta = theta - alpha / m * (1/( 1 + np.exp(-1 * X @ theta) )- y) @ X
#print(newTheta)
#迭代次数
cnt = 1
#更新theta,进行600次
while cnt < 500 :
theta = newTheta
newTheta = theta - alpha / m * (1/ (1 + np.exp(-1 * X @ theta)) - y) @ X
cnt = cnt + 1
#根据模型预测原来的值
predY = 1/( 1 + np.exp(-1 * X @ theta))
print(predY > 0.5)
执行结果:
可以看到,在原来的数据集上吻合的很好