热线电话:13121318867

登录
首页精彩阅读作为文科生,我是如何转行数据挖掘工程师的 | 附电信用户实战案例
作为文科生,我是如何转行数据挖掘工程师的 | 附电信用户实战案例
2022-02-23
收藏
作为文科生,我是如何转行<a href='/map/shujuwajue/' style='color:#000;font-size:inherit;'>数据挖掘</a>工程师的 | 附电信用户实战案例

随着大数据的时代的来临,各个行业都受到了数据分析不同程度的影响和作用。尤其是在电信行业,数据分析已经逐渐成为电信运营商的战略优势之一。

大家好,我是一名CDA持证人,今天想跟大家分享一下,我如何从文科生转行成为了一名电信行业的数据挖掘工程师。

主要内容分成以下三块:

  • 第一部分我作为文科生转行数据挖掘的历程;
  • 第二部分关于目前从事数据挖掘,主要针对商业数据挖掘所需要掌握的一些技能;
  • 第三部分案例分享:数据分析思维如何应用到电信行业,电信用户流失预测模型

01、文科生转行数据挖掘工程师的历程

首先看到第一部分的内容,也就是我的转行历程。

我高中那会儿读的是文科,大学期间学习了社会学专业。在本科期间,我也接触过一些统计学的知识,线性代数等知识也学过,但当时对这些学科将来的用途并不是很清楚。

参加工作后,最初我从事产品运营的相关工作。在工作过程中,我接触到了数据分析相关的内容。当时我感觉自己工作内容比较杂,也没有拿得出来的技能。

我认为数据分析很有前景,无论是文科生还是理科生都可以学,学起来也比较有趣,内容不枯燥,所以我渐渐开始学习数据分析。

这里我列了几个对我比较关键的节点,这些对我未来的工作有了较大的影响。

作为文科生,我是如何转行<a href='/map/shujuwajue/' style='color:#000;font-size:inherit;'>数据挖掘</a>工程师的 | 附电信用户实战案例

首先就是学数据挖掘,用的是SPSS Modeler。比较容易上手,入门也比较简单。SPSS Modeler虽然很好用,但其实很多时候不能满足数据清洗的一些需求,也有一些劣势,比如算法更新很慢,只有比较常规的算法,如果想用比较先进的算法,还是开源的软件提供的比较多。

之后我学习了Python,比较容易上手,语法也比较简洁。通过大量练习掌握了爬虫、数据清洗数据可视化等技能点。Python基本能满足日常工作的需求。

第三个节点是我学习了SQL和统计知识。SQL本身基础的知识不是特别复杂,然后主要靠练习,包括统计的一些知识,这也是我在之后的工作中不断学习的。

02、从事数据挖掘技能需求

目前我目前从事的是数据挖掘的相关工作,接下来讲一下工作中所需要的一些技能。

作为文科生,我是如何转行<a href='/map/shujuwajue/' style='color:#000;font-size:inherit;'>数据挖掘</a>工程师的 | 附电信用户实战案例

这部分可以分为硬技能和软技能。

硬技能

硬技能这里我分为理论基础、算法能力、分析工具和通用工具。下面具体来看一看。理论基础中统计知识是不可或缺的。后面的概率论、线性代数、微积分其实是跟偏算法相关。

算法方面主要需要一些机器学习深度学习的算法。比如分类、回归、聚类等一些比较基础的算法。

不同于算法工程师对算法的要求会比较高,像偏业务的数据挖掘的岗位,对算法的要求没那么高。你能够做到理解算法的基本原理跟应用场景,能够应用工具去实现它,能够解读算法最后的结果,也就差不多了,对数学的要求也并不太高。

关于深度学习,现在数据挖掘等算法岗也相对内卷,如果你不会也不了解深度学习就有点说不过去了,这方面可以了解一下。还需要掌握一些工具库,现在深度学习的工具库比较多,也有一些比较简便的工具库能协助实现相关的功能。

然后看到分析工具。其实目前主要用的也就是SQL跟Python,主要是看你公司的数据量,如果数据量不是很大的话,基础的一些SQL知识就够了,可能关系数据库就可以了,包括在单机里面,去运行Python也可以的;但是如果公司的数据量特别大的话,比如我目前是在Hadoop的平台做一些数据分析跟数据挖掘。如果本身的数据量就比较大,可能会用到Hive数据仓库等。

再看到建模工具,目前其实主流是Python,还有集成了Pyspark,这是用得比较多的。然后建模的话,考虑到数据量Python在80%的情况上都是够用的。

关于通用工具,Excel跟PPT都是比较基础的。下面这个Shell是开发工具,很多时候会涉及到一些开发的工作,比如说标签表的开发,然后就会用到Shell结合ETL自动化平台,调用需要的脚本进行自动化的运行。就相当于是每天它会自动的跑一些脚本,而不需要去手工或者是在单机操作,这些都是在平台上面自动完成的。

软技能

软技能这块简单看一下,包括像业务的理解,比如你进入任何一个行业,你前几个月会多花时间了解该行业的业务表,业务涉及的一些内容,核心的盈利业务是哪些。还有一些通用的能力,比如沟通、汇报能力等,因为你经常会需要将模型和分析报告讲给别人听,因此这些能力也是十分重要的。还有学习能力。数据行业的迭代比较快,需要有持续学习的能力。

03、数据分析项目实操

用Python创建电信客户流失模型

下面我们再来看一下数据分析在电信行业的应用,目前国内运营商运用大数据主要有五方面:

(1)网络管理和优化,包括基础设施建设优化和网络运营管理和优化;

(2)市场与精准营销,包括客户画像、关系链研究、精准营销、实时营销和个性化推荐;

(3)客户关系管理,包括客服中心优化和客户生命周期管理;

(4)企业运营管理,包括业务运营监控和经营分析;

(5)数据商业化指数据对外商业化。

接下来,今天给大家演示一下,把数据分析应用到电信行业的具体案例,这里教大家用Python写一个电信用户流失预测模型。

01、商业理解

流失客户是指那些曾经使用过产品或服务,由于对产品失去兴趣等种种原因,不再使用产品或服务的顾客。

电信服务公司、互联网服务提供商、保险公司等经常使用客户流失分析和客户流失率作为他们的关键业务指标之一,因为留住一个老客户的成本远远低于获得一个新客户。

预测分析使用客户流失预测模型,通过评估客户流失的风险倾向来预测客户流失。由于这些模型生成了一个流失概率排序名单,对于潜在的高概率流失客户,他们可以有效地实施客户保留营销计划。

下面我们就教你如何用Python写一个电信用户流失预测模型,以下是具体步骤和关键代码。

02、数据理解

此次分析数据来自于IBM Sample Data Sets,统计自某电信公司一段时间内的消费数据。共有7043笔客户资料,每笔客户资料包含21个字段,其中1个客户ID字段,19个输入字段及1个目标字段-Churn(Yes代表流失,No代表未流失),输入字段主要包含以下三个维度指标:用户画像指标、消费产品指标、消费信息指标。字段的具体说明如下:

作为文科生,我是如何转行<a href='/map/shujuwajue/' style='color:#000;font-size:inherit;'>数据挖掘</a>工程师的 | 附电信用户实战案例

03、数据读入和概览

首先导入所需包。

# 数据处理
import numpy as np
import pandas as pd
# 可视化
import matplotlib.pyplot as plt
import seaborn as sns
import plotly as py
import plotly.graph_objs as go
import plotly.figure_factory as ff
# 前处理
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
# 建模
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn import tree
from sklearn.ensemble import RandomForestClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.neural_network import MLPClassifier
from sklearn.svm import SVC
from lightgbm import LGBMClassifier
from xgboost import XGBClassifier
# 模型评估
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import confusion_matrix, accuracy_score, classification_report
from sklearn.metrics import roc_auc_score, roc_curve, scorer
from sklearn.metrics import recall_score, precision_score, f1_score, cohen_kappa_score
pd.set_option('display.max_columns'None)


读入数据集

df = pd.read_csv('./Telco-Customer-Churn.csv')
df.head()

作为文科生,我是如何转行<a href='/map/shujuwajue/' style='color:#000;font-size:inherit;'>数据挖掘</a>工程师的 | 附电信用户实战案例

04、数据初步清洗

首先进行初步的数据清洗工作,包含错误值和异常值处理,并划分类别型和数值型字段类型,其中清洗部分包含:

  • OnlineSecurity、OnlineBackup、DeviceProtection、TechSupport、StreamingTV、StreamingMovies:错误值处理
  • TotalCharges:异常值处理
  • tenure:自定义分箱
  • 定义类别型和数值型字段

# 错误值处理
repl_columns = ['OnlineSecurity''OnlineBackup''DeviceProtection',
'TechSupport','StreamingTV''StreamingMovies']
for i in repl_columns:
df[i] = df[i].replace({'No internet service' : 'No'})
# 替换值SeniorCitizen
df["SeniorCitizen"] = df["SeniorCitizen"].replace({1"Yes"0"No"})
# 替换值TotalCharges
df['TotalCharges'] = df['TotalCharges'].replace(' ', np.nan)
# TotalCharges空值:数据量小,直接删除
df = df.dropna(subset=['TotalCharges'])
df.reset_index(drop=True, inplace=True
# 重置索引
# 转换数据类型
df['TotalCharges'] = df['TotalCharges'].astype('float')
# 转换tenure
def transform_tenure(x):
if x <= 12:
return 'Tenure_1'
elif x <= 24:
return 'Tenure_2'
elif x <= 36:
return 'Tenure_3'
elif x <= 48:
return 'Tenure_4'
elif x <= 60:
return 'Tenure_5'
else:
return 'Tenure_over_5'
df['tenure_group'] = df.tenure.apply(transform_tenure)
# 数值型和类别型字段
Id_col = ['customerID']
target_col = ['Churn']
cat_cols = df.nunique()[df.nunique() < 10].index.tolist()
num_cols = [i for i in df.columns if i not in cat_cols + Id_col]
print('类别型字段:n', cat_cols)
print('-' * 30)
print('数值型字段:n', num_cols)

类别型字段
[
'gender''SeniorCitizen''Partner''Dependents''PhoneService''MultipleLines''InternetService''OnlineSecurity''OnlineBackup''DeviceProtection''TechSupport''StreamingTV''StreamingMovies''Contract''PaperlessBilling''PaymentMethod''Churn''tenure_group']

------------------------------

数值型字段
['tenure''MonthlyCharges''TotalCharges']

05、探索性分析

对指标进行归纳梳理,分用户画像指标,消费产品指标,消费信息指标。探索影响用户流失的关键因素。

1. 目标变量Churn分布

作为文科生,我是如何转行<a href='/map/shujuwajue/' style='color:#000;font-size:inherit;'>数据挖掘</a>工程师的 | 附电信用户实战案例

经过初步清洗之后的数据集大小为7032条记录,其中流失客户为1869条,占比26.6%,未流失客户占比73.4%。

df['Churn'].value_counts()
No 5163
Yes 1869
NameChurndtypeint64


trace0 = go.Pie(labels=df['Churn'].value_counts().index,
values=df['Churn'].value_counts().values,
hole=.5,
rotation=90,
marker=dict(colors=['rgb(154,203,228)''rgb(191,76,81)'],
line=dict(color='white', width=1.3))
)
data = [trace0]
layout = go.Layout(title='目标变量Churn分布')
fig = go.Figure(data=data, layout=layout)
py.offline.plot(fig, filename='./html/整体流失情况分布.html')

2.性别

作为文科生,我是如何转行<a href='/map/shujuwajue/' style='color:#000;font-size:inherit;'>数据挖掘</a>工程师的 | 附电信用户实战案例

分析可见,男性和女性在客户流失比例上没有显著差异。

plot_bar(input_col='gender', target_col='Churn', title_name='性别与是否流失的关系')

3. 老年用户

作为文科生,我是如何转行<a href='/map/shujuwajue/' style='color:#000;font-size:inherit;'>数据挖掘</a>工程师的 | 附电信用户实战案例

老年用户流失比例更高,为41.68%,比非老年用户高近两倍,此部分原因有待进一步探讨。

plot_bar(input_col='SeniorCitizen', target_col='Churn', title_name='老年用户与是否流失的关系')

4. 是否有配偶

作为文科生,我是如何转行<a href='/map/shujuwajue/' style='color:#000;font-size:inherit;'>数据挖掘</a>工程师的 | 附电信用户实战案例

从婚姻情况来看,数据显示,未婚人群中流失的比例比已婚人数高出13%。

plot_bar(input_col='Partner', target_col='Churn', title_name='是否有配偶与是否流失的关系')

5. 上网时长

作为文科生,我是如何转行<a href='/map/shujuwajue/' style='color:#000;font-size:inherit;'>数据挖掘</a>工程师的 | 附电信用户实战案例

经过分析,这方面可以得出两个结论:

  • 用户的在网时长越长,表示用户的忠诚度越高,其流失的概率越低;
  • 新用户在1年内的流失率显著高于整体流失率,为47.68%。


plot_bar(input_col='tenure_group', target_col='Churn', title_name='在网时长与是否流失的关系')

6. 付款方式

作为文科生,我是如何转行<a href='/map/shujuwajue/' style='color:#000;font-size:inherit;'>数据挖掘</a>工程师的 | 附电信用户实战案例

支付方式上,支付上,选择电子支票支付方式的用户流失最高,达到45.29%,其他三种支付方式的流失率相差不大。

pd.crosstab(df['PaymentMethod']df['Churn'])

作为文科生,我是如何转行<a href='/map/shujuwajue/' style='color:#000;font-size:inherit;'>数据挖掘</a>工程师的 | 附电信用户实战案例

plot_bar(input_col='PaymentMethod', target_col='Churn', title_name='付款方式与是否流失关系')

7. 月费用

作为文科生,我是如何转行<a href='/map/shujuwajue/' style='color:#000;font-size:inherit;'>数据挖掘</a>工程师的 | 附电信用户实战案例

整体来看,随着月费用的增加,流失用户的比例呈现高高低低的变化,月消费80-100元的用户相对较高。

plot_histogram(input_col='MonthlyCharges', title_name='月费用与是否流失关系')

8. 数值型属性相关性

作为文科生,我是如何转行<a href='/map/shujuwajue/' style='color:#000;font-size:inherit;'>数据挖掘</a>工程师的 | 附电信用户实战案例

从相关性矩阵图可以看出,用户的往来期间和总费用呈现高度相关,往来期间越长,则总费用越高。月消费和总消费呈现显著相关。

plt.figure(figsize=(1510))
sns.heatmap(df.corr(), linewidths=0.1, cmap='tab20c_r', annot=True)
plt.title('数值型属性的相关性', fontdict={'fontsize''xx-large''fontweight':'heavy'})
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.show()

06、特征选择

使用统计检定方式进行特征筛选。

# 删除tenure
df = df.drop('tenure', axis=1)
from feature_selection import Feature_select
# 划分X和y
X = df.drop(['customerID', 'Churn'], axis=1)
y = df['Churn']
fs = Feature_select(num_method='anova', cate_method='kf', pos_label='Yes')
x_sel = fs.fit_transform(X, y)


2020 09:30:02 INFO attr select success!
After select attr: ['DeviceProtection''MultipleLines''OnlineSecurity''TechSupport''tenure_group''PaperlessBilling''InternetService''PaymentMethod''SeniorCitizen''MonthlyCharges''Dependents''Partner''Contract''StreamingTV''TotalCharges''StreamingMovies''OnlineBackup']

经过特征筛选,gender和PhoneService字段被去掉。

07、建模前处理

python中,为满足建模需要,一般需要对数据做以下处理:

  • 对于二分类变量,编码为0和1;
  • 对于多分类变量,进行one_hot编码;
  • 对于数值型变量,部分模型如KNN神经网络、Logistic需要进行标准化处理。


# 筛选变量
select_features = x_sel.columns
# 建模数据
df_model = pd.concat([df['customerID'], df[select_features], df['Churn']], axis=1)
Id_col = ['customerID']
target_col = ['Churn']
# 分类型
cat_cols = df_model.nunique()[df_model.nunique() < 10].index.tolist()
# 二分类属性
binary_cols = df_model.nunique()[df_model.nunique() == 2].index.tolist()
# 多分类属性
multi_cols = [i for i in cat_cols if i not in binary_cols]
# 数值型
num_cols = [i for i in df_model.columns if i not in cat_cols + Id_col]
# 二分类-标签编码
le = LabelEncoder()
for i in binary_cols:
df_model[i] = le.fit_transform(df_model[i])
# 多分类-哑变量转换
df_model = pd.get_dummies(data=df_model, columns=multi_cols)
df_model.head()

作为文科生,我是如何转行<a href='/map/shujuwajue/' style='color:#000;font-size:inherit;'>数据挖掘</a>工程师的 | 附电信用户实战案例

08、模型建立和评估

首先使用分层抽样的方式将数据划分训练集和测试集。

# 重新划分
X = df_model.drop(['customerID''Churn'], axis=1)
y = df_model['Churn']
# 分层抽样
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0, stratify=y)
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
#修正索引
for i in [X_train, X_test, y_train, y_test]:
i.index = range(i.shape[0])


(5625, 31) (1407, 31) (5625,) (1407,)


# 保存标准化训练和测试数据
st = StandardScaler()
num_scaled_train = pd.DataFrame(st.fit_transform(X_train[num_cols]), columns=num_cols)
num_scaled_test = pd.DataFrame(st.transform(X_test[num_cols]), columns=num_cols)
X_train_sclaed = pd.concat([X_train.drop(num_cols, axis=1), num_scaled_train], axis=1)
X_test_sclaed = pd.concat([X_test.drop(num_cols, axis=1), num_scaled_test], axis=1)

然后建立一系列基准模型并比较效果。

作为文科生,我是如何转行<a href='/map/shujuwajue/' style='color:#000;font-size:inherit;'>数据挖掘</a>工程师的 | 附电信用户实战案例

假如我们关注roc指标,从模型表现效果来看,Naive Bayes效果最好。

我们也可以对模型进行进一步优化,比如对决策树参数进行调优。

parameters = {'splitter': ('best','random'),
'criterion': ("gini","entropy"),
"max_depth": [*range(320)],
}
clf = DecisionTreeClassifier(random_state=25)
GS = GridSearchCV(clf, parameters, scoring='f1', cv=10)
GS.fit(X_train, y_train)
print(GS.best_params_)
print(GS.best_score_)


{'criterion''entropy''max_depth': 5, 'splitter''best'}
0.585900839405024

数据分析咨询请扫描二维码

最新资讯
更多
客服在线
立即咨询