《机器学习实战》第3章课后题——预测隐形眼镜类型

因为自己凭印象写的,大致流程跟书上一样,细节不太一样,看了看书上的一些细节问题的确做的更好

本章学习的是用构建决策树来预测隐形眼睛类型,决策树算法优点是计算复杂度不高(用ID3算法到尽头,公式少且简单),结果易看懂(因为是字典形式,或者用图片的形式表现决策树),中间值缺失不敏感(因为可以凭借其他的信息判断所属类型),可以处理不相关特征数据(每个数据都是独立,谁大谁小互不影响)

还有用到了ID3算法,这个是重点。我就直接把书上原话搬过来。ID3算法推荐看一下,写的挺好的 https://blog.youkuaiyun.com/m0_37786726/article/details/79699972

熵定义为信息的期望值,在明晰这个概念之前,我们必须知道信息的定义。如果待分类的事
务可能划分在多个分类之中,则符号x i 的信息定义为

l(x_{i})=-log_{2}p(x_{i})
其中p(x i )是选择该分类的概率。
为了计算熵,我们需要计算所有类别所有可能值包含的信息期望值,通过下面的公式得到:

H=-\sum_{i=1}^{n}p(x_{i})log_{2}p(x_{i})

计算信息增益:Entropy就是上面的H

pi表示该分类方式所产生的第i组数据量和原数据量的比

Info_Gain越大,表示分裂后的熵越小,子节点变得越纯,分类的效果越好

pickle模块在python3安装的时候就有了

from math import log
from numpy import array, delete
from pickle import dump, load

def GetData(String):
    fl = open(String, 'r')
    lines = fl.readlines()
    DataSet = []
    for line in lines:
        line = line.split('\n')[0]          #去掉字符串最后一个换行符,取换行符前面的字符串
        linelist = line.split('\t')
        DataSet.append(linelist)
    return DataSet

def GetshannongEnt(dataSet):
    shannongEnt = 0.0
    l = len(dataSet)            #计算有多少组数据
    K = {}          #以字典的形式计算不同类型的个数
    for dataline in dataSet:
        if dataline[-1] not in K:
            K[dataline[-1]] = 1
        else:
            K[dataline[-1]] += 1
    for key in K.keys():
        shannongEnt -= K[key]/l*log(K[key]/2,2)
    return shannongEnt

def GetNewDataSet(DataSet, axis):
    NewDataSet = []
    Data = {}           #利用字典将DataSet中axis位置按照不同值分类
    for datalist in DataSet:
        if datalist[axis] not in Data:
            Data[datalist[axis]] = [datalist]
        else:
            Data[datalist[axis]].append(datalist)
    for key in Data.keys():         #将字典中的不同类插入到NewDataSet中
        NewDataSet.append(Data[key])
    return NewDataSet           #返回值应该是一个二维list,第一层list代表axis位置有几种类型的值,第二层list代表DataSet每一行中axis位置为这个值的行的集合

def ID3(DataSet):
    DataTree = {}
    FatherEntropy = GetshannongEnt(DataSet)
    Information_Add = 0.0
    best_i = 0
    for i in range(len(DataSet[0])-1):
        NewDataSet = GetNewDataSet(DataSet, i)
        SonEntropy = 0.0
        for NewDatalist in NewDataSet:
            SonEntropy += len(NewDatalist)/len(DataSet)*GetshannongEnt(NewDatalist)         #计算子节点们的熵
        if Information_Add < FatherEntropy - SonEntropy:
            Information_Add = FatherEntropy - SonEntropy            #计算信息增益
            best_i = i          #选出当前DataSet最好的分类位置
    if len(DataSet[0]) == 2:          #也就是只剩下最好的分类位置和最后的判定结果
        for Datalist in DataSet:
            if Datalist[best_i] not in DataTree:
                DataTree[Datalist[best_i]] = Datalist[-1]
        return DataTree
    else:
        for Datalist in DataSet:
            if Datalist[best_i] not in DataTree:
                key = Datalist.pop(best_i)        #将第i个位置的元素删除,返回删除的元素
                DataTree[key] = [Datalist]
            else:
                key = Datalist.pop(best_i)
                DataTree[key].append(Datalist)
        #现在的DataTree是张这个模样:{key1:[...],key2:[...],....},接下来变成字典嵌套,也就算把[...]变成字典
        for key in DataTree.keys():
            DataTree[key] = ID3(DataTree[key])
    return DataTree

def classify(DataTree, testData):
    for data in testData:
        DataTree = DataTree[data]
    return DataTree

def storeTree(DataTree, filename = 'PythonTest/机器学习/第二章的决策树.txt'):
    fl = open(filename, 'wb')           #python3:必须是wb因为是二进制文件,否则报错     python2:就可以直接是w    
    dump(DataTree,fl)
    fl.close()

def readTree(filename):
    fl = open(filename)
    return load(fl)
 #下面的是测试一下结果
storeTree(ID3(GetData('PythonTest/机器学习/machinelearninginaction-master/Ch03/lenses.txt')))
print(classify(ID3(GetData('PythonTest/机器学习/machinelearninginaction-master/Ch03/lenses.txt')),['pre', 'myope', 'no', 'normal']))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值