ITPub博客

首页 > 数据库 > 数据库开发技术 > Python中应用决策树算法预测客户等级

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

原创 数据库开发技术 作者:阿黎逸阳的代码 时间:2020-12-28 07:00:00 0 删除 编辑

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

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

    1.1 加载库

    1.2 加载数据

  2. 数据预处理

    2.1 分析标签列数据分布

    2.2  特征列数据分析

    2.3  年收入列正则化处理

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

  3. 模型训练与效果评估

  4. 完整代码



一、加载数据

 1  加载库

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

import osimport numpy as npimport pandas as pd
os.chdir(r'F:\公众号\4.决策树和随机森林')


 2  加载数据

接着用read_csv函数读取数据。

ori_date = pd.read_csv("customer.csv")  #读取数据

得到结果如下:

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

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


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

 1  分析标签列的数据分布

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

ori_date['member_card'].value_counts()
得到结果如下:

说明10281个顾客中,有5703个顾客被标记为青铜客户、2420个顾客被标记为普通客户、1198个顾客被标记为金牌客户、960个顾客被标记为银牌客户。
显然这是一个多分类问题,且这一列的数据类型为int64(整形),没有缺失值,所以不需要对该列进行缺失值处理。


 2  特征列数据分析

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

ori_date.columns
得到结果如下:

可以发现第一列是顾客编号,后面的列是顾客姓名、地址、电话号码、国家、受教育程度、年收入、性别、孩子数目、拥有汽车数目等。
本文挑选年收入、受教育程度、孩子数目和拥有汽车辆数做为特征变量(自变量)进行建模。感兴趣的同学可以自己尝试增删变量,看看模型结果会有什么变化。
在建模之前先来看看入模特征的数据特点,首先是年收入列,具体语句如下:
ori_date['yearly_income'].value_counts()
得到结果如下:

从结果中可以发现,年收入这一列存在$符号、空格、-等字符,需进行特殊处理。
再来看看受教育程度列的数据特点,具体语句如下:
ori_date['education'].value_counts()
得到结果如下:

可以发现这一列是文本型,如果要入模,需转换成数值型。
接着来看看孩子数目列的数据特点,具体语句如下:
ori_date['total_children'].value_counts()
得到结果如下:

可以发现这一列是数值型,且没有空值,无需处理,可直接入模。
最后来看下拥有汽车数目列的数据特点,具体语句如下:
ori_date['num_cars_owned'].value_counts()
得到结果如下:

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

 3  年收入列正则化处理

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

ori_date['yearly_income'] = ori_date['yearly_income'].str.replace('[^0-9]', '')ori_date['yearly_income'].value_counts()
得到结果如下:

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

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

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编码

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

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

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中使用如下语句可以实现:
from sklearn.preprocessing import OneHotEncoder
encoding = OneHotEncoder()newData = encoding.fit_transform(np.vstack(ori_date["education"].values)).todense()frame_new = pd.DataFrame(newData)
得到结果如下:



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

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

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

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  模型训练与效果评估

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

from sklearn.tree import DecisionTreeClassifierfrom 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左右,感兴趣的同学可以自己尝试调整入模变量和算法,看看能不能优化这个结果。


四、完整代码

本文全量代码如下:

import osimport numpy as npimport pandas as pdfrom sklearn.preprocessing import OneHotEncoderfrom sklearn.tree import DecisionTreeClassifierfrom 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实现。

往期回顾:

3D星空图V2版
520表白代码合集
用python绘制皮卡丘
叮—请查收你的圣诞礼物

娱乐圈排行榜动态条形图绘制

扫一扫关注我

19967879837

投稿微信号、手机号

原文作者:阿黎逸阳的代码;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2020-02-15

  • 博文量
    282
  • 访问量
    130883