文章目录
1. 混淆矩阵
混淆矩阵作用就是看一看在测试集样本集中:
- 真实值是 正例 的样本中,被分类为 正例 的样本数量有多少,这部分样本叫做真正例(TP,True Positive)
- 真实值是 正例 的样本中,被分类为 假例 的样本数量有多少,这部分样本叫做伪反例(FN,False Negative)
- 真实值是 假例 的样本中,被分类为 正例 的样本数量有多少,这部分样本叫做伪正例(FP,False Positive)
- 真实值是 假例 的样本中,被分类为 假例 的样本数量有多少,这部分样本叫做真反例(TN,True Negative)
True Positive :表示样本真实的类别
Positive :表示样本被预测为的类别
2. Precision(精准率)
精准率也叫做查准率,指的是对正例样本的预测准确率。即,真正例(预测对的正例)占预测结果中所有正例的比例。
3. Recall(召回率)
召回率也叫做查全率,指的是预测为真正例样本占所有真实正例样本的比重。即,真正例(预测对的正例)占真实结果中所有正例的比例。
例子:
样本集中有 6 个恶性肿瘤样本,4 个良性肿瘤样本,我们假设恶性肿瘤为正例,则:
模型 A: 预测对了 3 个恶性肿瘤样本,4 个良性肿瘤样本
- 真正例 TP 为:3
- 伪反例 FN 为:3
- 假正例 FP 为:0
- 真反例 TN:4
- 精准率:3/(3+0) = 100%
- 召回率:3/(3+3)=50%
4. F1-score
如果我们对模型的精度、召回率都有要求,希望知道模型在这两个评估方向的综合预测能力如何?则可以使用 F1-score 指标。
样本集中有 6 个恶性肿瘤样本,4 个良性肿瘤样本,我们假设恶性肿瘤为正例,则:
模型 A: 预测对了 3 个恶性肿瘤样本,4 个良性肿瘤样本
- 真正例 TP 为:3
- 伪反例 FN 为:3
- 假正例 FP 为:0
- 真反例 TN:4
- 精准率:3/(3+0) = 100%
- 召回率:3/(3+3)=50%
- F1-score:(2*3)/(2*3+3+0)=67%
模型 B: 预测对了 6 个恶性肿瘤样本,1个良性肿瘤样本
- 真正例 TP 为:6
- 伪反例 FN 为:0
- 假正例 FP 为:3
- 真反例 TN:1
- 精准率:6/(6+3) = 67%
- 召回率:6/(6+0)= 100%
- F1-score:(2*6)/(2*6+0+3)=80%
5. ROC曲线和AUC指标
5.1 ROC 曲线
ROC 曲线:我们分别考虑正负样本的情况:
- 正样本中被预测为正样本的概率,即:TPR (True Positive Rate)
- 负样本中被预测为正样本的概率,即:FPR (False Positive Rate)
ROC 曲线图像中,4 个特殊点的含义:
- (0, 0) 表示所有的正样本都预测为错误,所有的负样本都预测正确
- (1, 0) 表示所有的正样本都预测错误,所有的负样本都预测错误
- (1, 1) 表示所有的正样本都预测正确,所有的负样本都预测错误
- (0, 1) 表示所有的正样本都预测正确,所有的负样本都预测正确
5.2 绘制 ROC 曲线
假设:在网页某个位置有一个广告图片或者文字,该广告共被展示了 6 次,有 2 次被浏览者点击了。每次点击的概率如下:
样本 | 是否被点击 | 预测点击概率 |
---|---|---|
1 | 1 | 0.9 |
3 | 1 | 0.8 |
2 | 0 | 0.7 |
4 | 0 | 0.6 |
5 | 0 | 0.5 |
6 | 0 | 0.4 |
绘制 ROC 曲线:
阈值:0.9
- 原本为正例的 1、3 号的样本中 3 号样本被分类错误,则 TPR = 1/2 = 0.5
- 原本为负例的 2、4、5、6 号样本没有一个被分为正例,则 FPR = 0
阈值:0.8
- 原本为正例的 1、3 号样本被分类正确,则 TPR = 2/2 = 1
- 原本为负例的 2、4、5、6 号样本没有一个被分为正例,则 FPR = 0
阈值:0.7
- 原本为正例的 1、3 号样本被分类正确,则 TPR = 2/2 = 1
- 原本为负类的 2、4、5、6 号样本中 2 号样本被分类错误,则 FPR = 1/4 = 0.25
阈值:0.6
- 原本为正例的 1、3 号样本被分类正确,则 TPR = 2/2 = 1
- 原本为负类的 2、4、5、6 号样本中 2、4 号样本被分类错误,则 FPR = 2/4 = 0.5
阈值:0.5
- 原本为正例的 1、3 号样本被分类正确,则 TPR = 2/2 = 1
- 原本为负类的 2、4、5、6 号样本中 2、4、5 号样本被分类错误,则 FPR = 3/4 = 0.75
阈值 0.4
- 原本为正例的 1、3 号样本被分类正确,则 TPR = 2/2 = 1
- 原本为负类的 2、4、5、6 号样本全部被分类错误,则 FPR = 4/4 = 1
(0, 0.5)、(0, 1)、(0.25, 1)、(0.5, 1)、(0.75, 1)、(1, 1)
由 TPR 和 FPR 构成的 ROC 图像为:
5.3 AUC 值
- 图像越靠近 (0,1) 点则模型对正负样本的辨别能力就越强
- 图像越靠近 (0, 1) 点则 ROC 曲线下面的面积就会越大
- AUC 是 ROC 曲线下面的面积,该值越大,则模型的辨别能力就越强
- AUC 范围在 [0, 1] 之间
- 当 AUC= 1 时,该模型被认为是完美的分类器,但是几乎不存在完美分类器
AUC 值主要评估模型对正例样本、负例样本的辨别能力.
6. API介绍
6.1 分类评估报告api
sklearn.metrics.classification_report(y_true, y_pred, labels=[], target_names=None )
'''
y_true:真实目标值
y_pred:估计器预测目标值
labels:指定类别对应的数字
target_names:目标类别名称
return:每个类别精确率与召回率
'''
6.2 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:预测得分,可以是正例的估计概率、置信值或者分类器方法的返回值
练习-电信客户流失预测
1. 数据集介绍
-
AT&T数据,用户个人,通话,上网等信息数据
-
充分利用数据预测客户的流失情况
-
帮助挽留用户,保证用户基数和活跃程度
具体数据说明如下:
- CustomerID 客户ID
- Gender 性别
- partneratt 配偶是否也为att用户
- dependents_att 家人是否也是att用户
- landline 是否使用att固话服务
- internet_att/internet_other 是否使用att的互联网服务
- Paymentbank/creditcard/electroinc 付款方式
- MonthlyCharges 每月话费
- TotalCharges 累计话费
- Contract_month/1year 用户使用月度/年度合约
- StreamingTv/streamingMovies 是否使用在线视频或者电影app
- Churn 客户转化的flag
2. 处理流程
分析流程:数据概况分析->单变量分析->可视化->逻辑回归模型
数据概况分析
-
数据行/列数量
-
缺失值分布
单变量分析
-
数字型变量的描述指标(平均值,最大最小值,标准差)
-
类别型变量(多少个分类,各自占比)
-
正负样本占比
相关性分析与可视化
-
按类别交叉对比
-
变量之间的相关性分析
-
散点图/热力图
逻辑回归分析
-
模型建立
-
模型评估与优化
3. 案例实现
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
churn=pd.read_csv('data/churn.csv')
churn.info()
输出结果:
RangeIndex: 7043 entries, 0 to 7042
Data columns (total 16 columns):
Churn 7043 non-null object
gender 7043 non-null object
Partner_att 7043 non-null int64
Dependents_att 7043 non-null int64
landline 7043 non-null int64
internet_att 7043 non-null int64
internet_other 7043 non-null int64
StreamingTV 7043 non-null int64
StreamingMovies 7043 non-null int64
Contract_Month 7043 non-null int64
Contract_1YR 7043 non-null int64
PaymentBank 7043 non-null int64
PaymentCreditcard 7043 non-null int64
PaymentElectronic 7043 non-null int64
MonthlyCharges 7043 non-null float64
TotalCharges 7043 non-null float64
dtypes: float64(2), int64(12), object(2)
memory usage: 880.5+ KB
#预测目标是churn,是类别型变量 gender也是类别型变量 需要对类别型变量进行处理
churn.head()
输出结果:
Churn gender Partner_att Dependents_att landline internet_att
0 No Female 1 0 0 1
1 No Male 0 0 1 1
2 Yes Male 0 0 1 1
3 No Male 0 0 0 1
4 Yes Female 0 0 1 0
internet_other StreamingTV StreamingMovies Contract_Month Contract_1YR
0 0 0 0 1 0
1 0 0 0 0 1
2 0 0 0 1 0
3 0 0 0 0 1
4 1 0 0 1 0
PaymentBank PaymentCreditcard PaymentElectronic MonthlyCharges
0 0 0 1 29.85
1 0 0 0 56.95
2 0 0 0 53.85
3 1 0 0 42.30
4 0 0 1 70.70
TotalCharges
0 29.85
1 1889.50
2 108.15
3 1840.75
4 151.65
需要把churn和gender转变为数字型变量,使用get_dummies
churn=pd.get_dummies(churn)
churn.head()
输出结果:
Churn_No Churn_Yes gender_Female gender_Male
0 1 0 1 0
1 1 0 0 1
2 0 1 0 1
3 1 0 0 1
4 0 1 1 0
数据整理,将churn_yes保留,将female保留,drop不需要的数据
churn.drop(['Churn_No','gender_Male'],axis=1,inplace=True)
#变量大小写不规则,统一变成小写
churn.columns=churn.columns.str.lower()
churn.head()
输出结果
churn_yes gender_female
0 0 1
1 0 0
2 1 0
3 0 0
4 1 1
将churn_yes重命名
churn=churn.rename(columns={'churn_yes':'flag'})
#二分类模型,分析flag 1和0的占比
churn.flag.value_counts()
输出结果:
0 5174
1 1869
Name: flag, dtype: int64
churn.flag.value_counts(1)
输出结果:
0 0.73463
1 0.26537
Name: flag, dtype: float64
按照标签进行分组,查看不同标签分组的平均值
summary=churn.groupby('flag')
summary.mean()
输出结果:
partner_att dependents_att landline internet_att internet_other
flag
0 0.528218 0.344801 0.901044 0.379204 0.347700
1 0.357945 0.174425 0.909042 0.245586 0.693954
streamingtv streamingmovies contract_month contract_1yr paymentbank
flag
0 0.365868 0.369927 0.429068 0.252609 0.248550
1 0.435527 0.437667 0.885500 0.088818 0.138042
paymentcreditcard paymentelectronic monthlycharges totalcharges
flag
0 0.249324 0.250097 61.265124 2545.918081
1 0.124131 0.573034 74.441332 1528.514714
gender_female
flag
0 0.492656
1 0.502408
观察flag在0和1的情况下,所有自变量的差别 internet_other变量,在0的分组中,均值是0.35,在1的分组中,均值是0.69。数据显示如果使用别的公司的互联网,用户流失的概率就越高
sns.countplot(y='contract_month',hue='flag',data=churn)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hl5cTbE0-1689931630404)(/Users/zhangzimin/OneDrive/文档/数据分析研发课件/数据分析/02_机器学习/逻辑回归/images/plt_lr.png)]
结论:contract_month为1的客户流失的概率更高,即与非按月付费客户相比,按月付费客户流失比例高
逻辑回归模型
自变量可以分为几类,partner/dependents,internet,streaming,contract,payment,charges,后续大家可以自己挑选进行建模
这里先选取几个contract_month,internet_other与streamingtv
# 确定目标值和特征值
y=churn['flag']
x=churn[['contract_month','internet_other','streamingtv']]
#调用sklearn模块,随机抽取训练集与测试集
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3,random_state=100)
#使用sklearn
from sklearn import linear_model
lr=linear_model.LogisticRegression()
lr.fit(x_train,y_train)
模型的评估
y_pred_train=lr.predict(x_train)
y_pred_test=lr.predict(x_test)
import sklearn.metrics as metrics
metrics.accuracy_score(y_train,y_pred_train)
from sklearn.metrics import roc_auc_score
roc_auc_score(y_test, y_pred_test)
参数调整
从Y标签的类别分布上看,未流失用户为:5174 流失用户为:1869,属于样本分布不均衡问题,我们可以通过调整逻辑回归的模型参数来为占比较低的类别增加权重
LogisticRegression(class_weight='balanced')
除此之外我们可以进一步通过网格搜索来调整其它参数
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import GridSearchCV
kfold = StratifiedKFold(n_splits=5, shuffle=True)
lr = linear_model.LogisticRegression()
param_grid = {'solver': ['newton-cg', 'lbfgs', 'liblinear'],
'C': [0.001, 0.01, 1, 10, 100],'class_weight':['balanced']}
search = GridSearchCV(lr, param_grid, cv=kfold)
lr = search.fit(x_train, y_train)
我们打印获取到的最优参数组合
lr.best_params_
{‘C’: 1, ‘class_weight’: ‘balanced’, ‘solver’: ‘newton-cg’}
查看模型的回归系数
# x=churn[['contract_month','internet_other','streamingtv']]
lr.coef_
[[2.25630305 1.12102112 0.28519637]]
从结果中反应了特征重要性, contract_month 重要性最高,internet_other 其次,为了降低流失率,可以考虑针对月付费用户以及使用它网宽带的用户做针对性的营销
4. 小结
本小节,我们使用了逻辑回归算法做了用户流失分析的案例
- 除了直接预测用户是否会流失之外, 还可以利用模型中的回归系数得出对业务有帮助的建议
- 当样本类别分布不均衡时(如本例中,0样本是数量是5174,1样本数量是1869),可以通过添加参数class_weight='balanced’来增加样本占比较低类别的权重