将 PCA 应用于新数据
使用 readtable 将数据集加载到表中。数据集在文件 CreditRating_Historical.dat 中,其中包含历史信用评分数据。
creditrating = readtable('CreditRating_Historical.dat');
creditrating(1:5,:)
ans=5×8 table
ID WC_TA RE_TA EBIT_TA MVE_BVTD S_TA Industry Rating
_____ _____ _____ _______ ________ _____ ________ _______
62394 0.013 0.104 0.036 0.447 0.142 3 {'BB' }
48608 0.232 0.335 0.062 1.969 0.281 8 {'A' }
42444 0.311 0.367 0.074 1.935 0.366 1 {'A' }
48631 0.194 0.263 0.062 1.017 0.228 4 {'BBB'}
43768 0.121 0.413 0.057 3.647 0.466 12 {'AAA'}
第一列是每个观测值的 ID,最后一列是评分。将第二列至第七列指定为预测变量数据,并将最后一列 (Rating) 指定为响应。
X = table2array(creditrating(:,2:7));
Y = creditrating.Rating;
使用前 100 个观测值作为测试数据,其余的作为训练数据。
XTest = X(1:100,:);
XTrain = X(101:end,:);
YTest = Y(1:100);
YTrain = Y(101:end);
计算训练数据集 XTrain 的主成分。
[coeff,scoreTrain,~,~,explained,mu] = pca(XTrain);
此代码返回四个输出:coeff、scoreTrain、explained 和 mu。使用 explained(解释方差占总方差的百分比)计算解释至少 95% 变异性所需的成分的数目。使用 coeff(主成分系数)和 mu(XTrain 的估计均值)将 PCA 应用于测试数据集。在训练模型时,请使用 scoreTrain(主成分分数)而不是 XTrain。
显示由主成分解释的变异性百分比。
explained
explained = 6×1
58.2614
41.2606
0.3875
0.0632
0.0269
0.0005
前两个成分解释了 95% 以上的变异性。通过使用 while 循环,以编程方式计算解释至少 95% 变异性所需的成分的数目。
sum_explained = 0;
idx = 0;
while sum_explained < 95
idx = idx + 1;
sum_explained = sum_explained + explained(idx);
end
idx
idx = 2
使用前两个成分训练分类树。
scoreTrain95 = scoreTrain(:,1:idx);
mdl = fitctree(scoreTrain95,YTrain);
mdl 是一个 ClassificationTree 模型。
要对测试集使用训练模型,您需要使用从训练数据集获得的 PCA 来转换测试数据集。通过从 XTest 中减去 mu 再乘以 coeff 获得测试数据集的主成分分数。只需要前两个成分的分数,因此使用前两个系数 coeff(:,1:idx)。
scoreTest95 = (XTest-mu)*coeff(:,1:idx);
将经过训练的模型 mdl 和转换后的测试数据集 scoreTest 传递给 predict 函数,以预测测试集的评分。
YTest_predicted = predict(mdl,scoreTest95);
生成代码
生成代码,这些代码将 PCA 应用于数据并使用经过训练的模型预测评分。请注意,生成 C/C++ 代码需要 MATLAB® Coder™。
使用 saveLearnerForCoder 将分类模型保存到文件 myMdl.mat 中。
saveLearnerForCoder(mdl,'myMdl');
定义名为 myPCAPredict 的入口函数,该函数接受测试数据集 (XTest) 和 PCA 信息(coeff 和 mu),并返回测试数据的评分。
在入口函数的函数签名后面添加 %#codegen 编译器指令(即 pragma),以指示您要为此 MATLAB 算法生成代码。添加此指令指示 MATLAB 代码分析器帮助您诊断和修复在代码生成过程中可能导致错误的违规。
type myPCAPredict % Display contents of myPCAPredict.m
function label = myPCAPredict(XTest,coeff,mu) %#codegen
% Transform data using PCA
scoreTest = bsxfun(@minus,XTest,mu)*coeff;
% Load trained classification model
mdl = loadLearnerForCoder('myMdl');
% Predict ratings using the loaded model
label = predict(mdl,scoreTest);
myPCAPredict 使用 coeff 和 mu 将 PCA 应用于新数据,然后使用转换后的数据预测评分。这样,您就不必传递有可能特别大的训练数据。
注意:如果您点击位于此页右上角的按钮,并在 MATLAB® 中打开此示例,则 MATLAB® 将打开示例文件夹。该文件夹包括入口函数文件。
使用 codegen(MATLAB Coder) 生成代码。由于 C 和 C++ 是静态类型语言,因此必须在编译时确定入口函数中所有变量的属性。要指定数据类型和精确的输入数组大小,请使用 -args 选项传递表示具有特定数据类型和数组大小的值集的 MATLAB® 表达式。如果在编译时观测值数目未知,您也可以使用 coder.typeof(MATLAB Coder) 将输入指定为可变大小。有关详细信息,请参阅Specify Variable-Size Arguments for Code Generation。
codegen myPCAPredict -args {coder.typeof(XTest,[Inf,6],[1,0]),coeff(:,1:idx),mu}
codegen 生成 MEX 函数 myPCAPredict_mex,扩展名因平台而异。
验证生成的代码。
YTest_predicted_mex = myPCAPredict_mex(XTest,coeff(:,1:idx),mu);
isequal(YTest_predicted,YTest_predicted_mex)
ans = logical
1
isequal 返回逻辑值 1 (true),这意味着所有输入都相等。比较结果证实,mdl 的 predict 函数和 myPCAPredict_mex 函数返回相同的评分。