决策树C4.5预测号码快递送餐与广告骚扰,准确率达到98%以上

标签: | 发表时间:2017-12-29 14:09 | 作者:
出处:http://mp.weixin.qq.com
  • 前言

笔者最近在做机器学习,设计到数据挖掘几个算法,主要业务用于从高频号码中分类出指定类别。

从一个开发者转向一个数据分析者,同时兼顾写代码,这感觉不好受啊。

不多说,目前的算法因为都有标签,趋向采用监督学习方向方向进行分类,实验了knn不理想,今日使用了C4.5进行分类,采用指定的时间维度,准确率达到98%以上,狠狠激动了一把。



  • 算法,此算法未剪枝,后期进行二次修复。关于数据集,可联系本人邮箱localhost127001@126.com


'''

Created on 2017年12月15日


@author: Oprcalf

'''

from math import log

import operator

import common.arithmetic.tree.treePlotter as tp



def calcShannonEnt(dataSet):

    """

    输入:数据集

    输出:数据集的香农熵

    描述:计算给定数据集的香农熵;熵越大,数据集的混乱程度越大

    """

    numEntries = len(dataSet)

    labelCounts = {}

    for featVec in dataSet:

        currentLabel = featVec[-1]

        if currentLabel not in labelCounts.keys():

            labelCounts[currentLabel] = 0

        labelCounts[currentLabel] += 1

    shannonEnt = 0.0

    for key in labelCounts:

        prob = float(labelCounts[key]) / numEntries

        shannonEnt -= prob * log(prob, 2)

    return shannonEnt



def splitDataSet(dataSet, axis, value):

    """

    输入:数据集,选择维度,选择值

    输出:划分数据集

    描述:按照给定特征划分数据集;去除选择维度中等于选择值的项

    """

    retDataSet = []

    for featVec in dataSet:

        if featVec[axis] == value:

            reduceFeatVec = featVec[:axis]

            reduceFeatVec.extend(featVec[axis + 1:])

            retDataSet.append(reduceFeatVec)

    return retDataSet



def chooseBestFeatureToSplit(dataSet):

    """

    输入:数据集

    输出:最好的划分维度

    描述:选择最好的数据集划分维度

    """

    numFeatures = len(dataSet[0]) - 1

    baseEntropy = calcShannonEnt(dataSet)

    bestInfoGainRatio = 0.0

    bestFeature = -1

    for i in range(numFeatures):

        featList = [example[i] for example in dataSet]

        uniqueVals = set(featList)

        newEntropy = 0.0

        splitInfo = 0.0

        for value in uniqueVals:

            subDataSet = splitDataSet(dataSet, i, value)

            prob = len(subDataSet) / float(len(dataSet))

            newEntropy += prob * calcShannonEnt(subDataSet)

            splitInfo += -prob * log(prob, 2)

        infoGain = baseEntropy - newEntropy

        if (splitInfo == 0):  # fix the overflow bug

            continue

        infoGainRatio = infoGain / splitInfo

        if (infoGainRatio > bestInfoGainRatio):

            bestInfoGainRatio = infoGainRatio

            bestFeature = i

    return bestFeature



def majorityCnt(classList):

    """

    输入:分类类别列表

    输出:子节点的分类

    描述:数据集已经处理了所有属性,但是类标签依然不是唯一的,

          采用多数判决的方法决定该子节点的分类

    """

    classCount = {}

    for vote in classList:

        if vote not in classCount.keys():

            classCount[vote] = 0

        classCount[vote] += 1

    sortedClassCount = sorted(classCount.iteritems(),

                              key=operator.itemgetter(1), reversed=True)

    return sortedClassCount[0][0]



def createTree(dataSet, labels):

    """

    输入:数据集,特征标签

    输出:决策树

    描述:递归构建决策树,利用上述的函数

    """

    classList = [example[-1] for example in dataSet]

    if classList.count(classList[0]) == len(classList):

        # 类别完全相同,停止划分

        return classList[0]

    if len(dataSet[0]) == 1:

        # 遍历完所有特征时返回出现次数最多的

        return majorityCnt(classList)

    bestFeat = chooseBestFeatureToSplit(dataSet)

    bestFeatLabel = labels[bestFeat]

    myTree = {bestFeatLabel: {}}

    del(labels[bestFeat])

    # 得到列表包括节点所有的属性值

    featValues = [example[bestFeat] for example in dataSet]

    uniqueVals = set(featValues)

    for value in uniqueVals:

        subLabels = labels[:]

        myTree[bestFeatLabel][value] = createTree(

            splitDataSet(dataSet, bestFeat, value), subLabels)

    return myTree



def classify(inputTree, featLabels, testVec):

    """

    输入:决策树,分类标签,测试数据

    输出:决策结果

    描述:跑决策树

    """

    classLabel = ""

    firstStr = list(inputTree.keys())[0]

    secondDict = inputTree[firstStr]

    featIndex = featLabels.index(firstStr)

    for key in secondDict.keys():

        if testVec[featIndex] == key:

            if type(secondDict[key]).__name__ == 'dict':

                classLabel = classify(secondDict[key], featLabels, testVec)

            else:

                classLabel = secondDict[key]

    return classLabel



def classifyAll(inputTree, featLabels, testDataSet):

    """

    输入:决策树,分类标签,测试数据集

    输出:决策结果

    描述:跑决策树

    """

    classLabelAll = []

    n = len(testDataSet)

    correct = 0

    for testVec in testDataSet:

        label = classify(inputTree, featLabels, testVec)

        classLabelAll.append(label)

        if label == testVec[-1]:

            correct += 1

    accuracyRate = "准确率: " + str(correct / float(n))

    return classLabelAll, accuracyRate



def storeTree(inputTree, filename):

    """

    输入:决策树,保存文件路径

    输出:

    描述:保存决策树到文件

    """

    import pickle

    fw = open(filename, 'wb')

    pickle.dump(inputTree, fw)

    fw.close()



def grabTree(filename):

    """

    输入:文件路径名

    输出:决策树

    描述:从文件读取决策树

    """

    import pickle

    fr = open(filename, 'rb')

    return pickle.load(fr)



def createDataSet(dataset_file):

    '''

    返回dataset(列表集合)和features(列表)

    '''

    dataSet = []

    for index, line in enumerate(open(dataset_file, 'rU').readlines()):

        line = line.strip()

        fea_and_label = line.split(',')

        dataSet.append([float(fea_and_label[i]) for i in range(

            len(fea_and_label) - 1)] + [fea_and_label[len(fea_and_label) - 1]])

    labels = ['call1', 'call2', 'call3', 'call4', 'call5', 'call6']

    return dataSet, labels



def createTestSet(dataset_file):

    dataSet = []

    for index, line in enumerate(open(dataset_file, 'rU').readlines()):

        line = line.strip()

        fea_and_label = line.split(',')

        dataSet.append([float(fea_and_label[i]) for i in range(

            len(fea_and_label) - 1)] + [fea_and_label[len(fea_and_label) - 1]])

    return dataSet



def main():

    dataSet, labels = createDataSet("F:\\train.txt")

    labels_tmp = labels[:]  # 拷贝,createTree会改变labels

    desicionTree = createTree(dataSet, labels_tmp)

    #storeTree(desicionTree, 'classifierStorage.txt')

    #desicionTree = grabTree('classifierStorage.txt')

    print('决策树:\n', desicionTree)

    # tp.createPlot(desicionTree)

    testSet = createTestSet("F:\\test.txt")

    classifResult, accuracyRate = classifyAll(desicionTree, labels, testSet)

    print('分析的结果集:\n', classifResult)

    print('分析的准确率:\n', accuracyRate)



if __name__ == '__main__':

    main()


相关 [决策树 c4 预测] 推荐:

决策树C4.5预测号码快递送餐与广告骚扰,准确率达到98%以上

- -
笔者最近在做机器学习,设计到数据挖掘几个算法,主要业务用于从高频号码中分类出指定类别. 从一个开发者转向一个数据分析者,同时兼顾写代码,这感觉不好受啊. 不多说,目前的算法因为都有标签,趋向采用监督学习方向方向进行分类,实验了knn不理想,今日使用了C4.5进行分类,采用指定的时间维度,准确率达到98%以上,狠狠激动了一把.

使用ID3算法构造决策树

- - 四火的唠叨
文章系本人原创,转载请保持完整性并注明出自 《四火的唠叨》. 决策树是一个预测模型,它代表的是对象属性与对象值之间的一种映射关系. 树中每个节点表示某个对象,而每个分叉路径则代表的某个可能的属性值,而每个叶结点则对应从根节点到该叶节点所经历的路径所表示的对象的值. 这张图很好地解释了决策树:. 例子中可以找到两层的分类依据属性,第一层是晴/阴/雨,第二层是是否潮湿和是否刮风,分类依据的确定和先后顺序对决策树的质量有决定性的影响.

决策树仍是最好的数据挖掘算法

- 无藏 - 36氪
决策树仍是最好的数据挖掘算法:理由如下:. 决策树是白箱「white box」,意味着可以生成简单易懂的规则. 你可以通过查看决策树清楚明白各个分支,明白某个分支的影响,并且将其和其他分支进行对比. 决策树术为非参数「non-parametric」,意味着无需特定的数据分流. 决策树可以轻松应对连续变量和类别变量.

[原]从决策树学习谈到贝叶斯分类算法

- - 结构之法 算法之道
    第一篇:从决策树学习谈到贝叶斯分类算法.     最近在面试中,除了基础 &  算法 & 项目之外,经常被问到或被要求介绍和描述下自己所知道的几种分类或聚类算法,而我向来恨对一个东西只知其皮毛而不得深入,故写一个有关聚类 & 分类算法的系列文章以作为自己备试之用(尽管貌似已无多大必要,但还是觉得应该写下以备将来常常回顾思考).

分类算法——决策树——经典算法比较

- - 数据库 - ITeye博客
决策树是以实例为基础的归纳学习算法. 它从一组无次序、无规则的元组中推理出决策树表示形式的分类规则. 它采用自顶向下的递归方式,在决策树的内部结点进行属性值的比较,并根据不同的属性值从该结点向下分支,叶结点是要学习划分的类. 从根到叶结点的一条路径就对应着一条合取规则,整个决策树就对应着一组析取表达式规则.

预测

- lhb - 不许联想
药家鑫和夏俊峰一个面临二审,一个面临死刑复核. 在此预测一下,药家鑫二审肯定是死刑,如果再死刑复核,估计也是死刑. 夏俊峰死刑复核我看翻盘机会也不大,也是死刑. 对比这两个人的命运,正好相反,一个是人民不让他活,一个是人民之外的人不让他活. 药家鑫是很简单的杀人事件,除非药家鑫有什么更硬的来头,否责难逃惩罚.

预测之人生

- Triplewood - 三十而立,四十不惑
    投资也好,投机也罢,就是不断在预测未来的资产价格升跌.     我明知道不测不错,多测多错,但前几年一路测过来,无论对错已经成了惯性,就将连续剧一路继续下去吧.     最近两月在微博上预测了不少类别的资产的动向,现在简单总结罗列一下:. 中国的房价见五---十年的顶;. 中国A股股市已经见底,或曰二次探底已经结束.

Linux 2013年预测

- - Solidot

唾液能预测年龄

- 康爷 - Solidot
根据PLoS ONE上的报告,研究人员发现唾液能用于估算一个人的年龄. 加州大学洛杉矶分校的科学家可以通过DNA甲基化水平来推算一个人的年龄,误差在5.2年之内. 社会和遗传学中心主任Eric Vilain博士说:“仅仅通过唾液样本,我们就能准确推算一个人的年龄,不需要知道其它信息. ”他还表示,若是在烟头附近发现唾液,科学家可以利用这项技术推算唾液是来自20多岁还是70多岁的人.

4579元预测死期?

- sumsfm - 科学松鼠会
  你愿意花费4579元来预测自己的死期吗.   今年5月初,美国《新科学家》(New Scientist)以“端粒诺贝尔奖得主兜售生物年龄检测”为题做了一篇报道,介绍了伊丽莎白·布莱克伯恩(Elizabeth Blackburn)的“商业计划”.   这位2009年度的诺贝尔奖获得者、美国加州大学旧金山分校的教授,作为发起人,在美国加州成立了一家名为“端粒健康”(Telomere Health)的公司,起先主要是为各类端粒研究提供检测分析服务.