Logistic模型及其Scikit-learn实现

  • 概述
      Logistic回归属于概率型非线性回归,主要用于解决线性可分的分类问题。该模型利用函数Logistic function将单次实验的可能结果输出为概率。当变量之间存在多重共线性的,逻辑回归模型非常容易过拟合,此时用最小二乘估计的回归系数将会变得不准确,可采用岭回归和主成分回归来消除多重共线的参数。
      接下来讨论二分类情况下的Logistic回归的算法原理。二分类情况下,逻辑回归模型的因变量只有两个取值”是“和”否“,记为\{0,1\}。假设在自变量x_1,x_2,...x_n的作用下,因变量取“是”的概率是p,则取“否“的概率是1-p。逻辑回归研究的就是当因变量为p时,p与自变量x=[x_1,x_2,...x_p]的关系。由于P\in(0,1),而x\in R。现在想要找到一个映射将变量x映射到(0,1)之间,显然这样的映射是存在并且存在很多。
      Logistic模型采用了另一种方式,它通过构造p的对数几率\xi =ln\frac{p}{1-p}\in R,通过寻找\xix之间的关系,将问题转化为我们最为熟悉的多元线性回归模型求解问题。这也是在进行理论研究时惯用的思路:对于陌生领域的问题,将其转化为我们已知且熟悉的领域,用已建立的成熟体系去研究并解决这些问题。

几率:如果事情A发生的概率为p,则将比值\frac{p}{1-p}称之为事件A发生的几率。

言归正传,现在,只需估计多元线性回归模型\xi=ln\frac{p}{1-p}=\sum_{i=1}^{p}\omega_ix_i +b=\omega x+b的参数即可得到概率:
p=\frac{1}{1+e^{-\xi}}=\frac{1}{1+e^{-(wx+b)}}

也就是y取1的概率P(y=1|x)=\frac{1}{1+e^{-(wx+b)}},其中
\omega=[w_1,w_2,...w_p]
得到:
1-p=P(y=0|x)=1-\frac{1}{1+e^{-(wx+b)}}=\frac{1}{1+e^{(wx+b)}}
p的函数图像如下:

Logistic曲线

在此使用极大似然估计法来进行参数w,b的估计。为方便计算令P(y=1|x)=\pi(x),则P(y=0|x)=1-\pi(x),得到似然函数:
\prod_{i=1}^p P(y=y_i|x)=\prod_{i=1}^{p}\pi(x_i)^{y_i}[1-\pi(x_i)]^{1-y_i}
为方便计算,取自然对数得:
L(\omega)=ln\prod_{i=1}^p P(y=y_i|x)=ln\prod_{i=1}^{p}\pi(x_i)^{y_i}[1-\pi(x_i)]^{1-y_i}
L(\omega)=ln\prod_{i=1}^p P(y=y_i|x)=\sum_{i=1}^p[y_iln\pi(x_i)+(1-y_i)ln(1-\pi(x_i))]
整理得:
L(\omega)=\sum_{i=1}^p[y_i*(wx+b)-ln(1+e^{wx+b})]
对数似然函数取最大值的求解,一般来说将对数似然函数的相反数(NLL)作为模型的损失函数:
l(\omega,b)=-\sum_{i=1}^p[y_i*(wx+b)-ln(1+e^{wx+b})]
此时可使用梯度下降法求解NLL的最小值,得到w,b的值为了解决Logistic模型的过拟合问题可使用带正则项的损失函数。这点不再做详细讨论,可参考Logistic for sklearn

  • 实际应用
sklearn.linear_model.LogisticRegression(penalty='l2',dual=False,tol=0.0001,C=
1.0,fit_intercept=True,intercept_scaling=1,class_weight=None,random_state=N
one,solver='liblinear',max_iter=100,multi_class='ovr',verbose=0,warm_start=False,n_jobs=1)

penalty:正则化参数,可选l1或l2,分别对应l1正则化和l2正则化,默认为l2正则化。一般来说l2正则化可以处理大部分的过拟合问题,如果模型的泛化能力仍然较差或者模型的特征较多,需要过滤掉一些不重要的特征时,可考虑用l1正则化。penalty参数的选择还会影响损失函数优化算法即参数solver的选择,当使用l2正则化时,优化算法 {‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’}都可以使用。当penalty是L1正则化的话,就只能选择‘liblinear’了。这是因为L1正则化的损失函数不是连续可导的,而{‘newton-cg’, ‘lbfgs’,‘sag’}这三种优化算法时都需要损失函数的一阶或者二阶连续导数,‘liblinear’则不需要。

  监督算法在拟合过程中为了尽可能的兼顾每个数据,可能会导致模型泛化能力(模型应用到新样本的能力)较差,最直观的表现就是模型参数过于复杂,将这种情况成为模型的过拟合,一般发生在变量过多的时候。过拟合问题,一般有两种处理思路:

  • 减少变量个数
      保留更为重要的特征,舍弃一些不重要的特征,PCA是比较主流处理方式。
  • 正则化
      在模型的误差函数\xi_{(\theta_1,\theta_2...\theta_n)}=\sum_{i=0}^n \nabla f(\theta_i,x_i,y)中加上惩罚项\lambda \lVert x \rVert _p,使得新的误差函数:
    \bar\xi{_{(\theta_1,\theta_2...\theta_n)}}=\sum_{i=0}^n \nabla f(\theta_i,x_i,y)+\lambda \lVert x \rVert _p
    p=1时称之为l1正则化;p=2时称之为l2正则化,其实质就是当变量过多时,其范数会较大,此时通过调整\lambda使得惩罚项进一步变大,而为了保持误差函数\bar\xi{_{(\theta_1,\theta_2...\theta_n)}}最小,只能减小变量的参数(\theta_1,\theta_2...\theta_n)的值,也就是所谓的对参数进行‘惩罚’,当\lambda足够大时,某些变量对应的参数减小到0或者接近0可以直接舍弃,起到减少模型中的变量个数的作用。

dual:用来指明是否将原问题改成他的对偶问题,对偶问题可以理解成相反问题,比如原问题是求解最大值的线性规划,那么他的对偶问题就是转化为求解最小值的线性规划,适用于样本较小的数据集,因样本小时,计算复杂度较低。


tol:残差收敛条件,默认是0.0001,也就是只需要收敛的时候两步只差<0.0001就停止,可以设置更大或更小。(逻辑回归模型的损失函数是残差平方和)


C:正则化系数,正则化强度的导数,必须是一个正数,值越小,正则化强度越大,即防止过拟合的程度更大。


fit_intercept:是否将截距/方差加入到决策模型中,默认为True。


class_weight:class_weight是很重要的一个参数,是用来调节正负样本比例的,默认是值为None,也就是正负样本的权重是一样的,你可以以dict的形式给模型传入任意你认为合适的权重比,也可以直接指定一个值“balanced”,模型会根据正负样本的绝对数量比来设定模型最后结果的权重比。比如,有一数据集的正负样本绝对数量比为4:6,如果你给参数class_weight赋予balanced值,那么最后模型结果中,正负样本的权重比就会变成6:4。


random_state:随机种子的设置,默认是None,如果设置了随机种子,那么每次使用的训练集和测试集都是一样的,这样不管你运行多少次,最后的准确率都是一样的;如果没有设置,那么每次都是不同的训练集和测试集,最后得出的准确率也是不一样的。


solver:用来指明损失函数的优化方法,默认是‘liblinear’方法,sklearn自带了如下几种:

参数 说明
liblinear 使用了坐标轴下降法来迭代优化损失函数
lbfgs 拟牛顿法的一种,利用损失函数二阶导数矩阵(海森矩阵)来迭代优化损失函数
newton-cg 牛顿法的一种,利用损失函数二阶导数矩阵(海森矩阵)来迭代优化损失函数
sag 随机平均下降梯度,是梯度下降法的变种一种线性收敛算法,和一般的梯度下降算法的区别是每次迭代只使用部分样本计算梯度,使用于样本数据较多的时候

max_iter:算法收敛的最大迭代次数,即求取损失函数最小值的迭代次数,默认是100,


multi_class:分类方法参数选择,‘ovr’和‘multinomial’两个值可以选择,默认值为‘ovr’,如果分类问题是二分类问题,那么这两个参数的效果是一样的,主要体现在多分类问题上。对于多分类问题,"ovr"分类方法是:针对每一类别进行判断时,都会把这个分类问题简化为是/非两类问题;而‘multinomial’是从众多类别中选出两个类别,对这两个类别进行判断,待判断完成后,再从剩下的类别中再选出两类进行判断,直至最后判断完成。


verbose:英文意思是”冗余“,就是会输出一些模型运算过程中的东西(任务进程),默认是False,也就是不需要输出一些不重要的计算过程。


warm_start:是否使用上次的模型结果作为初始化,默认是False,表示不使用。


n_jobs:并行运算数量(核的数量),默认为1,如果设置为-1,则表示将电脑的cpu全部用上。


模型对象

coef_:返回各特征的系数,绝对值大小可以理解成特征重要性
intercept_:返回模型的截距
n_iter_:模型迭代次数


模型方法

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

  • 实例
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

path = '/Users/wcjb/Downloads/chapter5/demo/data/bankloan.xls'
bank = pd.read_excel(path)
  • 数据预处理

统计数据包含无效值(Nan,空值等)的个数

bank[bank.isnull().any(axis=1)].count()
年龄       0
教育       0
工龄       0
地址       0
收入       0
负债率      0
信用卡负债    0
其他负债     0
违约       0
dtype: int64

说明数据都是有效的

bank.describe()
sns.boxplot(bank['收入'])
bank[bank['收入']>100].count()
年龄       43
教育       43
工龄       43
地址       43
收入       43
负债率      43
信用卡负债    43
其他负债     43
违约       43
dtype: int64
sns.distplot(bank['收入'],bins=100)
bank['教育'].value_counts()
1    372
2    198
3     87
4     38
5      5
Name: 教育, dtype: int64
from sklearn.linear_model import LogisticRegression as LR
from sklearn.linear_model import RandomizedLogisticRegression as RLR
from sklearn.model_selection import train_test_split

x = bank.iloc[:,:8].values
y = bank.iloc[:,8].values
# 对原始数据集进行划分,0.7的训练集和0.3的测试集
xTrain,xTest,yTrain,yTest = train_test_split(x,y,test_size=0.3)
# 建立随机逻辑模型进行特征筛选
rlr = RLR()
rlr.fit(xTrain,yTrain)
RandomizedLogisticRegression(C=1, fit_intercept=True, memory=None,
               n_jobs=None, n_resampling=200, normalize=True,
               pre_dispatch='3*n_jobs', random_state=None,
               sample_fraction=0.75, scaling=0.5, selection_threshold=0.25,
               tol=0.001, verbose=False)
# 获取各个特征的分数
rlr.all_scores_
array([[0.035],
       [0.015],
       [0.6  ],
       [0.27 ],
       [0.   ],
       [0.945],
       [0.545],
       [0.065]])
# 获得特征筛选结果
rlr.get_support()
array([False, False,  True,  True, False,  True,  True, False])
print('有效特征为:%s'%','.join(bank.iloc[:,:8].columns[rlr.get_support()]))
有效特征为:工龄,地址,负债率,信用卡负债
  • 使用筛选出来的特征建立模型
x = bank[bank.columns[rir.get_support()]].value
model = LR()
model.fit(x,y)
LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
          intercept_scaling=1, max_iter=100, multi_class='warn',
          n_jobs=None, penalty='l2', random_state=None, solver='warn',
          tol=0.0001, verbose=0, warm_start=False)
# 模型的拟合优度
model.score(x,y)
0.8057142857142857
# 模型参数
model.coef_
array([[ 0.02554555,  0.05665878, -0.25871395, -0.10043876, -0.00983243,
         0.05724028,  0.64150199,  0.08319484]])
# 模型的常量(截距)
model.intercept_
array([-1.13355153])
# 模型在测试集预测的正确率
count = 0
for i in (model.predict(xTest)-yTest):
    if i==0:
        count+=1
count/len(yTest)
0.8285714285714286
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容