逻辑回归的原理
逻辑回归(Logistic Regression)
- 机器学习中的一种分类模型,逻辑回归是一种分类算法。
- 名字中带有回归,因为它与线性回归之间有一定的联系。
- 由于算法的简单和高效,在实际中应用非常广泛。
逻辑回归(Logistic Regression)应用场景
- 广告点击率
- 是否为垃圾邮件
- 是否患病
- 金融诈骗
- 虚假账号
看到上面的例子,我们可以发现其中的特点,那就是都属于两个类别之间的判断。逻辑回归主要是用来解决二分类问题。当然它也可以用于多分类问题。
什么叫做回归?
在这里通过画一个平面去更好的理解,所以都用单个特征或两个特征举例子。
假设现在有一些数据点(单特征值),我们利用一条直线对这些点进行拟合(该线称为最佳拟合直线),这个拟合过程就称作为回归。即找到一条直线y=wx+b,能够拟合特征值x和目标值y之间的关系。
注释:单特征与目标值的关系呈直线关系
假设现在有一些数据点(具有2个特征值), 我们利用一个平面对这些点进行拟合,这个拟合过程就称作为回归。当存在2个特征值x1, x2时,即找到一个平面y=w1x1+w2x2+b,能够拟合特征值x1, x2和目标值y之间的关系。
注释:两个特征与目标值呈现平面的关系
回归方程(函数):对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模。通用公式:

我们一般将θ叫做回归系数。
特点:只有一个自变量的情况称为单变量回归,多于一个自变量情况的叫做多元回归
引入Sigmoid函数
从上面的例子看,通过回归方程计算得到的结果是一个连续的数值型数据, 而逻辑回归用于分类问题(本文讨论二分类问题)。怎么将连续的数值型数据→有限的离散数据(如0、1) ?
那么就引入Sigmoid函数( 也叫Logistic函数)

原理分析
- 将连续数值z (-∞,∞) 输入到sigmoid函数当中,输出结果分布在[0, 1]区间。
- 将输出值看做是一个概率值, 若设定0.5为阈值,则概率值大于0.5为属于分类,小于0.5为不属于分类。
逻辑回归公式
将线性回归函数和sigmoid函数整合成一个公式,就变成了如下公式:

其中θ= [θ0, θ1, θ2, 03, … θn]
x= [x0, x1, x2, x3, … xn]
注:数据集(x0,x1….xn])通过线性回归函数计算出的结果,通过sigmoid函数映射到[0,1]区间进行分类。
比如:当hθ(x)=0.7, 那么说明有70%的概率输出为1。输出为0的概率是输出为1的补集,也就是30%。
如果我们有合适的参数列向量θ([θ0,θ1, … ,θn]),以及样本列向量(x0,x1, … ,xn]),那么我们对样本x分类就可以通过上述公式计算出一个概率,如果这个概率大于0.5,我们就可以说样本是正样本,否则样本是负样本。
损失函数
逻辑回归需要找到一条直线对样本点进行最佳拟合。
计算损失函数,并优化损失,使损失最小化。
损失函数=(y_predict -y_true)^2/样本总数
对于逻辑回归的y值不是连续数据,而是所属类别(真实值/预测值是否属于某个类别)。完整的损失函数如下:

损失优化
我们已经知道对于P值在[0,1]区间,log(P)是负值, P值越大,log(P)越大,|log(P)|值越小, 所以满足J(0)最大的0值即是我们需要求解的模型。
如何求解使J(0)最大的0值呢?因为是求最大值,所以我们需要使用梯度上升算法。
我们先看个简单的求极大值的例子。
f(x) = -x2 + 4x这个函数的极值怎么求?
求极值,先求函数的导数:
f'(x)= -2x+4
令导数为0,可求出x=2即取得函数f(x)的极大值。
极大值等于f(2)=4
实际中的函数不会这么简单,就算求出了函数的导数,也很难精确计算出函数的极值。此时我们就可以用迭代的方法来做。
就像爬坡一样,一点一点逼近极值。这种寻找最佳拟合参数的方法,就是梯度上升算法。
爬坡这个动作用数学公式表达即为:

其中,a为步长,也就是学习速率,控制更新的幅度。
python实例代码如下:
# 函数说明:梯度上升算法测试函数,求函数f(x) = -x^2+4x 的极大值
def Gradient_Ascent_test():
def f_prime(x_old): # f(x)的导数
return-2*x_old+4
X_old=-1 # 初始值,给一个小于x_ _new的值
X_new=0 # 梯度_上升算法初始值,即从(0,0)开始
alpha = 0.01 # 步长,也就是学习速率,控制更新的幅度
presision = 0.00000001 # 精度,也就是更新阈值
while abs(X_new - X_old) > presision:
X_old = X_new
X_new = X_old + alpha * f_prime(X_old) # 上面提到的公式
print(X_new) # 打印最终求解的极值近似值
核心代码
梯度上升
梯度上升算法在每次更新回归系数(最优参数)时,都需要遍历整个数据集。如果有数十亿样本和成干上万的特征,那么该方法的计算复杂度就太高了。因此,需要对算法进行改进。
随机梯度上升
每次更新回归系数(最优参数)的时候,不用所有样本,一次只用一个样本点去更新回归系数(最优参数),这样就可以有效减少计算量了,这种方法就叫做随机梯度.上升算法。
伪代码如下:
- 所有回归系数初始化为1
- 对数据集中每个样本
- 计算该样本的梯度
- 使用alpha x梯度更新回归系数值
- 返回回归系数值
比较
随机梯度上升
- h和误差error全是数值;
- 没有矩阵的转换过程,所有变量的数据类型都是NumPy数组。
梯度上升
- 变量h和误差error都是向量;
- 经过矩阵的转换过程后,变量的数据类型都是NumPy矩阵。
改进的随机梯度上升
①alpha动态减少机制。
alpha = 0.01 + 4/(1+j+i),其中j是迭代次数,i是样本点的下标。
※alpha随着迭代次数不断减小但永远不会减小到0 (因为包含一个常数项)。这样是为了保证在多次迭代之后新数据仍然具有一定的影响。
※如果需要处理的问题是动态变化的,那么可以适当加大上述常数项,来确保新的值获得更大的回归系数。
②样本随机选择机制。更新回归系数(最优参数)时,只使用一个样本点并且选择的样本点是随机的,每次迭代不使用已经用过的样本点。这样就有效地减少了计算量,并保证了回归效果。
③增加一个迭代次数作为第3个参数,默认值为150
Logistic回归的核心代码如下:
# sigmoid函数
def sigmoid(inX):
if inX >= 0:
return 1.0 / (1 + np.exp(-inX))
else:
return np.exp(inX) / (1 + np.exp(inX))
# 改进的随机梯度上升算法
def stocGradAscent(dataMatrix, classLabels, numlter=150):
m, n = np.shape(dataMatrix)
weights = np.ones(n)
for j in range(numlter):
randnums = np.random.permutation(m)
i = 0
for index in randnums:
alpha = 4/(1.0+j+i)+0.01
h = sigmoid(sum(dataMatrix[index]*weights))
error = classLabels[index] - h
weights = weights + alpha * error * dataMatrix[index]
i += 1
return weights
Logistic回归的一般过程:
- 收集数据:采用任意方法收集数据。
- 准备数据:由于需要进行距离计算,因此要求数据类型为数值型。另外,结构化数据格式则最佳。
- 分析数据:采用任意方法对数据进行分析。
- 训练算法:大部分时间将用于训练,训练的目的是为了找到最佳的分类回归系数。
- 测试算法:一旦训练步骤完成,分类将会很快。
- 使用算法:首先,我们需要输入一些数据,并将其转换成对应的结构化数值;接着,基于训练好的回归系数,就可以对这些数值进行简单的回归计算,判定它们属于哪个类别;在这之后,我们就可以在输出的类别上做一些其他分析工作。