机器学习数据预处理方法(基本信息探索)##1

news2024/10/6 21:27:30

文章目录

  • 基于Kaggle电信用户流失案例数据(可在官网进行下载)
      • 数据解读与数据预处理
      • 数据质量探索
      • 变量相关性探索分析

基于Kaggle电信用户流失案例数据(可在官网进行下载)

数据解读与数据预处理

建议使用jupyter lab进行运行

import numpy as np
import pandas as pd

tcc = pd.read_csv('WA_Fn-UseC_-Telco-Customer-Churn.csv')
pd.set_option('max_colwidth',200)
# 查看前五条数据
tcc.head(5)

在这里插入图片描述

# 查看数据集信息(字段解释)
tcc.info()

在这里插入图片描述

字段解释
customerID用户ID
gender性别
SeniorCitizen是否是老年人(1代表是)
Partner是否有配偶(Yes or No)
Dependents是否经济独立(Yes or No)
tenure用户入网时间
PhoneService是否开通电话业务(Yes or No)
MultipleLines是否开通多条电话业务(Yes 、 No or No phoneservice)
InternetService是否开通互联网服务(No、DSL数字网络或filber potic光线网络)
OnlineSecurity是否开通网络安全服务(Yes、No or No internetservice)
OnlineBackup是否开通在线备份服务(Yes、No or No internetservice)
DeviceProtection是否开通设备保护服务(Yes、No or No internetservice)
TechSupport是否开通技术支持业务(Yes、No or No internetservice)
StreamingTV是否开通网络电视(Yes、No or No internetservice)
StreamingMovies是否开通网络电影(Yes、No or No internetservice)
Contract合同签订方式(按月、按年或者两年)
PaperlessBilling是否开通电子账单(Yes or No)
PaymentMethod付款方式(bank transfer、credit card、electronic check、mailed check)
MonthlyCharges月度费用
TotalCharges总费用
Churn是否流失(Yes or No)

数据质量探索

  • 数据集正确性校验

首先是数据集正确性校验。一般来说数据集正确性校验分为两种,其一是检验数据集字段是否和数据字典中的字段一致,其二则是检验数据集中ID列有无重复。由于该数据集并为提供数据字典,因此此处主要校验数据集ID有无重复:

#查看ID列是否有重复列
tcc['customerID'].nunique() == tcc.shape[0]
#或
tcc.duplicated().sum()    # 返回值为0时说明没有重复行
  • 数据缺失值检验
# 定义缺失值查看函数
def missing (df):
    """
    计算每一列的缺失值及占比
    """
    missing_number = df.isnull().sum().sort_values(ascending=False)              # 每一列的缺失值求和后降序排序                  
    missing_percent = (df.isnull().sum()/df.isnull().count()).sort_values(ascending=False)          # 每一列缺失值占比
    missing_values = pd.concat([missing_number, missing_percent], axis=1, keys=['Missing_Number', 'Missing_Percent'])      # 合并为一个DataFrame
    return missing_values

missing(tcc)

在这里插入图片描述
从上述结果看出数据集中不存在缺失值。

  • 时序字段处理
tcc['tenure'].nunique( )
# 运行结果为73

该字段总共有73个不同的取值,结合此前所说,数据集是第三季度的用户数据,因此我们推断该字段应该是经过字典排序后的离散型字段。所谓字典排序,其本质是一种离散变量的转化方式,有时我们也可以将时序数据进行字典排序,该过程我们可以通过如下示例进行说明:
在这里插入图片描述
也就是说,在第三季度中,这些用户的行为发生在某73天内,因此入网时间字段有73个取值。不过由于该字段是经过字典排序后的结果,因此已经损失了原始信息,即每位用户实际的入网时间。而在实际的分析过程中,我们可以转化后的入网时间字段看成是离散变量,当然也可以将其视作连续变量来进行分析,具体选择需要依据模型来决定。此处我们先将其视作离散变量,后续根据情况来进行调整。

  • 连续/离散型变量标注

接下来,我们来标注每一列的数据类型,我们可以通过不同列表来存储不同类型字段的名称:

# 离散字段
category_cols = ['customerID', 'gender', 'SeniorCitizen', 'Partner', 'Dependents', 'tenure', 
                'PhoneService', 'MultipleLines', 'InternetService', 'OnlineSecurity', 'OnlineBackup', 
                'DeviceProtection', 'TechSupport', 'StreamingTV', 'StreamingMovies', 'Contract', 'PaperlessBilling',
                'PaymentMethod']

# 连续字段
numeric_cols = ['MonthlyCharges', 'TotalCharges']

# 标签
target = 'Churn'
 
# 验证是否划分能完全
assert len(category_cols) + len(numeric_cols) + 1 == tcc.shape[1]
#当然,大多数时候离散型字段都在读取时都是object类型,因此我们也可以通过如下方式直接提取object字段:
tcc.select_dtypes('object').columns

在这里插入图片描述
我们也可以通过如下方式查看每个离散变量的不同取值:

for feature in tcc[category_cols]:
        print(f'{feature}: {tcc[feature].unique()}')

在这里插入图片描述

  • 缺失值检验与填补

发现在连续特征中存在空格。则此时我们需要进一步检查空格字符出现在哪一列的哪个位置,我们可以通过如下函数来进行检验:

def find_index(data_col, val):
    """
    查询某值在某列中第一次出现位置的索引,没有则返回-1
    
    :param data_col: 查询的列
    :param val: 具体取值
    """
    val_list = [val]
    if data_col.isin(val_list).sum() == 0:
        index = -1
    else:
        index = data_col.isin(val_list).idxmax()
    return index

# 查看空格第一次出现在哪一列的哪个位置:
for col in numeric_cols:
    print(find_index(tcc[col], ' '))

我们也可以简单观察缺失’TotalCharges’信息的每条数据实际情况

tcc['TotalCharges']= tcc['TotalCharges'].apply(lambda x: x if x!= ' ' else np.nan).astype(float)
tcc['MonthlyCharges'] = tcc['MonthlyCharges'].astype(float)

tcc[tcc['TotalCharges'].isnull()]

在这里插入图片描述
我们发现,这11条数据的入网时间都是0,也就是说,这11位用户极有可能是在统计周期结束前的最后时间入网的用户,因此没有过去的总消费记录,但是却有当月的消费记录。也就是说,该数据集的过去总消费记录不包括当月消费记录,也就是不存在过去总消费记录等于0的记录。既然如此,我们就可以将这11条记录的缺失值记录为0,以表示在最后一个月统计消费金额前,这些用户的过去总消费金额为0:

tcc['TotalCharges'] = tcc['TotalCharges'].fillna(0)
tcc['TotalCharges'].describe()

在这里插入图片描述

  • 异常值检验
tcc[numeric_cols].describe()

在这里插入图片描述
异常值检测有很多方法,我们可以通过三倍标准差法来进行检验,即以均值-3倍标注差为下界,均值+3倍标准差为上界,来检测是否有超过边界的点:

tcc['MonthlyCharges'].mean() + 3 * tcc['MonthlyCharges'].std()    # 155.03183375363483
tcc['MonthlyCharges'].mean() - 3 * tcc['MonthlyCharges'].std()    # -25.5084488324364
tcc['TotalCharges'].mean() + 3 * tcc['TotalCharges'].std()        # 9080.117712630885 
tcc['TotalCharges'].mean() - 3 * tcc['TotalCharges'].std()        # -4520.649105503233

对比上表格能够发现,数据集并不存在异常值点。

  • 通过箱线图进行观察

此外,我们还可以通过箱线图来进行异常值点的识别,和3倍标准差法利用均值和方差进行计算不同,箱线图主要借助中位数和四分位数来进行计算,以上四分位数+1.5倍四分位距为上界、下四分位数-1.5倍四分位距为下界,超出界限则认为是异常值。我们可以借助plt.boxplot绘图函数迅速绘制箱线图来观察异常值点情况:

import seaborn as sns
import matplotlib.pyplot as plt

# MonthlyCharges上四分位数
Q3 = tcc[numeric_cols].describe()['MonthlyCharges']['75%']        # 89.95
# MonthlyCharges下四分位数
Q1 = tcc[numeric_cols].describe()['MonthlyCharges']['25%']        # 35.5
# # MonthlyCharges的四分位距
IQR = Q3 - Q1													  # 54.349999999999994
# 异常值上界
Q3 + 1.5 * IQR													  # 171.375
# 异常值下界
Q1 - 1.5 * IQR													  # -46.02499999999999
tcc['MonthlyCharges'].min(), tcc['MonthlyCharges'].max()		  # (18.25, 118.75)

同理我们观察TotalCharges的性质

Q3 = tcc[numeric_cols].describe()['TotalCharges']['75%']
Q1 = tcc[numeric_cols].describe()['TotalCharges']['25%']
IQR = Q3 - Q1
(Q1 - 1.5 * IQR, Q3 + 1.5 * IQR)								  # (-4683.525, 8868.675)

tcc['TotalCharges'].min(), tcc['TotalCharges'].max()			  #	(0.0, 8684.8)

不过需要知道的是,由于数据集中没有超出边界的异常值点,因此在实际绘制箱线图时,箱线图的边界会以数据集的极值为准:

plt.figure(figsize=(16, 6), dpi=200)
plt.subplot(121)
plt.boxplot(tcc['MonthlyCharges'])
plt.xlabel('MonthlyCharges')
plt.subplot(122)
plt.boxplot(tcc['TotalCharges'])
plt.xlabel('TotalCharges')

在这里插入图片描述
  能够发现,根据箱线图的判别结果,数据并没有异常值出现。当然,此外我们还能通过连续变量的分布情况来观察是否存在异常值:

plt.figure(figsize=(16, 6), dpi=200)
plt.subplot(121)
sns.histplot(tcc['MonthlyCharges'], kde=True) 
plt.subplot(122)
sns.histplot(tcc['TotalCharges'], kde=True)

在这里插入图片描述
当然,通过上述图像我们也能基本看出月消费金额和总消费金额的基本分布情况,对于大多数用户来说月消费金额和总消费金额都较小,而月消费金额所出现的波动,极有可能是某些套餐的组合定价。

变量相关性探索分析

  • 标签取值分布
y = tcc['Churn']
print(f'Percentage of Churn:  {round(y.value_counts(normalize=True)[1]*100,2)} %  --> ({y.value_counts()[1]} customer)\nPercentage of customer did not churn: {round(y.value_counts(normalize=True)[0]*100,2)}  %  --> ({y.value_counts()[0]} customer)')

Percentage of Churn: 26.54 % --> (1869 customer)
Percentage of customer did not churn: 73.46 % --> (5174 customer)

也就是在总共7000余条数据中,流失用户占比约为26%,整体来看标签取值并不均匀,但如果放到用户流失这一实际业务背景中来探讨,流失用户比例占比26%已经是非常高的情况了。当然我们也可以通过直方图进行直观的观察:

sns.displot(y)

在这里插入图片描述

  • 计算相关系数矩阵

当然,首先我们可以先计算相关系数矩阵,直接通过具体数值大小来表示相关性强弱。不过需要注意的是,尽管我们可以忽略变量的连续/离散特性,但为了更好的分析分类变量如何影响标签的取值,我们需要将标签转化为整型(也就是视作连续变量),而将所有的分类变量进行哑变量处理:

# 剔除ID列
df3 = tcc.iloc[:,1:].copy()

# 将标签Yes/No转化为1/0
df3['Churn'].replace(to_replace='Yes', value=1, inplace=True)
df3['Churn'].replace(to_replace='No',  value=0, inplace=True)

# 将其他所有分类变量转化为哑变量,连续变量保留不变
df_dummies = pd.get_dummies(df3)
df_dummies.head()

在这里插入图片描述此处需要注意pd.get_dummies会将非数值类型对象类型进行自动哑变量转化,而对数值类型对象,无论是整型还是浮点型,都会保留原始列不变:

df_dummies[['Churn', 'tenure', 'MonthlyCharges', 'TotalCharges']]

在这里插入图片描述

# 然后即可采用.corr方法计算相关系数矩阵:
df_dummies.corr()
# 当然,在所有的相关性中,我们较为关注特征和标签之间的相关关系,
# 因此可以直接挑选标签列的相关系数计算结果,并进行降序排序:
df_dummies.corr()['Churn'].sort_values(ascending = False)

# 运行结果
# Churn                                      1.000000
# Contract_Month-to-month                    0.405103
# OnlineSecurity_No                          0.342637
# TechSupport_No                             0.337281
# InternetService_Fiber optic                0.308020
# PaymentMethod_Electronic check             0.301919
# OnlineBackup_No                            0.268005
# DeviceProtection_No                        0.252481
# MonthlyCharges                             0.193356
# PaperlessBilling_Yes                       0.191825
# Dependents_No                              0.164221
# SeniorCitizen                              0.150889
# Partner_No                                 0.150448
# StreamingMovies_No                         0.130845
# StreamingTV_No                             0.128916
# StreamingTV_Yes                            0.063228
# StreamingMovies_Yes                        0.061382
# MultipleLines_Yes                          0.040102
# PhoneService_Yes                           0.011942
# gender_Female                              0.008612
# gender_Male                               -0.008612
# MultipleLines_No phone service            -0.011942
# PhoneService_No                           -0.011942
# MultipleLines_No                          -0.032569
# DeviceProtection_Yes                      -0.066160
# OnlineBackup_Yes                          -0.082255
# PaymentMethod_Mailed check                -0.091683
# PaymentMethod_Bank transfer (automatic)   -0.117937
# InternetService_DSL                       -0.124214
# PaymentMethod_Credit card (automatic)     -0.134302
# Partner_Yes                               -0.150448
# Dependents_Yes                            -0.164221
# TechSupport_Yes                           -0.164674
# OnlineSecurity_Yes                        -0.171226
# Contract_One year                         -0.177820
# PaperlessBilling_No                       -0.191825
# TotalCharges                              -0.199484
# DeviceProtection_No internet service      -0.227890
# StreamingMovies_No internet service       -0.227890
# InternetService_No                        -0.227890
# OnlineSecurity_No internet service        -0.227890
# StreamingTV_No internet service           -0.227890
# TechSupport_No internet service           -0.227890
# OnlineBackup_No internet service          -0.227890
# Contract_Two year                         -0.302253
# tenure                                    -0.352229
# Name: Churn, dtype: float64

需要知道的是,根据相关系数计算的基本原理,相关系数为正数,则二者为正相关,数值变化会更倾向于保持同步。例如Churn与Contract_Month-to-month相关系数为0.4,则说明二者存在一定的正相关性,即Contract_Month-to-month取值为1(更大)越有可能使得Churn取值为1。也就是在Contract字段的Month-to-month取值结果和最终流失的结果相关性较大,也就是相比其他条件,Contract取值为Month-to-month的用户流失概率较大,而tenure和Churn负相关,则说明tenure取值越大、用户流失概率越小。其他结果解读依此类推。

  • 热力图展示相关性

当然,我们也可以通过一些可视化的方式来展示特征和标签之间的相关性,例如可以考虑使用热力图进行相关性的可视化展示:

plt.figure(figsize=(15,8), dpi=200)
sns.heatmap (df_dummies.corr())

在这里插入图片描述

  • 柱状图展示相关性

当然,很多时候如果特征较多,热力图的展示结果并不直观,此时我们可以考虑进一步使用柱状图来进行表示:

sns.set()
plt.figure(figsize=(15,8), dpi=200)

df_dummies.corr()['Churn'].sort_values(ascending = False).plot(kind='bar')

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1434191.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

新书速览|PyTorch 2.0深度学习从零开始学

实战中文情感分类、拼音汉字转化、中文文本分类、拼音汉字翻译、强化学习、语音唤醒、人脸识别 01 本书简介 本书以通俗易懂的方式介绍PyTorch深度学习基础理论,并以项目实战的形式详细介绍PyTorch框架的使用。为读者揭示PyTorch 2.0进行深度学习项目实战的核心技…

PPYOLE

1:参考GitHub - PaddlePaddle/PaddleDetection: Object Detection toolkit based on PaddlePaddle. It supports object detection, instance segmentation, multiple object tracking and real-time multi-person keypoint detection. 2:开源项目 - 飞…

CPU vs GPU:不仅仅是一字之差

当今科学技术的飞速发展,社会已经迈入了信息时代的智能化阶段。人脸识别、智能客服、个性化推荐等应用已经深入到日常生活的各个方面。这些看得见的应用背后,是看不见的算力在默默地支撑着。在满足这些高算力需求的过程中,CPU 和 GPU 作为计算…

【Leetcode】第 383 场周赛

文章目录 100214. 边界上的蚂蚁题目思路代码结果 100204. 将单词恢复初始状态所需的最短时间 I题目思路代码结果 100189. 找出网格的区域平均强度题目思路代码结果 100203. 将单词恢复初始状态所需的最短时间 II题目思路代码结果 100214. 边界上的蚂蚁 题目 题目链接 给你一个…

Java21 + SpringBoot3集成七牛云对象存储OSS,实现文件上传

文章目录 前言实现步骤引入maven依赖修改配置文件创建七牛云配置类创建文件操作服务类创建文件操作控制器前端实现运行效果 总结 前言 近日心血来潮想做一个开源项目,目标是做一款可以适配多端、功能完备的模板工程,包含后台管理系统和前台系统&#xf…

Unity3D实现项目限制功能(使用次数限制和时间限制)

系列文章目录 unity工具 文章目录 系列文章目录前言一、时间限制1-1、代码如下: 二、次数限制2-1、 在Unity项目中需要对注册表进行操作,还需要设置一下API兼容级别设置成 .NET Framework2-2、设置如下图 Player里面2-3、代码如下: 三、同时…

不负书香,传承有我

随着科技的飞速发展,电子书、网络资源日益丰富,但实体书仍以其独特的魅力和不可替代性在每个人的生活中占据一席之地。为确保每一本书都能被正确、有序地摆放,为每一个读者提供便利,在2024年1月24日,曲阜师范大学计算机…

光隔离探头

一、前言。 光隔离探头的CMRR比高压差分探头要高很多,在一些共模电压较高的测量领域用的比较多,如:开关电源、逆变器等。但是市面上介绍光隔离探头的方案比较少,这里简要说明一下我的个人想法。 二、数字光和模拟光。 数字光就是通信上常用的光模块,传的是数字信号,带…

BZOJ0481. 树的重心之砍树Link Cut Centroids

题目 思路 分类讨论。 首先当树只有一个重心的时候,我们删掉最小的边再加上原边即可. 再看有两个重心的情况. 显然这棵树必定是类似这样的: 即删掉 A 后,以B 为根的子树是剩下的最大连通块,反之亦然. 那就可以得到一个结论: 删掉边 (A,B) 后,两棵树的大小相等. 那我们只…

BrainAGE作为大脑老化的神经影像标志物的十年

随着人口老龄化,神经退行性疾病的发病率越来越高,给个人和整个社会带来越来越大的负担。然而,个体的衰老速度是由环境、基因和表观遗传等各种因素以及各因素间的相互作用决定的。建立神经解剖学衰老过程的生物标志物,是神经科学的…

15:矩阵按键

矩阵按键 1、 矩阵按键的原理图分析2、 矩阵键盘的工作过程3、编程实战3.1、先通过LED灯进行按键测试3.2、通过静态数码管显示键值 1、 矩阵按键的原理图分析 (1)横向和纵向分割 (2)按键两端分别接不同的IO引脚 (3)按键的物理作用不变:按下接通电路,弹起…

ONLYOFFICE:一站式办公,探索高效办公新境界

写在前面ONLYOFFICE 介绍ONLYOFFICE 有哪些优势ONLYOFFICE 文档 8.0 发布如何体验 ONLYOFFICEONLYOFFICE 文档部分页面截图 写在前面 在当今这样一个数字化时代,办公软件已经成为我们日常工作中不可或缺的一部分,熟练使用 Office、WPS、腾讯文档、金山文…

openGauss学习笔记-215 openGauss性能调优-确定性能调优范围-性能日志

文章目录 openGauss学习笔记-215 openGauss性能调优-确定性能调优范围-性能日志215.1 性能日志概述215.2 性能日志收集的配置参数 openGauss学习笔记-215 openGauss性能调优-确定性能调优范围-性能日志 215.1 性能日志概述 性能日志主要关注外部资源的访问性能问题。 性能日…

户用光伏电站设计优化方案:为行业打造示范标杆

不可再生能源的日益消耗促使了大家对新能源的使用和推广,光伏发电已经成为国家和企业大力推崇的技术。其中,户用光伏发电是重要组成部分,有非常大的市场发展空间。然而,如何优化设计,提高效率,降低成本&…

牛客——中位数图(连续子数组和二维前缀和)

链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 题目描述 给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b。中位数是指把所有元素从小到大排列后,位于中间的数。 输入描述: 第一行为两个正…

Java统计GitLab代码量

1、生成密钥 2、添加依赖 <dependency><groupId>org.gitlab4j</groupId><artifactId>gitlab4j-api</artifactId><version>5.3.0</version></dependency> Java代码实现 统计所有项目的代码行数&#xff1a; private Stri…

C++函数分文件编写之VScode版

VScode实现函数的分文件编写 1.下载插件创建项目2.分文件编写内容3.修改主函数文件名 我在分享内容时经常用的软件是VScode&#xff0c;相信有些内存敏感或需要VScode便利性的小伙伴也是更愿意使用VScode。那么接下来我们就盘一盘怎样使用VScode实现分文件编写。 1.下载插件创建…

2023年06月CCF-GESP编程能力等级认证Python编程二级真题解析

Python等级认证GESP(1~6级)全部真题・点这里 一、单选题(共15题,共30分) 第1题 高级语言编写的程序需要经过以下()操作,可以生成在计算机上运行的可执行代码。 A:编辑 B:保存 C:调试 D:编译 答案:D 第2题 能够实现下面流程图功能的伪代码是( )。 A:if …

动力电池智能工厂数字孪生可视化,助力新能源汽车产业数字化转型

动力电池智能工厂数字孪生可视化&#xff0c;助力新能源汽车产业数字化转型。随着新能源汽车产业的快速发展&#xff0c;动力电池作为新能源汽车的核心组成部分&#xff0c;其生产制造的数字化转型也成为了行业关注的焦点。动力电池智能工厂数字孪生可视化平台作为一种新型的技…

【PyQt5】一些基本操作

文章目录 前言一、查看自己的PyQt版本代码运行结果 二、查看PyQt5 的类或者对象的属性代码运行结果demo_pulsresult 三、帮助文档代码结果 前言 包括以下 查看自己的PyQt版本、查看某个类的使用方法 一、查看自己的PyQt版本 代码 import PyQt5.QtCore print(PyQt5.QtCore.P…