From d52933e5b24ae882077e0230a1b887b514c5c385 Mon Sep 17 00:00:00 2001 From: jiangzhonglian Date: Wed, 23 Aug 2017 13:38:25 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=9B=B4=E6=96=B0=207.=E9=9B=86=E6=88=90?= =?UTF-8?q?=E6=96=B9=E6=B3=95=20md=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/7.集成方法-随机森林和AdaBoost.md | 28 +++++++++++--------- images/7.AdaBoost/过拟合图解.png | Bin 0 -> 20551 bytes images/7.RandomForest/RandomForest_Flow.jpg | Bin 87462 -> 0 bytes src/python/7.RandomForest/randomForest.py | 4 +-- 4 files changed, 18 insertions(+), 14 deletions(-) create mode 100644 images/7.AdaBoost/过拟合图解.png delete mode 100644 images/7.RandomForest/RandomForest_Flow.jpg diff --git a/docs/7.集成方法-随机森林和AdaBoost.md b/docs/7.集成方法-随机森林和AdaBoost.md index 99c0caf8..8d1bd3bf 100644 --- a/docs/7.集成方法-随机森林和AdaBoost.md +++ b/docs/7.集成方法-随机森林和AdaBoost.md @@ -84,13 +84,11 @@ 适用数据范围:数值型和标称型 ``` -### 项目案例: 随机森林 - -![随机森林](/images/7.RandomForest/RandomForest_Flow.jpg) +### 项目案例: 声纳信号分类 #### 项目概述 -这是 Gorman 和 Sejnowski 在研究使用神经网络的声纳信号分类中使用的数据集。任务是训练一个网络来区分声纳信号。 +这是 Gorman 和 Sejnowski 在研究使用神经网络的声纳信号分类中使用的数据集。任务是训练一个模型来区分声纳信号。 #### 开发流程 @@ -99,7 +97,7 @@ 准备数据:转换样本集。 分析数据:手工检查数据。 训练算法:在数据上,利用 random_forest() 函数进行优化评估,返回模型的综合分类结果。 -测试算法:在采用自定义 n_folds 循环的随机重抽样就行测试评估,得出综合的预测评分。 +测试算法:在采用自定义 n_folds 份随机重抽样 进行测试评估,得出综合的预测评分。 使用算法:本例没有完成此步骤,若你感兴趣可以构建完整的应用程序,从案例进行封装,就可以构造一个实际运行的类似系统 ``` @@ -226,7 +224,7 @@ def random_forest(train, test, max_depth, min_size, sample_size, n_trees, n_feat return predictions ``` -> 测试算法:在采用自定义 n_folds 循环的随机重抽样就行测试评估,得出综合的预测评分。 +> 测试算法:在采用自定义 n_folds 份随机重抽样 进行测试评估,得出综合的预测评分。 * 计算随机森林的预测结果的正确率 @@ -238,7 +236,7 @@ def evaluate_algorithm(dataset, algorithm, n_folds, *args): Args: dataset 原始数据集 algorithm 使用的算法 - n_folds 树的个数 + n_folds 数据的份数 *args 其他的参数 Returns: scores 模型得分 @@ -343,7 +341,7 @@ def evaluate_algorithm(dataset, algorithm, n_folds, *args): > 收集数据:提供的文本文件。 -训练数据:horseColicTraining.txt +训练数据:horseColicTraining.txt
测试数据:horseColicTest.txt ``` @@ -378,6 +376,10 @@ def loadDataSet(fileName): ![过拟合](/images/7.AdaBoost/过拟合.png) +* 通俗来说:就是把一些噪音数据也拟合进去的,如下图。 + +![过拟合](/images/7.AdaBoost/过拟合图解.png) + > 训练算法:在数据上,利用 adaBoostTrainDS() 函数训练出一系列的分类器。 ```python @@ -501,10 +503,12 @@ print m, errArr[predicting10 != mat(labelArrTest).T].sum(), errArr[predicting10 > ROC 评估方法 * ROC 曲线: 最佳的分类器应该尽可能地处于左上角 -* ![ROC曲线](/images/7.AdaBoost/ROC曲线.png) - * 对不同的 ROC 曲线进行比较的一个指标是曲线下的面积(Area Unser the Curve, AUC). - * AUC 给出的是分类器的平均性能值,当然它并不能完全代替对整条曲线的观察。 - * 一个完美分类器的 AUC 为1,而随机猜测的 AUC 则为0.5。 + +![ROC曲线](/images/7.AdaBoost/ROC曲线.png) + +* 对不同的 ROC 曲线进行比较的一个指标是曲线下的面积(Area Unser the Curve, AUC). +* AUC 给出的是分类器的平均性能值,当然它并不能完全代替对整条曲线的观察。 +* 一个完美分类器的 AUC 为1,而随机猜测的 AUC 则为0.5。 > 代价函数 diff --git a/images/7.AdaBoost/过拟合图解.png b/images/7.AdaBoost/过拟合图解.png new file mode 100644 index 0000000000000000000000000000000000000000..0bb222b7eae374e91b1f7b0d78d9becf73b4c4b7 GIT binary patch literal 20551 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

-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 PN%;%U{9pAS+MoCvy!H~) literal 0 HcmV?d00001 diff --git a/images/7.RandomForest/RandomForest_Flow.jpg b/images/7.RandomForest/RandomForest_Flow.jpg deleted file mode 100644 index 1382baec80c519da7fdf9f6b225063ee2f1e2a62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 87462 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%0A5NFU`%r)5+`18BkB|4qLx_J-K&;v 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 Date: Wed, 23 Aug 2017 14:19:32 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20PCA=20md=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/13.利用PCA来简化数据.md | 62 +++++++++++++++++++++++------------- src/python/13.PCA/pca.py | 55 +++++++++++++++++--------------- 2 files changed, 69 insertions(+), 48 deletions(-) diff --git a/docs/13.利用PCA来简化数据.md b/docs/13.利用PCA来简化数据.md index 988809b8..c8266b85 100644 --- a/docs/13.利用PCA来简化数据.md +++ b/docs/13.利用PCA来简化数据.md @@ -2,14 +2,7 @@ ![利用PCA简化数据_首页](/images/13.PCA/利用PCA简化数据_首页.jpg) -> 场景描述: - -* 我们正通过电视而非现场观看体育比赛,在电视的纯平显示器上有一个球。 -* 显示器大概包含了100万像素,而球则可能是由较少的像素组成,例如说一千个像素。 -* 人们实时的将显示器上的百万像素转换成为一个三维图像,该图像就给出运动场上球的位置。 -* 在这个过程中,人们已经将数据从一百万维降至了三维。这就被称为`降维(dimensionality reduction)` - -## 降维技术 +## 降维技术 概述 > 数据显示并非大规模特征下的唯一难题,对数据进行简化还有如下一系列的原因: @@ -48,25 +41,49 @@ * 假设数据为多个数据源的混合观察结果,这些数据源之间在统计上是相互独立的,而在PCA中只假设数据是不相关的。 * 同因子分析一样,如果数据源的数目少于观察数据的数目,则可以实现降维过程。 -## 主成分分析(PCA) -> PCA的优缺点 +## 降维技术 场景 -* 优点:降低数据的复杂性,识别最重要的多个特征。 -* 缺点:不一定需要,且可能损失有用信息。 -* 适用数据类型:数值型数据。 +* 我们正通过电视而非现场观看体育比赛,在电视的纯平显示器上有一个球。 +* 显示器大概包含了100万像素,而球则可能是由较少的像素组成,例如说一千个像素。 +* 人们实时的将显示器上的百万像素转换成为一个三维图像,该图像就给出运动场上球的位置。 +* 在这个过程中,人们已经将数据从一百万维降至了三维。这就被称为`降维(dimensionality reduction)` -> 通过PCA进行降维处理,我们就可以同时获得SVM和决策树的优点: -* 一方面,得到了和决策树一样简单的分类器,同时分类间隔和SVM一样好。 - * 1.第一个主成分就是来自于数据差异性最大(即 方差最大)的方向提取出来 - * 2.第二个主成分就是来自于数据差异性次大的方向,并且该方向于第一个主成分方向正交。 - * 3.通过数据集的协方差矩阵及其特征值分析,我们就可以得到这些主成分的值。 - * 一旦得到了协方差矩阵的特征向量,我们就可以保留最大的N个值。这些特征向量也给出了N个最重要特征的真实结构。我们可以通过将数据乘上这N个特征向量而将它转换到新的空间。 -* 例如下图: -* ![应用PCA降维](/images/13.PCA/应用PCA降维.png) +## PCA -## 对半导体数据进行降维处理 +### PCA 概述 + +主成分分析(Principal Component Analysis, PCA):`通俗理解:就是找出一个最主要的特征,然后进行分析。` + +### PCA 场景 + +`例如: 考察一个人的智力情况,就直接看数学成绩就行(存在:数学、语文、英语成绩)` + +### PCA 原理 + +> PCA 工作原理 + +通过PCA进行降维处理,我们就可以同时获得SVM和决策树的优点:(得到了和决策树一样简单的分类器,同时分类间隔和SVM一样好) +1. 第一个主成分就是来自于数据差异性最大(即: `方差最大`)的方向提取出来 +2. 第二个主成分就是来自于数据差异性次大的方向,并且该方向于第一个主成分方向`正交(orthogonal 如果是二维空间就叫垂直)`。 +3. 通过数据集的协方差矩阵及其特征值分析,我们就可以得到这些主成分的值。 +4. 一旦得到了协方差矩阵的特征向量,我们就可以保留最大的N个值。这些特征向量也给出了N个最重要特征的真实结构。 + 我们可以通过将数据乘上这N个特征向量而将它转换到新的空间。 + +例如下图: + +![应用PCA降维](/images/13.PCA/应用PCA降维.png) + +> PCA 优缺点 + +``` +优点:降低数据的复杂性,识别最重要的多个特征。 +缺点:不一定需要,且可能损失有用信息。 +适用数据类型:数值型数据。 +``` + +### 项目案例: 对半导体数据进行降维处理 ``` 半导体是在一些极为先进的工厂中制造出来的。设备的生命早期有限,并且话费极其巨大。 @@ -79,6 +96,7 @@ 目前该章节处理的方案是:将缺失值NaN(Not a Number缩写),全部用平均值来替代(如果用0来处理的策略就太差劲了)。 ``` + ## 本章小节 ``` diff --git a/src/python/13.PCA/pca.py b/src/python/13.PCA/pca.py index 52c1197e..b61dc69a 100644 --- a/src/python/13.PCA/pca.py +++ b/src/python/13.PCA/pca.py @@ -7,10 +7,9 @@ Update on 2017-05-18 @author: Peter Harrington/片刻 《机器学习实战》更新地址:https://github.com/apachecn/MachineLearning ''' -print(__doc__) from numpy import * -import matplotlib import matplotlib.pyplot as plt +print(__doc__) def loadDataSet(fileName, delim='\t'): @@ -106,6 +105,32 @@ def show_picture(dataMat, reconMat): plt.show() +def analyse_data(dataMat): + meanVals = mean(dataMat, axis=0) + meanRemoved = dataMat-meanVals + covMat = cov(meanRemoved, rowvar=0) + eigvals, eigVects = linalg.eig(mat(covMat)) + eigValInd = argsort(eigvals) + + topNfeat = 20 + eigValInd = eigValInd[:-(topNfeat+1):-1] + cov_all_score = sum(eigvals) + sum_cov_score = 0 + for i in range(0, len(eigValInd)): + line_cov_score = eigvals[eigValInd[i]] + sum_cov_score += line_cov_score + ''' + 我们发现其中有超过20%的特征值都是0。 + 这就意味着这些特征都是其他特征的副本,也就是说,它们可以通过其他特征来表示,而本身并没有提供额外的信息。 + + 最前面15个值的数量级大于10^5,实际上那以后的值都变得非常小。 + 这就相当于告诉我们只有部分重要特征,重要特征的数目也很快就会下降。 + + 最后,我们可能会注意到有一些小的负值,他们主要源自数值误差应该四舍五入成0. + ''' + print '主成分:%s, 方差占比:%s%%, 累积方差占比:%s%%' % (format(i+1, '2.0f'), format(line_cov_score/cov_all_score*100, '4.1f'), format(sum_cov_score/cov_all_score*100, '4.1f')) + + if __name__ == "__main__": # # 加载数据,并转化数据类型为float # dataMat = loadDataSet('input/13.PCA/testSet.txt') @@ -119,30 +144,8 @@ if __name__ == "__main__": # 利用PCA对半导体制造数据降维 dataMat = replaceNanWithMean() print shape(dataMat) + # # 分析数据 + # analyse_data(dataMat) lowDmat, reconMat = pca(dataMat, 20) print shape(lowDmat) show_picture(dataMat, reconMat) - - # meanVals = mean(dataMat, axis=0) - # meanRemoved = dataMat-meanVals - # covMat = cov(meanRemoved, rowvar=0) - # eigvals, eigVects = linalg.eig(mat(covMat)) - # eigValInd = argsort(eigvals) - - # topNfeat = 20 - # eigValInd = eigValInd[:-(topNfeat+1):-1] - # cov_all_score = sum(eigvals) - # sum_cov_score = 0 - # for i in range(0, len(eigValInd)): - # line_cov_score = eigvals[eigValInd[i]] - # sum_cov_score += line_cov_score - # ''' - # 我们发现其中有超过20%的特征值都是0。 - # 这就意味着这些特征都是其他特征的副本,也就是说,它们可以通过其他特征来表示,而本身并没有提供额外的信息。 - - # 最前面15个值的数量级大于10^5,实际上那以后的值都变得非常小。 - # 这就相当于告诉我们只有部分重要特征,重要特征的数目也很快就会下降。 - - # 最后,我们可能会注意到有一些小的负值,他们主要源自数值误差应该四舍五入成0. - # ''' - # print '主成分:%s, 方差占比:%s%%, 累积方差占比:%s%%' % (format(i+1, '2.0f'), format(line_cov_score/cov_all_score*100, '4.1f'), format(sum_cov_score/cov_all_score*100, '4.1f')) From b0c57257ca8346711f55e4be06f183578bf1576e Mon Sep 17 00:00:00 2001 From: jiangzhonglian Date: Wed, 23 Aug 2017 18:38:42 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=9B=B4=E6=96=B0=203.=E5=86=B3=E7=AD=96?= =?UTF-8?q?=E6=A0=91=20md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/3.决策树.md | 126 ++++++++++++++---- images/3.DecisionTree/熵的计算公式.jpg | Bin 0 -> 29211 bytes src/python/3.DecisionTree/DecisionTree.py | 45 ++++--- src/python/3.DecisionTree/decisionTreePlot.py | 2 +- .../3.DecisionTree/decisionTreePlot.pyc | Bin 0 -> 3912 bytes 5 files changed, 125 insertions(+), 48 deletions(-) create mode 100644 images/3.DecisionTree/熵的计算公式.jpg create mode 100644 src/python/3.DecisionTree/decisionTreePlot.pyc diff --git a/docs/3.决策树.md b/docs/3.决策树.md index 7ce8b86c..d024d7e7 100644 --- a/docs/3.决策树.md +++ b/docs/3.决策树.md @@ -89,11 +89,11 @@ ``` 收集数据:可以使用任何方法 -准备数据:树构造算法只适用于标称型数据,因此数值型数据必须离散化。 -分析数据:可以使用任何方法,构造树完成之后,我们应该检查图形是否符合预期。 +准备数据:树构造算法只适用于标称型数据,因此数值型数据必须离散化 +分析数据:可以使用任何方法,构造树完成之后,我们应该检查图形是否符合预期 训练算法:构造树的数据结构 -测试算法:使用经验树计算错误率 -使用算法:此步骤可以适用于任何监督学习算法,而使用决策树可以更好地理解数据的内在含义。 +测试算法:使用决策树执行分类 +使用算法:此步骤可以适用于任何监督学习算法,而使用决策树可以更好地理解数据的内在含义 ``` > 收集数据:可以使用任何方法 @@ -102,7 +102,7 @@ 我们利用 createDataSet() 函数输入数据 -```Python +```python def createDataSet(): dataSet = [[1, 1, 'yes'], [1, 1, 'yes'], @@ -112,13 +112,17 @@ def createDataSet(): labels = ['no surfacing', 'flippers'] return dataSet, labels ``` -> 准备数据:树构造算法只适用于标称型数据,因此数值型数据必须离散化。 +> 准备数据:树构造算法只适用于标称型数据,因此数值型数据必须离散化 此处,由于我们输入的数据本身就是离散化数据,所以这一步就省略了。 -计算给定数据集的香农熵 +> 分析数据:可以使用任何方法,构造树完成之后,我们应该检查图形是否符合预期 -```Python +![熵的计算公式](/images/3.DecisionTree/熵的计算公式.jpg) + +计算给定数据集的香农熵的函数 + +```python def calcShannonEnt(dataSet): # 求list的长度,表示计算参与训练的数据量 numEntries = len(dataSet) @@ -145,20 +149,55 @@ def calcShannonEnt(dataSet): 按照给定特征划分数据集 -```Python -def splitDataSet(dataSet, axis, value): +`将指定特征的特征值等于 value 的行剩下列作为子数据集。` + +```python +def splitDataSet(dataSet, index, value): + """splitDataSet(通过遍历dataSet数据集,求出index对应的colnum列的值为value的行) + 就是依据index列进行分类,如果index列的数据等于 value的时候,就要将 index 划分到我们创建的新的数据集中 + Args: + dataSet 数据集 待划分的数据集 + index 表示每一行的index列 划分数据集的特征 + value 表示index列对应的value值 需要返回的特征的值。 + Returns: + index列为value的数据集【该数据集需要排除index列】 + """ retDataSet = [] - for featVec in dataSet: - if featVec[axis] == value: - reducedFeatVec = featVec[:axis] - reducedFeatVec.extend(featVec[axis+1:]) + for featVec in dataSet: + # index列为value的数据集【该数据集需要排除index列】 + # 判断index列的值是否为value + if featVec[index] == value: + # chop out index used for splitting + # [:index]表示前index行,即若 index 为2,就是取 featVec 的前 index 行 + reducedFeatVec = featVec[:index] + ''' + 请百度查询一下: extend和append的区别 + list.append(object) 向列表中添加一个对象object + list.extend(sequence) 把一个序列seq的内容添加到列表中 + 1、使用append的时候,是将new_media看作一个对象,整体打包添加到music_media对象中。 + 2、使用extend的时候,是将new_media看作一个序列,将这个序列和music_media序列合并,并放在其后面。 + result = [] + result.extend([1,2,3]) + print result + result.append([4,5,6]) + print result + result.extend([7,8,9]) + print result + 结果: + [1, 2, 3] + [1, 2, 3, [4, 5, 6]] + [1, 2, 3, [4, 5, 6], 7, 8, 9] + ''' + reducedFeatVec.extend(featVec[index+1:]) + # [index+1:]表示从跳过 index 的 index+1行,取接下来的数据 + # 收集结果值 index列为value的行【该行需要排除index列】 retDataSet.append(reducedFeatVec) return retDataSet ``` 选择最好的数据集划分方式 -```Python +```python def chooseBestFeatureToSplit(dataSet): """chooseBestFeatureToSplit(选择最好的特征) @@ -169,14 +208,14 @@ def chooseBestFeatureToSplit(dataSet): """ # 求第一行有多少列的 Feature, 最后一列是label列嘛 numFeatures = len(dataSet[0]) - 1 - # label的信息熵 + # 数据集的原始信息熵 baseEntropy = calcShannonEnt(dataSet) # 最优的信息增益值, 和最优的Featurn编号 bestInfoGain, bestFeature = 0.0, -1 # iterate over all the features for i in range(numFeatures): # create a list of all the examples of this feature - # 获取每一个实例的第i+1个feature,组成list集合 + # 获取对应的feature下的所有数据 featList = [example[i] for example in dataSet] # get a set of unique values # 获取剔重后的集合,使用set对list数据进行去重 @@ -187,7 +226,9 @@ def chooseBestFeatureToSplit(dataSet): # 遍历当前特征中的所有唯一属性值,对每个唯一属性值划分一次数据集,计算数据集的新熵值,并对所有唯一特征值得到的熵求和。 for value in uniqueVals: subDataSet = splitDataSet(dataSet, i, value) + # 计算概率 prob = len(subDataSet)/float(len(dataSet)) + # 计算信息熵 newEntropy += prob * calcShannonEnt(subDataSet) # gain[信息增益]: 划分数据集前后的信息变化, 获取信息熵最大的值 # 信息增益是熵的减少或者是数据无序度的减少。最后,比较所有特征中的信息增益,返回最好特征划分的索引值。 @@ -199,11 +240,17 @@ def chooseBestFeatureToSplit(dataSet): return bestFeature ``` +``` +问:上面的 newEntropy 为什么是根据子集计算的呢? +答:因为我们在根据一个特征计算香农熵的时候,该特征的分类值是相同,这个特征这个分类的香农熵为 0; +这就是为什么计算新的香农熵的时候使用的是子集。 +``` + > 训练算法:构造树的数据结构 -创建树的函数代码 +创建树的函数代码如下: -```Python +```python def createTree(dataSet, labels): classList = [example[-1] for example in dataSet] # 如果数据集的最后一列的第一个值出现的次数=整个集合的数量,也就说只有一个类别,就只直接返回结果就行 @@ -237,7 +284,36 @@ def createTree(dataSet, labels): return myTree ``` -> 测试算法:使用经验树计算错误率 +> 测试算法:使用决策树执行分类 + +```python +def classify(inputTree, featLabels, testVec): + """classify(给输入的节点,进行分类) + + Args: + inputTree 决策树模型 + featLabels Feature标签对应的名称 + testVec 测试输入的数据 + Returns: + classLabel 分类的结果值,需要映射label才能知道名称 + """ + # 获取tree的根节点对于的key值 + firstStr = inputTree.keys()[0] + # 通过key得到根节点对应的value + secondDict = inputTree[firstStr] + # 判断根节点名称获取根节点在label中的先后顺序,这样就知道输入的testVec怎么开始对照树来做分类 + featIndex = featLabels.index(firstStr) + # 测试数据,找到根节点对应的label位置,也就知道从输入的数据的第几位来开始分类 + key = testVec[featIndex] + valueOfFeat = secondDict[key] + print '+++', firstStr, 'xxx', secondDict, '---', key, '>>>', valueOfFeat + # 判断分枝是否结束: 判断valueOfFeat是否是dict类型 + if isinstance(valueOfFeat, dict): + classLabel = classify(valueOfFeat, featLabels, testVec) + else: + classLabel = valueOfFeat + return classLabel +``` > 使用算法:此步骤可以适用于任何监督学习算法,而使用决策树可以更好地理解数据的内在含义。 @@ -247,7 +323,7 @@ def createTree(dataSet, labels): #### 项目概述 -隐形眼镜类型包括应材质、软材质以及不适合佩戴隐形眼镜。我们需要使用决策树预测患者需要佩戴的隐形眼镜类型。 +隐形眼镜类型包括硬材质、软材质以及不适合佩戴隐形眼镜。我们需要使用决策树预测患者需要佩戴的隐形眼镜类型。 #### 开发流程 @@ -270,20 +346,20 @@ presbyopic myope no reduced no lenses > 解析数据:解析 tab 键分隔的数据行 -```Python +```python lecses = [inst.strip().split('\t') for inst in fr.readlines()] lensesLabels = ['age', 'prescript', 'astigmatic', 'tearRate'] ``` > 分析数据:快速检查数据,确保正确地解析数据内容,使用 createPlot() 函数绘制最终的树形图。 -```Python +```python >>> treePlotter.createPlot(lensesTree) ``` > 训练算法:使用 createTree() 函数 -```Python +```python >>> lensesTree = trees.createTree(lenses, lensesLabels) >>> lensesTree {'tearRate': {'reduced': 'no lenses', 'normal': {'astigmatic':{'yes': @@ -299,7 +375,7 @@ lensesLabels = ['age', 'prescript', 'astigmatic', 'tearRate'] 使用 pickle 模块存储决策树 -```Python +```python def storeTree(inputTree, filename): impory pickle fw = open(filename, 'w') diff --git a/images/3.DecisionTree/熵的计算公式.jpg b/images/3.DecisionTree/熵的计算公式.jpg new file mode 100644 index 0000000000000000000000000000000000000000..58fbc8b3339f9c75a38d3f05d901bd854a36d291 GIT binary patch literal 29211 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� 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 literal 0 HcmV?d00001 diff --git a/src/python/3.DecisionTree/DecisionTree.py b/src/python/3.DecisionTree/DecisionTree.py index f34a568c..8251bb90 100755 --- a/src/python/3.DecisionTree/DecisionTree.py +++ b/src/python/3.DecisionTree/DecisionTree.py @@ -75,24 +75,24 @@ def calcShannonEnt(dataSet): return shannonEnt -def splitDataSet(dataSet, axis, value): - """splitDataSet(通过遍历dataSet数据集,求出axis对应的colnum列的值为value的行) - 就是依据axis列进行分类,如果axis列的数据等于 value的时候,就要将 axis 划分到我们创建的新的数据集中 +def splitDataSet(dataSet, index, value): + """splitDataSet(通过遍历dataSet数据集,求出index对应的colnum列的值为value的行) + 就是依据index列进行分类,如果index列的数据等于 value的时候,就要将 index 划分到我们创建的新的数据集中 Args: dataSet 数据集 待划分的数据集 - axis 表示每一行的axis列 划分数据集的特征 - value 表示axis列对应的value值 需要返回的特征的值。 + index 表示每一行的index列 划分数据集的特征 + value 表示index列对应的value值 需要返回的特征的值。 Returns: - axis列为value的数据集【该数据集需要排除axis列】 + index列为value的数据集【该数据集需要排除index列】 """ retDataSet = [] for featVec in dataSet: - # axis列为value的数据集【该数据集需要排除axis列】 - # 判断axis列的值是否为value - if featVec[axis] == value: - # chop out axis used for splitting - # [:axis]表示前axis行,即若 axis 为2,就是取 featVec 的前 axis 行 - reducedFeatVec = featVec[:axis] + # index列为value的数据集【该数据集需要排除index列】 + # 判断index列的值是否为value + if featVec[index] == value: + # chop out index used for splitting + # [:index]表示前index行,即若 index 为2,就是取 featVec 的前 index 行 + reducedFeatVec = featVec[:index] ''' 请百度查询一下: extend和append的区别 list.append(object) 向列表中添加一个对象object @@ -109,11 +109,11 @@ def splitDataSet(dataSet, axis, value): 结果: [1, 2, 3] [1, 2, 3, [4, 5, 6]] - [1, 2, 3, [4, 5, 6], 7, 8, 9 + [1, 2, 3, [4, 5, 6], 7, 8, 9] ''' - reducedFeatVec.extend(featVec[axis+1:]) - # [axis+1:]表示从跳过 axis 的 axis+1行,取接下来的数据 - # 收集结果值 axis列为value的行【该行需要排除axis列】 + reducedFeatVec.extend(featVec[index+1:]) + # [index+1:]表示从跳过 index 的 index+1行,取接下来的数据 + # 收集结果值 index列为value的行【该行需要排除index列】 retDataSet.append(reducedFeatVec) return retDataSet @@ -250,6 +250,7 @@ def grabTree(filename): fr = open(filename) return pickle.load(fr) + def fishTest(): # 1.创建数据和结果标签 myDat, labels = createDataSet() @@ -269,10 +270,11 @@ def fishTest(): myTree = createTree(myDat, copy.deepcopy(labels)) print myTree # [1, 1]表示要取的分支上的节点位置,对应的结果值 - # print classify(myTree, labels, [1, 1]) + print classify(myTree, labels, [1, 1]) # 画图可视化展现 - # dtPlot.createPlot(myTree) + dtPlot.createPlot(myTree) + def ContactLensesTest(): """ @@ -294,10 +296,9 @@ def ContactLensesTest(): lensesTree = createTree(lenses, lensesLabels) print lensesTree # 画图可视化展现 - # dtPlot.createPlot(lensesTree) + dtPlot.createPlot(lensesTree) if __name__ == "__main__": - fishTest() - # ContactLensesTest() - + # fishTest() + ContactLensesTest() diff --git a/src/python/3.DecisionTree/decisionTreePlot.py b/src/python/3.DecisionTree/decisionTreePlot.py index 59b97751..1cafebec 100644 --- a/src/python/3.DecisionTree/decisionTreePlot.py +++ b/src/python/3.DecisionTree/decisionTreePlot.py @@ -87,7 +87,7 @@ def plotTree(myTree, parentPt, nodeTxt): plotNode(secondDict[key], (plotTree.xOff, plotTree.yOff), cntrPt, leafNode) # 并打印输入对应的文字 plotMidText((plotTree.xOff, plotTree.yOff), cntrPt, str(key)) - # plotTree.yOff = plotTree.yOff + 1.0/plotTree.totalD + plotTree.yOff = plotTree.yOff + 1.0/plotTree.totalD def createPlot(inTree): diff --git a/src/python/3.DecisionTree/decisionTreePlot.pyc b/src/python/3.DecisionTree/decisionTreePlot.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c9f9da40bfa3aaeb625e63f6c66c212f8830389d GIT binary patch literal 3912 zcmcInO>Y}j6n!&xoY?s+5ZtIx1}aq%ZQ`UYEh-faN>mkzCSg((5vj5!Gh=%aXU3iP z+}e<=jM%YYgSuhMnt#BbV8^CEp%Om;&bed9NmRk6aXWAB`G)$e?lbL}Ni3$5c?n z7;6VzCG`U)M9a7sMHNhlQBuLA7~?9K5@SLI(_&1jU`C87?qO^G0=M=HiqdKtdL|5< zBz87@<1F90?%Y^fUMhXl3ee7GRPQV--B`GBr?eLOk&e*zI1NK*D`}^G=&U9|=+u(b zdF1(xC=Q*kLNAS@xb8%;^M!9Xezmda+$^nlZPQ57yUu24!qj=_r74D)B(Cg5UR?jK zk;L^TtWxw3e(Poo8{ADg+H{+tRJ8ZpB#CJl8$C5&=kQuu{L~ciPLp;V+%hGYm^XPY zUuh1!x8PfN5fVPDcyt>D06DVMp;CJau4Q%Z$Y%Y}hLuyDb#<8Qcdk8IQAc@YFg~Xa z^J=aqIKr9xwn}|2Blwf7EnV7{^*DYeI zxA5p06v`@CGgird+n%$^_LL=95U^t`enjPev8bNJ;_Ls!0v0~C02BV71;^#~hQPSou{+9wtTYoS00d9H7Pd@dUiwKsar=SSk!F|U+({Nw z?4xH)BhuM7sJwaSPh(OCkA4TmY3CR032V~wNjpA-NP=MvhCvtzrNMuIfe-+<;j$nv zB!))8h7+MbP#%;;0s<|9t9#a%6)13<^jw$V>~zHsovxoGX`nS-;B`Xn)KX6*L0F4X zVaEtJX=G#N`)8gE@WU8NAuSD0VqzD9FbwimnzVElIrP0RVn!MY!M)D1?81xV#6Zo4 z-&MV|-v5r6#*nbb*a)G`mfXxLEic6m`V|?4kUW>5k+oac`8xKpjD3i7Da&W1l8Zc_ zpw)muU4dL>Sj}AoRI`1%4B^UDM|yK=*bBQ%4Le3!)QU(Ck`Pmo0Nl&vGDJz(Os(p$ z_*;>naNmXLmRVdxA-hlMWT<^~87=eNw|j}jdmKQ*5#ym``LRhijr$=xBrZA>DkcPu z?L3MCF}g6$$KzxxJ&pw)V`rbBsu{-0x{QC~coKq5;`j~7G@J)VL;T@pBm<;!;E<^e z8p{NN&3QFj=6gidY|*L$lLl~sw|hBdVUE2~)kCNO6sQvXM`4m7a7HgLL(nvLRFHK5 z4A#MnB{h2y@9K!^{H6{I{b|;oyiiA@3i$y|hof0~LiW!~diqoHR@Q+v%p`|kyWGjs z7bng!+wRjyxh&2!*lk2eil__bQ9iI)5&Fb+2Ke&+upll(HvAuH|Oz86?({UAB;3 z?e}wK`-*)vOR+ozeY1*3|BfPyd%%zhd(X0X`w?h+;5vvfyA%@H*aNSr!=doG z3z%E@EBLvKtO}I|N_UCYO%_bX8UKWJS6CHQq?}|t{Swyjh+@6LKL-SZ idk0C-Zib(eIhuEef;F83vrrbNiWiFcVxjm^@$$df!y4`Y literal 0 HcmV?d00001 From 6e6b1bb96f724c5c4fe8809603637e692b72206d Mon Sep 17 00:00:00 2001 From: jiangzhonglian Date: Wed, 23 Aug 2017 20:33:35 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=9B=B4=E6=96=B0=207.=E9=9B=86=E6=88=90?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/7.集成方法-随机森林和AdaBoost.md | 53 ++++++++++++++++++++------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/docs/7.集成方法-随机森林和AdaBoost.md b/docs/7.集成方法-随机森林和AdaBoost.md index 8d1bd3bf..b55edbba 100644 --- a/docs/7.集成方法-随机森林和AdaBoost.md +++ b/docs/7.集成方法-随机森林和AdaBoost.md @@ -93,15 +93,15 @@ #### 开发流程 ``` -收集数据:提供的文本文件。 -准备数据:转换样本集。 -分析数据:手工检查数据。 -训练算法:在数据上,利用 random_forest() 函数进行优化评估,返回模型的综合分类结果。 -测试算法:在采用自定义 n_folds 份随机重抽样 进行测试评估,得出综合的预测评分。 -使用算法:本例没有完成此步骤,若你感兴趣可以构建完整的应用程序,从案例进行封装,就可以构造一个实际运行的类似系统 +收集数据:提供的文本文件 +准备数据:转换样本集 +分析数据:手工检查数据 +训练算法:在数据上,利用 random_forest() 函数进行优化评估,返回模型的综合分类结果 +测试算法:在采用自定义 n_folds 份随机重抽样 进行测试评估,得出综合的预测评分 +使用算法:若你感兴趣可以构建完整的应用程序,从案例进行封装,也可以参考我们的代码 ``` -> 收集数据:提供的文本文件。 +> 收集数据:提供的文本文件 样本数据:sonar-all-data.txt @@ -139,17 +139,17 @@ def loadDataSet(filename): > 训练算法:在数据上,利用 random_forest() 函数进行优化评估,返回模型的综合分类结果 -* 数据随机化 +* 样本数据随机无放回抽样-用于交叉验证 ```python def cross_validation_split(dataset, n_folds): - """cross_validation_split(将数据集进行抽重抽样 n_folds 份,数据可以重复重复抽取,每一次list的元素是无重复的) + """cross_validation_split(将数据集进行抽重抽样 n_folds 份,数据可以重复重复抽取) Args: dataset 原始数据集 n_folds 数据集dataset分成n_flods份 Returns: - dataset_split list集合,存放的是:将数据集进行抽重抽样 n_folds 份,数据可以重复重复抽取,每一次list的元素是无重复的 + dataset_split list集合,存放的是:将数据集进行抽重抽样 n_folds 份,数据可以重复重复抽取 """ dataset_split = list() dataset_copy = list(dataset) # 复制一份 dataset,防止 dataset 的内容改变 @@ -161,13 +161,38 @@ def cross_validation_split(dataset, n_folds): index = randrange(len(dataset_copy)) # 将对应索引 index 的内容从 dataset_copy 中导出,并将该内容从 dataset_copy 中删除。 # pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。 - # fold.append(dataset_copy.pop(index)) # 无放回的方式 - fold.append(dataset_copy[index]) # 有放回的方式 + fold.append(dataset_copy.pop(index)) # 无放回的方式 + # fold.append(dataset_copy[index]) # 有放回的方式 dataset_split.append(fold) # 由dataset分割出的n_folds个数据构成的列表,为了用于交叉验证 return dataset_split ``` +* 训练数据集随机化 + +```python +# Create a random subsample from the dataset with replacement +def subsample(dataset, ratio): # 创建数据集的随机子样本 + """random_forest(评估算法性能,返回模型得分) + + Args: + dataset 训练数据集 + ratio 训练数据集的样本比例 + Returns: + sample 随机抽样的训练样本 + """ + + sample = list() + # 训练样本的按比例抽样。 + # round() 方法返回浮点数x的四舍五入值。 + n_sample = round(len(dataset) * ratio) + while len(sample) < n_sample: + # 有放回的随机采样,有一些样本被重复采样,从而在训练集中多次出现,有的则从未在训练集中出现,此则自助采样法。从而保证每棵决策树训练集的差异性 + index = randrange(len(dataset)) + sample.append(dataset[index]) + return sample +``` + * 特征随机化 ```python @@ -242,7 +267,7 @@ def evaluate_algorithm(dataset, algorithm, n_folds, *args): scores 模型得分 """ - # 将数据集进行抽重抽样 n_folds 份,数据可以重复重复抽取,每一次 list 的元素是无重复的 + # 将数据集进行随机抽样,分成 n_folds 份,数据无重复的抽取 folds = cross_validation_split(dataset, n_folds) scores = list() # 每次循环从 folds 从取出一个 fold 作为测试集,其余作为训练集,遍历整个 folds ,实现交叉验证 @@ -277,7 +302,7 @@ def evaluate_algorithm(dataset, algorithm, n_folds, *args): return scores ``` -> 使用算法:本例没有完成此步骤,若你感兴趣可以构建完整的应用程序,从案例进行封装,就可以构造一个实际运行的类似系统 +> 使用算法:若你感兴趣可以构建完整的应用程序,从案例进行封装,也可以参考我们的代码 [完整代码地址](https://github.com/apachecn/MachineLearning/blob/master/src/python/7.RandomForest/randomForest.py):