0%

经典机器学习算法——逻辑回归

逻辑回归模型


​ 逻辑回归算法是一种根据现有数据对分类边界线(Decision Boundary)建立回归公式,以此进行分类的模型。逻辑回归首先赋予每个特征相同的回归参数,然后使用梯度下降算法来不断优化各个回归参数,最终根据回归参数来对新样本进行进行预测。

注意:虽然名叫逻辑回归,但是实际上是一种分类模型

工作原理

1
2
3
4
5
每个回归系数初始化为 1
重复 R 次:
计算整个数据集的梯度
使用 步长 x 梯度 更新回归系数的向量(梯度下降)
返回回归系数

逻辑回归算法的特点

优点:计算代价低,可解释性强

缺点:容易欠拟合,分类精度可能不高

使用数据类型:数值型数据和标称型数据(只存在是和否两种结果的将数据)

sigmod函数

​ sigmod是一种近似的越阶函数,可以将任意的输入值,然后将其映射为0到1之间的值,其公式和函数图像如下图:

sigmod公式

sigmod函数

​ 在逻辑回归中先使用每个特征乘以一个回归系数,将其乘积作为sigmod函数中的z,即

逻辑回归中的z

​ 然后将其得到的值用sigmod函数映射到0到1,可以理解为被分为1类的概率。

梯度上升算法

​ 要找到某个函数的最大值,最好的方式就是沿着梯度方向不断地去寻找,如果梯度记做▽ ,则函数 f(x, y) 的梯度由下式表示:

sigmod函数

这个梯度意味着要沿 x 的方向移动 f(x, y)对x求偏导 ,沿 y 的方向移动 f(x, y)对y求偏导 。其中,函数f(x, y) 必须要在待计算的点上有定义并且可微。下图是一个具体的例子。梯度上升图

​ 上图展示了整个梯度上升的过程,梯度上升算法在到到每个点后都会从新估计移动的方向,而这个方向就是梯度方向,移动的速度大小由参数α控制。

训练过程

​ 训练算法:使用梯度上升寻找最佳参数

1
2
3
4
5
6
> 每个回归系数初始化为 1
> 重复 R 次:
> 计算整个数据集的梯度
> 使用 步长 x 梯度 更新回归系数的向量(梯度下降)
> 返回回归系数
>

​ 其中步长为超参数alpha,而梯度的计算如下:

梯度1

即每个点的数据和其输入数据相同。因此权重的更新可以使用:

w:=w+α error x

其中α为常数步长,error为在当前参数值下与目标值的误差经过sigmod函数处理后的值,x为当当前样本的输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import numpy as np

def sigmod(x):
return 1/1+np.exp(-x)

def gradAscend(dataSet,labelSet,alpha,maxCycles):

#将输入的数据转为向量格式
dataMat = np.mat(dataSet)
labelMat = np.mat(labelSet).tramsponse()
#获取输入数据的维度
m,n = np.shape(dataMat)
#初始化回归系数
weights = np.ones((n,1))
#对回归系数进行迭代更新

for i in range(maxCycles):
#计算使用当前回归系数LR的hx值,结果为(m,1)维向量
h = sigmod(dataMat*weights)
#计算误差
error = labelMat-h
#根据梯度进行回归系数更新
weights = weights + alpha*dataMat.transponse()*error
return weights

随机梯度上升算法

​ 随机梯度上升算法起到的作用和一般的梯度上升算法是一样的,只是由于一般的梯度上升算法在每次更新回归系数时需要遍历整个数据集,因此当数据量变动很大时,一般的梯度上升算法的时间消耗将会非常大,因此提出了每次只使用一个样本来进行参数更新的方式,随机梯度上升(下降)

随机梯度上升算法的特点:

​ 1.每次参数更新只使用一个样本,速度快

​ 2.可进行在线更新,是一个在线学习算法(也是由于每次回归系数更新只使用一个样本)

工作原理:

1
2
3
4
5
所有回归系数初始化为 1
对数据集中每个样本
计算该样本的梯度
使用 alpha x gradient 更新回归系数值
返回回归系数值

初步随机梯度下降代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def stocgradAscend(dataSet,labelSet):
#1.这里没有转换成矩阵的过程,整个过程完全都是在Numpy数据完成的
alpha = 0.01

m,n = np.shape(dataSet)

weights = np.ones((n,1))
#2.回归系数更新过程中的h、error都是单个值,而在一般梯度上升算法中使用的是矩阵操作
for i in range(m):
h = np.sigmod(dataSet[i]*weights)
error = h - labelSet[i]
weights = weights + alpha*error*dataSet[i]

return weights

但是这种随机梯度上升算法在在实际的使用过程出现了参数最后难以收敛,最终结果周期性波动的问题,针对这种问题我们对这个问题将随机梯度下降做了下面两种优化

​ 1.改进为 alpha 的值,alpha 在每次迭代的时候都会调整。另外,虽然 alpha 会随着迭代次数不断减少,但永远不会减小到 0,因为我们在计算公式中添加了一个常数项。

​ 2.修改randomIndex的值,从以前顺序的选择样本更改为完全随机的方式来选择用于回归系数的样本,每次随机从列表中选出一个值,然后从列表中删掉该值(再进行下一次迭代)。

最终版随机梯度下降:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def stocgradAscend(dataSet,labelSet,numsIter=150):

m,n = np.shape(dataSet)
weights = np.ones(n,1)
alpha = 0.01

for i in range(numsIter):
#生成数据的索引
dataIndex = range(m)
for i in range(m):
#alpha会随着i和j的增大不断减小
alpha = 4/(i+j+1.0)+0.001 # alpha 会随着迭代不断减小,但永远不会减小到0,因为后边还有一个常数项0.0001
#生成随机选择要进行回归系数更新的数据索引号
randomIndex = np.random.uniform(0,len(dataIndex))
h = sigmod(np.sum(dataSet[dataIndex[randomIndex]]*weights))
error = h - dataSet[dataIndex[randomIndex]]*weights
weights = weights + alpha*error*dataSet[dataIndex[randomIndex]]
#在数据索引中删除
del(dataIndex[randomIndex])
return weights

预测过程

​ LR模型的预测过程很简单,只需要根据训练过程训练出的参数,计算sigmod(w*x),如果这个值大于0.5,则分为1,反之则为0

1
2
3
4
5
6
def classfyLR:(inX,weights)
prob = sigmod(np.sum(weights*inX))
if prob>=0.5
return 1
else:
return 0

注:这里的阈值其实是可以自行设定的

一些其他相关问题


1.LR模型和最大熵模型

​ (1).logistic回归模型和最大熵模型都属于对数线性模型

​ (2).当最大熵模型进行二分类时,最大熵模型就是逻辑回归模型

​ (3) 学习他们的模型一般采用极大似估计或正则化的极大似然估计

​ (4)二者可以形式化为无约束条件下的最优化问题

2.LR模型的多分类

​ 逻辑回归也可以作用于多分类问题,对于多分类问题,处理思路如下:将多分类问题看做多个二分类,然后在各个sigmod得到的分数中区最大的值对应的类作为最终预测标签。