不知道你们是否有同感,在刚接触逻辑回归算法时候,大家多多少少都听过逻辑回归和线性回归的不同,虽然叫逻辑回归,但是完全不是回归的数值预测,而是进行分类,总是强调分类和数值预测这点的不同,很容易忽略两个算法本质上的关联。所以,本文不准备把这两个算法拆解开,算法既然叫逻辑回归,自然和“回归”脱不了关系。本文就从线性回归和逻辑回归的关联讲起,看看逻辑回归的“回归”体现在哪一步骤中,并通过公式推导探索逻辑回归的原理。
我们不再使用吴恩达教授的房价预测的例子,来看“小白鼠”的例子~
若研究老鼠死亡率和毒物用量的关联,可知,随着毒物用量的增加,老鼠死亡率上升,若使用线性回归,如下:
从值域上看,线性回归是发散式方程,其因变量取值范围为( − ∞ -\infty −∞, + ∞ +\infty +∞),很明显死亡率>1是不合理的。这个时候对于这种输出概率的问题,我们希望把值控制在0-1之间。我们可以想到把线性回归的值带入到某一函数中进行转换,使输出值的范围压制在0-1之间
。
我们可以使用哪种变换函数呢?可以想到的有“单位阶跃函数”: f ( z ) = { 0 , z<0 0.5 , z=0 1 , z>0 f(z)=\begin{cases}0,& \text{z<0}\\0.5,&\text{z=0}\\1,&\text{z>0}\end{cases} f(z)=⎩⎪⎨⎪⎧0,0.5,1,z<0z=0z>0但是,问题在于单位阶跃函数是分段函数,不连续、不可导的性质不方便使用。
所以,我们常用logit函数,也称sigmoid函数: f ( z ) = 1 1 + e − z f(z)=\frac{1}{1+e^{-z}} f(z)=1+e−z1
首先,来看看sigmoig函数图形:
可以看到sigmoid函数的特点:连续、单调、可导。
ps.sigmoid函数一个优良的性质在于: f ′ ( z ) = f ( z ) ( 1 − f ( z ) ) f'(z)=f(z)(1-f(z)) f′(z)=f(z)(1−f(z))
1 ( 1 + e − z ) ′ = [ ( 1 + e − z ) − 1 ] ′ = − ( 1 + e − z ) − 2 ( − e − z ) = e − z ( 1 + e − z ) 2 = 1 + e − z − 1 ( 1 + e − z ) 2 = 1 ( 1 + e − z ) − 1 ( 1 + e − z ) 2 = 1 ( 1 + e − z ) ( 1 − 1 ( 1 + e − z ) ) \frac{1}{(1+e^{-z})}'=[(1+e^{-z})^{-1}]'=-(1+e^{-z})^{-2}(-e^{-z})=\frac{e^{-z}}{(1+e^{-z})^2}=\frac{1+e^{-z}-1}{(1+e^{-z})^2}=\frac{1}{(1+e^{-z})}-\frac{1}{(1+e^{-z})^2}=\frac{1}{(1+e^{-z})}(1-\frac{1}{(1+e^{-z})}) (1+e−z)1′=[(1+e−z)−1]′=−(1+e−z)−2(−e−z)=(1+e−z)2e−z=(1+e−z)21+e−z−1=(1+e−z)1−(1+e−z)21=(1+e−z)1(1−(1+e−z)1)
由上述可知,我们将线性回归的结果 z = θ 0 + θ 1 x 1 + θ 2 x 2 + . . . + θ n x n z=\theta_0+\theta_1x_1+\theta_2x_2+...+\theta_nx_n z=θ0+θ1x1+θ2x2+...+θnxn带入sigmoid函数,有: y = 1 ( 1 + e − z ) = 1 ( 1 + e − ( θ 0 + t h e t a 1 x 1 + . . . θ n x n ) ) [ 1 ] y=\frac{1}{(1+e^{-z})}=\frac{1}{(1+e^{-(\theta_0+theta_1x_1+...\theta_nx_n)})}^{[1]} y=(1+e−z)1=(1+e−(θ0+theta1x1+...θnxn))1[1]
由式[1]可得 z = θ 0 + t h e t a 1 x 1 + . . . θ n x n = l n y 1 − y z=\theta_0+theta_1x_1+...\theta_nx_n=ln\frac{y}{1-y} z=θ0+theta1x1+...θnxn=ln1−yy
由于此时 y y y的取值是0-1之间的概率,可将其看做样本 x x x作为正例“1”的可能性, 1 − y 1-y 1−y即为反例"0"的可能性, y 1 − y \frac{y}{1-y} 1−yy称为odds(优势),反映 x x x作为正例的相对可能性。上述,对odds取对数,称为odds ratio优势比,也称“对数几率”: o d d s r a t i o = l n y 1 − y odds ratio=ln\frac{y}{1-y} oddsratio=ln1−yy这就是逻辑回归的由来,实际上就是用线性回归的结果,带入转换函数,逼近真实标记的对数几率。
由上可知,逻辑回归的值域为[0,1],此时,我们常用逻辑回归解决二分类问题。如何进行分类?我们需要设定一个阈值(threshold),输出概率 y y y大于这个阈值时归为类1,小于这个阈值,归于类0.
例如,电信客户流失预警,我们判断客户流失与否,流失即为类1,保留客户即为类0.如何根据输出判断客户是否流失呢?我们可以把阈值设定为最普遍的0.5,逻辑回归输出值>0.5时,认为客户流失,否则不流失。
其他的二分类问题,都可以使用逻辑回归解决。
在具有两个类的统计分类问题中,决策边界或决策表面是超曲面,其将基础向量空间划分为两个集合,一个集合。 分类器将决策边界一侧的所有点分类为属于一个类,而将另一侧的所有点分类为属于另一个类。——百度百科
我们假设阈值为0.5, y < 0.5 y<0.5 y<0.5时即为类“0”; y > 0.5 y>0.5 y>0.5时即为类“1”,此时有:
Y = { 0 , y < 0.5 1 , y > 0.5 Y=\begin{cases} 0 ,&y<0.5\\1, &y>0.5\end{cases} Y={0,1,y<0.5y>0.5 → \rightarrow → Y = { 0 , z < 0 1 , z > 0 Y=\begin{cases} 0 ,&z<0\\1, &z>0\end{cases} Y={0,1,z<0z>0 → \rightarrow → Y = { 0 , X θ < 0 1 , X θ > 0 Y=\begin{cases} 0 ,&X\theta<0\\1, &X\theta>0\end{cases} Y={0,1,Xθ<0Xθ>0
假设,我们的输入变量有 x 1 , x 2 x_1,x_2 x1,x2,逻辑回归: y = 1 1 + e − ( θ 0 + θ 1 x 1 + θ 2 x 2 ) = 1 1 + e − ( X θ ) y=\frac{1}{1+e^{-(\theta_0+\theta_1x_1+\theta_2x_2)}}=\frac{1}{1+e^{-(X\theta)}} y=1+e−(θ0+θ1x1+θ2x2)1=1+e−(Xθ)1
此时,我们取 y = 0.5 y=0.5 y=0.5,对应横坐标(线性回归的输出值): z = X θ z=X\theta z=Xθ的取值为0。有决策边界: θ 0 + θ 1 x 1 + θ 2 x 2 = 0 \theta_0+\theta_1x_1+\theta_2x_2=0 θ0+θ1x1+θ2x2=0
图中紫色直线即为决策边界。
由线性回归,可以得到同样的逻辑回归损失函数: J ( θ ) = 1 m ∑ i = 1 m 1 2 ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta)=\frac{1}{m}\sum_{i=1}^{m}\frac{1}{2}(h_\theta(x^{(i)})-y^{(i)})^2 J(θ)=m1∑i=1m21(hθ(x(i))−y(i))2
令 c o s t = 1 2 ( h θ ( x ) − y ) 2 cost=\frac{1}{2}(h_\theta(x)-y)^2 cost=21(hθ(x)−y)2,我们最小化 J ( θ ) J(\theta) J(θ)相当于最小化cost。但是我们不能直接对cost使用梯度下降法求解,因为cost中 h θ ( x ) = 1 1 + e − X θ h_\theta(x)=\frac{1}{1+e^{-X\theta}} hθ(x)=1+e−Xθ1导致 J ( θ ) J(\theta) J(θ)是非凸函数,无法收敛到全局最小。因此,我们需要对cost进行转换。
此时逻辑回归使用的损失函数 [ 2 ] ^{[2]} [2]为: c o s t ( h θ ( x ) , y ) = { − l o g ( h θ ( x ) ) , if y = 1 − l o g ( 1 − h θ ( x ) ) , if y = 0 cost(h_\theta(x),y)=\begin{cases}-log(h_\theta(x)),&\text{if $y=1$}\\-log(1-h_\theta(x)),&\text{if $y=0$}\end{cases} cost(hθ(x),y)={−log(hθ(x)),−log(1−hθ(x)),if y=1if y=0
代价函数的图像为:
当 y = 1 y=1 y=1, h θ ( x ) = 1 ℎ_\theta(x)=1 hθ(x)=1时, c o s t = 0 cost=0 cost=0;
当 y = 0 y=0 y=0, h θ ( x ) = 1 ℎ_\theta(x)=1 hθ(x)=1时, c o s t = ∞ cost=\infty cost=∞;
当 y = 1 y=1 y=1, h θ ( x ) = 0 ℎ_\theta(x)=0 hθ(x)=0时, c o s t = ∞ cost=\infty cost=∞;
当 y = 0 y=0 y=0, h θ ( x ) = 0 ℎ_\theta(x)=0 hθ(x)=0时, c o s t = 0 cost=0 cost=0.
综上, c o s t ( h θ ( x ) − y ) = − y l o g ( h θ ( x ) ) − ( 1 − y ) l o g ( h θ ( x ) ) cost(h_\theta(x)-y)=-ylog(h_\theta(x))-(1-y)log(h_\theta(x)) cost(hθ(x)−y)=−ylog(hθ(x))−(1−y)log(hθ(x))即可得到上述[2]式逻辑回归常用的cost function。
将cost function带入逻辑回归的损失函数,得: J ( θ ) = 1 m ∑ i = 1 m c o s t ( h θ ( x ( i ) ) , y ( i ) ) = − 1 m ∑ i = 1 m [ y ( i ) l o g h θ ( x ( i ) ) + ( 1 − y ( i ) ) l o g ( 1 − h θ ( x ( i ) ) ) ] J(\theta)=\frac{1}{m}\sum_{i=1}^{m}cost(h_\theta(x^{(i)}),y^{(i)})=-\frac{1}{m}\sum_{i=1}^{m}[y^{(i)}logh_\theta(x^{(i)})+(1-y^{(i)})log(1-h_\theta(x^{(i)}))] J(θ)=m1i=1∑mcost(hθ(x(i)),y(i))=−m1i=1∑m[y(i)loghθ(x(i))+(1−y(i))log(1−hθ(x(i)))]
最后,附上cost函数推导的笔记:
ps.为了书写方便 y ( i ) y^{(i)} y(i)写为 y i y_i yi
1.导入库
import matplotlib.pyplot as plt
import numpy as np
from sklearn.metrics import classification_report,confusion_matrix
from sklearn import preprocessing
from sklearn import linear_model
# 数据是否需要标准化
scale = False
2.数据导入和转换
# 载入数据
data = np.genfromtxt("data/LR-testSet.csv", delimiter=",")
x_data = data[:,:-1]
y_data = data[:,-1] #最后一列为标签
def plot():
x1_0 = []
x1_1 = []
x2_0 = []
x2_1 = []
for i in range(len(x_data)):
if y_data[i]==0:
x1_0.append(x_data[i,0])
x2_0.append(x_data[i,1])
else:
x1_1.append(x_data[i,0])
x2_1.append(x_data[i,1])
# 画图
scatter0 = plt.scatter(x1_0, x2_0, c='b', marker='o')
scatter1 = plt.scatter(x1_1, x2_1, c='r', marker='x')
#画图例
plt.legend(handles=[scatter0,scatter1],labels=['label0','label1'],loc='best')
plot()
plt.show()
model = linear_model.LogisticRegression()
model.fit(x_data, y_data)
4.画决策边界
if scale == False:
# 画图
plot()
x_test = np.array([[-4],[3]])
y_test = (-model.intercept_ - x_test*model.coef_[0][0])/model.coef_[0][1]
plt.plot(x_test, y_test, 'k')
plt.show()
5.模型预测
predictions = model.predict(x_data)
print(classification_report(y_data, predictions))
#混淆矩阵
print(confusion_matrix(y_data, predictions))
《机器学习》·周志华
吴恩达机器学习课程