机器学习(一)使用pandas进行数据探索

import numpy as np
import pandas as pd
import warnings
warnings.filterwarnings('ignore')
 

通过 read_csv() 方法读取数据,然后使用 head() 方法查看前 5 行数据。

df = pd.read_csv(

'https://labfile.oss.aliyuncs.com/courses/1283/telecom_churn.csv')

df.head()

上图中的每行对应一位客户,每列对应客户的一个特征。

让我们查看一下该数据库的维度、特征名称和特征类型。

df.shape

上述结果表明,我们的列表包含 3333 行和 20 列。下面我们尝试打印列名。

df.columns

我们还可以使用 info() 方法输出 DataFrame 的一些总体信息。

df.info()

bool、int64、float64 和 object 是该数据库特征的数据类型。这一方法同时也会显示是否有缺失值,上述结果表明在该数据集中不存在缺失值,因为每列都包含 3333 个观测,和我们之前使用 shape 方法得到的数字是一致的。

astype() 方法可以更改列的类型,下列公式将 Churn 离网率 特征修改为 int64 类型。

df['Churn'] = df['Churn'].astype('int64')

describe() 方法可以显示数值特征(int64 和 float64)的基本统计学特性,如未缺失值的数值、均值、标准差、范围、四分位数等。

df.describe()

通过 include 参数显式指定包含的数据类型,可以查看非数值特征的统计数据。

df.describe(include=['object', 'bool'])

value_counts() 方法可以查看类别(类型为 object )和布尔值(类型为 bool )特征。让我们看下 Churn 离网率 的分布。

df['Churn'].value_counts()

上述结果表明,在 3333 位客户中, 2850 位是忠实客户,他们的 Churn 值为 0。调用 value_counts() 函数时,加上 normalize=True 参数可以显示比例。

df['Churn'].value_counts(normalize=True)

排序

DataFrame 可以根据某个变量的值(也就是列)排序。比如,根据每日消费额排序(设置 ascending=False 倒序排列)。

df.sort_values(by='Total day charge', ascending=False).head()

此外,还可以根据多个列的数值排序。下面函数实现的功能为:先按 Churn 离网率 升序排列,再按 Total day charge 每日总话费 降序排列,优先级 Churn > Tatal day charge。

df.sort_values(by=['Churn', 'Total day charge'],
 ascending=[True, False]).head()

索引和获取数据

DataFrame 可以以不同的方式进行索引。

使用 DataFrame['Name'] 可以得到一个单独的列。比如,离网率有多高?

df['Churn'].mean()

对一家公司而言,14.5% 的离网率是一个很糟糕的数据,这么高的离网率可能导致公司破产。

布尔值索引同样很方便,语法是 df[P(df['Name'])],P 是在检查 Name 列每个元素时所使用的逻辑条件。这一索引的输出是 DataFrame 的 Name 列中满足 P 条件的行。

让我们使用布尔值索引来回答这样以下问题:离网用户的数值变量的均值是多少?

df[df['Churn'] == 1].mean()

离网用户在白天打电话的总时长的均值是多少?

df[df['Churn'] == 1]['Total day minutes'].mean()

未使用国际套餐(International plan == NO)的忠实用户(Churn == 0)所打的最长的国际长途是多久?

df[(df['Churn'] == 0) & (df['International plan'] == 'No')

]['Total intl minutes'].max()

DataFrame 可以通过列名、行名、行号进行索引。loc方法为通过名称索引,iloc 方法为通过数字索引。

通过 loc 方法输出 0 至 5 行、State 州 至 Area code 区号 的数据。

df.loc[0:5, 'State':'Area code']

通过 ilo 方法输出前 5 行的前 3 列数据(和典型的 Python 切片一样,不含最大值)。

df.iloc[0:5, 0:3]

df[:1] 和 df[-1:] 可以得到 DataFrame 的首行和末行。

df[-1:]

应用函数到单元格、列、行

下面通过 apply() 方法应用函数 max 至每一列,即输出每列的最大值。

df.apply(np.max)

apply() 方法也可以应用函数至每一行,指定 axis=1 即可。在这种情况下,使用 lambda 函数十分方便。比如,下面函数选中了所有以 W 开头的州。

df[df['State'].apply(lambda state: state[0] == 'W')].head()

map() 方法可以通过一个 {old_value:new_value} 形式的字典替换某一列中的值。

d = {'No': False, 'Yes': True}

df['International plan'] = df['International plan'].map(d)

df.head()

当然,使用 repalce() 方法一样可以达到替换的目的。

df = df.replace({'Voice mail plan': d})
df.head()

分组(Groupby)

Pandas 下分组数据的一般形式为:

df.groupby(by=grouping_columns)[columns_to_show].function()

对上述函数的解释:

在下面的例子中,我们根据 Churn 离网率 变量的值对数据进行分组,显示每组的统计数据。

columns_to_show = ['Total day minutes', 'Total eve minutes',
 'Total night minutes']
df.groupby(['Churn'])[columns_to_show].describe(percentiles=[])

和上面的例子类似,只不过这次将一些函数传给 agg(),通过 agg() 方法对分组后的数据进行聚合。

columns_to_show = ['Total day minutes', 'Total eve minutes',

'Total night minutes']

df.groupby(['Churn'])[columns_to_show].agg([np.mean, np.std, np.min, np.max])

汇总表

Pandas 中的透视表定义如下:

透视表(Pivot Table)是电子表格程序和其他数据探索软件中一种常见的数据汇总工具。它根据一个或多个键对数据进行聚合,并根据行和列上的分组将数据分配到各个矩形区域中。

通过 pivot_table() 方法可以建立透视表,其参数如下:

现在,通过 pivot_table() 方法查看不同区号下白天、夜晚、深夜的电话量的均值。

df.pivot_table(['Total day calls', 'Total eve calls', 'Total night calls'],

['Area code'], aggfunc='mean')

pivot_table() 其他的使用方法见 Pandas 百题大冲关的透视表部分。

交叉表(Cross Tabulation)是一种用于计算分组频率的特殊透视表,在 Pandas 中一般使用 crosstab() 方法构建交叉表。

构建一个交叉表查看样本的 Churn 离网率 和 International plan 国际套餐 的分布情况。

pd.crosstab(df['Churn'], df['International plan'])

构建一个交叉表查看 Churn 离网率 和 Voice mail plan 语音邮件套餐 的分布情况。

pd.crosstab(df['Churn'], df['Voice mail plan'], normalize=True)

上述结果表明,大部分用户是忠实用户,同时他们并不使用额外的服务(国际套餐、语音邮件)。

增减 DataFrame 的行列

在 DataFrame 中新增列有很多方法,比如,使用 insert()方法添加列,为所有用户计算总的 Total calls 电话量。

total_calls = df['Total day calls'] + df['Total eve calls'] + 
 df['Total night calls'] + df['Total intl calls']
# loc 参数是插入 Series 对象后选择的列数
# 设置为 len(df.columns)以便将计算后的 Total calls 粘贴到最后一列
df.insert(loc=len(df.columns), column='Total calls', value=total_calls)
df.head()

上面的代码创建了一个中间 Series 实例,即 tatal_calls,其实可以在不创造这个实例的情况下直接添加列。

df['Total charge'] = df['Total day charge'] + df['Total eve charge'] +

df['Total night charge'] + df['Total intl charge']

df.head()

使用 drop() 方法删除列和行。

# 移除先前创捷的列
df.drop(['Total charge', 'Total calls'], axis=1, inplace=True)
# 删除行
df.drop([1, 2]).head()

对上述代码的部分解释:

预测离网率

首先,通过上面介绍的 crosstab() 方法构建一个交叉表来查看 International plan 国际套餐 变量和 Churn 离网率 的相关性,同时使用 countplot() 方法构建计数直方图来可视化结果。

# 加载模块,配置绘图
import matplotlib.pyplot as plt
import seaborn as sns
sns.countplot(x='International plan', hue='Churn', data=df)

上图表明,开通了国际套餐的用户的离网率要高很多,这是一个很有趣的观测结果。也许,国际电话高昂的话费让客户很不满意。

同理,查看 Customer service calls 客服呼叫 变量与 Chunrn 离网率 的相关性,并可视化结果。

pd.crosstab(df['Churn'], df['Customer service calls'], margins=True)

sns.countplot(x='Customer service calls', hue='Churn', data=df)

上图表明,在客服呼叫 4 次之后,客户的离网率显著提升。

为了更好的突出 Customer service call 客服呼叫 和 Churn 离网率 的关系,可以给 DataFrame 添加一个二元属性 Many_service_calls,即客户呼叫超过 3 次(Customer service calls > 3)。看下它与离网率的相关性,并可视化结果。

df['Many_service_calls'] = (df['Customer service calls'] > 3).astype('int')
pd.crosstab(df['Many_service_calls'], df['Churn'], margins=True)
sns.countplot(x='Many_service_calls', hue='Churn', data=df)

现在我们可以创建另一张交叉表,将 Churn 离网率 与 International plan 国际套餐 及新创建的 Many_service_calls 多次客服呼叫 关联起来。

pd.crosstab(df['Many_service_calls'] & df['International plan'], df['Churn'])

上表表明,在客服呼叫次数超过 3 次并且已办理 International Plan 国际套餐 的情况下,预测一名客户不忠诚的准确率(Accuracy)可以达到 85.8%,计算公式如下:

准确率(Accuracy)=frac{TP+TN}{TP+TN+FP+FN}=frac{2841+19}{2841+9+19+464} imes100%

准确率(Accuracy)=TP+TN+FP+FN

TP+TN

​=2841+9+19+464

2841+19

​×100

其中,TP 表示将 True 预测为 True 的数量,TN 表示将 Flase 预测为 Flase 的数量,FP 表示将 Flase 预测为 True 的数量,FN 表示将 True 预测为 Flase 的数量。

相关链接

python3 numpy学习之Pandas工具(一)

展开阅读全文

页面更新:2024-05-02

标签:数据   客服   统计数据   数值   变量   套餐   透视   函数   索引   特征   机器   参数   客户   方法   用户   体育   国际

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top