• 决策树与随机森林在分类预测中的应用(附源码)


     写在前面

            今天给大家分享一下基于决策树和随机森林在乳腺癌分类中实战。决策树和随机森林是白盒模型,数学建模中常用到这两种模型,用于预测或分类,随机森林还可以进行特征选择,故很推荐大家学习!!!

    决策树原理

            决策树通过把样本实例从根节点排列到某个叶子节点来对其进行分类。树上的每个非叶子节点代表对一个属性取值的测试,其分支就代表测试的每个结果;而树上的每个叶子节点均代表一个分类的类别,树的最高层节点是根节点。

    858701dbbd0844cab260d8a13c8dfca7.png

            由上图可知,决策树采用自顶向下的递归方式,从树的根节点开始,在它的内部节点上进行属性值的测试比较。然后按照给定实例的属性值确定对应的分支,最后在决策树的叶子节点得到结论。这个过程在以新的节点为根的子树上重复。

    决策树的优点与缺点

    优点:

    决策树容易理解和实现。

    对于决策树,数据的准备往往是比较简单或者是不必要的。其它技术往往要求先把数据归一化,比如去掉多余的或者空白的属性。

    能够同时处理数据型和常规型属性。其它的技术往往要求数据属性的单一。

    是一个白盒模型。如果给定一个观察的模型,那么根据所产生的决策树很容易推出相应的逻辑表达式。

    缺点

    对于各类别样本数量不一致的数据,在决策树当中信息增益的结果偏向于那些具有更多数值的特征。

    决策树内部节点的判别具有明确性,这种明确性可能会带来误导。

    随机森林

            随机森林算法基于Bootstrap方法重采样,产生多个训练集。不同的是,随机森林算法在构建决策树的时候,采用了随机选取分裂属性集的方法。

    代码实战

    1、决策树分类代码

    1. %% I. 清空环境变量
    2. clear all
    3. clc
    4. warning off
    5. %% II. 导入数据 第一列是序号 第二列是良性还是恶性(乳腺癌) 后面是特征属性30
    6. load data.mat
    7. %%
    8. % 1. 随机产生训练集/测试集
    9. a = randperm(569);
    10. Train = data(a(1:500),:); %产生500个训练集
    11. Test = data(a(501:end),:); %剩下的是测试集 69
    12. %%
    13. % 2. 训练数据
    14. P_train = Train(:,3:end);
    15. T_train = Train(:,2);
    16. %%
    17. % 3. 测试数据
    18. P_test = Test(:,3:end);
    19. T_test = Test(:,2);
    20. %% III. 创建决策树分类器
    21. ctree = ClassificationTree.fit(P_train,T_train);
    22. %%
    23. % 1. 查看决策树视图
    24. view(ctree);
    25. view(ctree,'mode','graph');
    26. %% IV. 仿真测试
    27. T_sim = predict(ctree,P_test);
    28. %% V. 结果分析
    29. count_B = length(find(T_train == 1));
    30. count_M = length(find(T_train == 2));
    31. rate_B = count_B / 500;
    32. rate_M = count_M / 500;
    33. total_B = length(find(data(:,2) == 1));
    34. total_M = length(find(data(:,2) == 2));
    35. number_B = length(find(T_test == 1));
    36. number_M = length(find(T_test == 2));
    37. number_B_sim = length(find(T_sim == 1 & T_test == 1));
    38. number_M_sim = length(find(T_sim == 2 & T_test == 2));
    39. disp(['病例总数:' num2str(569)...
    40. ' 良性:' num2str(total_B)...
    41. ' 恶性:' num2str(total_M)]);
    42. disp(['训练集病例总数:' num2str(500)...
    43. ' 良性:' num2str(count_B)...
    44. ' 恶性:' num2str(count_M)]);
    45. disp(['测试集病例总数:' num2str(69)...
    46. ' 良性:' num2str(number_B)...
    47. ' 恶性:' num2str(number_M)]);
    48. disp(['良性乳腺肿瘤确诊:' num2str(number_B_sim)...
    49. ' 误诊:' num2str(number_B - number_B_sim)...
    50. ' 确诊率p1=' num2str(number_B_sim/number_B*100) '%']);
    51. disp(['恶性乳腺肿瘤确诊:' num2str(number_M_sim)...
    52. ' 误诊:' num2str(number_M - number_M_sim)...
    53. ' 确诊率p2=' num2str(number_M_sim/number_M*100) '%']);
    54. %% VI. 叶子节点含有的最小样本数对决策树性能的影响
    55. leafs = logspace(1,2,10);
    56. N = numel(leafs);
    57. err = zeros(N,1);
    58. for n = 1:N
    59. t = ClassificationTree.fit(P_train,T_train,'crossval','on','minleaf',leafs(n));
    60. err(n) = kfoldLoss(t);
    61. end
    62. plot(leafs,err);
    63. xlabel('叶子节点含有的最小样本数');
    64. ylabel('交叉验证误差');
    65. title('叶子节点含有的最小样本数对决策树性能的影响')
    66. %% VII. 设置minleaf为13,产生优化决策树
    67. OptimalTree = ClassificationTree.fit(P_train,T_train,'minleaf',13);
    68. view(OptimalTree,'mode','graph')
    69. %%
    70. % 1. 计算优化后决策树的重采样误差和交叉验证误差
    71. resubOpt = resubLoss(OptimalTree)
    72. lossOpt = kfoldLoss(crossval(OptimalTree))
    73. %%
    74. % 2. 计算优化前决策树的重采样误差和交叉验证误差
    75. resubDefault = resubLoss(ctree)
    76. lossDefault = kfoldLoss(crossval(ctree))
    77. %% VIII. 剪枝
    78. [~,~,~,bestlevel] = cvLoss(ctree,'subtrees','all','treesize','min')
    79. cptree = prune(ctree,'Level',bestlevel);
    80. view(cptree,'mode','graph')
    81. %%
    82. % 1. 计算剪枝后决策树的重采样误差和交叉验证误差
    83. resubPrune = resubLoss(cptree)
    84. lossPrune = kfoldLoss(crossval(cptree))

     2、随机森林代码

    1. %% I. 清空环境变量
    2. clear all
    3. clc
    4. warning off
    5. %% II. 导入数据
    6. load data.mat
    7. %%
    8. % 1. 随机产生训练集/测试集
    9. a = randperm(569);
    10. Train = data(a(1:500),:);
    11. Test = data(a(501:end),:);
    12. %%
    13. % 2. 训练数据
    14. P_train = Train(:,3:end);
    15. T_train = Train(:,2);
    16. %%
    17. % 3. 测试数据
    18. P_test = Test(:,3:end);
    19. T_test = Test(:,2);
    20. %% III. 创建随机森林分类器
    21. model = classRF_train(P_train,T_train);
    22. %% IV. 仿真测试
    23. [T_sim,votes] = classRF_predict(P_test,model);
    24. %% V. 结果分析
    25. count_B = length(find(T_train == 1));
    26. count_M = length(find(T_train == 2));
    27. total_B = length(find(data(:,2) == 1));
    28. total_M = length(find(data(:,2) == 2));
    29. number_B = length(find(T_test == 1));
    30. number_M = length(find(T_test == 2));
    31. number_B_sim = length(find(T_sim == 1 & T_test == 1));
    32. number_M_sim = length(find(T_sim == 2 & T_test == 2));
    33. disp(['病例总数:' num2str(569)...
    34. ' 良性:' num2str(total_B)...
    35. ' 恶性:' num2str(total_M)]);
    36. disp(['训练集病例总数:' num2str(500)...
    37. ' 良性:' num2str(count_B)...
    38. ' 恶性:' num2str(count_M)]);
    39. disp(['测试集病例总数:' num2str(69)...
    40. ' 良性:' num2str(number_B)...
    41. ' 恶性:' num2str(number_M)]);
    42. disp(['良性乳腺肿瘤确诊:' num2str(number_B_sim)...
    43. ' 误诊:' num2str(number_B - number_B_sim)...
    44. ' 确诊率p1=' num2str(number_B_sim/number_B*100) '%']);
    45. disp(['恶性乳腺肿瘤确诊:' num2str(number_M_sim)...
    46. ' 误诊:' num2str(number_M - number_M_sim)...
    47. ' 确诊率p2=' num2str(number_M_sim/number_M*100) '%']);
    48. %% VI. 绘图
    49. figure
    50. index = find(T_sim ~= T_test);
    51. plot(votes(index,1),votes(index,2),'r*')
    52. hold on
    53. index = find(T_sim == T_test);
    54. plot(votes(index,1),votes(index,2),'bo')
    55. hold on
    56. legend('错误分类样本','正确分类样本')
    57. plot(0:500,500:-1:0,'r-.')
    58. hold on
    59. plot(0:500,0:500,'r-.')
    60. hold on
    61. line([100 400 400 100 100],[100 100 400 400 100])
    62. xlabel('输出为类别1的决策树棵数')
    63. ylabel('输出为类别2的决策树棵数')
    64. title('随机森林分类器性能分析')
    65. %% VII. 随机森林中决策树棵数对性能的影响
    66. Accuracy = zeros(1,20);
    67. for i = 50:50:1000 %模拟从50棵树到1000棵树的一个结果,每次增加50棵 i
    68. %每种情况,运行100次,取平均值
    69. accuracy = zeros(1,100);
    70. for k = 1:100
    71. % 创建随机森林
    72. model = classRF_train(P_train,T_train,i);
    73. % 仿真测试
    74. T_sim = classRF_predict(P_test,model);
    75. accuracy(k) = length(find(T_sim == T_test)) / length(T_test);
    76. end
    77. Accuracy(i/50) = mean(accuracy);
    78. end
    79. % 1. 绘图
    80. figure
    81. plot(50:50:1000,Accuracy)
    82. xlabel('随机森林中决策树棵数')
    83. ylabel('分类正确率')
    84. title('随机森林中决策树棵数对性能的影响')

    结果展示

     1、决策树

    59122aaaa37f427ab554b43dd250ecf3.png

    e8f2b06e3f0449d79b6956c4508d2e9e.pngcd5164a0443842ed9e3bc3bfa99a05cf.png

     2、随机森林

    128221438264461dbd62bcc2600df51e.png

     3f8bea77d3d649d5aed17038a6056707.png

  • 相关阅读:
    安科瑞为工业能效提升行动计划提供EMS解决方案-安科瑞黄安南
    显示杂谈(二)winscope的使用
    【数据结构】链式二叉树(超详细)
    Unity - Shader - Projector 高空云层底下透明阴影
    lua中select函数的用法
    初级图论
    【DevOps工具篇】LDAP服务器(slapd)的冗余和扩展功能
    Redis的开发利用
    java计算机毕业设计springboot+vue南天在线求助系统
    图表背后的故事:数据可视化的威力与影响
  • 原文地址:https://blog.csdn.net/qq_45013535/article/details/127766738