zoukankan      html  css  js  c++  java
  • python机器学习(六)回归算法-逻辑回归

     

    一、概述

    1.1、概念

    是一种名为“回归”的线性分类器,是由线性回归变化而来的,一种广泛使用于分类问题中的广义回归算法。

    1.2、按预测标签的数据类型分

    连续型变量:通过线性回归方程z,线性回归使用输入的特征矩阵X来输出一组连续型的标签值y_pred,以完成各种预测连续型变量的任务(比如预测产品销量,预测股价等等)
    离散型变量:通过Sigmoid函数变换,线性回归方程z变换为g(z),使得模型的值分布在(0,1)之间,且当g(z)接近0时样本的标签为类别0,当g(z)接近1时样本的标签为类别1,这样就得到了一个分类模型。

     
    线性回归方程式

    1.3、公式

     
    公式

    其中,y(x)就是我们逻辑回归返回的标签值。

    1.4、本质

    y(x)的形似几率取对数就是线性回归,对数几率回归,就是逻辑回归。

    二、重要概念

    Sigmoid函数:Sigmoid函数是一个S型的函数,当自变量z趋近正无穷时,因变量g(z)趋近于1,而当z趋近负无穷时,g(z)趋近于0,它能够将任何实数映射到(0,1)区间,使其可用于将任意值函数转换为更适合二分类的函数。

     
    Sigmoid函数
     
    Sigmoid函数公式

    因为这个性质,Sigmoid函数也被当作是归一化的一种方法,与我们之前学过的MinMaxSclaer同理,是属于数据预处理中的“缩放”功能,可以将数据压缩到[0,1]之内。区别在于,MinMaxScaler归一化之后,是可以取到0和1的(最大值归一化后就是1,最小值归一化后就是0),但Sigmoid函数只是无限趋近于0和1。

    损失函数:是一个评估指标,来衡量参数为 的模型拟合训练集时产生的信息损失的大小,并以此衡量参数的优劣。
    损失函数小,模型在训练集上表现优异,拟合充分,参数优秀。
    损失函数大,模型在训练集上表现差劲,拟合不足,参数糟糕。
    我们追求,能够让损失函数最小化的参数组合。
    注意:没有”求解参数“需求的模型没有损失函数,比如KNN,决策树。

     
    损失函数公式


    θ表示求解出来的一组参数,m是样本的个数, yi 是样本 i 上真实的标签, yθ(xi)是样本 i 上,基于参数θ计算出来的逻辑回归返回值,xi 是样本 i 各个特征的取值。我们的目标,就是求解出使 J(θ)最小的 θ 取值。注意,在逻辑回归的本质函数y(x)里,特征矩阵x是自变量,参数是 θ。但在损失函数中,参数θ是损失函数的自变量,x和y都是已知的特征矩阵和标签,相当于是损失函数的参数。不同的函数中,自变量和参数各有不同,因此大家需要在数学计算中,尤其是求导的时候避免混淆。

    三、sklearn中的逻辑回归

    linear_model.LogisticRegression 逻辑回归分类器(又叫logit回归,最大熵分类器
    linear_model.SGDClassifier 利用梯度下降求解的线性分类器(SVM,逻辑回归等等)
    linear_model.SGDRegressor 利用梯度下降最小化正则化后的损失函数的线性回归模型
    
    metrics.log_loss 对数损失,又称逻辑损失或交叉熵损失
    metrics.confusion_matrix 混淆矩阵,模型评估指标之一
    metrics.roc_auc_score ROC曲线,模型评估指标之一
    metrics.accuracy_score 精确性,模型评估指标之一
    
    
    sklearn.linear_model.LogisticRegression(penalty='l2', C = 1.0)
    Logistic: 回归分类器
    coef_:回归系数
    

    四、重要参数

    正则化参数, penalty&C:

    正则化: 是用来防止模型过拟合的过程,常用的有L1正则化和L2正则化两种选项,分别通过在损失函数后加上参数向量 的L1范式和L2范式的倍数来实现。这个增加的范式,被称为“正则项”,也被称为"惩罚项"。

    penalty: 可以输入"l1"或"l2"来指定使用哪一种正则化方式,不填写默认"l2"。
    注意,若选择"l1"正则化,参数solver仅能够使用求解方式”liblinear"和"saga“,若使用“l2”正则化,参数solver中所有的求解方式都可以使用。

    C:C正则化强度的倒数,必须是一个大于0的浮点数,不填写默认1.0,即默认正则项与损失函数的比值是1:1。C越小,损失函数会越小,模型对损失函数的惩罚越重,正则化的效力越强,参数会逐渐被压缩得越来越小。

    # L1正则化和L2正则化的比较
    from sklearn.linear_model import LogisticRegression as LR
    from sklearn.datasets import load_breast_cancer
    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn.model_selection import train_test_split
    from sklearn.metrics import accuracy_score
    data = load_breast_cancer()
    X = data.data
    y = data.target
    data.data.shape
    lrl1 = LR(penalty="l1",solver="liblinear",C=0.5,max_iter=1000)
    lrl2 = LR(penalty="l2",solver="liblinear",C=0.5,max_iter=1000)
    #逻辑回归的重要属性coef_,查看每个特征所对应的参数
    lrl1 = lrl1.fit(X,y)
    lrl1.coef_
    
     
    lrl1.coef_输出结果
    (lrl1.coef_ != 0).sum(axis=1)
    lrl2 = lrl2.fit(X,y)
    lrl2.coef_
    
     
    lrl2.coef_输出结果


    结论:L1正则化会将参数压缩为0,L2正则化只会让参数尽量小,不会取到0。

    max_iter:
    逻辑回归的数学目的是求解能够让模型最优化,拟合程度最好的参数的值,即求解能够让损失函数 最小化的值。对于二元逻辑回归来说,有多种方法可以用来求解参数 ,最著名的是梯度下降法(Gradient Descent)。

     
    梯度下降法

    在这个图像上随机放一个小球,当我松手,这个小球就会顺着这个华丽的平面滚落,直到滚到深蓝色的区域——损失函数的最低点。为了严格监控这个小球的行为,我让小球每次滚动的距离有限,不让他一次性滚到最低点,并且最多只允许它滚动100步,还要记下它每次滚动的方向,直到它滚到图像上的最低点。

    可以看见,小球从高处滑落,在深蓝色的区域中来回震荡,最终停留在了图像凹陷处的某个点上。非常明显,我们可以观察到几个现象:

    首先,小球并不是一开始就直向着最低点去的,它先一口气冲到了蓝色区域边缘,后来又折回来,我们已经规定了小球是多次滚动,所以可见,小球每次滚动的方向都是不同的。

    另外,小球在进入深蓝色区域后,并没有直接找到某个点,而是在深蓝色区域中来回震荡了数次才停下。这有两种可能:1) 小球已经滚到了图像的最低点,所以停下了,2) 由于我设定的步数限制,小球还没有找到最低点,但也只好在100步的时候停下了。也就是说,小球不一定滚到了图像的最低处。

    小球其实就是一组组的坐标点(θ1,θ2,J) ;小球每次滚动的方向就是那一个坐标点的梯度向量的方向,因为每滚动一步,小球所在的位置都发生变化,坐标点和坐标点对应的梯度向量都发生了变化,所以每次滚动的方向也都不一样;人为设置的100次滚动限制,就是sklearn中逻辑回归的参数max_iter,代表着能走的最大步数,即最大迭代次数。

    solver:
    sklearn为我们提供了多种求解逻辑回归参数θ 的方法(梯度下降法是其中著名的一种),让我们可以使用不同的求解器来计算逻辑回归。求解器的选择,由参数"solver"控制,共有五种选择。其中“liblinear”是二分类专用,也是现在的默认求解器。

    • liblinear : 坐标下降法
    • lbfgs:拟牛顿法的一种,利用损失函数二阶导数矩阵(海森矩阵)来迭代优化损失函数。
    • newton-cg : 牛顿法的一种,利用损失函数二阶导数矩阵(海森矩阵)来迭代优化损失函数。
    • sag :随机平均梯度下降,与普通梯度下降法的区别是每次迭代仅仅用一部分的样本来计算梯度。
    • saga:随机平均梯度下降的进化,稀疏多项逻辑回归的首选。

    multi_class:
    输入"ovr", "multinomial", "auto"来告知模型,我们要处理的分类问题的类型。默认是"ovr"。

    • 'ovr':表示分类问题是二分类,或让模型使用"一对多"的形式来处理多分类问题。
    • 'multinomial':表示处理多分类问题,这种输入在参数solver是'liblinear'时不可用。
    • "auto":表示会根据数据的分类情况和其他参数来确定模型要处理的分类问题的类型。比如说,如果数据是二分
      类,或者solver的取值为"liblinear","auto"会默认选择"ovr"。反之,则会选择"nultinomial"。

    样本不平衡参数class_weight:
    样本不平衡是指在一组数据集中,标签的一类天生占有很大的比例,或误分类的代价很高,即我们想要捕捉出某种特定的分类的时候的状况。

    例如:银行要判断“一个新客户是否会违约”,通常不违约的人vs违约的人会是99:1的比例,真正违约的人其实是非常少的。这种分类状况下,即便模型什么也不做,全把所有人都当成不会违约的人,正确率也能有99%,这使得模型评估指标变得毫无意义,根本无法达到我们的“要识别出会违约的人”的建模目的。

    因此我们要使用参数class_weight对样本标签进行一定的均衡,给少量的标签更多的权重,让模型更偏向少数类,向捕获少数类的方向建模。该参数默认None,此模式表示自动给与数据集中的所有标签相同的权重,即自动1:1。当误分类的代价很高的时候,我们使用”balanced“模式,我们只是希望对标签进行均衡的时候,什么都不填就可以解决样本不均衡问题。

    五、案例介绍

    5.1、数据描述
    (1)699条样本,共11列数据,第一列用语检索的id,后9列分别是与肿瘤相关的医学特征,最后一列表示肿瘤类型的数值。
    (2)包含16个缺失值,用”?”标出。

    原始数据的下载地址:
    https://archive.ics.uci.edu/ml/machine-learning-databases/

    5.2、特征选择:
    PCA和SVD一般不用,大多数时候不适用于逻辑回归。逻辑回归是由线性回归演变而来,线性回归的一个核心目的是通过求解参数来探究特征X与标签y之间的关系,而逻辑回归也传承了这个性质,我们常常希望通过逻辑回归的结果,来判断什么样的特征与分类结果相关,因此我们希望保留特征的原貌。PCA和SVD的降维结果是不可解释的,因此一旦降维后,我们就无法解释特征和标签之间的关系了。

    import pandas as pd
    import numpy as np
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    from sklearn.linear_model import LogisticRegression
    from sklearn.metrics import classification_report
    # 构造列标签名字
    column = ['Sample code number','Clump Thickness', 'Uniformity of Cell Size','Uniformity of Cell Shape','Marginal Adhesion', 'Single Epithelial Cell Size','Bare Nuclei','Bland Chromatin','Normal Nucleoli','Mitoses','Class']
    # 读取数据
    data = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data", names=column)
    # print(data.head())

    5.3、数据缺失处理,标准化

    # 缺失值进行处理
    data = data.replace(to_replace='?', value=np.nan)
    data = data.dropna()
    # 进行数据的分割
    x_train, x_test, y_train, y_test = train_test_split(data[column[1:10]], data[column[10]], test_size=0.25)
    # 进行标准化处理
    std = StandardScaler()
    x_train = std.fit_transform(x_train)
    x_test = std.transform(x_test)

    5.4、估计器流程

    # 逻辑回归预测
    lg = LogisticRegression(C=1.0)
    lg.fit(x_train, y_train)
    print(lg.coef_)
    y_predict = lg.predict(x_test)
    print("准确率:", lg.score(x_test, y_test))
    print("召回率:", classification_report(y_test, y_predict, labels=[2, 4], target_names=["良性", "恶性"]))
    完整代码:
    import pandas as pd
    import numpy as np
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    from sklearn.linear_model import LogisticRegression
    from sklearn.metrics import classification_report
    # 构造列标签名字
    column = ['Sample code number','Clump Thickness', 'Uniformity of Cell Size','Uniformity of Cell Shape','Marginal Adhesion', 'Single Epithelial Cell Size','Bare Nuclei','Bland Chromatin','Normal Nucleoli','Mitoses','Class']
    # 读取数据
    data = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data", names=column)
    # print(data.head())
    # 缺失值进行处理
    data = data.replace(to_replace='?', value=np.nan)
    data = data.dropna()
    # 进行数据的分割
    x_train, x_test, y_train, y_test = train_test_split(data[column[1:10]], data[column[10]], test_size=0.25)
    # 进行标准化处理
    std = StandardScaler()
    x_train = std.fit_transform(x_train)
    x_test = std.transform(x_test)
    # 逻辑回归预测
    lg = LogisticRegression(C=1.0)
    lg.fit(x_train, y_train)
    print(lg.coef_)
    y_predict = lg.predict(x_test)
    print("准确率:", lg.score(x_test, y_test))
    print("召回率:", classification_report(y_test, y_predict, labels=[2, 4], target_names=["良性", "恶性"]))
     
     
    输出结果
    C:Anaconda3python.exe "C:Program FilesJetBrainsPyCharm 2019.1.1helperspydevpydevconsole.py" --mode=client --port=53808
    import sys; print('Python %s on %s' % (sys.version, sys.platform))
    sys.path.extend(['C:\app\PycharmProjects', 'C:/app/PycharmProjects'])
    Python 3.7.6 (default, Jan  8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)]
    Type 'copyright', 'credits' or 'license' for more information
    IPython 7.12.0 -- An enhanced Interactive Python. Type '?' for help.
    PyDev console: using IPython 7.12.0
    Python 3.7.6 (default, Jan  8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] on win32
    runfile('C:/app/PycharmProjects/ArtificialIntelligence/test.py', wdir='C:/app/PycharmProjects/ArtificialIntelligence')
    [[1.29014513 0.02841081 0.63541132 0.51761702 0.40995793 1.36777915
      1.06877681 0.55433123 0.98039778]]
    准确率: 0.9707602339181286
    召回率:               precision    recall  f1-score   support
              良性       0.97      0.98      0.98       111
              恶性       0.97      0.95      0.96        60
        accuracy                           0.97       171
       macro avg       0.97      0.97      0.97       171
    weighted avg       0.97      0.97      0.97       171

    六、总结

    应用:
    广告点击率预测、电商购物搭配推荐、股价预测、产品销量预测

    优点:

    • 线性回归的数据要求:正态分布,消除多重共线性,现实数据无法满足;逻辑回归不需要对数据进行处理
    • 对线性关系的拟合效果好
    • 逻辑回归计算速度快
    • 返回的分类结果不是固定的0和1,而是以小数形式呈现的类概率数字
    • 抗噪音能力强

    缺点:当特征空间很大时,逻辑回归的性能不是很好
    (看硬件能力)

  • 相关阅读:
    Hadoop2.0 HA集群搭建步骤
    了解何为DML、DDL、DCL
    搭建Hadoop平台(新手入门)
    周记1
    IT小小鸟
    Python中的函数修饰符
    python_类方法和静态方法
    Python的log模块日志写两遍的问题
    python——装饰器例子一个
    初识HIVE
  • 原文地址:https://www.cnblogs.com/huanghanyu/p/13057809.html
Copyright © 2011-2022 走看看