机器学习&深度学习基础(机器学习基础的算法概述及代码)

参考:机器学习&深度学习算法及代码实现

Python3机器学习html

传统机器学习算法

决策树、K邻近算法、支持向量机、朴素贝叶斯、神经网络、Logistic回归算法,聚类等。node

1、机器学习算法及代码实现–决策树git

决策树学习笔记(Decision Tree)

引自:Python3《机器学习实战》学习笔记(二):决策树基础篇之让咱们从相亲提及

github:https://github.com/Jack-Cherish/Machine-Learning/tree/master/Decision%20Treegithub

决策树(decision tree)是一种基本的分类与回归方法。算法

决策树算法的核心在于决策树的构建,每次选择让总体数据香农熵(描述数据的混乱程度)减少最多的特征,使用其特征值对数据进行划分,每次消耗一个特征,不断迭代分类,直到全部特征消耗完(选择剩下数据中出现次数最多的类别做为这堆数据的类别),或剩下的数据全为同一类别,没必要继续划分,至此决策树构建完成,以后咱们依照这颗决策树对新进数据进行分类。网络

一个相亲的例子:数据结构

结点和模块的概念:app

 一个决策树,长方形表明判断模块(decision block),椭圆造成表明终止模块(terminating block),表示已经得出结论,能够终止运行。从判断模块引出的左右箭头称做为分支(branch),它能够达到另外一个判断模块或者终止模块。咱们还能够这样理解,分类决策树模型是一种描述对实例进行分类的树形结构。决策树由结点(node)和有向边(directed edge)组成。结点有两种类型:内部结点(internal node)和叶结点(leaf node)。内部结点表示一个特征或属性,叶结点表示一个类。如图所示的决策树,长方形和椭圆形都是结点。长方形的结点属于内部结点,椭圆形的结点属于叶结点,从结点引出的左右箭头就是有向边。而最上面的结点就是决策树的根结点(root node)。机器学习

 使用决策树作预测须要如下过程:函数

  • 收集数据:可使用任何方法。好比想构建一个相亲系统,咱们能够从媒婆那里,或者经过参访相亲对象获取数据。根据他们考虑的因素和最终的选择结果,就能够获得一些供咱们利用的数据了。
  • 准备数据:收集完的数据,咱们要进行整理,将这些全部收集的信息按照必定规则整理出来,并排版,方便咱们进行后续处理。
  • 分析数据:可使用任何方法,决策树构造完成以后,咱们能够检查决策树图形是否符合预期。
  • 训练算法:这个过程也就是构造决策树,一样也能够说是决策树学习,就是构造一个决策树的数据结构。
  • 测试算法:使用经验树计算错误率。当错误率达到了可接收范围,这个决策树就能够投放使用了。
  • 使用算法:此步骤可使用适用于任何监督学习算法,而使用决策树能够更好地理解数据的内在含义。

 决策树构建的准备工做

3个步骤:特征选择、决策树的生成和决策树的修剪。

1 特征选择

    特征选择在于选取对训练数据具备分类能力的特征。这样能够提升决策树学习的效率,若是利用一个特征进行分类的结果与随机分类的结果没有很大差异,则称这个特征是没有分类能力的。经验上扔掉这样的特征对决策树学习的精度影响不大。一般特征选择的标准是信息增益(information gain)或信息增益比,为了简单,本文章使用信息增益做为选择特征的标准。那么,什么是信息增益?在讲解信息增益以前,让咱们看一组实例,贷款申请样本数据表。

ID 年龄 有工做 有本身的房子 信贷状况 类别(是否个给贷款)
1 青年 通常
2 青年
3 青年
4 青年 通常
5 青年 通常
6 中年 通常
7 中年
8 中年
9 中年 很是好
10 中年 很是好
11 老年 很是好
12 老年
13 老年
14 老年 很是好
15 老年 通常

 

    但愿经过所给的训练数据学习一个贷款申请的决策树,用以对将来的贷款申请进行分类,即当新的客户提出贷款申请时,根据申请人的特征利用决策树决定是否批准贷款申请。

    特征选择就是决定用哪一个特征来划分特征空间。好比,咱们经过上述数据表获得两个可能的决策树,分别由两个不一样特征的根结点构成。

 图(a)所示的根结点的特征是年龄,有3个取值,对应于不一样的取值有不一样的子结点。图(b)所示的根节点的特征是工做,有2个取值,对应于不一样的取值有不一样的子结点。两个决策树均可以今后延续下去。

问题是:究竟选择哪一个特征更好些?这就要求肯定选择特征的准则。直观上,若是一个特征具备更好的分类能力,或者说,按照这一特征将训练数据集分割成子集,使得各个子集在当前条件下有最好的分类,那么就更应该选择这个特征。信息增益就可以很好地表示这一直观的准则。

    什么是信息增益呢?在划分数据集以前以后信息发生的变化成为信息增益,知道如何计算信息增益,咱们就能够计算每一个特征值划分数据集得到的信息增益,得到信息增益最高的特征就是最好的选择。

香农熵

     如何计算信息增益。集合信息的度量方式成为香农熵或者简称为熵(entropy),

    熵定义为信息的指望值。在信息论与几率统计中,熵是表示随机变量不肯定性的度量。若是待分类的事务可能划分在多个分类之中,则符号xi的信息定义为 

其中p(xi)是选择该分类的几率。

  经过上式,咱们能够获得全部类别的信息。为了计算熵,咱们须要计算全部类别全部可能值包含的信息指望值(数学指望),经过下面的公式获得: 

   期中n是分类的数目。熵越大,随机变量的不肯定性就越大。

    当熵中的几率由数据估计(特别是最大似然估计)获得时,所对应的熵称为经验熵(empirical entropy)。什么叫由数据估计?好比有10个数据,一共有两个类别,A类和B类。其中有7个数据属于A类,则该A类的几率即为十分之七。其中有3个数据属于B类,则该B类的几率即为十分之三。浅显的解释就是,这几率是咱们根据数据数出来的。咱们定义贷款申请样本数据表中的数据为训练数据集D,则训练数据集D的经验熵为H(D),|D|表示其样本容量,及样本个数。设有K个类Ck,k = 1,2,3,···,K,|Ck|为属于类Ck的样本个数,这经验熵公式能够写为 

根据此公式计算经验熵H(D),分析贷款申请样本数据表中的数据。最终分类结果只有两类,即放贷和不放贷。根据表中的数据统计可知,在15个数据中,9个数据的结果为放贷,6个数据的结果为不放贷。因此数据集D的经验熵H(D)为: 

 通过计算可知,数据集D的经验熵H(D)的值为0.971。

3.1.2 编写代码计算经验熵

    在编写代码以前,咱们先对数据集进行属性标注。

  • 年龄:0表明青年,1表明中年,2表明老年;
  • 有工做:0表明否,1表明是;
  • 有本身的房子:0表明否,1表明是;
  • 信贷状况:0表明通常,1表明好,2表明很是好;
  • 类别(是否给贷款):no表明否,yes表明是。

    肯定这些以后,咱们就能够建立数据集,并计算经验熵了,代码编写以下:

# -*- coding: UTF-8 -*-
from math import log """ 函数说明:建立测试数据集 Parameters: 无 Returns: dataSet - 数据集 labels - 分类属性 Author: Jack Cui Modify: 2017-07-20
""" def createDataSet(): dataSet = [[0, 0, 0, 0, 'no'], #数据集 [0, 0, 0, 1, 'no'], [0, 1, 0, 1, 'yes'], [0, 1, 1, 0, 'yes'], [0, 0, 0, 0, 'no'], [1, 0, 0, 0, 'no'], [1, 0, 0, 1, 'no'], [1, 1, 1, 1, 'yes'], [1, 0, 1, 2, 'yes'], [1, 0, 1, 2, 'yes'], [2, 0, 1, 2, 'yes'], [2, 0, 1, 1, 'yes'], [2, 1, 0, 1, 'yes'], [2, 1, 0, 2, 'yes'], [2, 0, 0, 0, 'no']] labels = ['年龄', '有工做', '有本身的房子', '信贷状况'] #分类属性 return dataSet, labels #返回数据集和分类属性 """ 函数说明:计算给定数据集的经验熵(香农熵) Parameters: dataSet - 数据集 Returns: shannonEnt - 经验熵(香农熵)
""" def calcShannonEnt(dataSet): numEntires = len(dataSet) #返回数据集的行数 labelCounts = {} #保存每一个标签(Label)出现次数的字典 for featVec in dataSet: #对每组特征向量进行统计 currentLabel = featVec[-1] #提取标签(Label)信息 if currentLabel not in labelCounts.keys(): #若是标签(Label)没有放入统计次数的字典,添加进去 labelCounts[currentLabel] = 0 labelCounts[currentLabel] += 1 #Label计数 shannonEnt = 0.0 #经验熵(香农熵) for key in labelCounts: #计算香农熵 prob = float(labelCounts[key]) / numEntires #选择该标签(Label)的几率 shannonEnt -= prob * log(prob, 2) #利用公式计算 return shannonEnt #返回经验熵(香农熵) if __name__ == '__main__': dataSet, features = createDataSet() print(dataSet) print(calcShannonEnt(dataSet))

 

信息增益

    在上面,咱们已经说过,如何选择特征,须要看信息增益。也就是说,信息增益是相对于特征而言的,信息增益越大,特征对最终的分类结果影响也就越大,咱们就应该选择对最终分类结果影响最大的那个特征做为咱们的分类特征。

,信息增益是相对于特征而言的。因此,特征A对训练数据集D的信息增益g(D,A),定义为集合D的经验熵H(D)与特征A给定条件下D的经验条件熵H(D|A)之差,即

 

编写代码计算信息增益

# -*- coding: UTF-8 -*-
from math import log """ 函数说明:计算给定数据集的经验熵(香农熵) Parameters: dataSet - 数据集 Returns: shannonEnt - 经验熵(香农熵) Author: Jack Cui Modify: 2017-03-29
""" def calcShannonEnt(dataSet): numEntires = len(dataSet) #返回数据集的行数 labelCounts = {} #保存每一个标签(Label)出现次数的字典 for featVec in dataSet: #对每组特征向量进行统计 currentLabel = featVec[-1] #提取标签(Label)信息 if currentLabel not in labelCounts.keys(): #若是标签(Label)没有放入统计次数的字典,添加进去 labelCounts[currentLabel] = 0 labelCounts[currentLabel] += 1 #Label计数 shannonEnt = 0.0 #经验熵(香农熵) for key in labelCounts: #计算香农熵 prob = float(labelCounts[key]) / numEntires #选择该标签(Label)的几率 shannonEnt -= prob * log(prob, 2) #利用公式计算 return shannonEnt #返回经验熵(香农熵) """ 函数说明:建立测试数据集 Parameters: 无 Returns: dataSet - 数据集 labels - 分类属性 Author: Jack Cui Modify: 2017-07-20
""" def createDataSet(): dataSet = [[0, 0, 0, 0, 'no'], #数据集 [0, 0, 0, 1, 'no'], [0, 1, 0, 1, 'yes'], [0, 1, 1, 0, 'yes'], [0, 0, 0, 0, 'no'], [1, 0, 0, 0, 'no'], [1, 0, 0, 1, 'no'], [1, 1, 1, 1, 'yes'], [1, 0, 1, 2, 'yes'], [1, 0, 1, 2, 'yes'], [2, 0, 1, 2, 'yes'], [2, 0, 1, 1, 'yes'], [2, 1, 0, 1, 'yes'], [2, 1, 0, 2, 'yes'], [2, 0, 0, 0, 'no']] labels = ['年龄', '有工做', '有本身的房子', '信贷状况'] #分类属性 return dataSet, labels #返回数据集和分类属性 """ 函数说明:按照给定特征划分数据集 Parameters: dataSet - 待划分的数据集 axis - 划分数据集的特征 value - 须要返回的特征的值 Returns: 无 Author: Jack Cui Modify: 2017-03-30
""" def splitDataSet(dataSet, axis, value): retDataSet = [] #建立返回的数据集列表 for featVec in dataSet: #遍历数据集 if featVec[axis] == value: reducedFeatVec = featVec[:axis] #去掉axis特征 reducedFeatVec.extend(featVec[axis+1:]) #将符合条件的添加到返回的数据集 retDataSet.append(reducedFeatVec) return retDataSet #返回划分后的数据集 """ 函数说明:选择最优特征 Parameters: dataSet - 数据集 Returns: bestFeature - 信息增益最大的(最优)特征的索引值
""" def chooseBestFeatureToSplit(dataSet): numFeatures = len(dataSet[0]) - 1 #特征数量 baseEntropy = calcShannonEnt(dataSet) #计算数据集的香农熵 bestInfoGain = 0.0 #信息增益 bestFeature = -1 #最优特征的索引值 for i in range(numFeatures): #遍历全部特征 #获取dataSet的第i个全部特征 featList = [example[i] for example in dataSet] uniqueVals = set(featList) #建立set集合{},元素不可重复 newEntropy = 0.0 #经验条件熵 for value in uniqueVals: #计算信息增益 subDataSet = splitDataSet(dataSet, i, value) #subDataSet划分后的子集 prob = len(subDataSet) / float(len(dataSet)) #计算子集的几率 newEntropy += prob * calcShannonEnt(subDataSet) #根据公式计算经验条件熵 infoGain = baseEntropy - newEntropy #信息增益 print("第%d个特征的增益为%.3f" % (i, infoGain)) #打印每一个特征的信息增益 if (infoGain > bestInfoGain): #计算信息增益 bestInfoGain = infoGain #更新信息增益,找到最大的信息增益 bestFeature = i #记录信息增益最大的特征的索引值 return bestFeature #返回信息增益最大的特征的索引值 if __name__ == '__main__': dataSet, features = createDataSet() print("最优特征索引值:" + str(chooseBestFeatureToSplit(dataSet)))
相关文章
相关标签/搜索