本文章内容基于《机器学习实战》这本书,书中有很多地方简化了数学算法,并不适合入门小白,比如我,因为有很多数学知识,此书并不讲,而这些数学知识,抽取出来可以单独出一本书。所以数学基础薄弱的同学还要单独补数学只是,本博文,会将数学只是补充进来,我补充的更加详细,主要是自己不理解的地方都写了出来,欢迎各位指正。
为了节约读者时间,缩短篇幅,我删除废话,力求精简,只讲数学算法实现的核心部分。
第三章 决策树
信息增益(information gain)
计算熵(entropy)公式
信息与熵(entropy)的通俗解释
警察小明发现一个案件有4个嫌疑人,分别为ABCD,现在他要选出正确的凶手,在已经知道凶手只有一个的情况下,4名嫌疑人是凶手的概率都为P(x)=1/4,为了能选出正确的凶手,小明需要分析案件的案情,能为小明提供线索找出正确凶手的称为信息。现在分析信息的混乱程度,就是信息熵,在小明不知道ABCD谁是凶手的情况下,案情的信息熵(凶手的不确定性)为 ,假设,根据新的线索,小明发现嫌疑人C的可能性为1/2, 那么其他嫌疑人的可能性为1/6, 那么这个新的线索提供的信息量为多大? 如下计算
所以在警察小明在知道嫌疑人有1/2可能性的情况下,不确定性(熵):1.79
小明在不知道ABCD谁是凶手的情况下,不确定性(熵):2
小明在根据新线索确定C为凶手的可能性为1/2的情况下,新线索提供的信息量为:2-1.79=0.21
计算给定数据集的熵
#计算给定数据集的香农熵
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
熵越高,则混合的数据也越多,我们可以在数据集中添加更多的分类,观察熵是如何变化的。
得到熵之后,我们就可以按照获取最大信息增益的方法划分数据集,下一节我们将具体学习
如何划分数据集以及如何度量信息增益。
划分数据集
1.1特征选择与条件熵
在生成决策树的过程中需要选择合适的特征作为决策树的划分依据,那么特征如何选择,我们使用信息增益来确定,如何计算信息增益,我们需要计算在每一个特征下的条件熵,然后选择信息收益最大的特征最为决策树的划分条件,首先要确定条件熵的概念。以使得信息增益最大(max information Gain)的特征(feature)来划分数据集,在此特征下的熵就是条件熵。
- 2信息增益计算公式
递归构造决策树
使用决策树预测隐形眼镜类型
#用决策树来划分隐形眼镜类别
fr=open('lenses.txt') #创建文件流
lenses=[inst.strip().split('\t') for inst in fr.readlines()]#以Tab键分割数据
lensesLabels=['age','prescript','astigmatic','tearRate']#创建标签数据集
lensesTree=trees.createTree(lenses,lensesLabels)#创建决策树
用matplotlib来创建决策树图
treePlotter.createPlot(lensesTree)
图3-8 由ID3算法产生的决策树
决策树总结
图3-8所示的决策树非常好地匹配了实验数据,然而这些匹配选项可能太多了。我们将这
种问题称为过度匹配(overfitting)(过拟合)。为了减少过度匹配问题,我们可以
剪掉非必要的叶子节点。如果叶子节点只能增加少许信息,则可以删除该节点,
并将它加在其他叶子节点中。
使用决策树预测隐形眼镜类型全过程的数学分析
数据集信息:
- 特征(4个):age(年龄)、prescript(症状)、astigmatic(是否散光)、tearRate(眼泪数量)
- 隐形眼镜类别(3个):硬材质(hard)、软材质(soft)、不适合佩戴隐形眼镜(no lenses)
在没有进行任何处理之前:
hard:3个,soft:4个,no lenses:11个
熵为
2.选择合适的划分数据集
假设选年龄段作为划分的依据:
假设选其他三个标签划分,熵,信息增益如下
由此可知选择眼泪数量作为划分依据,信息增益最大,信息熵越小,数据混乱度越小。接下来重复当上述步奏即可构造出决策树。
2021年8月29凌晨1:04,今天解决了决策树的思想。
第4章朴素贝叶斯
1.使用条件概率来分类
上面就是贝叶斯的公式,而最基础的应用就是朴素贝叶斯,为什么是“朴素”,因为,朴素贝叶斯的前提是各个特征之间(上面公式中的x,y)是相互独立的,不受任何影响,这大大简化了数学的推理条件,但是在实际中,特征之间可能存在千丝万缕的关系,所以朴素贝叶斯任然有一定的局限性。朴素贝叶斯,还有应用思想:
1.基于伯努利分布:这种是最简单的,是基于特征的二分类,也就是说,特征在测试数据中出现就视为1,不出现就视为0,没有其他情况,所以所有特征权重一样,而特征如果重复出现,则只视为出现一次,而基于多项式的分布,则会统计特征出现的次数,出现次数越多,则特征权重越大,越容易影响分类结果。
2.基于多项式分布:略
3.基于高斯分布:略
核心代码讲解
1.使用朴素贝叶斯训练模型
def trainNB0(trainMatrix,trainCategory):
numTrainDocs = len(trainMatrix) #得到训练样本的个数为6个
numWords = len(trainMatrix[0]) #得到字典的长度为32个特征
pAbusive = sum(trainCategory)/float(numTrainDocs) #得到侮辱类在所有样本中的概率
p0Num = ones(numWords); p1Num = ones(numWords) #change to ones()
p0Denom = 2.0; p1Denom = 2.0 #change to 2.0
for i in range(numTrainDocs): #遍历6个句子样本
if trainCategory[i] == 1: #如果是侮辱类
p1Num += trainMatrix[i] #侮辱类句子样本中所有特征词出现个数,结果是一个一秩矩阵
p1Denom += sum(trainMatrix[i])#用sum统计侮辱类句子样本中出现的词语个数,
else: #如果是非侮辱类
p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i]) #统计单词次数,重复的单词只算一次
p1Vect = log(p1Num/p1Denom) #用单词出现次数矩阵除以在侮辱类样本的单词总数,进行广播运算,得到p(x|c1),就是每个特征在侮辱类的概率
p0Vect = log(p0Num/p0Denom) #用单词出现次数矩阵除以在非侮辱类样本的单词总数,进行广播运算,得到p(x|c1),就是每个特征在非侮辱类的概率
return p0Vect,p1Vect,pAbusive
上面就是使用朴素贝叶斯的公式,进行计算,保存模型,关键就是计算各个特征单词在分类样本中出现的概率,保存起来,然后在下一次出现的测试集中进行计算。在实际使用过程中样本的采集非常重要,下面给出本例子中的朴素贝叶斯的计算公式
上述代码,有两点需要注意
1是p0Num = ones(numWords); p1Num = ones(numWords) #change to ones()
为什么由零矩阵改为ones矩阵,主要是防止在矩阵在运算过程中出现无穷小值相乘,最后造成概率为零的情况,就将所有的特征词出现个数初始化为1.
p0Denom = 2.0; p1Denom = 2.0 #change to 2.0
2.分母为啥初始化为2,在 log(p1Num/p1Denom) 运算中,防止出现log(1)=0的情况。