前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python中应用决策树算法预测客户等级

Python中应用决策树算法预测客户等级

作者头像
阿黎逸阳
发布2021-01-11 11:09:44
1.4K0
发布2021-01-11 11:09:44
举报
文章被收录于专栏:阿黎逸阳的代码

机器学习越来越多地在企业应用,本文跟大家分享一个采用python,应用决策树算法对跨国食品超市顾客等级进行预测的具体案例。

如果想先行了解决策树算法原理,可以阅读本公众号的文章决策树-ID3算法和C4.5算法

本文目录

  1. 加载数据 1.1 加载库 1.2 加载数据
  2. 数据预处理 2.1 分析标签列数据分布 2.2 特征列数据分析 2.3 年收入列正则化处理 2.4 受教育程度列One-hot编码
  3. 模型训练与效果评估
  4. 完整代码

一、加载数据

1 加载库

首先加载pandas库,并设置数据读取文件夹。

代码语言:javascript
复制
import os
import numpy as np
import pandas as pd

os.chdir(r'F:\公众号\4.决策树和随机森林')

2 加载数据

接着用read_csv函数读取数据。

代码语言:javascript
复制
ori_date = pd.read_csv("customer.csv")  #读取数据

得到结果如下:

本文数据10281行、28列,其中每一行代表一个顾客。每一列代表一个特征,其中member_card列表示标签列。

注:如需本文数据,请到公众号中回复“决策树预测客户等级”即可免费获取。

二、数据预处理

在建模之前需要对标签列进行分析、入模特征进行挑选处理。先来看看标签列的数据特征吧。

1 分析标签列的数据分布

首先用value_counts函数看下标签列的分布情况,并查看该列是否存在缺失值和有问题的值。

代码语言:javascript
复制
ori_date['member_card'].value_counts()

得到结果如下:

说明10281个顾客中,有5703个顾客被标记为青铜客户、2420个顾客被标记为普通客户、1198个顾客被标记为金牌客户、960个顾客被标记为银牌客户。

显然这是一个多分类问题,且这一列的数据类型为int64(整形),没有缺失值,所以不需要对该列进行缺失值处理。

2 特征列数据分析

首先来看下数据框中有哪些列,具体语句如下:

代码语言:javascript
复制
ori_date.columns

得到结果如下:

可以发现第一列是顾客编号,后面的列是顾客姓名、地址、电话号码、国家、受教育程度、年收入、性别、孩子数目、拥有汽车数目等。

本文挑选年收入、受教育程度、孩子数目和拥有汽车辆数做为特征变量(自变量)进行建模。感兴趣的同学可以自己尝试增删变量,看看模型结果会有什么变化。

在建模之前先来看看入模特征的数据特点,首先是年收入列,具体语句如下:

代码语言:javascript
复制
ori_date['yearly_income'].value_counts()

得到结果如下:

从结果中可以发现,年收入这一列存在$符号、空格、-等字符,需进行特殊处理。

再来看看受教育程度列的数据特点,具体语句如下:

代码语言:javascript
复制
ori_date['education'].value_counts()

得到结果如下:

可以发现这一列是文本型,如果要入模,需转换成数值型。

接着来看看孩子数目列的数据特点,具体语句如下:

代码语言:javascript
复制
ori_date['total_children'].value_counts()

得到结果如下:

可以发现这一列是数值型,且没有空值,无需处理,可直接入模。

最后来看下拥有汽车数目列的数据特点,具体语句如下:

代码语言:javascript
复制
ori_date['num_cars_owned'].value_counts()

得到结果如下:

可以发现这一列同样是数值型,且没有空值,无需处理,可直接入模。

3 年收入列正则化处理

一种办法是只保留年收入列中的数值作为入模变量,具体语句如下:

代码语言:javascript
复制
ori_date['yearly_income'] = ori_date['yearly_income'].str.replace('[^0-9]', '')
ori_date['yearly_income'].value_counts()

得到结果如下:

其中.str.replace('[^0-9]', '')表示把年收入中非数值字符替换成空,即只保留数值字符。

另一种办法是只保留年收入下限作为入模变量,具体语句如下:

代码语言:javascript
复制
ori_date['yearly_income'] = ori_date['yearly_income'].str.split(" ").str[0].str.replace('[^0-9]', '')
ori_date['yearly_income'].value_counts()

得到结果如下:

可以发现第二种方法只保留了收入下限。

本文采用的是第一种方法,感兴趣的同学可以试试第二种办法,看看两种方法得到的变量入模后有多少区别。

4 受教育程度列One-hot编码

从上文的分析中可以发现,受教育程度列是文本列,需要转换成数值才可以入模。

有些同学可能会说,直接该列的文本转换成相应的数值即可,具体语句如下:

代码语言:javascript
复制
from sklearn.preprocessing import LabelEncoder

encoding = LabelEncoder()
encoding.fit(ori_date['education'])
education_new = encoding.transform(ori_date["education"])
education_new = pd.DataFrame(education_new)
education_new.iloc[:,0].value_counts()

得到结果如下:

对比原始数据:

可以发现Bachelors Degree(学士学历)、Graduate Degree(研究生学历)、High School Degree (高中学历)、Partial College(大学在读)、Partial High School(高中在读)分别用数值0、1、2、3、4替换。

根据常识可知在学历上,学士学历和大学在读相比学士学历和高中学历更相近。在数值上0和2相比0和3更相近。因此用数值随机替换后表现的却是高中学历和学士学历更相近,显然不合理。

所以在建模时一般采用的是One-hot编码,避免由于数值替换带来的关联性。

为了大家能更好地理解One-hot编码,给大家引入一个实例进行说明。

假设现在有8名顾客,每名顾客都有对应的受教育程度(原始列)。由于要把受教育程度入模,所以要把文本型的数据转换成数值型的。

首先找出受教育程度的所有类别(本例中是五种),把这五种受教育程度每一个都当成一列,如果顾客受教育程度是该种类别的就标记为1,否则标记为0。

从上图可以看出,顾客5的受教育程度是Graduate Degree,所以在该列标记为1,其它列标记为0,同理可得顾客6的标记方法。

One-hot编码会把原始的一列扩展成多列,在python中使用如下语句可以实现:

代码语言:javascript
复制
from sklearn.preprocessing import OneHotEncoder

encoding = OneHotEncoder()
newData = encoding.fit_transform(np.vstack(ori_date["education"].values)).todense()
frame_new = pd.DataFrame(newData)

得到结果如下:

三、模型训练

在第二节对数据进行了预处理,本节正式进入模型训练。在模型训练之前,要把特征变量(自变量)和标签变量(因变量)区分出来。

1 区分特征变量和标签变量

区分特征变量和标签变量的语句如下:

代码语言:javascript
复制
X = pd.merge(ori_date[["yearly_income", "total_children", "num_cars_owned"]],frame_new, left_index = True, right_index = True)  #特征变量
y = ori_date['member_card']  #标签变量

其中特征变量X由原始数据中的年收入、孩子数目、拥有汽车辆数,以及受教育程度扩展的One-hot编码组成。

标签变量y由member_card构成。

2 模型训练与效果评估

本文采用决策树算法进行建模,并用交叉验证的方法给出模型评分,具体代码如下:

代码语言:javascript
复制
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score

clf = DecisionTreeClassifier()
scores = cross_val_score(clf, X, y, scoring = 'accuracy')
print(np.mean(scores))

其中,clf=DecisionTreeClassifier表示分类器采用的决策树算法。

cross_val_score表示对自变量X和因变量y采用clf对应的算法,进行交叉验证。每一次都有一列真实值和预测值,两者进行对比算出这次训练的得分,依次保存到scores中。

最终的分数采用多次结果的加权平均来表示。

得到结果如下:

可以发现采用决策树算法进行分类,最终得分0.74左右,感兴趣的同学可以自己尝试调整入模变量和算法,看看能不能优化这个结果。

四、完整代码

本文全量代码如下:

代码语言:javascript
复制
import os
import numpy as np
import pandas as pd
from sklearn.preprocessing import OneHotEncoder
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score

#数据读取
os.chdir(r'F:\公众号\4.决策树和随机森林')
ori_date = pd.read_csv("customer.csv")
#年收入正则化处理
ori_date['yearly_income'] = ori_date['yearly_income'].str.replace('[^0-9]', '')
#ori_date['yearly_income'] = ori_date['yearly_income'].str.split(" ").str[0].str.replace('[^0-9]', '')
#受教育程度列One-hot编码
encoding = OneHotEncoder()
newData = encoding.fit_transform(np.vstack(ori_date["education"].values)).todense()
frame_new = pd.DataFrame(newData)
#确定特征变量和标签变量
X = pd.merge(ori_date[["yearly_income", "total_children", "num_cars_owned"]],frame_new, left_index = True, right_index = True)  #特征变量
y = ori_date['member_card']  #标签变量
#模型训练和效果评估
clf = DecisionTreeClassifier()
scores = cross_val_score(clf, X, y, scoring = 'accuracy')
print(np.mean(scores))

决策树算法在python中实现已全部讲解完毕,感兴趣的同学可以跟着本文的步骤,自己用python实现。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-12-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 阿黎逸阳的代码 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档