算法原理
随机森林由多个决策树构成,每棵树在训练时使用随机选择的样本和特征子集。在分类任务中,每棵树对新的输入样本进行分类,最终的分类结果由多数树的分类结果决定。这种方法可以提高预测的准确性,并且通过平均或投票机制减少过拟合的风险。
决策树示例
假如共有5个学生样本:每个学生的属性包含姓名、年龄、身高、体重,现有需要通过一个决策树对这些学生进行分类,决策树就是根据这些属性对学生进行分类,如下面的样本所示:小明在年龄方面与其它学生相比,较小,因此作为第一个区分特征,如下图中的决策树,首先通过年龄特征将小明区分出来;然后对样本2、3、4,即小李、小刘和小王进行进一步区分,可见,小刘身高明显较高,因此通过身高特征将小刘区分出来;然后对样本2、4,即小李和小王进行区分,此时通过体重将两者区分开来。
样本示例:
样本编号 姓名 年龄 身高(cm) 体重(kg)
1 小明 11 145 37.5
2 小李 21 172 65
3 小刘 22 178 70
4 小王 23 170 55
样本对应决策树:
决策树示意图
随机森林实现过程:
1. 数据准备
- 加载数据集:加载待处理的数据集,如鸢尾花数据集。
- 数据分割:通常需要将数据集分割为训练集和测试集,以便后续评估模型性能。
2. 参数设置
- 树的数量:决定随机森林中决策树的数量,这个参数也称为
n_estimators
。 - 特征选择:设置在每个决策树节点分裂时考虑的特征数量。
- 最小叶节点样本数:设置决策树叶节点的最小样本数,这个参数有助于控制过拟合。
- bootstrap 采样:决定是否在构建每棵决策树时使用 bootstrap 采样方法从原始数据集中抽取样本。
3. 构建决策树
对于随机森林中的每一棵决策树:
- 样本抽取:如果使用 bootstrap 采样,从训练集中有放回地随机抽取样本。
- 特征随机选择:在每个决策节点,随机选择一部分特征,然后选择最佳分裂特征进行节点分裂。
- 树的构建:使用选定的特征和样本构建决策树,直到满足停止条件(如达到最大深度、最小叶节点样本数或纯度)。
4. 模型训练
- 集成多棵树:重复步骤3,构建多棵决策树,每棵树都在数据的一个随机子集上训练。
- 存储模型:将每棵树的模型存储在森林中。
5. 预测和投票
- 分类问题:对于新的输入样本,每棵树给出一个类别预测,然后通过多数投票机制决定最终的类别预测。
- 回归问题:对于新的输入样本,每棵树给出一个数值预测,然后计算这些预测的平均值作为最终的回归预测。
6. 模型评估
- 测试集评估:使用测试集评估随机森林模型的性能,计算准确率、精确率、召回率等指标。
- 特征重要性:评估每个特征对模型预测的贡献度。
示例
数据集介绍
鸢尾花(Iris)数据集是机器学习和统计分类中最著名的数据集之一,常被用作分类算法的测试数据。这个数据集包含150个样本,分为3个类别,每个类别有50个样本。每个样本有4个特征,分别是:
- 花萼长度(Sepal Length):花萼的最大长度,单位为厘米。
- 花萼宽度(Sepal Width):花萼的最大宽度,单位为厘米。
- 花瓣长度(Petal Length):花瓣的最大长度,单位为厘米。
- 花瓣宽度(Petal Width):花瓣的最大宽度,单位为厘米。
这些特征都是连续的数值型数据。鸢尾花数据集的三个类别分别是:
- Iris Setosa(山鸢尾)
- Iris Versicolor(变色鸢尾)
- Iris Virginica(维吉尼亚鸢尾)
对该数据集通过matlab进行可视化,可视化效果图如下所示:
效果图中的四个feature和4个特征的对应关系如下:
feature1
:花萼长度(Sepal Length)- 单位为厘米。feature2
:花萼宽度(Sepal Width)- 单位为厘米。feature3
:花瓣长度(Petal Length)- 单位为厘米。feature4
:花瓣宽度(Petal Width)- 单位为厘米。
效果图中每张图表示的是两个特征组合后样本的分布结果,从左到右、从上到下,每张图分别表示不同的两个特征组合后样本的分布图。
实现代码及步骤效果
% 1. 数据准备
load fisheriris
data = meas; % 特征数据
labels = species; % 标签
% 随机分割数据集为训练集和测试集
cv = cvpartition(labels, 'HoldOut', 0.3);
idx = cv.test;
% 训练集
trainData = data(~idx, :);
trainLabels = labels(~idx);
% 测试集
testData = data(idx, :);
testLabels = labels(idx);
% 2. 参数设置
nTrees = 100; % 树的数量
numVariablesToSample = 'sqrt'; % 或者使用 2 或 'all'
minLeafSize = 1; % 最小叶节点样本数
numVariablesToSample = 'all'; % 使用所有特征
% 3. 构建决策树
model = TreeBagger(nTrees, trainData, trainLabels, ...
'OOBPrediction', 'On', ...
'MinLeafSize', minLeafSize, ...
'NumVariablesToSample', numVariablesToSample, ...
'OOBPredictorImportance', 'On'); % 确保这一行在这里
% 4. 进行预测
predictions = predict(model, testData);
% 5. 评估模型性能
confMat = confusionmat(testLabels, predictions);
accuracy = sum(diag(confMat)) / sum(confMat(:));
% 显示混淆矩阵和准确率
disp('Confusion Matrix:');
disp(confMat);
disp(['Accuracy: ', num2str(accuracy)]);
获得的混淆矩阵如下所示:
混淆矩阵的行列分别为三个类别:如图所示的混淆矩阵表示:属于类别1的样本在通过随机森林分类器的识别下全部被识别为类别1;属于类别2的样本有13个被识别为类别2,有2个被识别为类别3,属于类别3的样本全部被识别为类别3。
获得的分类正确率如下所示:
% 6. 计算特征重要性
imp = model.OOBPermutedVarDeltaError;
% 可视化特征重要性
figure;
bar(imp);
xlabel('Features');
ylabel('Importance');
title('Feature Importance');
set(gca, 'XTickLabel', {'SepalLength', 'SepalWidth', 'PetalLength', 'PetalWidth'});
获得的特征重要性图如下图所示:
如图所示:在识别鸢尾花类别中,第三个特征的重要性最大,第二个特征的重要性最小。
% 7. 可视化训练集和测试集
figure;
gscatter(data(:,1), data(:,2), labels);
hold on;
gscatter(trainData(:,1), trainData(:,2), trainLabels, 'g', 'o', 5);
gscatter(testData(:,1), testData(:,2), testLabels, 'r', 'x', 5);
title('Training and Testing Data');
legend('Setosa', 'Versicolor', 'Virginica', 'Train', 'Test');
hold off;
可视化结果如下图所示:
如图所示,为三个类别的鸢尾花数据各自的训练样本和测试样本的分布,其中三种颜色的表示三个类别的训练样本,叉号的表示测试样本。 可见,本次随机选取的测试样本的分布过于集中到绿色类别样本中,需要对测试样本进行进一步的样本多样化的调整,才能得到更加可靠可信的结果。