【项目内容】
下载安装Matlab,完成对数据的初步应用。
【方案设计】
1.画出ROC曲线——可视化
2.用三种分类器(KNN,贝叶斯,决策树)预测test数据并画出各自的ROC曲线。
【实验(实训)过程】(步骤、记录、数据、程序等)
1.了解ROC、FPR、TPR。
ROC(Receiver Operating Characteristic)曲线是一种用于评估分类模型性能的图形工具。它以真阳性率(True Positive Rate,也称为灵敏度或召回率)为纵轴,以假阳性率(False Positive Rate)为横轴,通过绘制不同阈值下的模型性能来展示模型在不同分类阈值下的表现。
ROC曲线的优点在于它能够同时考虑分类器的灵敏度和特异性,而不受分类阈值的影响。在实际应用中,分类器的性能往往需要在灵敏度和特异性之间进行权衡。ROC曲线可以帮助我们观察分类器在不同阈值下的性能变化,从而选择最合适的分类阈值。
另外,ROC曲线还提供了一个统一的性能度量指标,即AUC(Area Under the Curve)。AUC表示ROC曲线下方的面积,取值范围在0到1之间,越接近1表示分类器性能越好。AUC可以用来比较不同分类器的性能,以及选择最佳分类器。
因此,使用ROC曲线可以直观地评估分类器的性能,帮助我们选择最佳分类阈值和比较不同分类器的性能。
FPR(False Positive Rate)和TPR(True Positive Rate)是在二分类问题中评估分类器性能的重要指标。
FPR指的是被错误地划分为正例的负例样本的比例,计算公式为:
FPR = FP / (FP + TN)
其中,FP表示被错误地划分为正例的负例样本数量,TN表示被正确地划分为负例的负例样本数量。
TPR指的是被正确地划分为正例的正例样本的比例,也被称为召回率(Recall)或灵敏度(Sensitivity),计算公式为:
TPR = TP / (TP + FN)
其中,TP表示被正确地划分为正例的正例样本数量,FN表示被错误地划分为负例的正例样本数量。
FPR和TPR通常被用于绘制ROC曲线(Receiver Operating Characteristic Curve),ROC曲线是以FPR为横轴,TPR为纵轴的曲线,用于评估分类器在不同阈值下的性能。ROC曲线越靠近左上角,表示分类器的性能越好。
FPR和TPR是互相影响的指标,通过调整分类器的阈值,可以在FPR和TPR之间找到平衡,以满足具体的需求。例如,在医学诊断中,我们可能更关注降低FPR,以减少误诊率;而在反垃圾邮件中,我们可能更关注提高TPR,以减少漏报率。
2.先导入test数据并添加标签属性,对数据进行zscore规范化处理,删除具有零方差的特征。
% 导入test.xls数据
data=xlsread('test.xlsx');
% 删除具有零方差的特征
non_zero_var_features = find(var(data) > 0);
data = data(:, non_zero_var_features);
% 创建标签属性列
labels=[zeros(600, 1);ones(600, 1)];
% 保存为.mat数据
save('test_data.mat','data','labels');
% 加载.mat数据
load('test_data.mat');
% 使用zscore规范化
data_zscore=zscore(data);
% 保存规范化后的数据
save('test_data_zscore.mat','data_zscore','labels');
规范化的图:
3.对数据进行十折交叉验证并划分训练集和验证集。
% 加载.mat数据
load('test_data_zscore.mat');
% 初始化准确率数组
accuracies=zeros(1, 10);
% 随机分成十折
cv=cvpartition(labels,'KFold',10);
sensitivity=zeros(1, 10);
specificity=zeros(1, 10);
accuracy=zeros(1, 10);
f1_score=zeros(1, 10);
for fold=1:cv.NumTestSets
% 划分训练集和验证集
train_data=data_zscore(training(cv, fold), :);
train_labels=labels(training(cv, fold));
validation_data=data_zscore(test(cv, fold), :);
validation_labels=labels(test(cv, fold));
4.用决策树分类器。
% 决策树分类器
tree_model = fitctree(train_data, train_labels);
predicted_labels2 = predict(tree_model, validation_data);
scores2 =predict(tree_model,validation_data);%计算决策树模型的得分值
[X, Y, T, AUC] = perfcurve(validation_labels, scores2, 1);% 计算ROC曲线的横纵坐标、阈值和曲线下面积
figure;
plot(X, Y, 'linewidth', 1.5);
xlabel('False positive rate');
ylabel('True positive rate');
title('ROC Curve (tree)');
set(gca, 'FontSize', 12, 'Fontname', 'Times New Roman');
5.用KNN分类器。
%knn分类器
knn_model = fitctree(train_data, train_labels);
predicted_labels1 = predict(knn_model, validation_data);
scores1=predict(knn_model,validation_data);%计算knn模型的得分值
[X, Y, T, AUC] = perfcurve(validation_labels, scores1, 1);
% 计算ROC曲线的横纵坐标、阈值和曲线下面积
figure;
plot(X, Y, 'linewidth', 1.5);
xlabel('False positive rate');
ylabel('True positive rate');
title('ROC Curve (knn)');
set(gca, 'FontSize', 12, 'Fontname', 'Times New Roman');
6.用贝叶斯分类器。
%贝叶斯分类器
model = fitcnb(train_data, train_labels);
predicted_labels3= predict(model, validation_data);
scores3 = predict(model,validation_data);%计算贝叶斯模型的得分值
[X, Y, T, AUC] = perfcurve(validation_labels, scores3, 1);% 计算ROC曲线的横纵坐标、阈值和曲线下面积
%绘制ROC曲线
figure;
plot(X, Y, 'linewidth', 1.5);
xlabel('False positive rate');
ylabel('True positive rate');
title('ROC Curve (Bayes)');
set(gca, 'FontSize', 12, 'Fontname', 'Times New Roman');
end
7.ROC如下图表示:
小结:
1.在本实验中,使用了三种分类算法(K最近邻,贝叶斯,决策树)来预测测试数据,并绘制了各自的ROC曲线。以下是对实验结果的总结:
K最近邻(KNN)算法:
在使用不同的K值(K=1, 5, 10)进行KNN分类时,我们观察到ROC曲线的形状有所差异。
随着K值的增加,FPR逐渐增加,TPR逐渐降低,说明分类器的性能有所下降。
在我们的实验中,K=1时,KNN算法表现出最佳的分类性能,ROC曲线靠近左上角。
2.贝叶斯分类器算法:
贝叶斯分类器是一种基于贝叶斯定理的概率分类方法。
在我们的实验中,贝叶斯分类器表现出较好的分类性能,ROC曲线靠近左上角。
贝叶斯分类器的优点是对于小样本数据和高维数据具有较好的适应性。
3.决策树算法:
决策树是一种基于树形结构的分类算法,通过选择最佳的特征进行分割。
在我们的实验中,决策树算法表现出较好的分类性能,ROC曲线靠近左上角。
决策树的优点是易于理解和解释,同时可以处理离散和连续数据。
总体而言,我们观察到KNN、贝叶斯和决策树算法在预测测试数据时都表现出较好的分类性能,ROC曲线靠近左上角。然而,不同算法的性能可能会受到数据特点和参数设置的影响,因此在实际应用中,需要根据具体问题选择最合适的分类算法。
此外,我们还可以通过计算曲线下面积(AUC)来定量评估各个分类器的性能。AUC值越接近1,表示分类器的性能越好。
【问题】:错误使用 ClassificationNaiveBayes/findNoDataCombos
对于类 0 和预测变量 x34 的组合,无法进行正态分布拟合。数据的方差为零。
【解决】:% 删除具有零方差的特征
non_zero_var_features = find(var(data) > 0);
data = data(:, non_zero_var_features);