所以文档都用来做笔记,便于翻阅复习,如有侵权,联系我哈,可删除~~
什么是逻辑回归:
LR是linear regression还是logistics regression呐?
两者的区别:线性回归的预测是无界限的,则需要根据可能的分类设置阈值,来作为分类问题;而逻辑回归的值域被严格限制为 0 到 1,逻辑回归并不是回归而是分类,是一种定性的分析,线性回归用来预测数值,是定量的,不适合用在分类上。当我们想将线性回归应用到分类问题中该怎么办呢?比如二分类问题,将X对应的y分为类别0和类别1。我们知道,线性回归本身的输出是连续的,也就是说要将连续的值分为离散的0和1。答案很容易想到,找到一个联系函数,将X映射到y∈{0,1}。可能大家立马会想到单位阶跃函数(unit-step Function),单位阶跃函数的确直接明了,小于0为类别0,大于0为类别1,等于0则皆可。但是有一个原则性的问题,我们需要的联系函数,必须是一个单调可微的函数,也就是说必须是连续的。逻辑回归使用的联系函数是Sigmoid函数(S形函数)中的最佳代表,即对数几率函数(Logistic Function)。
逻辑回归的对数几率函数是关于X的线性函数。
举个例子:
预测明天的气温是多少度,属于回归问题。
预测明天是阴、晴还是雨,属于分类问题。
下面来看下logistics regression:“逻辑回归”这个名称的由来,通过线性回归拟合数据,而后使用逻辑函数来预测分类的结果。
也有另外一种解释:如何用连续的数值去预测离散的标签值呢?--->从线性回归到逻辑回归原因
线性回归的输出是一个数值,而不是一个标签,显然不能直接解决二分类问题。那我如何改进我们的回归模型来预测标签呢?
一个最直观的办法就是设定一个阈值,比如0,如果我们预测的数值 y > 0 ,那么属于标签A,反之属于标签B,采用这种方法的模型又叫做感知机(Perceptron)。
另一种方法,我们不去直接预测标签,而是去预测标签为A概率,我们知道概率是一个[0,1]区间的连续数值,那我们的输出的数值就是标签为A的概率。一般的如果标签为A的概率大于0.5,我们就认为它是A类,否则就是B类。这就是我们的这次的主角逻辑回归模型 (Logistics Regression)。
适用场景:
应用场景:
- 用于分类场景, 尤其是因变量是二分类(0/1,True/False,Yes/No)时我们应该使用逻辑回归。
- 不要求自变量和因变量是线性关系
存在的问题:
- 防止过拟合和低拟合,应该让模型构建的变量是显著的。一个好的方法是使用逐步回归方法去进行逻辑回归。
- 逻辑回归需要大样本量,因为最大似然估计在低样本量的情况下不如最小二乘法有效。
- 独立的变量要求没有共线性。
原理:
模型:
附上线性回归的最小二乘推导,矩阵求导也还是有大学问滴:
损失函数:
用来衡量模型的输出与真实输出的差别,最大化输出概率。
优化方法:
与线性回归不同的是,逻辑回归由于其联系函数的选择,它的参数估计方法不再使用最小二乘法,而是极大似然法(Maximum Likelihood Method)。最小二乘法是最小化预测和实际之间的欧氏距离,极大似然法的思想也是如出一辙的,但是它是通过最大化预测属于实际的概率来最小化预测和实际之间的“距离”。
为什么可以用梯度下降法?
因为逻辑回归的损失函数L是一个连续的凸函数(conveniently convex)。这样的函数的特征是,它只会有一个全局最优的点,不存在局部最优。对于GD跟SGD最大的潜在问题就是它们可能会陷入局部最优。然而这个问题在逻辑回归里面就不存在了,因为它的损失函数的良好特性,导致它并不会有好几个局部最优。当我们的GD跟SGD收敛以后,我们得到的极值点一定就是全局最优的点,因此我们可以放心地用GD跟SGD来求解。
梯度下降,使用梯度G进行W的更新,随机梯度下降,不直接使用损失函数的梯度去更新,而是使用期望为G的替代函数T(W)来更新W。
梯度下降:核心思想就是先随便初始化一个W0,然后给定一个步长k,w0-->wn,从而最后靠近到达取得最大值的点,即不断进行下面的迭代过程,直到达到指定次数,或者梯度等于0为止。
随机梯度下降:如果我们能够在每次更新过程中,加入一点点噪声扰动,可能会更加快速地逼近最优值。所以使用期望为G的替代函数T来更新W。随机抽出一个样本,代替整体样本,相当于获得了梯度的无偏估计值。
代码:
底层函数是怎么开发的呐?
1 初始化函数,初始化学习率、迭代的次数:__init__()
def __init__(self, learning_rate=.1, n_iterations=4000):
self.learning_rate = learning_rate
self.n_iterations = n_iterations
2.初始化参数,参数矩阵w里的大小范围在(-limit,limit)之间,矩阵大小为(n_features,1)。w加入b的值相当于把偏置值加进去.
def initialize_weights(self, n_features):
# 初始化参数
# 参数范围[-1/sqrt(N), 1/sqrt(N)]
limit = np.sqrt(1 / n_features)
w = np.random.uniform(-limit, limit, (n_features, 1))
b = 0
self.w = np.insert(w, 0, b, axis=0)
3.sigmoid函数
def sigmoid(x):
return 1 / (1 + np.exp(-x))
4.逻辑回归的主要核心函数吗,X加多一列全1的值,这样wx相当于wx + b。然后根据迭代的次数,利用梯度下降法循环优化w,w_grad是梯度。
def fit(self, X, y):
m_samples, n_features = X.shape
self.initialize_weights(n_features)
# 为X增加一列特征x1,x1 = 0
X = np.insert(X, 0, 1, axis=1)
y = np.reshape(y, (m_samples, 1))
# 梯度训练n_iterations轮
for i in range(self.n_iterations):
h_x = X.dot(self.w)
y_pred = sigmoid(h_x)
w_grad = X.T.dot(y_pred - y)
self.w = self.w - self.learning_rate * w_grad
5.预测函数,利用优化求得的w预测数据的分类。
def predict(self, X):
X = np.insert(X, 0, 1, axis=1)
h_x = X.dot(self.w)
y_pred = np.round(sigmoid(h_x))
return y_pred.astype(int)
完整 版本代码:
# -*- coding: utf-8 -*-
from numpy import *
from matplotlib import pyplot as plt
def plot_best_fit(wei, data_set, label):
weights = wei
data_set = array(data_set)
n = shape(data_set)[0]
xcourd1 = []; ycourd1 = []
xcourd2 = []; ycourd2 = []
for i in range(n):
if int(label[i]) == 1:
xcourd1.append(data_set[i, 1]); ycourd1.append(data_set[i, 2])
else:
xcourd2.append(data_set[i, 1]); ycourd2.append(data_set[i, 2])
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(xcourd1, ycourd1, s=30, c='red', marker='s')
ax.scatter(xcourd2, ycourd2, s=30, c='green')
x = arange(-3.0, 3.0, 0.1)
y = (-weights[0] - weights[1]*x)/weights[2]
ax.plot(x, y)
plt.xlabel('X1'); plt.ylabel('X2')
plt.show()
def load_data():
data_set = []
label = []
fr = open('./text.txt')
for line in fr.readlines():
line = line.strip().split()
data_set.append([1.0, float(line[0]), float(line[1])])
label.append(int(line[2]))
return data_set, label
def sigmoid(x):
return 1.0 / (1 + exp(-x))
# 梯度下降算法 GD
def train(data_set, label):
data_matrix = mat(data_set)
label = mat(label).transpose()
m, n = shape(data_matrix)
alpha = 0.001
max_cycles = 500
weights = ones((n, 1))
for k in range(max_cycles):
h = sigmoid(data_matrix*weights)
error = h - label
weights = weights - alpha * data_matrix.transpose() * error
return weights
# on line to study SGD
def stoc_grad_descent(data_set, label):
m, n = shape(data_set)
alpha = 0.01
weights = ones(n)
for i in range(m):
h = sigmoid(sum(data_set[i]*weights))
error = h - label[i]
weights = weights - alpha * error * data_set[i]
return weights
# on line to study prove
def prove_grad_ascent(data_set, label, num_iter=450):
m, n = shape(data_set)
weights = ones(n)
for j in range(num_iter):
data_index = range(m)
for i in range(m):
alpha = 4/(1.0+j+i)+0.01 # prevent swings
# choose a random value to prevent periodic swings
rand_index = int(random.uniform(0, len(data_index)))
h = sigmoid(sum(data_set[rand_index]*weights))
error = label[rand_index] - h
weights = weights + alpha * error * data_set[rand_index]
del data_index[rand_index]
return weights
if __name__ == "__main__":
data_set, label = load_data()
#print label
#weights = train(array(data_set), label)
#weights = stoc_grad_ascent(array(data_set), label)
weights = prove_grad_ascent(array(data_set), label)
plot_best_fit(weights, data_set, label)
参考git:
逻辑回归( Logistic Regression)的Python源码的实现 - 知乎
逻辑回归的可解释性:
逻辑回归最大的特点就是可解释性很强。
在模型训练完成之后,我们获得了一组n维的权重向量 w跟偏差 b。
对于权重向量w,它的每一个维度的值,代表了这个维度的特征对于最终分类结果的贡献大小。假如这个维度是正,说明这个特征对于结果是有正向的贡献,那么它的值越大,说明这个特征对于分类为正起到的作用越重要。
对于偏差b (Bias),一定程度代表了正负两个类别的判定的容易程度。假如b是0,那么正负类别是均匀的。如果b大于0,说明它更容易被分为正类,反之亦然。
根据逻辑回归里的权重向量在每个特征上面的大小,就能够对于每个特征的重要程度有一个量化的清楚的认识,这就是为什么说逻辑回归模型有着很强的解释性的原因。
线性回归和逻辑回归的区别和联系:
-
线性回归和逻辑回归都是广义线性回归模型的特例
-
线性回归只能用于回归问题,逻辑回归用于分类问题(可由二分类推广至多分类)
-
线性回归无联系函数或不起作用,逻辑回归的联系函数是对数几率函数,属于Sigmoid函数
-
线性回归使用最小二乘法作为参数估计方法,逻辑回归使用极大似然法作为参数估计方法
LR模型的可解释性:
从特征的权重可以看到不同的特征对最后结果的影响,某个特征的权重值比较高,那么这个特征最后对结果的影响会比较大。
优点:
一是逻辑回归的算法已经比较成熟,预测较为准确;
二是模型求出的系数易于理解,便于解释,不属于黑盒模型,尤其在银行业,80%的预测是使用逻辑回归;
三是结果是概率值,可以做ranking model;
四是训练快。
缺点:
分类较多的y都不是很适用;对于自变量的多重共线性比较敏感,所以需要利用因子分析或聚类分析来选择代表性的自变量;另外预测结果呈现S型,两端概率变化小,中间概率变化大比较敏感,导致很多区间的变量的变化对目标概率的影响没有区分度,无法确定阈值。
故事:
1.Logistic并非逻辑的意思,其语义来自Logarithm:对数。这更体现了Logistic Regression的本质。周志华老师在其书《机器学习》中,给出了一个更恰当的中文名称:对数几率回归。我觉得这个翻译比起不搭边的“逻辑回归”,或者画蛇添足的“逻辑斯谛回归”更靠谱。
2.对数几率回归的“回归”并非针对可以应用的问题,而是来自其父级:广义线性回归模型。对数几率回归之所以用于离散的分类而不是连续的回归,是因为它将本来连续的输出,通过对数几率函数,映射到了非线性的{0,1}空间上,所以它可以有效地解决二分类问题(甚至可推广至多分类)
3.Odds(几率)和Probability(概率)之间是有区别的。Probability是指,期望的结果/所有可能出现的结果。Odds是指,期望的结果/不期望出现的结果
参考博客:
2.里面的概念介绍的很好浅析机器学习:线性回归 & 逻辑回归 - 知乎
3.推导公式很好:逻辑回归原理详细推导_碧空之戈的博客-CSDN博客_逻辑回归原理
4.适用场景:https://www.jianshu.com/p/b628c90e1c1c
5.详尽解释LR的优缺点:机器学习(四)— 逻辑回归LR - 深度机器学习 - 博客园