逻辑回归是解决分类问题的,本质是求概率再分类
功能:做二分类(1/0)任务,并给出相应概率。
比如
- 区分是否是垃圾邮件
- 银行判断用户是否会办信用卡
在回归问题上再多做一步,就可以作为分类算法来使用了。逻辑回归只能解决二分类问题,如果是多分类问题,LR本身是不支持的。
1.逻辑回归和线性回归的比较
逻辑回归和线性回归同属于广义线性模型,前者解决分类问题而后者解决回归问题。
他们的本质都是得到一条直线,不同的是
- 线性回归的直线是尽可能的去拟合输入变量x的分布,使得训练集中所有样本点到直线的距离最短;
- 而逻辑回归的直线是尽可能去拟合决策边界,使得训练集样本中的样本点尽可能分离开。
线性回归直接分析x和y的关系,逻辑回归分析y取某个值的概率和x的关系,两者的目的是不同的。
2.Sigmoid函数
我们想要的函数应该是,能接受所有的输入然后预测出类别。
在二分类情况下,我们希望函数能输出0或1,拥有这种性质的函数称为单位阶跃函数,
单位阶跃函数的问题:在0点位置函数从0瞬间跳跃到1,这个瞬间跳跃过程很难处理,函数不连续不好求导。幸运的是Sigmoid函数也有类似的性质,且数学上更容易处理。
f
(
x
)
=
1
1
+
e
−
z
f(x) = \frac{1} {1+e^{-z}}
f(x)=1+e−z1
将x拉大之后,图像如下:
3.逻辑回归
Z=WX
z
=
w
0
+
w
1
∗
x
1
+
w
2
∗
x
2
z=w_0+w_1*x_1 + w_2*x_2
z=w0+w1∗x1+w2∗x2
通过线性模型和Sigmoid函数结合,我们可以得到逻辑回归的公式:
y = 1 1 + e − ( W X ) y = \frac{1} {1+e^{-(WX)}} y=1+e−(WX)1
这样y就是(0,1)的取值。对式子进行变换可得:
l
o
g
y
1
−
y
=
w
x
+
b
log\frac{y}{1-y} = wx+b
log1−yy=wx+b
二项Logistic回归:
P
(
y
=
0
∣
x
)
=
1
1
+
e
w
∗
x
P(y=0|x) = \frac{1}{1+e^{w*x}}
P(y=0∣x)=1+ew∗x1
P
(
y
=
1
∣
x
)
=
e
w
∗
x
1
+
e
w
∗
x
P(y=1|x) = \frac{e^{w*x}} {1+e^{w*x}}
P(y=1∣x)=1+ew∗xew∗x
4.逻辑回归的损失函数
H = 1 1 + e − ( W X ) H = \frac{1} {1+e^{-(WX)}} H=1+e−(WX)1,cost函数
-log(H), y=1
-log(1-H), y=0
我们把这两个损失函数综合起来:
−
[
y
l
o
g
(
H
)
+
(
1
−
y
)
l
o
g
(
1
−
H
)
]
-[ylog(H) + (1-y)log(1-H)]
−[ylog(H)+(1−y)log(1−H)]
求最优的决策边界求法: d C o s t d w = d C d H ∗ d H d Z ∗ d Z d W = X T ( 1 1 + e − ( W X ) − y ) \frac{dCost}{dw} = \frac{dC}{dH}* \frac{dH}{dZ}* \frac{dZ}{dW} = X^T(\frac{1} {1+e^{-(WX)}}-y) dwdCost=dHdC∗dZdH∗dWdZ=XT(1+e−(WX)1−y) (推导过程…)
5.逻辑回归实战
# Logistic Regression
# import lib
import numpy as np
import matplotlib.pyplot as plt
# def loaddata
def loaddata(filename):
file = open(filename)
x=[]
y=[]
for lines in file.readlines():
lines = lines.strip().split()
x.append([1, float(lines[0]), float(lines[1])])
y.append(float(lines[-1]))
xmat = np.mat(x)
ymat = np.mat(y).T
file.close()
return xmat, ymat
# w_cal
def w_cal(xmat, ymat, alpha = 0.001, maxIter = 10000):
#W初始化
W = np.mat(np.random.randn(3,1))
#W update
for i in range(maxIter):
H = 1/(1+np.exp(-xmat*W))
dw = xmat.T*(H - ymat)
W -= alpha*dw
return W
# implement
xmat, ymat = loaddata('ylb.txt')
print('xmat:',xmat, xmat.shape)
print('ymat:',ymat, ymat.shape)
W = w_cal(xmat,ymat)
print('W:',W)
# show
w0 = W[0,0]
w1 = W[1,0]
w2 = W[2,0]
plotx1 = np.arange(1,7,0.01)
plotx2 = -w0/w2-w1/w2*plotx1
plt.plot(plotx1,plotx2,c='r',label='decsion boundary')
plt.scatter(xmat[:,1][ymat == 0].A,xmat[:,2][ymat == 0].A,marker='^',s=150,label='label=0')
plt.scatter(xmat[:,1][ymat == 1].A,xmat[:,2][ymat == 1].A,s=150,label='label=1')
plt.grid()
plt.legend()
plt.show()
其中ylb.txt的数据内容是
2 1 0
2 2 0
5 4 1
4 5 1
2 3 0
3 2 0
6 5 1
4 1 0
6 3 1
7 4 1
当迭代次数maxIter依次取值为100,1000,10000时的图如下:
maxIter=100
maxIter=1000
maxIter=10000