机器学习-第四章 逻辑回归

逻辑回归 = 有监督学习,有特征,有标签,且标签是离散的=适用于二分类
原理:数据,经过线性回归→预测值→Sigmoid激活函数→概率[0,1]
基于你写的阈值→决定是A还是B

目录

1.逻辑回归简介
2.逻辑回归原理
3.逻辑回归API函数和案例
4.分类问题评估
混淆矩阵、精确率、召回率、FI-score、AUC指标、ROC指标
True 真
False 假
Positive 正例
Negative 反例

预测值-正例 预测值-反例
真实值-正例 TP真正例 伪反例FN
真实值-反例 FP伪正例 真反例TN

精确率=tp/(tp+fp)
召回率=tp/()tp+fn)

5.电信客户流失预测案例

1.逻辑回归简介

1.逻辑回归应用场景

预测疾病、银行信任贷款、情感分析、…二分类问题利器

2.Sigmoid函数

激活函数,s型函数
原理:把线性回归处理后的值→通过Sigmoid激活函数 映射到[0,1]/之间→结合阈值,划分正负样本

在这里插入图片描述

3.概率
  • 概率:时间发生的可能性
    PA=0.4 PB=0.6
  • 联合概率:两个或多个随机变量同时发生的概率
    AB同时发生 PAPB=0.4*0.6
  • 条件概率:在A发生的情况下 发生B P(B|A)=0.4*0.6
4.极大似然估计
  • 核心思想 :根据观测到的结果来估计模型算法中未知参数
  • 案例:一枚不均匀硬币,假定正面概率为θ,抛了6次得到结果D={正,正,正,正,反,反},每次投掷事件都相互独立,估计θ是多少?
    -
5.数学基础-对数函数

在这里插入图片描述

总结

在这里插入图片描述

2.逻辑回归原理

1、逻辑回归概念

  • Logistic Regression
    • 一种分类模型
    • 将线性回归的输出作为逻辑回归的输入
    • 输出值在 (0, 1) 之间(表示概率)

2、基本思想

  1. 使用线性模型
    f(x) = w^T x + b
    根据特征的重要性计算一个值
  2. 将f(x)通过 sigmoid 函数 映射为概率值
    h(w) = sigmoid(w^T x + b)
  3. 设定阈值(例如 0.5):
    • 概率值 > 0.5 → 预测为 1 类
    • 概率值 ≤ 0.5 → 预测为 0 类

3、假设函数

h(w) =sigmoid(w^T x + b)
(线性回归的输出作为逻辑回归的输入)

4.案例:逻辑回归预测过程

在这里插入图片描述

5. 损失函数

1.损失函数
在这里插入图片描述
2.计算例子
在这里插入图片描述
3.损失函数
在这里插入图片描述
在这里插入图片描述

逻辑回归 损失函数 = -极大似然估计函数

总结

1.逻辑回归原理
思想:解决分类问题,把线性回归的输出作为逻辑 回归的输入

2.逻辑回归的损失函数-对数似然损失
数学表达式:极大似然估计的负数
在这里插入图片描述
损失函数设计思想:预测值为A.B两个类别,真实类别所在位置,概率值越大越好

3.逻辑回归API函数和案例

癌症预估

1.API介绍

sklearn.linear_model.LogisticRegression(solver=‘liblinear’,penalty=‘l2’,C=1.0)

  • 1.liblinear 对小数据集场景训练速度更快,sag和saga对大数据集更快一些
  • 2.正则化:
    • sag、saga支持L2正则化或者没有正则化
    • liblinear和saga支持L1正则化
  • 3.penalty:正则化的种类L1或者L2
  • 4.C 正则化粒度
  • 5.默认将类别数量少的当作正例
2.癌症分类预测
1.数据描述

1.699条样本,共11列数据,第一列用于检索的id,后9列分别是与肿瘤相关的医学特征,最后一列表示肿瘤类型的数值。
2.3包含16个缺失值,用?标注
3.2表示良性,4表示恶性

"""
案例:
    演示 逻辑回归 模型 实现  癌症预测

逻辑回归模型介绍:
    概述:
        属于有监督学习, 有特征 有标签  表示是练得
        适用于二分类
    原理:
        把线性回归处理后的预测值→通过sigmoid激活函数,映射到[0,1]概率→基于自定义的阈值,结合概率来分类
    损失函数:
        极大似然估计函数的负数形式
机器学习项目流程
    1.抓取数据
    2.数据预处理
    3.特征过程
    4.模型训练
    5.模型预测
    6.模型评估
"""

# 导包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score

# 1.抓取数据
data = pd.read_csv('./data/breast-cancer-wisconsin.csv')
data.info()

# 2.数据预处理
# 2.1 数据清洗 把?替换为NaN
data.replace('?', np.nan, inplace=True) #inplace默认为False,不修改原数据,改为True则修改原数据
# 2.2 删除有NaN的行
data.dropna(inplace=True) # inplace默认为False,不修改原数据,改为True则修改原数据
data.info() # 原来有699行数据,现在有683行数据,删除了16条数据

# 3.特征过程
# 3.1 取特征和标签
x = data.iloc[:, 1:-1] #取所有行,列取第一行到倒数第二行  包前不包后
target = data.iloc[:, -1] #取所有行,列取最后一列
# 3.2 训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(x, target, test_size=0.2, random_state=22)
# 3.3 标准化
transfer = StandardScaler()
# 对训练集标准化
x_train = transfer.fit_transform(x_train) #训练+标准化
x_test = transfer.transform(x_test) #只标准化

# 4.模型训练
# 4.1 创建模型对象 y→逻辑回归对象
estimator = LogisticRegression()

# 4.2 训练
estimator.fit(x_train, y_train)

# 5.模型预测
y_pre = estimator.predict(x_test)

# 6.模型评估
# 正确率=准确率=预测对的/样本总数
print('准确率:', accuracy_score(y_test, y_pre))
print('准确率', estimator.score(x_test, y_test))
print('评估报告:', classification_report(y_test, y_pre, labels=[2, 4], target_names=['良性', '恶性']))

# 思考 逻辑回归模型能用准确率评估吗?
# 逻辑回归模型不能用准确率评估,准确率只能用来评估二分类模型,逻辑回归模型是二分类模型,准确率是二分类模型评估的指标。
#可以,但不正确,因为逻辑回归模型主要用于二分类,即a类还是b类,不能说97%的a类,3%的b类。
# 所以要通过 混淆矩阵来评测,即:精确率、召回率、F1-score、AUC、ROC曲线

4.分类问题评估

1.混淆矩阵

*True 真
False 假
Positive 正例
Negative 反例*
预测值- 正例 预测值假例
真实值-正例 真正例TP 伪反例FN
真实值-假例 伪正例FP 真反例TN

2.混淆矩阵案例

已知10样本,6个恶性肿瘤,4个良性肿瘤,我们假设恶性肿瘤为正例
模型A:预测了3个恶性肿瘤,4个良性肿瘤样本
TP=3,FN=3
FP=0,TN=4
模型B:预测了6个恶性肿瘤,1个良性肿瘤样本
TP=6,FN=0
FP=3,TN=1

3.精确率、召回率、F1

1.精确率 Precision

查准率,对正例样本的预测准确率。
比如,把恶性肿瘤当作正例样本,想知道模型对恶性肿瘤的预测准确率。
计算方法:P=TP/(TP+FP)
模型A:P=3/(3+0)=1
模型B:P=6/(6+3)=2/3

2.召回率 Recall

也叫查全率,指的是预测为真正例样本占所有真实正例样本的比重。
例如:恶性肿瘤当作正例样本,我们相知带模型是否能把所有的恶性肿瘤患者都预测出来。
计算方法:P=TP/(TP+FN)
模型A:P=3/(3+3)=1/2
模型B:P=6/(6+0)=1

2.F1-score

若对模型的精度、召回率都有要求,希望只带模型在这两个评估方向的综合能力?
计算方法:P=2PrecisionRecall/(Precision+Recall)
模型A:P=210.5/1.5=67%
模型B:P=22/31/5/3=80%

4.恶性肿瘤案例

已知10样本,6个恶性肿瘤,4个良性肿瘤,我们假设恶性肿瘤为正例
模型A:预测了3个恶性肿瘤,4个良性肿瘤样本
TP=3,FN=3
FP=0,TN=4
精确率 = TP/()

模型B:预测了6个恶性肿瘤,1个良性肿瘤样本
TP=6,FN=0
FP=3,TN=1

"""
案例:
    演示混淆矩阵 和精确率 召回率 F1

回顾:逻辑回归
    概述
        属于有监督信息,即 有特征 有标签,且标签是离散的。
        适用于二分类
    评估:
        精确率、召回率、F1值

混淆矩阵
    概述:
        用来描述真实值和预测值之间关系的
    图解:
                        预测值标签-正例  预测值标签-反例
        真实值标签-正例    真正例TP         伪反例FN
        真实值标签-反例    伪反例FP         真反例TN

    单词:
        True:真
        False:假
        Positive:正例
        Negative:反例

    结论:
        1.默认使用分类少的充当正例
        2.精确率 = 真正例在预测正例中的占比,tp/(tp+fp)
        3.召回率 = 真正例在真正例中的占比,tp/(tp+fn)
        4.f1值 = 2*(精确率*召回率)/(精确率+召回率)

"""
# 导包
import pandas as pd
from sklearn.metrics import confusion_matrix,precision_score,recall_score,f1_score

# 需求:已知有10个样本,6个恶性肿瘤样本-正例,4个良性样本-反例。
#模型A预测结果为:预测对了3个恶性肿瘤,预测对了4个良性肿瘤。
#模型B预测结果为:预测对了6个恶性肿瘤,预测对了1个良性肿瘤。
#请针对上述的数据集,求出混淆矩阵,精确率,召回率,F1值

# 1. 定义变量,记录:样本数据
y_train = ['恶性', '恶性', '恶性', '恶性', '恶性', '恶性',    '良性', '良性', '良性', '良性']

# 2.定义变量,记录模型A的预测结果
y_pred_A = ['恶性', '恶性', '恶性', '良性', '良性', '良性',    '良性', '良性', '良性', '良性']

# 3.定义变量,记录模型B的预测结果
y_pred_B = ['恶性', '恶性', '恶性', '恶性', '恶性', '恶性',    '良性', '恶性', '恶性', '恶性']

# 4.用标签标记  正例,反例
label = ['恶性', '良性']
df_label = ['恶性(正例)', '良性(反例)']

# 5.针对于真实值(y_train) 和模型AA的预测结果(y_pred_A)进行混淆矩阵
cm_A=confusion_matrix(y_train, y_pred_A, labels=label)
print('混淆矩阵:',cm_A)

# 6.为了测试结果更好看,把上述的混淆矩阵转换为DataFrame
df_A = pd.DataFrame(cm_A, index=df_label, columns=label)
print(df_A)
"""
        恶性  良性
恶性(正例)   3   3
良性(反例)   0   4
"""

# 7.针对于真实值(y_train) 和模型B的预测结果(y_pred_B)进行混淆矩阵
cm_B=confusion_matrix(y_train, y_pred_B, labels=label)
print('混淆矩阵:',cm_B)

# 8.为了测试结果更好看,把上述的混淆矩阵转换为DataFrame
df_B = pd.DataFrame(cm_B, index=df_label, columns=label)
print(df_B)
"""
        恶性  良性
恶性(正例)   6   0
良性(反例)   3   1
"""

#  9.计算模型A的精确率、召回率、F1值
precision_A = precision_score(y_train, y_pred_A, pos_label='恶性') #1
recall_A = recall_score(y_train, y_pred_A, pos_label='恶性') #0.5
f1_A = f1_score(y_train, y_pred_A, pos_label='恶性') #0.6
print('模型A的精确率:',precision_A)
print('模型A的召回率:',recall_A)
print('模型A的F1值:',f1_A)

# 10.计算模型B的精确率、召回率、F1值
precision_B = precision_score(y_train, y_pred_B, pos_label='恶性') #0.6  6/9
recall_B = recall_score(y_train, y_pred_B, pos_label='恶性') #1 6/6
f1_B = f1_score(y_train, y_pred_B, pos_label='恶性') #0.8 2*0.6*1/1.6
print('模型B的精确率:',precision_B)
print('模型B的召回率:',recall_B)
print('模型B的F1值:',f1_B)

4.AUC指标和ROC曲线

1.真正率TPR和假正率FPR

正样本中被预测为正样本的概率TPR-True Postive Rate
负样本中被预测为正样本的概率FPR-False Postive Rate
通过这两个指标可以描述模型对正/负样本的分辨能力

2.ROC曲线

是一种用于评估分类模型性能的可视化工具,ROC曲线以模型的真正率TPR为纵轴,假正率FPR为横轴,将模型在不同于之下的表现以曲线的形式展现出来。

3.AUC曲线下的面积

ROC曲线的优劣可以通过曲线下的面积AUC来衡量,AUC越大表示分类器性能越好。
当AUC=0.5时,表示分类器的性能等同于随机猜测
当AUC=1时,表示分类器的性能完美,能够完全正确的将正负例分类。

在这里插入图片描述

4.ROC曲线图像中,4个特殊点含义

(0,0)-所有负样本都预测正确,所有正样本都预测错误
(1,0)-所有负样本都预测错误,所有正样本都预测错误-最不好
(1,1)-所有负样本都预测错误,所有正样本都预测正确
(0,1)-所有负样本都预测正确,所有正样本都预测正确-最好的效果

5.ROC曲线上的每个点代表模型在不同阈值下的性能表现

越靠近(0,1)点则模型对正负样本的辨别能力就越强
AUC=1→完美

6.AUC ROC案例

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

7.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:预测得分,可以是正例的估计概率、置信值或者分类器方法的返回值

分类评估报告API
sklearn.metrics.classification_report(y_true,y_pred,labels=[],target_names=None)
y_true:真实目标值
y_pred:估计器预测目标值
labels:指定类别对应的数字
target_names:目标类别名称
return:每个类别精确率与召回率

总结

在这里插入图片描述

5. 电信客户流失预测-逻辑回归案例

1.案例需求

已知:用户个人,通话,上网信息等
需求:通过分析特征属性确定用户流失的原因,以及哪些因素可能导致用户流失。建立预测模型来判断用户是否流失,并提出用户流失预警策略。
数据集介绍:

"""
案例:
    通过逻辑回归算法,针对于电信用户数据建模,进行流失预测分析
"""

# 导包
import pandas as pd
import numpy as np

import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, accuracy_score, precision_score, recall_score, f1_score

from sklearn.model_selection import train_test_split


# 1.定义函数,演示:数据预处理
def dm01_data_preprocessing():
    # 1.读取csv文件,获取df对象
    churn_df = pd.read_csv('./data/churn.csv')
    # 2.查看数据集
    churn_df.info()
    print(churn_df.head(5))
    # 3. Churn 和 gender 列是object,需要转换成数值型,one-hot编码处理
    churn_df = pd.get_dummies(churn_df, columns=['Churn', 'gender'])
    print(churn_df.head(5))
    churn_df.info()
    # 4. 删除无用的列
    churn_df.drop(['Churn_No', 'gender_Female'], axis=1, inplace=True)
    print(churn_df.head(5))
    churn_df.info()

    # 5. 修改列名Churn_Yes →为 flag
    churn_df.rename(columns={'Churn_Yes': 'flag'}, inplace=True)
    print(churn_df.head(5))
    churn_df.info()

    # 6.查看数据分布 flag
    print(churn_df['flag'].value_counts()) # 0: 5174  1: 1869  不均匀

# 2.定义函数,演示:数据可视化
def dm02_data_visualization():
    # 1.加载数据
    churn_df = pd.read_csv('./data/churn.csv')
    # 2.one-hot编码处理
    churn_df = pd.get_dummies(churn_df, columns=['Churn', 'gender'])
    # 3.删除冗余的列
    churn_df.drop(['Churn_No', 'gender_Female'], axis=1, inplace=True)
    # 4.重命名
    churn_df.rename(columns={'Churn_Yes': 'flag'}, inplace=True)
    # 5.查看数据分布
    print(churn_df['flag'].value_counts())

    # 6.查看列名,方便获取列名
    print(churn_df.columns)
    # ['Partner_att', 'Dependents_att', 'landline', 'internet_att',
    #  'internet_other', 'StreamingTV', 'StreamingMovies', 'Contract_Month',
    #  'Contract_1YR', 'PaymentBank', 'PaymentCreditcard', 'PaymentElectronic',
    #  'MonthlyCharges', 'TotalCharges', 'flag', 'gender_Male']
    # 5.sns 可视化
    sns.countplot( data=churn_df,x='Contract_Month')
    plt.show()
    # 参1:数据集  参2:x轴列名-阅读会员 参3:hue 分组
    sns.countplot(data=churn_df, x='Contract_Month', hue='flag')
    plt.show()

# 3. 定义函数,演示:逻辑回归算法的模型训练,预测,评估
def dm03_logistic_regression():
    # 1.加载数据
    churn_df = pd.read_csv('./data/churn.csv')

    # 2.数据预处理
    # 2.1 one-hot编码处理
    churn_df = pd.get_dummies(churn_df, columns=['Churn', 'gender'])
    # 2.2 删除无用的列
    churn_df.drop(['Churn_No', 'gender_Female'], axis=1, inplace=True)
    # 2.3 重命名
    churn_df.rename(columns={'Churn_Yes': 'flag'}, inplace=True)
    # 2.4 获取特征和标签
    x = churn_df[['Contract_Month','internet_other','PaymentElectronic']]
    y = churn_df['flag']    #False 流失 True 不流失
    # 2.5 训练集和测试集
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=22)

    # 3.逻辑回归模型训练
    estimator = LogisticRegression()
    estimator.fit(x_train, y_train)

    # 4.模型预测
    y_pre = estimator.predict(x_test)
    print(y_pre)

    # 5.模型评估
    print('准确率:', estimator.score(x_test, y_test))
    print('准确率:', accuracy_score(y_test, y_pre))

    print('精确率:', precision_score(y_test, y_pre))
    print('召回率:', recall_score(y_test, y_pre))
    print('F1-score:', f1_score(y_test, y_pre))
    # macro avg-宏平平均值,对每个标签的精确率和召回率求平均值,取平均值作为宏平均值
    # weighted avg-加权平均值,对每个标签的精确率和召回率求平均值,对标签的权重为标签的样本数量
    print('评估报告:', classification_report(y_test, y_pre, labels=[0, 1], target_names=['正常', '流失']))





# 4.测试
if __name__ == '__main__':
    # dm01_data_preprocessing()
    # dm02_data_visualization()
    dm03_logistic_regression()
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐