python 数据分析 电信_电信用户流失数据分析

#coding: utf-8

## 电信客户流失预测

### 1、导入数据

importnumpy as npimportpandas as pdimportos#https://catboost.ai/docs/concepts/python-reference_catboost_predict.html#导入相关的包

importmatplotlib.pyplot as pltimportseaborn as snsfrom pylab importrcParamsimportmatplotlib.cm as cmimportsklearnfrom sklearn importpreprocessingfrom sklearn.preprocessing import LabelEncoder #编码转换

from sklearn.preprocessing importStandardScalerfrom sklearn.model_selection importStratifiedShuffleSplitfrom sklearn.ensemble import RandomForestClassifier #随机森林

from sklearn.svm import SVC, LinearSVC #支持向量机

from sklearn.linear_model import LogisticRegression #逻辑回归

from sklearn.neighbors import KNeighborsClassifier #KNN算法

from sklearn.naive_bayes import GaussianNB #朴素贝叶斯

from sklearn.tree import DecisionTreeClassifier #决策树分类器

from xgboost importXGBClassifierfrom catboost importCatBoostClassifierfrom sklearn.ensemble importAdaBoostClassifierfrom sklearn.ensemble importGradientBoostingClassifierfrom sklearn.metrics importclassification_report, precision_score, recall_score, f1_scorefrom sklearn.metrics importconfusion_matrixfrom sklearn.model_selection importGridSearchCVfrom sklearn.metrics importmake_scorerfrom sklearn.ensemble importVotingClassifierfrom sklearn.decomposition importPCAfrom sklearn.cluster importKMeansfrom sklearn.metrics importsilhouette_scoreimportwarnings

warnings.filterwarnings('ignore')

get_ipython().magic('matplotlib inline')#读取数据文件

telcom=pd.read_csv('F:\\python\\电信用户数据\\WA_Fn-UseC_-Telco-Customer-Churn.csv')### 2、查看数据集信息

telcom.head(10)#查看数据集大小

telcom.shape#获取数据类型列的描述统计信息

telcom.describe()### 3、数据清洗

#查找缺失值

pd.isnull(telcom).sum()

telcom["Churn"].value_counts()#数据集中有5174名用户没流失,有1869名客户流失,数据集不均衡。

telcom.info()#TotalCharges表示总费用,这里为对象类型,需要转换为float类型

#convert_objects已经弃用 ,注意astype如果遇到空值,转换成数值型就会报错

telcom['TotalCharges'].replace(' ',np.nan,inplace=True)

telcom['TotalCharges']=telcom['TotalCharges'].astype(np.float64) #convert_numeric=True表示强制转换数字(包括字符串),不可转换的值变为NaN

telcom["TotalCharges"].dtypes#再次查找是否存在缺失值

pd.isnull(telcom["TotalCharges"]).sum()#这里存在11个缺失值,由于数量不多我们可以直接删除这些行

#删除缺失值所在的行

telcom.dropna(inplace=True)

telcom.shape#数据归一化处理#对Churn 列中的值 Yes和 No分别用 1和 0替换,方便后续处理

telcom['Churn'].replace(to_replace = 'Yes', value = 1,inplace =True)

telcom['Churn'].replace(to_replace = 'No', value = 0,inplace =True)

telcom['Churn'].head()

telcom['Churn'].replace(to_replace='Yes', value=1, inplace=True)

telcom['Churn'].replace(to_replace='No', value=0, inplace=True)

telcom['Churn'].head()### 4、数据可视化呈现

#查看流失客户占比

"""画饼图参数:

labels (每一块)饼图外侧显示的说明文字

explode (每一块)离开中心距离

startangle 起始绘制角度,默认图是从x轴正方向逆时针画起,如设定=90则从y轴正方向画起

shadow 是否阴影

labeldistance label 绘制位置,相对于半径的比例, 如<1则绘制在饼图内侧

autopct 控制饼图内百分比设置,可以使用format字符串或者format function

'%1.1f'指小数点前后位数(没有用空格补齐)

pctdistance 类似于labeldistance,指定autopct的位置刻度

radius 控制饼图半径"""churnvalue=telcom["Churn"].value_counts()

labels=telcom["Churn"].value_counts().index

rcParams["figure.figsize"]=6,6plt.pie(churnvalue,labels=labels,colors=["whitesmoke","yellow"], explode=(0.1,0),autopct='%1.1f%%', shadow=True)

plt.title("Proportions of Customer Churn")

plt.show()#性别、老年人、配偶、亲属对流客户流失率的影响

f, axes = plt.subplots(nrows=2, ncols=2, figsize=(10,10))

plt.subplot(2,2,1)

gender=sns.countplot(x="gender",hue="Churn",data=telcom,palette="Pastel2") #palette参数表示设置颜色,这里设置为主题色Pastel2

plt.xlabel("gender")

plt.title("Churn by Gender")

plt.subplot(2,2,2)

seniorcitizen=sns.countplot(x="SeniorCitizen",hue="Churn",data=telcom,palette="Pastel2")

plt.xlabel("senior citizen")

plt.title("Churn by Senior Citizen")

plt.subplot(2,2,3)

partner=sns.countplot(x="Partner",hue="Churn",data=telcom,palette="Pastel2")

plt.xlabel("partner")

plt.title("Churn by Partner")

plt.subplot(2,2,4)

dependents=sns.countplot(x="Dependents",hue="Churn",data=telcom,palette="Pastel2")

plt.xlabel("dependents")

plt.title("Churn by Dependents")#提取特征

charges=telcom.iloc[:,1:20]#对特征进行编码

"""离散特征的编码分为两种情况:

1、离散特征的取值之间没有大小的意义,比如color:[red,blue],那么就使用one-hot编码

2、离散特征的取值有大小的意义,比如size:[X,XL,XXL],那么就使用数值的映射{X:1,XL:2,XXL:3}"""corrDf= charges.apply(lambdax: pd.factorize(x)[0])

corrDf .head()#构造相关性矩阵

corr =corrDf.corr()

corr#使用热地图显示相关系数

'''heatmap 使用热地图展示系数矩阵情况

linewidths 热力图矩阵之间的间隔大小

annot 设定是否显示每个色块的系数值'''plt.figure(figsize=(20,16))

ax= sns.heatmap(corr, xticklabels=corr.columns, yticklabels=corr.columns,

linewidths=0.2, cmap="YlGnBu",annot=True)

plt.title("Correlation between variables")#结论:从上图可以看出,互联网服务、网络安全服务、在线备份业务、设备保护业务、技术支持服务、网络电视和网络电影之间存在较强的相关性,多线业务和电话服务之间也有很强的相关性,并且都呈强正相关关系。

#使用one-hot编码

tel_dummies = pd.get_dummies(telcom.iloc[:,1:21])

tel_dummies.head()

telcom.info()#电信用户是否流失与各变量之间的相关性

plt.figure(figsize=(15,8))

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

plt.title("Correlations between Churn and variables")#由图上可以看出,变量gender 和 PhoneService 处于图形中间,其值接近于 0 ,这两个变量对电信客户流失预测影响非常小,可以直接舍弃。

#网络安全服务、在线备份业务、设备保护业务、技术支持服务、网络电视、网络电影和无互联网服务对客户流失率的影响

covariables=["OnlineSecurity", "OnlineBackup", "DeviceProtection", "TechSupport", "StreamingTV", "StreamingMovies"]

fig,axes=plt.subplots(nrows=2,ncols=3,figsize=(16,10))for i, item inenumerate(covariables):

plt.subplot(2,3,(i+1))

ax=sns.countplot(x=item,hue="Churn",data=telcom,palette="Pastel2",order=["Yes","No","No internet service"])

plt.xlabel(str(item))

plt.title("Churn by"+str(item))

i=i+1plt.show()#由上图可以看出,在网络安全服务、在线备份业务、设备保护业务、技术支持服务、网络电视和网络电影六个变量中,没有互联网服务的客户流失率值是相同的,都是相对较低。# #这可能是因为以上六个因素只有在客户使用互联网服务时才会影响客户的决策,这六个因素不会对不使用互联网服务的客户决定是否流失产生推论效应。

#签订合同方式对客户流失率的影响

sns.barplot(x="Contract",y="Churn", data=telcom, palette="Pastel1", order= ['Month-to-month', 'One year', 'Two year'])

plt.title("Churn by Contract type")#由图上可以看出,签订合同方式对客户流失率影响为:按月签订 > 按一年签订 > 按两年签订,这可能表明,设定长期合同对留住现有客户更有效。

#付款方式对客户流失率的影响

plt.figure(figsize=(10,5))

sns.barplot(x="PaymentMethod",y="Churn", data=telcom, palette="Pastel1", order= ['Bank transfer (automatic)', 'Credit card (automatic)', 'Electronic check','Mailed check'])

plt.title("Churn by PaymentMethod type")#由图上可以看出,在四种支付方式中,使用Electronic check的用户流流失率最高,其他三种支付方式基本持平,因此可以推断电子账单在设计上影响用户体验。

### 5、数据预处理

#由前面结果可知,CustomerID表示每个客户的随机字符,对后续建模不影响,我这里选择删除CustomerID列;gender 和 PhoneService 与流失率的相关性低,可直接忽略。

telcomvar=telcom.iloc[:,2:20]

telcomvar.drop("PhoneService",axis=1, inplace=True)#提取ID

telcom_id = telcom['customerID']

telcomvar.head()#对客户的职位、月费用和总费用进行去均值和方差缩放,对数据进行标准化

"""标准化数据,保证每个维度的特征数据方差为1,均值为0,使得预测结果不会被某些维度过大的特征值而主导。"""scaler= StandardScaler(copy=False)#fit_transform()的作用就是先拟合数据,然后转化它将其转化为标准形式

scaler.fit_transform(telcomvar[['tenure','MonthlyCharges','TotalCharges']])#tranform()的作用是通过找中心和缩放等实现标准化

telcomvar[['tenure','MonthlyCharges','TotalCharges']]=scaler.transform(telcomvar[['tenure','MonthlyCharges','TotalCharges']])#使用箱线图查看数据是否存在异常值

plt.figure(figsize = (8,4))

numbox= sns.boxplot(data=telcomvar[['tenure','MonthlyCharges','TotalCharges']], palette="Set2")

plt.title("Check outliers of standardized tenure, MonthlyCharges and TotalCharges")#由以上结果可以看出,在三个变量中不存在明显的异常值

#查看对象类型字段中存在的值

defuni(columnlabel):print(columnlabel,"--" ,telcomvar[columnlabel].unique()) #unique函数去除其中重复的元素,返回唯一值

telcomobject=telcomvar.select_dtypes(['object'])for i inrange(0,len(telcomobject.columns)):

uni(telcomobject.columns[i])#综合之前的结果来看,在六个变量中存在No internet service,即无互联网服务对客户流失率影响很小,这些客户不使用任何互联网产品,因此可以将No internet service 和 No 是一样的效果,可以使用 No 替代 No internet service

telcomvar.replace(to_replace='No internet service', value='No', inplace=True)

telcomvar.replace(to_replace='No phone service', value='No', inplace=True)for i inrange(0,len(telcomobject.columns)):

uni(telcomobject.columns[i])#使用Scikit-learn标签编码,将分类数据转换为整数编码

deflabelencode(columnlabel):

telcomvar[columnlabel]=LabelEncoder().fit_transform(telcomvar[columnlabel])for i inrange(0,len(telcomobject.columns)):

labelencode(telcomobject.columns[i])for i inrange(0,len(telcomobject.columns)):

uni(telcomobject.columns[i])### 6、构建模型

#### (1)建立训练数据集和测试数据集

"""我们需要将数据集拆分为训练集和测试集以进行验证。

由于我们所拥有的数据集是不平衡的,所以最好使用分层交叉验证来确保训练集和测试集都包含每个类样本的保留人数。

交叉验证函数StratifiedShuffleSplit,功能是从样本数据中随机按比例选取训练数据(train)和测试数据(test)

参数 n_splits是将训练数据分成train/test对的组数,可根据需要进行设置,默认为10

参数test_size和train_size是用来设置train/test对中train和test所占的比例

参数 random_state控制是将样本随机打乱"""X=telcomvar

y=telcom["Churn"].values

sss=StratifiedShuffleSplit(n_splits=5, test_size=0.2, random_state=0)print(sss)print("训练数据和测试数据被分成的组数:",sss.get_n_splits(X,y))#建立训练数据和测试数据

for train_index, test_index insss.split(X, y):print("train:", train_index, "test:", test_index)

X_train,X_test=X.iloc[train_index], X.iloc[test_index]

y_train,y_test=y[train_index], y[test_index]#输出数据集大小

print('原始数据特征:', X.shape,'训练数据特征:',X_train.shape,'测试数据特征:',X_test.shape)print('原始数据标签:', y.shape,'训练数据标签:',y_train.shape,'测试数据标签:',y_test.shape)#### (2)选择机器学习算法

#使用分类算法,这里选用10种分类算法

Classifiers=[["Random Forest",RandomForestClassifier()],

["Support Vector Machine",SVC()],

["LogisticRegression",LogisticRegression()],

["KNN",KNeighborsClassifier(n_neighbors=5)],

["Naive Bayes",GaussianNB()],

["Decision Tree",DecisionTreeClassifier()],

["AdaBoostClassifier", AdaBoostClassifier()],

["GradientBoostingClassifier", GradientBoostingClassifier()],

["XGB", XGBClassifier()],

["CatBoost", CatBoostClassifier(logging_level='Silent')]

]#### (3)训练模型

Classify_result=[]

names=[]

prediction=[]for name,classifier inClassifiers:

classifier=classifier

classifier.fit(X_train,y_train)

y_pred=classifier.predict(X_test)

recall=recall_score(y_test,y_pred)

precision=precision_score(y_test,y_pred)

f1score=f1_score(y_test,y_pred,average='binary')

class_eva=pd.DataFrame([recall,precision,f1score])

Classify_result.append(class_eva)

name=pd.Series(name)

names.append(name)

y_pred=pd.Series(y_pred)

prediction.append(y_pred)#### (4)评估模型

#评估模型

"""召回率(recall)的含义是:原本为对的当中,预测为对的比例(值越大越好,1为理想状态)

精确率、精度(precision)的含义是:预测为对的当中,原本为对的比例(值越大越好,1为理想状态)

F1分数(F1-Score)指标综合了Precision与Recall的产出的结果

F1-Score的取值范围从0到1的,1代表模型的输出最好,0代表模型的输出结果最差。"""names=pd.DataFrame(names)

names=names[0].tolist()

result=pd.concat(Classify_result,axis=1)

result.columns=names

result.index=["recall","precision","f1score"]

result#综上所述,在10种分类算法中朴素贝叶斯(Naive Bayes)的F1分数最大为63.31%,所以使用朴素贝叶斯模型效果最好。

### 7、实施方案

#预测数据集特征(由于没有提供预测数据集,这里选取后10行作为需要预测的数据集)

pred_X = telcomvar.tail(10)#提取customerID

pre_id = telcom_id.tail(10)#使用朴素贝叶斯方法,对预测数据集中的生存情况进行预测

model =GaussianNB()

model.fit(X_train,y_train)

pred_y=model.predict(pred_X)#预测结果

predDf = pd.DataFrame({'customerID':pre_id, 'Churn':pred_y})

predDf

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构与算法(Python) 一、引入概念 1-01算法引入 1-02 时间复杂度与大O表示法 1-03-最坏时间复杂度与计算规则 1-04-常见时间复杂度与大小关系 1-05-代码执行时间测量模块 1-06-Python列表类型不同操作的时间效率 1-07-Python列表与字典操作的时间复杂度 1-08-数据结构引入 二、顺序表 2-01 内存、类型本质、连续存储 recv 2-02 基本顺序表与元素外围顺序表 recv 2-03 顺序表的一体式结构与分离式结构 recv 2-04 顺序表数据区替换与扩充 recv 三、栈 3-01 栈与队列的概念 3-02 栈的实现 3-03 队列与双端队列的实现 四、链表 4-01 链表的提出 4-02 单链表的ADT模型 4-03 Python中变量标识的本质 4-04 单链表及结点的定义代码 4-05 单链表的判空、长度、遍历与尾部添加结点的代码实现 4-06 单链表尾部添加和在指定位置添加 4-07 单链表查找和删除元素 4-08 单链表与顺序表的对比 4-09 单向循环链表遍历和求长度 4-10 单向循环链表添加元素 4-11 单向循环链表删除元素 4-12 单向循环链表删除元素复习及链表扩展 4-13 双向链表及添加元素 4-14 双向链表删除元素 五、排序与搜索 5-01 排序算法的稳定性 5-02 冒泡排序及实现 5-03 选择排序算法及实现 5-04 插入算法 5-05 插入排序 5-06 插入排序2 5-07 希尔排序 5-08 希尔排序实现 5-09 快速排序 5-10 快速排序实现1 (1) 5-10 快速排序实现1 5-11 快速排序实现2 5-12 归并排序 5-13 归并排序 代码执行流程 5-14 归并排序时间复杂度及排序算法复杂度对比 5-15 二分查找 5-16 二分查找时间复杂度 六、树和树的算法 6-01 树的概念 6-02 二叉树的概念 6-03 二叉树的广度优先遍历 6-04 二叉树的实现 6-05 二叉树的先序、中序、后序遍历 6-06 二叉树由遍历确定一棵树 ———————————————— 版权声明:本文为CSDN博主「dwf1354046363」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/dwf1354046363/article/details/119832814
Python中进行电信客户流失预测分析,通常会涉及到数据预处理、特征工程、模型选择和训练、以及结果评估。这里是一个简化的示例,我们将使用scikit-learn库来演示线性回归模型作为预测工具。首先,确保你已经安装了必要的库,如pandas, numpy, scikit-learn等。 ```python # 导入所需库 import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_squared_error, r2_score from sklearn.preprocessing import StandardScaler # 加载数据(假设你有一个CSV文件) data = pd.read_csv('telecom_customer_data.csv') # 数据预处理 # 检查并处理缺失值 data = data.dropna() # 或者使用其他方法填充缺失值 # 将分类变量转换为数值(例如,使用OneHotEncoder或LabelEncoder) data = pd.get_dummies(data) # 定义目标变量(客户流失) target_column = 'churn' X = data.drop(target_column, axis=1) y = data[target_column] # 划分数据集(70%训练集,30%测试集) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) # 特征缩放(可选) scaler = StandardScaler() X_train = scaler.fit_transform(X_train) X_test = scaler.transform(X_test) # 创建并训练模型 model = LinearRegression() model.fit(X_train, y_train) # 预测 y_pred = model.predict(X_test) # 评估模型性能 mse = mean_squared_error(y_test, y_pred) r2 = r2_score(y_test, y_pred) print(f"Mean Squared Error: {mse}") print(f"R^2 Score: {r2}") # 相关问题-- 1. 在实际应用中,如何选择合适的特征对模型性能影响更大? 2. 如何处理非线性关系,如果电信数据包含非线性特征? 3. 进一步提升模型性能时,你可能会尝试哪些机器学习算法或深度学习模型? ``` 这个例子是一个基础框架,实际分析可能需要根据具体的数据和业务需求进行调整。你可以根据上述代码扩展到更复杂的特征工程、使用不同模型、或者探索交叉验证和网格搜索等高级技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值