Logistic Regression称为逻辑回归,简称LR,是机器学习中一个很基础的模型,是一种广义的线性回归模型,关于Logistic Regression的知识在这里就不再累述,我们一起来吧Logistic Regression进行一次数学推导来理解其中的原理。
Logistic Regression虽然中文名称带有“回归”二字,但是本质上是一个二分类模型,所以这里运用到了一个Logistic function(Sigmoid function):
g(z)=11+e−z
g
(
z
)
=
1
1
+
e
−
z
用以下Python代码可以将此函数的图像输出:
import matplotlib.pyplot as plt
import numpy as np
z = np.linspace(-6, 6, 50)
y = 1/(1+np.exp(-z))
plt.plot(x, y)
plt.show()
得到sigmoid function的图像:
这是一个值域在(0,1)的函数,有一个预测函数h(x) (h for hypothesis),也就是预测y的值,一般来说y>0.5,y predict 1;y <0.5, y predict 0。
对于z来说:
z=θ0x0+θ1x1+θ2x2+...+θixi+...+θnxn(x0=1)=θ0+θ1x1+θ2x2+...+θixi+...+θnxn=θTx
z
=
θ
0
x
0
+
θ
1
x
1
+
θ
2
x
2
+
.
.
.
+
θ
i
x
i
+
.
.
.
+
θ
n
x
n
(
x
0
=
1
)
=
θ
0
+
θ
1
x
1
+
θ
2
x
2
+
.
.
.
+
θ
i
x
i
+
.
.
.
+
θ
n
x
n
=
θ
T
x
由上述数学表达式对z做一下替换可得:
hθ(x)=g(θTx)=11+e−θTx
h
θ
(
x
)
=
g
(
θ
T
x
)
=
1
1
+
e
−
θ
T
x
对于此数学表达式而言,对于x取值分别分类到0和1的概率分别是:
P(y=0|x;θ)=1−hθ(x)P(y=1|x;θ)=hθ(x)
P
(
y
=
0
|
x
;
θ
)
=
1
−
h
θ
(
x
)
P
(
y
=
1
|
x
;
θ
)
=
h
θ
(
x
)
由上述式子可以合起来写出:
P(y|x;θ)=(hθ(x))y(1−hθ(x))1−y
P
(
y
|
x
;
θ
)
=
(
h
θ
(
x
)
)
y
(
1
−
h
θ
(
x
)
)
1
−
y
然后取上式的似然函数可以得到式子:
L(θ)=∏i=1mP(y(i)|x(i);θ)=∏i=1m(hθ(x(i)))y(i)(1−hθ(x(i)))1−y(i)
L
(
θ
)
=
∏
i
=
1
m
P
(
y
(
i
)
|
x
(
i
)
;
θ
)
=
∏
i
=
1
m
(
h
θ
(
x
(
i
)
)
)
y
(
i
)
(
1
−
h
θ
(
x
(
i
)
)
)
1
−
y
(
i
)
因为得到的此似然函数是连乘的,不方便计算,所以统一对此似然函数取对数,就可以得到:
ℓ(θ)=logL(θ)=∑i=1m(y(i)loghθ(x(i))+(1−y(i))log(1−hθ(x(i))))
ℓ
(
θ
)
=
log
L
(
θ
)
=
∑
i
=
1
m
(
y
(
i
)
log
h
θ
(
x
(
i
)
)
+
(
1
−
y
(
i
)
)
log
(
1
−
h
θ
(
x
(
i
)
)
)
)
然后此问题可以等价于求:
θ∗=argminm(ℓ(θ))
θ
∗
=
arg
min
m
(
ℓ
(
θ
)
)
这时可以采用梯度下降算法,整个式子对θj求偏导可以得到:
∂∂θj(ℓ(θ))=∂∂θj(∑i=1my(i)log(h(x(i)))+(1−y(i))log(1−hθ(x(i))))=(y(i)hθ(x(i))+1−y(i)1−hθ(x(i))(−1))∂∂θj(hθ(x(i)))=(y(i)g(θTx)−1−y(i)1−g(θTx))∂∂θj(g(θTx))=(y(i)1g(θTx)−(1−y(i))11−g(θTx))g(θTx)(1−g(θTx))∂θTx∂θj=(y(i)(1−g(θTx)−(1−y(i))g(θTx))∂∂θj(θ0+θ1x1+θ2x2+...+θjxj+...+θnxn)=(y(i)−g(θTx))xj
∂
∂
θ
j
(
ℓ
(
θ
)
)
=
∂
∂
θ
j
(
∑
i
=
1
m
y
(
i
)
log
(
h
(
x
(
i
)
)
)
+
(
1
−
y
(
i
)
)
log
(
1
−
h
θ
(
x
(
i
)
)
)
)
=
(
y
(
i
)
h
θ
(
x
(
i
)
)
+
1
−
y
(
i
)
1
−
h
θ
(
x
(
i
)
)
(
−
1
)
)
∂
∂
θ
j
(
h
θ
(
x
(
i
)
)
)
=
(
y
(
i
)
g
(
θ
T
x
)
−
1
−
y
(
i
)
1
−
g
(
θ
T
x
)
)
∂
∂
θ
j
(
g
(
θ
T
x
)
)
=
(
y
(
i
)
1
g
(
θ
T
x
)
−
(
1
−
y
(
i
)
)
1
1
−
g
(
θ
T
x
)
)
g
(
θ
T
x
)
(
1
−
g
(
θ
T
x
)
)
∂
θ
T
x
∂
θ
j
=
(
y
(
i
)
(
1
−
g
(
θ
T
x
)
−
(
1
−
y
(
i
)
)
g
(
θ
T
x
)
)
∂
∂
θ
j
(
θ
0
+
θ
1
x
1
+
θ
2
x
2
+
.
.
.
+
θ
j
x
j
+
.
.
.
+
θ
n
x
n
)
=
(
y
(
i
)
−
g
(
θ
T
x
)
)
x
j
对于上式的第三步推导到第四部有很多朋友都有所不解,我们来把最后一个偏导项展开来推导,就明白了:
∂∂θj(g(θTx))=∂∂θj(11+e−θTx)=∂∂θTx(11+e−θTx)∂θTx∂θj=e−θTx(1+e−θTx)2∂θTx∂θj=e−θTx+1−1(1+e−θTx)2∂θTx∂θj=(11+e−θTx−1(1+e−θTx)2)∂θTx∂θj=11+e−θTx(1−11+e−θTx)∂θTx∂θj=g(θTx)(1−g(θTx))∂θTx∂θj
∂
∂
θ
j
(
g
(
θ
T
x
)
)
=
∂
∂
θ
j
(
1
1
+
e
−
θ
T
x
)
=
∂
∂
θ
T
x
(
1
1
+
e
−
θ
T
x
)
∂
θ
T
x
∂
θ
j
=
e
−
θ
T
x
(
1
+
e
−
θ
T
x
)
2
∂
θ
T
x
∂
θ
j
=
e
−
θ
T
x
+
1
−
1
(
1
+
e
−
θ
T
x
)
2
∂
θ
T
x
∂
θ
j
=
(
1
1
+
e
−
θ
T
x
−
1
(
1
+
e
−
θ
T
x
)
2
)
∂
θ
T
x
∂
θ
j
=
1
1
+
e
−
θ
T
x
(
1
−
1
1
+
e
−
θ
T
x
)
∂
θ
T
x
∂
θ
j
=
g
(
θ
T
x
)
(
1
−
g
(
θ
T
x
)
)
∂
θ
T
x
∂
θ
j
综上所有的推导过程,我们可以得到梯度下降的结果:
θj:=θj−α(hθ(x(i))−y(i))x(i)j
θ
j
:=
θ
j
−
α
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
x
j
(
i
)
其中α是learning rate,表示每次下降的幅度,这个α不能过大,过大的话会导致θj无法收敛,α过小的话会导致θj收敛的速度很慢,所以在收敛的过程中,需要朋友们自己来调整这个参数,如上就是LR的完整详细的推导过程,不知对你是否有帮助呢。
为了便于理解,我们一起来用Python来实现一个例子(我用的是jupyter notebook),在这里我先贴上我的代码,具体我们再来分析:
gradient decent method
theta := theta - alpha * (theta * X - Y) * X
alpha – learning rate
import numpy as np
from numpy.linalg import inv
from numpy import dot
from numpy import mat
dataset = pd.read_csv('./Desktop/dataset/data.csv')
tempx = dataset.iloc[:,0:3]
tempx['x0'] = 1
X = tempx.iloc[:,[3,0,1,2]]
Y = dataset.iloc[:, 3].values.reshape(200,1)
theta_gradient = np.array([1., 1., 1., 1.]).reshape(4,1)
alpha_new = 0.01
temp = theta_gradient
X0 = X.iloc[:, 0].values.reshape(200,1)
X1 = X.iloc[:, 1].values.reshape(200,1)
X2 = X.iloc[:, 2].values.reshape(200,1)
X3 = X.iloc[:, 3].values.reshape(200,1)
for i in range(10000):
temp[0] = theta_gradient[0] - alpha_new*np.sum(dot(X,theta_gradient)*X0 - Y)/200
temp[1] = theta_gradient[1] - alpha_new*np.sum(dot(X,theta_gradient)*X1 - Y)/200
temp[2] = theta_gradient[2] - alpha_new*np.sum(dot(X,theta_gradient)*X2 - Y)/200
temp[3] = theta_gradient[3] - alpha_new*np.sum(dot(X,theta_gradient)*X3 - Y)/200
theta_gradient = temp
print(theta_gradient)
在这段代码中的数据集是我自己生成的,生成数据集的代码如下:
import random
def Y(X1, X2, X3):
return 0.65 * X1 + 0.70 * X2 - 0.55 * X3 + 1.95
def Produce():
filename = 'data.csv'
with open(filename, 'w') as file:
file.write('X1,X2,X3,Y\n')
for i in range(200):
random.seed()
x1 = random.random()
x2 = random.random()
x3 = random.random()
y = Y(x1, x2, x3)
try:
file.write(str(x1) + ',' + str(x2) + ',' + str(x3) + ',' + str(y) + '\n')
except Exception, e:
print 'Write Error'
print str(e)
if __name__ == '__main__':
Produce()
我在LR的代码中对我的data.csv中的数据进行了处理,处理成我需要的格式,然后进行10000次梯度下降直到收敛为止,学习率是0.01,最终我们可以求出theta_gradient。我们一起动动手就可以完全理解Logistic Regression的原理了,希望这篇博客能对你有所帮助,本人水平有限,如有错误,希望读者轻喷,不吝指教,谢谢,如您有转载,请标明出处。