西瓜数据集3.0a:西瓜数据集3.0a.zip

第八章

8.1

假设硬币正面朝上的概率为第八章  课后习题 - 图1,反面朝上的概率为第八章  课后习题 - 图2。令第八章  课后习题 - 图3代表抛第八章  课后习题 - 图4次硬币所得正面朝上的次数,则最多第八章  课后习题 - 图5次正面朝上的概率为
第八章  课后习题 - 图6
第八章  课后习题 - 图7,由Hoeffding不等式
第八章  课后习题 - 图8
试着推导出式子第八章  课后习题 - 图9
解:
第八章  课后习题 - 图10

8.2

对于0/1损失函数来说,指数损失函数并非仅有的一致替代函数。考虑式子第八章  课后习题 - 图11。试证明,任意损失函数第八章  课后习题 - 图12,若对于第八章  课后习题 - 图13在区间第八章  课后习题 - 图14上单调递减,则第八章  课后习题 - 图15是0/1损失函数的一致替代函数。(第八章  课后习题 - 图16是基分类器的线性组合)
解:
第八章  课后习题 - 图17
第八章  课后习题 - 图18是对第八章  课后习题 - 图19得单调递减函数,那么可以认为第八章  课后习题 - 图20是对第八章  课后习题 - 图21得单调递增函数。此时,第八章  课后习题 - 图22,即达到了贝叶斯最优错误率,所以第八章  课后习题 - 图23是0/1损失函数得一致替代函数。

8.3

从网上下载或自己编程实现AdaBoost,以不剪枝决策树为基学习器,在西瓜数据集3.0a上训练一个AdaBoost集成,并与图8.4进行比较。

8.4

GradientBoosting是一种常用的Boosting算法,试分析其与AdaBoost的异同。
解:

  • 相同之处:GradientBoosting与AdaBoost相同的地方在于要生成多个分类器以及每个分类器都有一个权值,最后将所有分类器加权累加起来。
  • 不同之处:AdaBoost通过每个分类器的分类结果改变每个样本的权值用于新的分类器和生成权值,但每个样本不会改变;GradinetBoosting将每个分类器对样本的预测值与真实值的差值传入下一个分类器来生成新的分类器和权值(这个差值就是下降方向),而每个样本的权值不变。

    8.5

    试变成实现Bagging,以决策树桩为基学习器,在西瓜数据集3.0a上训练一个Bagging集成,并与图8.6比较。
    image.png
    解:
    (1)决策树桩:决策树桩是最简单的线性分类器,分类原理
    决策树桩分类实例:
    数据:5个拉拉队员的数据
拉拉队员 身高 体重 性别
1 170 55
2 160 45
3 180 65
4 165 50
5 170 50

如果我们想根据拉拉队员的身高体重对其进行分类,很明显,体重>50的都是男队员,体重<=50的都是女队员,剩下的工作就是让机器根据这些数据自己学习找到合适的阈值。设计出来的算法就是决策树桩的算法了。
为此,我们将问题更加细化以下,使用体重作为特征,性别作为标签进行分类(Y=1判别性别为男,Y=0判别性别为女)。
决策树桩的模型是找到一个一维的线性模型,因此其模型函数可以看作第八章  课后习题 - 图25,其中第八章  课后习题 - 图26是阈值,我们规定,当第八章  课后习题 - 图27时,预测第八章  课后习题 - 图28,否则第八章  课后习题 - 图29。为了找到一个合适的阈值第八章  课后习题 - 图30使用最简单的线性搜索就可以解决,算法如下

L = 1; minErr = 99999; for t = min(x) to max(x) by L do   numErr = numberOfErrors(t)   if numErr <= minErr     minErr = numErr     tbest = t   end if end for return tbest

在这个算法中,我们从第八章  课后习题 - 图31的最小值开始搜索,直到第八章  课后习题 - 图32的最大值。每次更新第八章  课后习题 - 图33时给第八章  课后习题 - 图34增加第八章  课后习题 - 图35这么大。 numberOfErrors 函数用来统计我们在t作为阈值的情况下,分类的错误数目,这样搜索了一遍后,就能找到一个错误最少的tbest作为我们决策树桩的阈值。
其中学习步长第八章  课后习题 - 图36的作用十分重要,如果第八章  课后习题 - 图37过大的话,可能会不小心错过最优解,但是L过小的话,又会导致算法运行时间过长。因此调整一个合适的L值是十分必要的。
(2)Bagging算法思想

  • 1.给定一个弱学习算法,和一个训练集;
  • 2.单个弱学习算法准确率不高;
  • 3.将该学习算法使用多次,得出预测函数序列,进行投票;
  • 4.最后结果准确率将得到提高.

(3)Bagging算法流程
第八章  课后习题 - 图38
(4)解题思路
(5)决策树桩选择合适的阈值来进行二分类的过程中时,怎么找到合适的阈值?
别人的回答
回答一:

  • 首先对这个连续变量排序。比如说年龄,把所有样本中年龄的数值从小到大排序。
  • 在数据没有重复的假设下,如果有n个样本,那么排序后的数据之间应该有n-1个间隔。
  • 决策树会对这n-1个间隔进行逐一尝试(分叉),每个不同的分叉,会带来不同的gini指数,我们最终选gini指数最小的那个分叉作为最优分叉,也就是阈值。

理论上是这样进行的,但是实际情况是为了一些计算优化,可能会进行一些随机搜索,而不一定是遍历。
上面这个过程就把那个连续变量进行了一分为二(第一次离散化),比如说年龄被分成了0到20岁,20到100岁。
接下来,当决策树继续生长时,之前一分为二的连续特征可能会再次被选中。比如说20到100岁这个分叉被选中,我们再次重复上面那三个步骤,再去寻找下一个次分叉的阈值。这次得到的结果可能是20到35,35到100岁。
以此反复,这样一个连续变量就不停地被离散化,直到模型达到停止的条件。
回答二:
假如训练集上有Age这么个特征,数值分别为
10,11, 16, 18, 20, 35
那么在这个节点上,算法会自动考虑下面几种划分的可能

  1. Age <=10 Age>10
  2. Age <=11 Age>11
  3. Age <=16 Age>16
  4. Age <=18 Age>18
  5. Age <=20 Age>20

六个数值点,所以就有5个对应划分的可能。对这5个可能一一尝试,选出损失函数最小的那个。
回答三:
对于数值特征,决策树会对所有取值一一尝试,直到选择到最好的。
对于分类,就是对应gini最小
对于回归,就是对应rmse最小
(6)基尼指数 第八章  课后习题 - 图39 基尼不纯度指标
在CART算法中,基尼不纯度表示一个随机选中的样本在子集中被分错的可能性。基尼不纯度为这个样本被选中的概率✖它被分错的概率。当一个节点中所有样本都是一个类时,基尼不纯度为零。
假设第八章  课后习题 - 图40,令第八章  课后习题 - 图41是样本被赋予第八章  课后习题 - 图42的概率,则基尼指数可以通过如下计算:
第八章  课后习题 - 图43
例子链接

有房者 婚姻状况 年收入 拖欠贷款者
单身 125k
已婚 100k
单身 70k
已婚 120k
离异 95k
已婚 60k
离异 220k
单身 85k
已婚 75k
单身 90k

image.png

  • 从房子属性来看 | | 有房 | 没房 | | —- | —- | —- | | 没贷款 | 3 | 4 | | 贷款 | 0 | 3 |

第八章  课后习题 - 图45

  • 婚姻状况属性来看,它 的取值有三种 | | 单身或已婚 | 离异 | | —- | —- | —- | | 否 | 6 | 1 | | 是 | 2 | 1 |

第八章  课后习题 - 图46

单身或离异 已婚
3 4
3 0

第八章  课后习题 - 图47

离异或已婚 单身
5 2
1 2

第八章  课后习题 - 图48

  • 从年入属性来看,它是一个连续的属性,连续的取值采用分裂点进行分裂

image.png
所以找对阈值为97时的Gini指数最小。
(7)代码:
计算密度的最优分类阈值和信息增益:

  1. function [threshold_optimal,entropy_add,data_result] = density(data)
  2. %因为有含糖率和密度两个属性,所以要用ID3来判断这部分,单独写一个函数
  3. % clear;
  4. % clc;
  5. % load('dataset.mat');
  6. % data = watermelon;
  7. %根据Gini指数找到合适的阈值点
  8. [density_matrix,position] = sort(data(:,1));
  9. %根据位置信息找到排序后的结果
  10. density_matrix = [density_matrix,data(position,3)];
  11. %设定阈值矩阵
  12. for i = 1:size(density_matrix,1)-1
  13. threshold_matrix(i) = (density_matrix(i)+density_matrix(i+1))/2;
  14. end
  15. for i = 1:length(threshold_matrix)
  16. threshold_small_bad_watermelon_number = 0;
  17. threshold_small_good_watermelon_number = 0;
  18. threshold_big_bad_watermelon_number = 0;
  19. threshold_big_good_watermelon_number = 0;
  20. for j = 1:size(density_matrix,1)
  21. if density_matrix(j,1)<threshold_matrix(i) || density_matrix(j,1) == threshold_matrix(i)
  22. if density_matrix(j,2) ==1
  23. threshold_small_good_watermelon_number = threshold_small_good_watermelon_number+1;
  24. else
  25. threshold_small_bad_watermelon_number = threshold_small_bad_watermelon_number+1;
  26. end
  27. end
  28. if density_matrix(j,1)>threshold_matrix(i)
  29. if density_matrix(j,2) == 1
  30. threshold_big_good_watermelon_number = threshold_big_good_watermelon_number+1;
  31. else
  32. threshold_big_bad_watermelon_number = threshold_big_bad_watermelon_number+1;
  33. end
  34. end
  35. end
  36. %计算基尼指数
  37. %因为式子太长,所以简化tsgwn = threshold_small_good_watermelon_number;同理
  38. tsgwn = threshold_small_good_watermelon_number;
  39. tsbwn = threshold_small_bad_watermelon_number;
  40. tbgwn = threshold_big_good_watermelon_number;
  41. tbbwn = threshold_big_bad_watermelon_number;
  42. threshold_sum = tsgwn+tsbwn+tbgwn+tbbwn;
  43. Gini_index_small = 1-(tsgwn/(tsgwn+tsbwn))^2-(tsbwn/(tsgwn+tsbwn))^2;
  44. Gini_index_big = 1-(tbgwn/(tbgwn+tbbwn))^2-(tbbwn/(tbgwn+tbbwn))^2;
  45. Gini_index = (tsgwn+tsbwn)/(threshold_sum)*(Gini_index_small)+(tbgwn+tbbwn)/(threshold_sum)*(Gini_index_big);
  46. Gini_index_matrix(i) = Gini_index;
  47. end
  48. %找到最小的基尼指数,然后找到阈值
  49. [Gini_index_minimum,position] = min(Gini_index_matrix);
  50. threshold_optimal = threshold_matrix(position);
  51. % 找到最优阈值下的信息熵
  52. %计算好瓜和坏瓜的信息熵
  53. good_watermelon = 0;
  54. bad_watermelon = 0;
  55. for j=1:size(data,1)
  56. if data(j,3) == 1
  57. good_watermelon = good_watermelon+1;
  58. else
  59. bad_watermelon = bad_watermelon+1;
  60. end
  61. end
  62. p_good_watermelon = good_watermelon/(size(data,1));
  63. p_bad_watermelon = bad_watermelon/(size(data,1));
  64. information_entropy = -p_good_watermelon*mylog(p_good_watermelon)-p_bad_watermelon*mylog(p_bad_watermelon);
  65. % tsgw threshold_small_good_watermelon的缩写
  66. %
  67. tsgw = 0;
  68. tsbw = 0;
  69. tbgw = 0;
  70. tbbw = 0;
  71. for i = 1:size(data,1)
  72. if density_matrix(i,1) < threshold_optimal
  73. if density_matrix(i,2) == 1
  74. tsgw = tsgw+1;
  75. else
  76. tsbw = tsbw+1;
  77. end
  78. else
  79. if density_matrix(i,2) == 1
  80. tbgw = tbgw+1;
  81. else
  82. tbbw = tbbw+1;
  83. end
  84. end
  85. end
  86. disp(tsgw);
  87. disp(tsbw);
  88. disp(tbgw);
  89. disp(tbbw);
  90. entropy_threshold_small = -(tsbw/(tsbw+tsgw))*mylog(((tsbw)/(tsbw+tsgw)))-(tsgw/(tsbw+tsgw))*mylog(tsgw/(tsbw+tsgw));
  91. entropy_threshold_big = -(tbbw/(tbbw+tbgw))*mylog(((tbbw)/(tbbw+tbgw)))-(tbgw/(tbbw+tbgw))*mylog(tbgw/(tbbw+tbgw));
  92. entropy_threshold = (tsgw +tsbw)/(tsgw+tsbw+tbgw+tbbw)*entropy_threshold_small+(tbgw+tbbw)/(tsgw+tsbw+tbgw+tbbw)*entropy_threshold_big;
  93. entropy_add = information_entropy - entropy_threshold;
  94. disp('信息增益');
  95. disp(entropy_add);
  96. %计算分类结果
  97. % data_result(:,1) = data(:,1);
  98. for i=1:size(data,1)
  99. if data(i,1) <threshold_optimal || data(i,1) == threshold_optimal
  100. data_result(i,1) = -1;
  101. else
  102. data_result(i,1) = 1;
  103. end
  104. end
  105. end

最优阈值:0.3815;信息增益:0.1819
计算含糖率的最优阈值和信息增益:代码同上(只需要修改数据)

  1. function [threshold_optimal,entropy_add,data_result] = sugar(data)
  2. %因为有含糖率和密度两个属性,所以要用ID3来判断这部分,单独写一个函数
  3. % clear;
  4. % clc;
  5. % load('dataset.mat');
  6. % data = watermelon;
  7. % step_length = 0.01;
  8. %根据Gini指数找到合适的阈值点
  9. [sugar_matrix,position] = sort(data(:,2));
  10. %根据位置信息找到排序后的结果
  11. sugar_matrix = [sugar_matrix,data(position,3)];
  12. %设定阈值矩阵
  13. for i = 1:size(sugar_matrix,1)-1
  14. threshold_matrix(i) = (sugar_matrix(i)+sugar_matrix(i+1))/2;
  15. end
  16. for i = 1:length(threshold_matrix)
  17. threshold_small_bad_watermelon_number = 0;
  18. threshold_small_good_watermelon_number = 0;
  19. threshold_big_bad_watermelon_number = 0;
  20. threshold_big_good_watermelon_number = 0;
  21. for j = 1:size(sugar_matrix,1)
  22. if sugar_matrix(j,1)<threshold_matrix(i) || sugar_matrix(j,1) == threshold_matrix(i)
  23. if sugar_matrix(j,2) ==1
  24. threshold_small_good_watermelon_number = threshold_small_good_watermelon_number+1;
  25. else
  26. threshold_small_bad_watermelon_number = threshold_small_bad_watermelon_number+1;
  27. end
  28. end
  29. if sugar_matrix(j,1)>threshold_matrix(i)
  30. if sugar_matrix(j,2) == 1
  31. threshold_big_good_watermelon_number = threshold_big_good_watermelon_number+1;
  32. else
  33. threshold_big_bad_watermelon_number = threshold_big_bad_watermelon_number+1;
  34. end
  35. end
  36. end
  37. %计算基尼指数
  38. %因为式子太长,所以简化tsgwn = threshold_small_good_watermelon_number;同理
  39. tsgwn = threshold_small_good_watermelon_number;
  40. tsbwn = threshold_small_bad_watermelon_number;
  41. tbgwn = threshold_big_good_watermelon_number;
  42. tbbwn = threshold_big_bad_watermelon_number;
  43. threshold_sum = tsgwn+tsbwn+tbgwn+tbbwn;
  44. Gini_index_small = 1-(tsgwn/(tsgwn+tsbwn))^2-(tsbwn/(tsgwn+tsbwn))^2;
  45. Gini_index_big = 1-(tbgwn/(tbgwn+tbbwn))^2-(tbbwn/(tbgwn+tbbwn))^2;
  46. Gini_index = (tsgwn+tsbwn)/(threshold_sum)*(Gini_index_small)+(tbgwn+tbbwn)/(threshold_sum)*(Gini_index_big);
  47. Gini_index_matrix(i) = Gini_index;
  48. end
  49. %找到最小的基尼指数,然后找到阈值
  50. [Gini_index_minimum,position] = min(Gini_index_matrix);
  51. threshold_optimal = threshold_matrix(position);
  52. % 找到最优阈值下的信息熵
  53. %计算好瓜和坏瓜的信息熵
  54. good_watermelon = 0;
  55. bad_watermelon = 0;
  56. for j=1:size(data,1)
  57. if data(j,3) == 1
  58. good_watermelon = good_watermelon+1;
  59. else
  60. bad_watermelon = bad_watermelon+1;
  61. end
  62. end
  63. p_good_watermelon = good_watermelon/(size(data,1));
  64. p_bad_watermelon = bad_watermelon/(size(data,1));
  65. information_entropy = -p_good_watermelon*mylog(p_good_watermelon)-p_bad_watermelon*mylog(p_bad_watermelon);
  66. % tsgw threshold_small_good_watermelon的缩写
  67. %
  68. tsgw = 0;
  69. tsbw = 0;
  70. tbgw = 0;
  71. tbbw = 0;
  72. for i = 1:size(data,1)
  73. if sugar_matrix(i,1) < threshold_optimal
  74. if sugar_matrix(i,2) == 1
  75. tsgw = tsgw+1;
  76. else
  77. tsbw = tsbw+1;
  78. end
  79. else
  80. if sugar_matrix(i,2) == 1
  81. tbgw = tbgw+1;
  82. else
  83. tbbw = tbbw+1;
  84. end
  85. end
  86. end
  87. disp(tsgw);
  88. disp(tsbw);
  89. disp(tbgw);
  90. disp(tbbw);
  91. entropy_threshold_small = -(tsbw/(tsbw+tsgw))*mylog(((tsbw)/(tsbw+tsgw)))-(tsgw/(tsbw+tsgw))*mylog(tsgw/(tsbw+tsgw));
  92. entropy_threshold_big = -(tbbw/(tbbw+tbgw))*mylog(((tbbw)/(tbbw+tbgw)))-(tbgw/(tbbw+tbgw))*mylog(tbgw/(tbbw+tbgw));
  93. entropy_threshold = (tsgw +tsbw)/(tsgw+tsbw+tbgw+tbbw)*entropy_threshold_small+(tbgw+tbbw)/(tsgw+tsbw+tbgw+tbbw)*entropy_threshold_big;
  94. entropy_add = information_entropy - entropy_threshold;
  95. disp('信息增益');
  96. disp(entropy_add)
  97. for i=1:size(data,2)
  98. if data(i,2) <threshold_optimal || data(i,2) == threshold_optimal
  99. data_result(i,1) = -1;
  100. else
  101. data_result(i,1) = 1;
  102. end
  103. end
  104. end

最优阈值:0.2045;信息增益:0.2337
其中的mylog函数,是由于第八章  课后习题 - 图50所以重写的

  1. function y = mylog(x)
  2. if x==0
  3. y=0;
  4. else
  5. y = log(x);
  6. end
  7. end

自主采样法,抽出第八章  课后习题 - 图51个数据集

  1. function [s,t]=zizhu(data)
  2. t = data;
  3. [m,n] = size(data);
  4. s = zeros(m,n);
  5. labels = [];
  6. for i=1:m
  7. index = UNIDRND(m);
  8. labels = [labels index];
  9. s(i,:) = data(index,:);
  10. end
  11. kind=unique(labels);
  12. disp(length(kind))
  13. t(kind,:) = [];

接下来通过第八章  课后习题 - 图52个数据集得到第八章  课后习题 - 图53个分类器,可以把上面的密度和含糖率的阈值和信息增益计算写成函数来调用

  1. clear;
  2. clc;
  3. load('dataset.mat');
  4. data = watermelon;
  5. data_initial = data;
  6. data_update = data;
  7. T=5;
  8. for t = 1:T
  9. density_data_result_matrix(:,1) = data_initial(:,1);
  10. data_random = zizhu(data_initial(:,1));
  11. data_update(:,1) = data_random;
  12. [threshold,entropy,data_result] = density(data_update);
  13. density_threshold_matrix(t) = threshold;
  14. density_data_result_matrix(:,t+1) = data_result;
  15. end
  16. xlswrite('C:\Users\25626\Desktop\density_data_result_matrix.xlsx',density_data_result_matrix');
  17. for t = 1:T
  18. sugar_data_result_matrix(:,1) = data_initial(:,2);
  19. data_random1 = zizhu(data_initial(:,2));
  20. data_update(:,2) = data_random1;
  21. [threshold,entropy,data_result1] = sugar(data_update);
  22. sugar_threshold_matrix(t) = threshold;
  23. sugar_data_result_matrix(:,t+1) = data_result1;
  24. end
  25. xlswrite('C:\Users\25626\Desktop\sugar_data_result_matrix.xlsx', sugar_data_result_matrix');

最后的预测结果
使用随机的抽样数据得出的结果:
密度

阈值\样本 1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1
0.6770 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 1 1
0.2940 1 1 1 1 1 1 1 1 1 1 -1 1 -1 -1 -1 1 1
0.7080 -1 1 -1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
0.2940 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1
0.6080 1 1 -1 -1 1 1 -1 1 -1 -1 -1 -1 1 -1 -1 1 -1

含糖率

阈值\样本 1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1
0.2655 -1 -1 -1 -1 -1 -1 -1 1 1 -1 1 -1 -1 1 -1 1 -1
0.0740 1 1 1 1 1 1 1 1 1 1 -1 -1 -1 1 1 1 1
0.0420 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 -1
0.2640 1 1 1 1 -1 -1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
0.3700 -1 -1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

最后还差一个投票输出的代码,but I’m lazy第八章  课后习题 - 图54。这个比较简单。

8.6

试着分析Bagging通常为何难以提升朴素贝叶斯分类器的性能。
解:
Bagging主要是降低分类器的方差,而朴素贝叶斯分类器没有方差可以减少。对全训练样本生成的朴素贝叶斯分类器是最优的分类器,不能随机抽样来提高泛化性能。

8.7

试着分析随机森林为什么比决策树Bagging集成的训练速度更快。
解:
随机森林不仅会随机样本,还会在所有样本属性中随机集中出来计算。这样每次生成分类器时都是对部分属性计算最优,速度会比Bagging计算全属性要快。

8.8

MultiBosting算法将AdaBoost作为Bagging学习的基学习器,Iterative Bagging算法则是将Bagging作为AdaBoost的基学习器。试着比较二者的优缺点。
解:
MultiBoosting由于集成了Bagging,Wagging,AdaBoost,可以有效的降低误差和方差,特别是误差。但是训练样本和预测成本都会显著增加
Iterative Bagging相比Bagging会降低误差,但是方差上升。由于Bagging本身就是一种降低方差的算法,所以Iterative Bagging相当于Bagging与单分类器的折中。

8.9

试着设计一种可视化的多样性度量,对习题8.3和习题8.5中得到的集成进行评估,并与第八章  课后习题 - 图55-误差图比较。

8.10

试着设计一种能提升第八章  课后习题 - 图56近邻分类器性能的集成学习算法。
解:
可以使用Bagging来提升第八章  课后习题 - 图57近邻分类器的性能,每次随机抽取出一个子样本,并训练一个第八章  课后习题 - 图58近邻分类器,对测试样本进行分类,最终投票得到最多的一种分类。