Kaggle案例精选——电信客户流失预测(Telecom Customer Churn Prediction)Part Two:数据标准化;主成分分析机器可视化;相关分析与热力图;客户画像与雷达图

继续之前的内容。

4 Data Preprocessing:数据预处理+其他变量信息展示

4.1 数据预处理

# 数据预处理
from sklearn.preprocessing import LabelEncoder, StandardScaler

# 客户ID列
Id_col = ['customerID']
# 目标列
target_col = ['Churn']
# 分类变量列
cat_cols = telcom.nunique()[telcom.nunique()<6].keys().tolist()
cat_cols = [x for x in cat_cols if x not in target_col]
# 数值变量列
num_cols = [x for x in telcom.columns if x not in cat_cols+target_col+Id_col]
# 二元类型列
bin_cols = telcom.nunique()[telcom.nunique()==2].keys().tolist()
# 多元类型变量列
multi_cols = [i for i in cat_cols if i not in bin_cols]

# 对二元类型列的表情进行解析(label encoding)
le = LabelEncoder()
for i in bin_cols:
    telcom[i] = le.fit_transform(telcom[i])
    
# 复制多元类型列
telcom = pd.get_dummies(data=telcom, columns=multi_cols)

# 对数值型数据进行标准化
std = StandardScaler()
scaled = std.fit_transform(telcom[num_cols])
scaled = pd.DataFrame(scaled, columns=num_cols)

# 将原始的数值型列删除,将进行标准化之后的数值列与原数据表合并
df_telcom_og = telcom.copy()
telcom = telcom.drop(columns=num_cols, axis=1)
telcom = telcom.merge(scaled, left_index=True, right_index=True, how='left')

以上代码无结果输出

  • 作用是将变量按照不同的类型进行划分,进行数值型数据的标准化操作
  • 为下文的变量信息总览、PCA(主成分分析)和相关分析做铺垫

4.2 变量信息总览

summary = (df_telcom_og[[i for i in df_telcom_og.columns if i not in Id_col]].describe().transpose().reset_index())
summary = summary.rename(columns={
    
    'index':'feature'})
summary = np.around(summary, 3)

val_list = [summary['feature'], summary['count'], summary['mean'], summary['std'],
            summary['min'], summary['25%'], summary['50%'], summary['75%'], summary['max']]
trace = go.Table(header=dict(values=summary.columns.tolist(),
                             line=dict(color=['#506784']),
                             fill=dict(color=['#119DFF'])),
                 cells=dict(values=val_list,
                            line=dict(color=['#506784']),
                            fill=dict(color=['lightgrey', '#F5F8FF'])),
                 columnwidth=[200, 60, 100, 100, 60, 60, 80, 80, 80])
layout = go.Layout(dict(title='Variable Summary'))
fig = go.Figure(data=[trace], layout=layout)
py.iplot(fig)

#%%
# 删除tenure_group变量
# 为之后绘图做准备,删除无用的列。
telcom = telcom.drop(columns=['tenure_group_Tenure_0_12', 'tenure_group_Tenure_12_24', 'tenure_group_Tenure_24_48',
                              'tenure_group_Tenure_48_60', 'tenure_group_Tenure_gt_60'], axis=1)

结果输出:
输出一个包含定义信息的表格:
变量自定义信息总览

4.3 变量相关系数矩阵(热力图)

# 计算相关性
corr = telcom.corr()
# 提取矩阵标签
matrix_cols = corr.columns.tolist()
# 转化为array数据类型
corr_array = np.array(corr)

# 绘图
trace = go.Heatmap(z=corr_array, x=matrix_cols, y=matrix_cols, 
                   colorscale='Viridis', colorbar=dict(
        title='Pearson Correlation Coefficient', 
        titleside='right'
                   ))
layout = go.Layout(dict(title='Correlation Matrix for variables', 
                        autosize=False, height=720, width=800, 
                        margin=dict(r=0, l=210, t=25, b=210), 
                        yaxis=dict(tickfont=dict(size=9)), 
                        xaxis=dict(tickfont=dict(size=9))))
data = [trace]
fig = go.Figure(data=data, layout=layout)
py.iplot(fig)

结果输出:

  • 不知道为什么,我的热力图优点漂移,这里直接贴上原文的结果图:
    变量相关性矩阵热力图
  • 正相关性中表现较为突出的变量有:总消费与存续期间之间的相关系数为0.826,正相关性很强;总消费与月消费相关系数为0.651, 相关性较强;月消费与开通光纤互联网服务之间的相关系数为0.78,相关性很强;此外,月消费与开通数字电影和数字电视之间的相关性均略微大于0.62,存在较强相关性。
  • 负相关性中比较值得注意的变量有:签约月合同与存续期间之间的相关系数为-0.65,负相关性较强;月消费与是否开通互联网服务存在较强负相关性,系数为-0.76.

4.4 PCA分析及结果可视化

from sklearn.decomposition import PCA

pca = PCA(n_components=2)

X = telcom[[i for i in telcom.columns if i not in Id_col+target_col]]
Y = telcom[target_col+Id_col]

principal_components = pca.fit_transform(X)
pca_data = pd.DataFrame(principal_components, columns=['PC1', 'PC2'])
pca_data = pca_data.merge(Y, left_index=True, right_index=True, how='left')
pca_data['Churn'] = pca_data['Churn'].replace({
    
    1:'Churn', 0:'Not Churn'})

def pca_scatter(target, color):
    tracer = go.Scatter(x=pca_data[pca_data['Churn']==target]['PC1'],
                        y=pca_data[pca_data['Churn']==target]['PC2'],
                        name=target, mode='markers',
                        marker=dict(color=color, line=dict(width=0.5), symbol='diamond-open'),
                        text='Customer Id:' + pca_data[pca_data['Churn']==target]['customerID'])
    return tracer
layout = go.Layout(dict(title='Visualising data with prinsipal components',
                        plot_bgcolor='rgb(243,243,243)',
                        paper_bgcolor='rgb(243,243,243)',
                        xaxis=dict(gridcolor='rgb(255,255,255)',
                                   title='principal component 1',
                                   zerolinewidth=1, ticklen=5, gridwidth=2),
                        yaxis=dict(gridcolor='rgb(255,255,255)',
                                   title='principal component 2',
                                   zerolinewidth=1, ticklen=5, gridwidth=2),
                        height=600))
trace1 = pca_scatter('Churn', 'red')
trace2 = pca_scatter('Not Churn', 'royalblue')
data = [trace2, trace1]
fig = go.Figure(data=data, layout=layout)
py.iplot(fig)

结果输出:
PCA结果可视化展现

  • PCA试图提取两个主成分(PC1, PC2)来解释数据
  • 从上图可以看出,使用两个主成分来绘制的散点图,按照是否流失进行分类后,散点的交集还是比较多。但是散点密度较大的部分还是可以适当区分开来。
  • 以上代码给出的是PCA的提取及可视化方法,并代表提取出来的2个主成分就是区分是否流失的最有变量个数。

4.5 客户情况的二元变量分布情况(雷达图)——可用于客户画像可视化展现

# 分离二元类型列
bi_cs = telcom.nunique()[telcom.nunique()==2].keys()
dat_rad = telcom[bi_cs]

# 绘制流失和未流失客户的雷达图
def plot_radar(df, aggregate, title):
    data_frame = df[df['Churn']==aggregate]
    data_frame_x = data_frame[bi_cs].sum().reset_index()
    data_frame_x.columns = ['feature', 'yes']
    data_frame_x['no'] = data_frame.shape[0] - data_frame_x['yes']
    data_frame_x = data_frame_x[data_frame_x['feature'] != 'Churn']

    # 计算yes出现的次数
    trace1 = go.Scatterpolar(r=data_frame_x['yes'].values.tolist(),
                             theta=data_frame_x['feature'].tolist(),
                             fill='toself', name='count of 1\'s', mode='markers+lines',
                             marker=dict(size=5))
    # 计算no的次数
    trace2 = go.Scatterpolar(r=data_frame_x['no'].values.tolist(),
                             theta=data_frame_x['feature'].tolist(),
                             fill='toself', name='count of 0\'s', mode='markers+lines',
                             marker=dict(size=5))
    layout = go.Layout(dict(polar=dict(radialaxis=dict(visible=True,
                                                       side='counterclockwise',
                                                       showline=True,
                                                       linewidth=2,
                                                       tickwidth=2,
                                                       gridcolor='white',
                                                       gridwidth=2),
                                       angularaxis=dict(tickfont=dict(size=10),
                                                        layer='below traces'),
                                       bgcolor='rgb(243,243,243)'),
                            paper_bgcolor='rgb(243,243,243)',
                            title=title, height=700))
    data = [trace2, trace1]
    fig = go.Figure(data=data, layout=layout)
    py.iplot(fig)

# 绘图
plot_radar(dat_rad, 1, 'Churn - Customers')
plot_radar(dat_rad, 0, 'Non Churn - Customers')

代码解释

  • bi_cs用于存储telcom数据集中二元分类变量(即,是或者否)的值。
  • count of 0’s是指二元分类变量中为No的记录的计数;counts of 1‘s则为Yes的记录条数计数。
  • 按照是否流失客户进行分组,看看流失与未流失客户中不同二元分类的个数的计数有多少。绘制成雷达图。

结果输出
已流失客户中的二元分类变量的雷达图

  • 已流失客户中,未开通电话服务;签约方式不为1、2年续约, 未开通网络服务的客户比较多。
  • 已流失客户中,签约方式为每月签约、开通电话服务、使用无纸化账单的客户比较多。
  • 首先,通讯公司的电话服务为基本业务,因而不论客户是否流失,一般都使用电话服务。
  • 其次,采用短期签约方式的客户,可能仅为使用公司产品,后期流失可能性较大。
  • 未开通网络服务的客户更容易流失,可见提高网络服务质量能够增加客户忠诚度。
  • 还需要注意客户对于无纸化账单递送方式的信息反馈,可能是由于无纸化账单容易使客户忽略支出情况,造成公司不合理扣费误解,导致客户流失。此处还需要进行额外调查。
    未流失客户中二元变量雷达图
  • 从是否开通业务的阴影面积看,未开通服务的客户占大多数
  • 跟其他人合伙共同使用产品的人数比未合伙的客户多。可见,如果业务涉及多人,就能够大大增加产品的粘性。——人还是懒惰的。

转载地址:

kaggle典型客户流失数据分析预测精品案例!

数据集下载地址:

数据集,更多notebook浏览地址

猜你喜欢

转载自blog.csdn.net/Haoyu_xie/article/details/108572708