请选择 进入手机版 | 继续访问电脑版

数据分析师 论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2794|回复: 0

决策树算法的Python实现—基于金融场景实操

[复制链接]

1

主题

1

帖子

35

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
35
发表于 2018-11-15 15:16:17 | 显示全部楼层 |阅读模式
科学总把简单的问题转化的很复杂,在彰显其严谨的同时,也把大部分学习者挡在了门外;本次分享,jacky带你拨开云雾,深入浅出,走进决策树算法的世界!
基本概念
  • 决策树(Decision Tree)
    • 它通过对训练样本的学习,并建立分类规则,然后依据分类规则,对新样本数据进行分类预测,属于有监督学习。
  • 优点
    • 在相对短的时间内,能够对大型数据做出可行且效果良好的结果;
    • 使用者不需要了解很多的背景知识,通过决策树就能够直观形象的了解分类规则;
    • 1)决策树易于理解和实现
    • 2)决策树能够同时处理数值型和非数值型数据

逻辑-类比
决策树分类的思想类似于找对象,例如一个女孩的母亲要给这个女孩介绍男朋友,于是母女俩有了下面的对话:
女儿问:“多大年龄了”;母亲答:“26”
女儿接着问:“长得帅不帅?”;母亲答:“挺帅的。”
女儿问:“收入高不?”;母亲答:“不算很高,中等情况”
女儿问:“是公务员吗?”;母亲答:“是,在财政局上班”
最后,女儿做出决定说:“那好,我去见见!”
这个女孩的决策过程就是典型的分类树决策:
在来看一个金融场景下的举例:客户向银行贷款的时候,银行对用户的贷款资格做一个评估的流程:
2.jpg
首先银行工作人员询问客户是否有房产,如何回答有,则判断客户可以偿还贷款,如果没有则进入第二层的属性判断询问,是否结婚,如何已婚,两个人可以负担的起贷款,则判断为可以偿还,否则进入第三层的属性判断询问,月薪是否超过五千,如果满足,则判断为可以偿还,否则给出不能偿还贷款的结论。
看完上面两个例子,我们可以看出,决策树是非常实用的,下面我们就进入正式案例的讲解;

案例实操
下面以金融场景举例:
(一)情景铺垫
用户购买金融产品的过程“类似于”理财,对于P2P平台来说,严格来说,这个过程称之为撮合。
用户在金融平台上充值购买相应期限和约定利率的金融产品,产品到期后,用户有两种选择一种是提现(赎回),另一种就是复投。
对于用户到期赎回的理解是比较简单的,比如你在2018年1月1日买了6个月10万元定存金融产品,那么在2018年7月1日的时候,你可以选择连本带息全部赎回,当然你也可以在到期日选择在平台还款时,继续投资,这个过程就是复投。
(二)需解决的问题
作为金融平台来说,为了把控风险,保证资金的流动性,都一定要提前预测(预判)未来一段时间内的用户充值和提现金额。
那么,准确预测用户到期是否复投,对于我们金融从业者和管理人员来说,就是特别重要了。
  • 那么,我们可以提出我们亟需解决的问题:
    • 用户到期是否复投,我们该怎样预判?
(三)一个初步模型的建立
场景:预测用户是否复投
注:以下数据源模拟真实数据编撰
1.选择特征变量-featureDate(1)数据源抓取
  1. import pandas
  2. data = pandas.read_csv(
  3. 'file:///Users/apple/Desktop/jacky_reinvest.csv',
  4. encoding='GBK')
  5. print(data)
复制代码


  • jacky注解(1):上面这份数据源已经经过了预处理(数据清理),在实际工作种,我们拿到数据源的第一步一定是做数据清理的。在实操种,是否有预处理这个过程,也是数据科学与传统的统计科学的重要区别之一;本文数据示例,为了分享方便,示例数据还是比较规整的,但在实际工作中,一定不要忘了数据清洗这一步。
  • jacky注解(2): 初始心里预期是一个产品概念,就是用户在购买定存金融产品的时候,可以预先设定是否需要复投,当然这只是一个预设定,在用户购买到赎回这个过程中,我们都可以随时变更。复投模式是一个过去式,也是最终的复投结果,所以下面我们会把这列当作目标变量来处理。
(2)哑变量处理(虚拟变量转化)
需处理的特征变量有:
  • 金融产品
  • 初始心里预期
  • 客户类别
    1. #调用Map方法进行可比较大小虚拟变量的转换
    2. productDict={
    3. '12个月定存':4,'6个月定存':3,'3个月定存':2,'1个月定存':1
    4. }
    5. data['产品Map']=data['金融产品'].map(productDict)

    6. #调用get_dummyColumns方法进行不可比较大小虚拟变量的转换
    7. dummyColumns = ['初始心里预期','客户类别',]
    8. for column in dummyColumns:
    9.     data[column]= data[column].astype('category')

    10. dummiesData=pandas.get_dummies(
    11.     data,
    12.     columns=dummyColumns,prefix=dummyColumns
    13.     ,prefix_sep='_',dummy_na=False,drop_first=False)

    14. #挑选可以建模的变量 featureData
    15. fData = dummiesData[[
    16.     '购买金额','产品Map','初始心里预期_复投','客户类别_VIP用户'
    17. ]]
    复制代码

  • jacky注解(3):关于哑变量更详细的说明,可以参照我《特征工程三部曲》这篇文章,哑变量处理要处理的就是离散变量,购买金额的列,因为都是连续型数据,所以就谈不上虚拟变量处理的。
  • jacky注解(4):离散变量分为有比较关系的离散变量和无比较关系的离散变量,所以需要用map方法和get_dummyColumns方法分别处理;
2.选择目标变量-targerDate
  1. #设定目标变量 targetData
  2. tData = dummiesData['复投模式']
复制代码


  • jacky注解(5):目标变量是我们分析问题的目标和结果,从目标变量既定的历史数据中,我们可以”喂养”数据,继而训练数据,最终达到洞察预测数据的目的。
3.决策树问题的求解与建模
  1. #生成决策树
  2. from sklearn.tree import DecisionTreeClassifier
  3. #设置最大叶子数为8
  4. dtModel = DecisionTreeClassifier(max_leaf_nodes=8)
复制代码


  • jacky注解(6):生成决策树并设置最大叶子树为8,使⽤sklearn的DecisionTreeClassifer类进⾏行决策树问题的求解与建模,关于最大叶子树,可以在看过图形化之后,在反过来理解这部分,就简单的多了,在这里我们可以先理解为这是一个很常用的参数即可。
4.10折交叉验证
  1. #模型检验-交叉验证法
  2. from sklearn.model_selection import cross_val_score
  3. cross_val_score(
  4.     dtModel,
  5.     fData,tData,cv=10
  6. )
复制代码


  • jacky注解(7):从控制台的输出可以看出,每次验证的评分都超过0.9,是一个非常不错的模型,可以用于实践;
5.模型训练
  1. #训练模型
  2. dtModel=dtModel.fit(fData,tData)
复制代码

5.jpg
控制台结果输出:
6.模型可视化
决策树的绘图方法:
  • sklearn.tree.export_graphviz(… …)
    • dtModel:决策树模型
    • out_file:图形数据的输出路径
    • class_names:目标属性的名称,一般用于中文化
    • feature_names:特征属性的名称,一般用于种文化
    • filled= True :是否使用颜色填充
    • rounded=True:边框是否采用圆角边框
    • special_characters: 是否有特殊字符
      1. #模型可视化
      2. import pydotplus
      3. from sklearn.externals.six import StringIO  #生成StringIO对象
      4. from sklearn.tree import export_graphviz

      5. dot_data = StringIO() #把文件暂时写在内存的对象中

      6. export_graphviz(
      7.     dtModel,
      8.     out_file=dot_data,
      9.     class_names=['复投','不复投'],
      10.     feature_names=['购买金额','产品Map',
      11.                    '初始心里预期_不复投','客户类别_VIP用户'],
      12.     filled=True,rounded=True,special_characters=True
      13. )
      14. graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
      15. graph.write_png('shujudata.png')
      复制代码
      3.jpg
  • jacky注解(8):需要提前安装graphviz软件
  • jacky注解(9):最大叶子树,一般设置为8个,因为叶子数太多,决策树的结构越复杂,太复杂的结构就会导致训练过度的问题,因此,在决策树算法中,设置合适叶子数是非常重要的。
  • jacky注解(10):gini值越接近于0,那么结果就越显而易见,如果越接近于1,那么结果就越难判定;
完整代码展示
  1. #---author:朱元禄---

  2. import pandas
  3. data = pandas.read_csv(
  4. 'file:///Users/apple/Desktop/jacky_reinvest.csv',
  5. encoding='GBK'
  6. )

  7. #调用Map方法进行可比较大小虚拟变量的转换
  8. productDict={
  9. '12个月定存':4,'6个月定存':3,'3个月定存':2,'1个月定存':1
  10. }
  11. data['产品Map']=data['金融产品'].map(productDict)

  12. #调用get_dummyColumns方法进行可比较大小虚拟变量的转换
  13. dummyColumns = ['初始心里预期','客户类别',]
  14. for column in dummyColumns:
  15.     data[column]= data[column].astype('category')

  16. dummiesData=pandas.get_dummies(
  17.     data,
  18.     columns=dummyColumns,prefix=dummyColumns
  19.     ,prefix_sep='_',dummy_na=False,drop_first=False)

  20. #挑选可以建模的变量 featureData
  21. fData = dummiesData[[
  22.     '购买金额','产品Map','初始心里预期_复投','客户类别_VIP用户'
  23. ]]

  24. #设定目标变量 targetData
  25. tData = dummiesData['复投模式']

  26. #生成决策树
  27. from sklearn.tree import DecisionTreeClassifier

  28. #设置最大叶子数为8
  29. dtModel = DecisionTreeClassifier(max_leaf_nodes=8)

  30. '''
  31. #模型检验-交叉验证法
  32. from sklearn.model_selection import cross_val_score

  33. cross_val_score(
  34.     dtModel,
  35.     fData,tData,cv=10
  36. )
  37. '''
  38. #训练模型
  39. dtModel=dtModel.fit(fData,tData)

  40. #模型可视化
  41. import pydotplus
  42. from sklearn.externals.six import StringIO  #生成StringIO对象
  43. from sklearn.tree import export_graphviz

  44. dot_data = StringIO() #把文件暂时写在内存的对象中

  45. export_graphviz(
  46.     dtModel,
  47.     out_file=dot_data,
  48.     class_names=['复投','不复投'],
  49.     feature_names=['购买金额','产品Map',
  50.                    '初始心里预期_不复投','客户类别_VIP用户'],
  51.     filled=True,rounded=True,special_characters=True
  52. )
  53. graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
  54. graph.write_png('shujudata.png')
复制代码

注: 之后jacky会推出视频教学,敬请关注,数据源请在Python数据交流区中下载

3.jpg
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|航航科技-乐之数据云-数据分析部落社群

GMT+8, 2021-6-19 05:58 , Processed in 0.162663 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表