逻辑回归
逻辑回归的应用场景
- 广告点击率 是否会被点击
- 是否为垃圾邮件
- 是否患病
- 金融诈骗
- 虚假账号
解决二分类问题,经过线性回归之后再经过sigmoid激活函数得出结果
逻辑回归的原理
输入
h(w) = w_1x_1 + w_2x_2 + w_3x_3... + b 
逻辑回归的输入就是一个线性回归的结果。
激活函数 sigmoid函数
g(\theta ^T x) = \frac {1}{1+e^{\theta ^T x}}
- 分析- 回归的结果输入到sigmoid函数当中
 - 输出结果:[0, 1]区间中的一个概率值,默认为0.5为阈值逻辑回归最终的分类是通过属于某个类别的概率值来判断是否属于某个类别,并且这个类别默认标记为1(正例),另外的一个类别会标记为0(反例)。(方便损失计算) 
输出结果解释(重要):假设有两个类别A,B,并且假设我们的概率值为属于A(1)这个类别的概率值。现在有一个样本的输入到逻辑回归输出结果0.6,那么这个概率值超过0.5,意味着我们训练或者预测的结果就是A(1)类别。那么反之,如果得出结果为0.3那么,训练或者预测结果就为B(0)类别
损失以及优化
损失
逻辑回归的损失,称之为对数似然损失,公式如下:
cost(h_\theta(x),y) = \left\{
  \begin{array}{lr}
    -log(\theta(x)) &   if  y=1 \\
    -log(1-h_\theta(x)) &   if  y=0
  \end{array}
\right.
综合完整损失函数
cost(h_\theta(x),y) = \sum_{i=1} {^m} - y_ilog(h_\theta(x)) -(1-y_i)log(1-h_\theta(x))
看到这个式子,其实跟我们讲的信息熵类似。
优化
同样使用梯度下降优化算法,去减少损失函数的值。这样去更新逻辑回归前面对应算法的权重参数,提升原本属于1类别的概率,降低原本是0类别的概率。
逻辑回归API
- sklearn.linear_model.LogisticRegression(solver='liblinear', penalty='l2', C = 1.0)- solver:优化求解方式(默认开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数)
 - sag:根据数据集自动选择,随机平均梯度下降
 - penalty:正则化的种类
 - C:正则化力度默认将类别数量少的当做正例 
LogisticRegression方法相当于 SGDClassifier(loss="log", penalty=" "),SGDClassifier实现了一个普通的随机梯度下降学习,也支持平均随机梯度下降法(ASGD),可以通过设置average=True。而使用LogisticRegression(实现了SAG)
- 准确率 :所有的预测正确(正类负类)的占总的比重。 
- 精确率 : 也叫查准率,即正确预测为正的占全部预测为正的比例(不准错,宁愿漏检,也不能让现有的预测有错)。 
- 召回率 : 即正确预测为正的占全部实际为正的比例(不准漏,宁可错杀一千,也不放过一个)。 
- F-Score:权衡精确率(Precision)和召回率(Recall),一般来说准确率和召回率呈负相关,一个高,一个就低,如果两个都低,一定是有问题的。 一般来说,精确度和召回率之间是矛盾的,这里引入F1-Score作为综合指标,就是为了平衡准确率和召回率的影响,较为全面地评价一个分类器。F1是精确率和召回率的调和平均。F1-score越大说明模型质量更高。 
F1 = \frac { 2 * 精确率 * 召回率}{精确率+召回率}
ROC曲线与AUC指标
衡量样本不均衡下的评估
TPR 与 FPR
- TPR = TP / ( TP + FN )- 所有真实类别为1的样本中,预测类别为1的比例
 
- FPR = FP / ( FP + TN )- 所有真实类别为0的样本中,预测类别为1的比例
 
ROC曲线
- ROC曲线的横轴就是FPRate,纵轴就是TPRate,二者相等时表示的意义则是:对于不论真实类别是1还是0的样本,分类器预测为1的概率是相等的,此时AUC为0.5
图中蓝色的线则是ROC曲线,ROC曲线和横轴、纵轴围成的面积就是AUC指标。

AUC指标
- AUC的概率意义是随机取一对正负样本,正样本得分大于负样本得分的概率
- AUC的最小值为0.5,最大值为1,取值越高越好
- AUC = 1,完美分类器,采用这个模型预测时,不管设定什么阈值都能得出完美预测。绝大多数预测的场合,不存在完美分类器。
- 0.5 < AUC < 1 ,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。
- 如果AUC小于0.5的话,就用1-AUC,此时就叫做反向预测。- AUC 只能用来评价二分类
- AUC 非常适合评价样本不均衡中的分类器性能
 
AUC计算API
from sklearn.metrics import roc_auc_score
    sklearn.metrics.roc_auc_score(y_true,y_score)
        计算ROC曲线的面积,即AUC的值
        y_true:每个样本的真实类别,必须为0(反例),1(正例)标记
        y_score:预测得分,可以是正常的估计概率、置信值或者分类器方法的返回值
预测癌症 代码
# 逻辑回归一般是二分类问题
"""
这一部分用逻辑回归来分类breast是否良性
这里需要注意的有一下:
    LogisticRegression方法相当于SGDClassifier(loss="log",penalty=" ")
    SGDClassifier实现了一个普通的随机梯度下降学习,
    也支持平均梯度下降ASGD, 可以设置average=True来开启
"""
from sklearn.linear_model import LogisticRegression, SGDClassifier
from sklearn.model_selection import train_test_split
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import classification_report, roc_auc_score, roc_curve
import matplotlib.pyplot as plt
def load_data():
    """
    先获取数据
    处理数据
        有缺失值
    数据集划分 测试 训练
    特征工程
        无量纲化-标准化(不要用归一化 之前有笔记)
    逻辑回归预估器
    模型评估
    :return x_train, x_test, y_train, y_test:
    """
    column_name = ['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']
    # # 网上直接下载
    # path = "http://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data"
    # original_data = pd.read_csv(path, names=column_name)
    # 文件读取
    original_data = pd.read_csv("breast-cancer-wisconsin.data", names=column_name)
    # 缺失值处理
    # 第一步先替换 ? 为 nan
    data = original_data.replace(to_replace="?", value=np.nan)
    # 第二步可以选择前面笔记里面自己写的的过滤nan也可以用简单的方法如下:
    data.dropna(inplace=True)
    print("检测是否还有缺失值(全为false表示没有缺失值)\n", data.isnull().any())  # 检测是否还有缺失值
    # 第三步 筛选特征值和目标值
    x = data.iloc[:, 1:-1]  # 表示每一行数据都要, 从第一列到倒数第二列的column字段也要
    y = data["Class"]
    x_train, x_test, y_train, y_test = train_test_split(x, y)
    return x_train, x_test, y_train, y_test
def logic_Regression():
    """
    逻辑回归的真实值是分类, 也就是是否属于某一个类别,和线性回归不一样
    线性回归损失函数: (y_predict-y_true)平方和/总数
    逻辑回归损失函数: 对数似然损失(https://blog.csdn.net/u014182497/article/details/82252456)
    逻辑回归用sigmoid函数为例子: 需要把结果映射到sigmoid函数上
    分两种情况:(见截图) y轴表示损失值, 横轴x表示映射结果.(分段函数)
    当真实值为1 见 对数似然损失-1.png
    当真实值为0 见 对数似然损失-2.png
    不难理解,需要对着图看
    逻辑回归损失值得到后需要用梯度下降来优化
    后续就差不多
    :return:
    """
    x_train, x_test, y_train, y_test = load_data()
    # 第四步: 开始特征工程
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)
    # 第五步, 预估器流程
    estimator = LogisticRegression()  # 默认参数
    estimator.fit(x_train, y_train)
    print("逻辑回归_权重系数为: ", estimator.coef_)
    print("逻辑回归_偏置为:", estimator.intercept_)
    # store_model(estimator, "logic_regression_model01.pkl")  # 保存模型
    # estimator = load_model("logic_regression_model01.pkl")  # 加载模型
    # 第六步, 模型评估
    y_predict = estimator.predict(x_test)
    print("逻辑回归_预测结果", y_predict)
    print("逻辑回归_预测结果对比:", y_test == y_predict)
    score = estimator.score(x_test, y_test)
    print("准确率为:", score)
    # 2是良性的 4是恶性的
    """
    但是实际上这个预测结果不是我们想要的, 以上只能说明预测的正确与否,
    而事实上, 我们需要一种评估方式来显示我们对恶性breast的预测成功率, 也就是召回率
    同时可以查看F1-score的稳健性
    (召回率和精确率看笔记和截图)
    所以下面换一种评估方法
    """
    Score = classification_report(y_test, y_predict, labels=[2, 4],
                                  target_names=["良性", "恶性"])
    print("查看精确率,召回率,F1-score\n", Score)
    # support表示样本量
    """
    ROC曲线和AUC指标(样本分类不均衡的情况下,可以使用这种方法)
    AUC = 0.5 是瞎猜模型
    AUC = 1 是最好的模型
    AUC < 0.5 属于反向毒奶
    更多的看截图
    """
    # 需要转换为0,1表示
    y_true = np.where(y_test > 3, 1, 0)  # 表示大于3为1,反之为0(class值为2和4)
    return_value = roc_auc_score(y_true, y_predict)
    print("ROC曲线和AUC返回值为(三角形面积)", return_value)
    fpr, tpr, thresholds = roc_curve(y_true, y_predict)
    plt.plot(fpr, tpr)
    plt.show()
    return None
if __name__ == '__main__':
    logic_Regression()