探究算法细节,深入了解算法原理


逻辑回归LR

  • 1. 二分类
  • 1.1二元逻辑回归的模型
  • 1.2 二元逻辑回归的损失函数(目标函数)
  • 1.3 二元逻辑回归的损失函数的优化方法
  • 1.4 二元逻辑回归的正则化
  • 2. 多分类
  • 2.1 多元逻辑回归的概率分布
  • 3. sklearn.linear_model.LogisticRegression
  • 3.1 sklearn LR模型参数详解
  • 3.2 sklearn LR模型的对象和方法
  • 3.3 sklearn LR模型使用例子
  • 4. 样本不均衡时的LR模型的损失函数


1. 二分类

1.1二元逻辑回归的模型

  • 逻辑回归(Logistics Regression),是分类模型,不是回归模型,主要用于二分类,也可以完成多分类。
  • LR模型,训练速度快,足够解决普通的分类问题。
  • 逻辑函数又称为sigmoid函数

二元LR模型一般形式为:
二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二分类
其中 二元逻辑回归 输入 向前 向后 二元逻辑回归模型_似然函数_02二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二元逻辑回归 输入 向前 向后_03二元逻辑回归 输入 向前 向后 二元逻辑回归模型_似然函数_04

二元逻辑回归 输入 向前 向后 二元逻辑回归模型_损失函数_05 ,当二元逻辑回归 输入 向前 向后 二元逻辑回归模型_损失函数_06

1.2 二元逻辑回归的损失函数(目标函数)

直接使用平方损失函数,会导致损失函数非凸,优化过程容易陷入局部最优点。
似然函数推导损失函数。

二分类,样本输出只有0或1,则有
二元逻辑回归 输入 向前 向后 二元逻辑回归模型_损失函数_07

二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二元逻辑回归 输入 向前 向后_08

合并成一个式子,得到y的概率分布表达式为:
二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二分类_09

似然函数的表达式为(m个样本):
二元逻辑回归 输入 向前 向后 二元逻辑回归模型_似然函数_10

对数似然函数取反,即为损失函数
最大化似然函数,最小化损失函数

二元逻辑回归 输入 向前 向后 二元逻辑回归模型_损失函数_11

称为交叉熵损失函数

  • 当y=0时,二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二元逻辑回归 输入 向前 向后_12二元逻辑回归 输入 向前 向后 二元逻辑回归模型_似然函数_13趋近于0,则损失很小,趋近于1,则损失很大,即惩罚很大
  • 当y=1时,二元逻辑回归 输入 向前 向后 二元逻辑回归模型_损失函数_14二元逻辑回归 输入 向前 向后 二元逻辑回归模型_似然函数_13趋近于1,则损失很小,趋近于0,则损失很大,即惩罚很大

m个样本的损失函数:
二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二元逻辑回归 输入 向前 向后_16

1.3 二元逻辑回归的损失函数的优化方法

最小化损失函数,常用梯度下降法

二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二元逻辑回归 输入 向前 向后_17向量进行链式法则求导

二元逻辑回归 输入 向前 向后 二元逻辑回归模型_似然函数_18

二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二分类_19

参数更新:
二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二分类_20

假设样本数为m,特征维度为n,则 二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二分类_21二元逻辑回归 输入 向前 向后 二元逻辑回归模型_损失函数_22矩阵,每个列向量是一个样本,二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二元逻辑回归 输入 向前 向后_17二元逻辑回归 输入 向前 向后 二元逻辑回归模型_似然函数_24的列向量,y和二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二元逻辑回归 输入 向前 向后_25二元逻辑回归 输入 向前 向后 二元逻辑回归模型_损失函数_26的向量

1.4 二元逻辑回归的正则化

常见的有L1正则化、L2正则化

二元逻辑回归 输入 向前 向后 二元逻辑回归模型_似然函数_27

二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二元逻辑回归 输入 向前 向后_28

L1正则化,损失函数的优化方法常用的有:坐标轴下降法、最小角回归法
L2正则化,损失函数的优化方法:梯度下降法

2. 多分类

2.1 多元逻辑回归的概率分布

对于多元逻辑回归的处理方法

  • 认为某类为1,其余类为0,称为 one-vs-rest
  • 每次选择两类样本做二分类,称为one-vs-one

对于二分类的推导,y的输出只有0或1
二元逻辑回归 输入 向前 向后 二元逻辑回归模型_损失函数_29

二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二分类_30

二元逻辑回归 输入 向前 向后 二元逻辑回归模型_损失函数_31

对于多分类,样本输出y的取值假设为 1,2,…,K

看作多个二分类,以第 K 类为基准,则有

二元逻辑回归 输入 向前 向后 二元逻辑回归模型_损失函数_32

二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二元逻辑回归 输入 向前 向后_33

二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二元逻辑回归 输入 向前 向后_34

二元逻辑回归 输入 向前 向后 二元逻辑回归模型_似然函数_35

二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二元逻辑回归 输入 向前 向后_36

得到多元逻辑回归的概率分布为:
二元逻辑回归 输入 向前 向后 二元逻辑回归模型_损失函数_37

二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二分类_38

3. sklearn.linear_model.LogisticRegression

3.1 sklearn LR模型参数详解

class LogisticRegression(penalty=’l2’, dual=False, tol=0.0001, C=1.0, 
fit_intercept=True, intercept_scaling=1, class_weight=None,
random_state=None, solver=’warn’, max_iter=100, multi_class=’warn’,
verbose=0, warm_start=False, n_jobs=None)

参数说明:
1、penalty

  • 正则项,可选L1或L2。
  • 如果使用L2正则化依然过拟合,或者特征非常多,希望做特征选择,可以考虑L1正则化。
  • 正则化的选择会影响损失函数优化算法的选择,L2正则化,{newton-cg,lbfgs,liblinear,sag}都可以选择,L1正则化只能选择 liblinear优化算法。因为L1正则化的损失函数不是连续可导的,而{newton-cg,lbfgs,sag}都需要损失函数一阶或二阶连续导数

2、dual

  • 用来指明是否将原问题转换成对偶问题
  • 对偶问题类似于相反问题,比如求解最大值的线性规划,转换成求解最小值的线性规划
  • 当样本数大于特征数,选择False,并且只能在liblinear+l2 penalty情况下使用

3、tol

  • 残差收敛条件,收敛的时候两步之差<tol就停止。

4、C

  • 正则化系数,必须是正数,值越小,正则化强度越大,防止过拟合的程度越大,二元逻辑回归 输入 向前 向后 二元逻辑回归模型_二元逻辑回归 输入 向前 向后_39

5、fit_intercept

  • 指定是否将常量(bias or intercept)加入到 decision function

6、intercept_scaling

  • 仅在优化算法 liblinear 情况下使用
  • x变成[x, self.intercept_scaling],就是w0或者b

7、class_weight

  • 调节正负样本比例,默认为None,可以选择 “balanced”,可以传入字典 {class_label:weight}
  • balanced,自动调整与输入数据中的类频率成反比的权重
  • 如果制定了sample_weight,class_weight将与sample_weight相乘

8、random_state

  • 随机种子的设置,使用相同的训练集和测试集,运行多少次,结果都一样

9、solver

  • 损失函数的优化算法,{liblinear,lbfgs,newton-cg,sag,saga}
  • newton-cg, lbfgs和sag 只能用于L2正则化。
  • liblinear对L1正则化和L2正则化都适用。
  • sag,数据量较少时不宜选用,数据量很大时,为了速度,sag是第一选择。

10、max_iter

  • 优化算法收敛的最大迭代次数,适用于{newton-cg,lbfgs,sag}

11、multi_class

  • 可选 ovr、auto和multinomial,二分类问题效果一样,主要用于多分类问题
  • 如果二分类,或者liblinear优化算法,自动选择ovr,其他选择 multinational
  • ovr:把分类问题简化成是/非两类问题 one-vs-rest
  • multinomial:每次选出两个类别进行判断,再从剩下的类别中选出两个进行判断 one-vs-one

12、verbose

  • “冗余的”,会输出一些模型运算过程,默认0,不输出
  • 对于liblinear,lbfgs,设置任意正数,输出详细过程

13、warm_start

  • 是否使用上次的模型结果作为初始化

14、n_jobs

  • 并行化时使用的CPU核的数量,-1表示使用所有的CPU核

3.2 sklearn LR模型的对象和方法

模型对象

  • coef_:返回各特征的系数,绝对值大小可以理解成特征重要性
  • intercept_:返回模型的截距,即偏置

模型方法

  • decision_function(X):返回决策函数值(比如svm中的决策距离)
  • predict_proba(X):返回每个类别的概率值(有几类就返回几列值)
  • predict_log_proba(X):返回概率值的log值(即将概率取对数)
  • predict(X):返回预测结果值(0/1)
  • score(X, y=None):返回正确率
  • get_params(deep=True):返回估计器的参数

3.3 sklearn LR模型使用例子

from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
X, y = load_iris(return_X_y=True)
print("data and label size: ",X.shape,y.shape)  # 3类,4个特征

clf = LogisticRegression(penalty='l2',C=0.8,class_weight='balanced',
	                     random_state=1, solver='lbfgs', max_iter=500, 
	                     multi_class='multinomial', n_jobs=1)

clf.fit(X, y)
#print(clf.decision_function(X))
print(clf.score(X,y))
print(clf.predict(X[0:5, :]))       # 每个样本的预测类别
print(clf.predict_proba(X[0:5, :])) # 每个样本每一类的预测概率
print(clf.get_params(deep=True))    # 超参数
print(clf.coef_)       # 参数,shape=(4,3)
print(clf.intercept_)  # 偏置,shape=(3,)

输出结果为:

data and label size:  (150, 4) (150,)                                                                                                                                   
0.9733333333333334                                                                                                                                                      
[0 0 0 0 0]                                                                                                                                                             
[[9.78571369e-01 2.14285809e-02 4.97036800e-08]                                                                                                                         
 [9.67528768e-01 3.24711382e-02 9.34656464e-08]                                                                                                                         
 [9.82653272e-01 1.73466871e-02 4.06294555e-08]                                                                                                                         
 [9.72519756e-01 2.74801246e-02 1.19497174e-07]                                                                                                                         
 [9.82584586e-01 1.74153725e-02 4.17372134e-08]]                                                                                                                        
{'C': 0.8, 'class_weight': 'balanced', 'dual': False, 'fit_intercept': True, 'intercept_scaling': 1, 
'max_iter': 500, 'multi_class': 'multinomial', 'n_jobs': 1, 'penalt
y': 'l2', 'random_state': 1, 'solver': 'lbfgs', 'tol': 0.0001, 'verbose': 0, 'warm_start': False}                                                                       
[[-0.41970458  0.88110727 -2.36861993 -1.01249304]                                                                                                                      
 [ 0.48079601 -0.3330422  -0.17330735 -0.84848953]                                                                                                                      
 [-0.06109144 -0.54806507  2.54192728  1.86098257]]                                                                                                                     
[  9.44748223   2.1768459  -11.62432814]

4. 样本不均衡时的LR模型的损失函数

LR源码:第119行
https://github.com/scikit-learn/scikit-learn/blob/7b136e9/sklearn/linear_model/logistic.py">https:///scikit-learn/scikit-learn/blob/7b136e9/sklearn/linear_model/logistic.py

# Logistic loss is the negative of the log of the logistic function.
out = -np.sum(sample_weight * log_logistic(yz)) + .5 * alpha * np.dot(w, w)
# sample_weight, shape(n_samples,)每个样本分配一个权重

(1)样本不平衡的问题
样本不均衡时,训练时损失函数会偏向样本多的一方,造成训练时的损失函数很小,但是对样本较少的类别识别率不高。

(2)解决办法

  • 对样本多的类别降采样(随机抽样)
  • 对样本少的类别过采样
  • 修改损失函数

(3)修改损失函数—加权交叉熵

  • 正负样本的权重与样本数成反比,比如正样本30,负样本70,则正样本权重是0.7,负样本权重是0.3
  • 权重是类别样本数的反比例,正样本权重 (70+30)/30=3.33,负样本权重 (70+30)/70=1.42

二元逻辑回归 输入 向前 向后 二元逻辑回归模型_损失函数_40