用决策树建模预测谁是潜在的客户,这里将客户分为两种类型,根据训练数据中的判定条件,构建决策树,构建决策树分为以下几个步骤:

  • 决策树的节点结构
    class decisionnode 中包含了5个数据项,分别是

    1. col: 代表该节点用训练数据的哪一列作为判断条件
    2. value: 以cols条件的value值作为切分节点,value若为数值型属性,则按照大于小于value进行切分;若Wie标称属性,则按照等于和不等于进行切分。总之,根据cols和value的值将父节点切分为两个叶子节点。
    3. result: 表示叶子节点中所含各种类型的训练数据的字典,除叶节点外,其余节点中该项均为None.
    4. tb: 当判断条件为真时分裂得到的左子树
    5. fb: 当判断条件为假时分裂得到的右子树
  • 衡量节点的类别混合程度:使用熵不纯度和GINI不纯度。熵为0时代表纯度很高,只有一种类别,熵不为0时表示有类别混杂。熵值越大,表示混合程度越高。

  • 获取当前节点的最优划分属性。CART决策树采用GINI指数,而ID3和C4.5决策树则采用信息增益和信息增益比来决定最优的划分属性。方法是遍历所有的划分属性,遍历该划分属性的所有可能取值,计算在该划分属性和划分取值下将父节点划分为两个子节点后的信息增益。取所有划分属性和划分取值中信息增益最大的划分父节点。依次类推,递归的构建决策树。仅当信息增益不再大于0时,节点的分裂结束。
    注意,此种方法下,决策树将会完全生长,完全生长的决策树将会引发过拟合问题,故而CART决策树有后剪枝步骤。

  • 剪枝: 剪枝的过程就是对有相同父节点的两个叶节点进行检查,若将其合并,判断熵值的增加值是否小于某一特定的阈值,如果小于,则将两个叶节点删除,将父节点作为叶节点,其包含的样本为原来两个叶节点包含样本的和。如果熵值的增加值小于该阈值,则结束剪枝过程。可以看出,剪枝的结果依赖于阈值的选择,如果阈值太大,则剪枝后的决策树将会很小。

  • 附:当要使用决策树作回归分析时,应当将衡量最优划分条件的标准从熵值的减少量改为方差的减少量。即一个叶节点中如果样本的方差很小,表示该叶子节点中的样本数值都很接近,表示该节点的切分效果很好。

代码及注释如下:

# -*- coding:utf-8 -*-
__author__ = 'Bai Chenjia'# 训练数据,每行前四项代表特征,最后一项代表类别
my_data = [['slashdot', 'USA', 'yes', 18, 'None'],['google', 'France', 'yes', 23, 'Premium'],['digg', 'USA', 'yes', 24, 'Basic'],['kiwitobes', 'France', 'yes', 23, 'Basic'],['google', 'UK', 'no', 21, 'Premium'],['(direct)', 'New Zealand', 'no', 12, 'None'],['(direct)', 'UK', 'no', 21, 'Basic'],['google', 'USA', 'no', 24, 'Premium'],['slashdot', 'France', 'yes', 19, 'None'],['digg', 'USA', 'no', 18, 'None'],['google', 'UK', 'no', 18, 'None'],['kiwitobes', 'UK', 'no', 19, 'None'],['digg', 'New Zealand', 'yes', 12, 'Basic'],['slashdot', 'UK', 'no', 21, 'None'],['google', 'UK', 'yes', 18, 'Basic'],['kiwitobes', 'France', 'yes', 19, 'Basic']]# 决策树的节点结构class decisionnode:# 决策树节点初始化def __init__(self, col=-1, value=None, results=None, tb=None, fb=None):self.col = col   # 代表该节点用训练数据的哪一列作为判断条件self.value = value   # 表示col判断条件为value时为真,不为value为假,以此划分节点self.results = results  # 表示某一节点中各种类别的字典。除叶节点外,其余节点该项都未Noneself.tb = tb  # 当value为真时的子树self.fb = fb  # 当value为假时的子树# 拆分数据集合,rows为父节点所有的数据,column代表根据第column的判断条件拆分,等于value则为真,否则为假
def divideset(rows, column, value):set1, set2 = [], []# 如果是数值型数据,则以大于小于拆分if isinstance(value, int) or isinstance(value, float):for row in rows:if row[column] >= value:set1.append(row)else:set2.append(row)# 如果是标称数据,则以等于或不等于进行拆分else:for row in rows:if row[column] == value:set1.append(row)else:set2.append(row)return (set1, set2)# 待统计的数据集rows,返回一个字典,键为类别,值为该类别的数据个数
# 返回的字典用于下一步计算数据的混杂程度
def uniquecounts(rows):results = {}for row in rows:results.setdefault(row[len(row) - 1], 0)results[row[len(row) - 1]] += 1return results# 计算rows中不同类别的 熵 不纯度
# 熵为0时表示纯度很高,只有一种类别。熵值越高,表明混杂程度越高
def entropy(rows):from math import loglog2 = lambda x: log(x) / log(2)results = uniquecounts(rows)# 此处计算开始时的熵值ent = 0.0for r in results.keys():p = float(results[r]) / len(rows)ent -= p * log2(p)return ent# 以递归方式构造决策树
def buildtree(rows, scoref=entropy):if len(rows) == 0:return decisionnode()# 计算信息增益,从而确定划分属性,信息增益为父节点的熵值减去两个子节点熵值的加权平均和# 信息增益越大,表明选择该属性作为划分越好best_gain = 0.0best_criteria = Nonebest_sets = Nonecolumn_count = len(rows[0]) - 1# 循环列,循环判定条件for col in range(column_count):# 统计该判定条件所有的valuevalues = []for row in rows:if row[col] not in values:values.append(row[col])# 父节点的熵e1 = scoref(rows)for value in values:set1, set2 = divideset(rows, col, value)e2 = scoref(set1)e3 = scoref(set2)p = float(len(set1)) / float(len(rows))gain = e1 - p * e2 - (1 - p) * e3# 记录信息增益最高的划分条件if best_gain < gain:best_gain = gainbest_criteria = (col, value)best_sets = (set1, set2)# 创建子分支if best_gain > 0:trueBranch = buildtree(best_sets[0])falseBranch = buildtree(best_sets[1])  # 递归继续划分子节点return decisionnode(col=best_criteria[0], value=best_criteria[1], results=None,tb=trueBranch, fb=falseBranch)# 信息增益为0或负数,表明应该停止分割,该节点为叶节点,叶节点的results不为空else:return decisionnode(results=uniquecounts(rows))# 将建立的决策树以文本方式打印输出
def printtree(tree, indent=''):# 这是一个叶节点吗if tree.results is not None:print str(tree.results)else:# 打印判断条件print str(tree.col) + ':' + str(tree.value) + '? '# 打印分支print indent + 'T->',printtree(tree.tb, indent+'  ')print indent + 'F->',printtree(tree.fb, indent+'  ')# 对新观测的数据进行分类
def classify(observation, tree):# 如果不是叶节点if tree.results is None:if isinstance(tree.value, int) or isinstance(tree.value, float):# 大于if observation[tree.col] >= tree.value:return classify(observation, tree.tb)else:return classify(observation, tree.fb)else:if observation[tree.col] == tree.value:return classify(observation, tree.tb)else:return classify(observation, tree.fb)else:return tree.results# 剪枝,剪枝的过程就是对具有相同父节点的两个叶节点进行检查,判断如果将其合并,熵的增加量是否会小于某一
# 阈值,如果小于,则将这两个叶节点合并成一个节点,否则结束
def prune(tree, mingain):# 如果分支不是叶节点,则对其进行剪枝操作if tree.tb.results is None:prune(tree.tb, mingain)  # 向下递归,直到到达叶节点为止if tree.fb.results is None:prune(tree.fb, mingain)  # 向下递归,知道到达叶节点为止# 如果两个子分支都是叶节点,则考察能否进行剪枝if tree.tb.results is not None and tree.fb.results is not None:tb, fb = [], []for v, c in tree.tb.results.items():tb += [[v]] * cfor v, c in tree.fb.results.items():fb += [[v]] * c# 计算合并后熵的减少情况delta = entropy(tb + fb) - (entropy(tb) + entropy(fb))/2if delta < mingain:tree.tb, tree.fb = None, Nonetree.results = uniquecounts(tb + fb)if __name__ == '__main__':"""# 测试函数dividesetset1, set2 = divideset(my_data, 2, 'yes')print set1[:]print set2[:]"""# 测试uniquecounts"""results = uniquecounts(my_data)for key, value in results.items():print key, value""""""e = entropy(my_data)print e"""# 建立决策树tree = buildtree(my_data)# 打印输出决策树#printtree(tree)# 预测#res = classify(['(direct)', 'USA', 'yes', 5], tree)#print "结果: ", res.items()[:]# 剪枝prune(tree, 1.0)printtree(tree)

集体智慧编程——使用决策树发现潜在客户相关推荐

  1. 《集体智慧编程》读书笔记2

    最近重读<集体智慧编程>,这本当年出版的介绍推荐系统的书,在当时看来很引领潮流,放眼现在已经成了各互联网公司必备的技术. 这次边阅读边尝试将书中的一些Python语言例子用C#来实现,利于 ...

  2. 《集体智慧编程》读书笔记4

    最近重读<集体智慧编程>,这本当年出版的介绍推荐系统的书,在当时看来很引领潮流,放眼现在已经成了各互联网公司必备的技术. 这次边阅读边尝试将书中的一些Python语言例子用C#来实现,利于 ...

  3. 《集体智慧编程》数学公式

    这篇博客的目的主要是为了记录这些公式,取自原书附录B. 1.欧几里得距离(Euclidean Distance) 用途:计算距离,衡量相似度 公式: 代码实现: def euclidean(p, q) ...

  4. 《集体智慧编程》——第一章导读

    为什么80%的码农都做不了架构师?>>>    什么是集体智慧 其含义是指:为了长早新的想法,而将一群人的行为.偏好或思想组合在一起. 完成这项工作的一种最为基础的方法,便是使用调查 ...

  5. 《集体智慧编程》读书笔记10

    最近重读<集体智慧编程>,这本当年出版的介绍推荐系统的书,在当时看来很引领潮流,放眼现在已经成了各互联网公司必备的技术. 这次边阅读边尝试将书中的一些Python语言例子用C#来实现,利于 ...

  6. 《集体智慧编程》笔记(1 / 12):集体智慧导言

    文章目录 什么是集体智慧 什么是机器学习 机器学习的局限性 真实生活中的例子 学习型算法的其他用途 小结 Netflix, Google都适用了先进算法,将来自不同人群的数据加以组合,进而得出新的结论 ...

  7. 《集体智慧编程》笔记(2 / 12):提供推荐

    Making Recommendations 文章目录 协作型过滤 搜集偏好 寻找相近的用户 欧几里得距离评价 皮尔逊相关度评价 应该选用哪一种相似性度量方法 为评分者打分 推荐物品 匹配相似商品 构 ...

  8. 《集体智慧编程》第九章

    1.P210 函数scaledata()在运行时会报错: AttributeError: 'list' object has no attribute 'data' 这是由于函数scaledata() ...

  9. 读书笔记《集体智慧编程》Chapter 2 : Make Recommendations

    本章概要 本章主要介绍了两种协同过滤(Collaborative Filtering)算法,用于个性化推荐: 基于用户的协同过滤(User-Based Collaborative Filtering, ...

最新文章

  1. 根据测试路径自动生成测试用例_自拍教程75Python 根据测试用例选择测试资源
  2. 使用Linq判断DataTable数据是否重复
  3. Bootstrap全局css样式_表格
  4. 64位win7使用debug的方法
  5. Java里的稀疏矩阵Sparse Array
  6. Docker系列之二:基于容器的自动构建
  7. mysql have_mysql having的用法
  8. rust实现wss访问_Rust的所有权,第2部分
  9. 站在BERT肩膀上的NLP新秀们(PART II)
  10. 数据结构C#版笔记--啥夫曼树(Huffman Tree)与啥夫曼编码(Huffman Encoding)
  11. 【JUC】JDK1.8源码分析之ConcurrentSkipListMap(二)
  12. Linux输入子系统浅析
  13. 【合肥黑马程序员】SpringBoot应用Docker化
  14. TensorFlow激励函数
  15. 由计算机病毒引起的问题属于,多数情况下由计算机病毒程序引起的问题属于()故障。A.硬件B.软件C.操作D.电源...
  16. 免费文案生成器-免费文案改写神器
  17. 周志华机器学习--线性模型
  18. python装饰器原理wraps(method)(self)_理解Python中装饰器最佳方法~
  19. 牛市来了,我却被矿机收割了
  20. 电子元器件:三极管参数笔记(持续记录)

热门文章

  1. 简单利用Dialog实现Ios从底部弹出的效果,合QQ空间里面的发表说说弹出拍照的效果类似
  2. DBeaver无法连接SQL Server
  3. 模电学习第三天--三极管梳理
  4. python中的数值类型有哪些,Python中数值类型有哪些
  5. Unity2D游戏使游戏角色跳跃的脚本(包括长按跳跃加成)
  6. ACM程序设计书中题目--J(大写字母的更替)
  7. Android 绘制渐变色
  8. 11 万字的字节码编程系列合集放送(ASM、Javassist、Byte-buddy、Javaagent)
  9. 古诗文网站之网络爬虫
  10. MogaFX外汇储备与经济危机