第24节 特征选择(续)
5、 调节正则化参数
robotarm 测试数据集具有7168 训练样本 1024测试样本 32 特征
>> clear
load(fullfile(matlabroot,'examples','stats','robotarm.mat'))
nca = fsrnca(Xtrain,ytrain,'FitMethod','exact', ...
'Solver','lbfgs');
figure
plot(nca.FeatureWeights,'ro')
xlabel('Feature index')
ylabel('Feature weight')
grid on
有一半的权重不等于0。计算当前的损失函数数值
>> L = loss(nca,Xtest,ytest)
L =
0.0837
为了改善结果,使用五折交叉验证法来调整lambda的数值(以下计算需要花一点时间)
>> rng(1)
n = length(ytrain);
cvp = cvpartition(length(ytrain),'kfold',5); % 五折交叉
numvalidsets = cvp.NumTestSets;
lambdavals = linspace(0,50,20)*std(ytrain)/n; % 备选lambda的数值
lossvals = zeros(length(lambdavals),numvalidsets);
for i = 1:length(lambdavals)
for k = 1:numvalidsets
X = Xtrain(cvp.training(k),:);
y = ytrain(cvp.training(k),:);
Xvalid = Xtrain(cvp.test(k),:);
yvalid = ytrain(cvp.test(k),:);
nca = fsrnca(X,y,'FitMethod','exact', ...
'Solver','minibatch-lbfgs','Lambda',lambdavals(i), ...
'GradientTolerance',1e-4,'IterationLimit',30);
lossvals(i,k) = loss(nca,Xvalid,yvalid,'LossFunction','mse');
end
end
meanloss = mean(lossvals,2); % 平均误差
figure
plot(lambdavals,meanloss,'ro-')
xlabel('Lambda')
ylabel('Loss (MSE)')
grid on
[~,idx] = min(meanloss) % 求最小值
bestlambda = lambdavals(idx) % 最佳的lambda
bestloss = meanloss(idx) % 最佳的平均误差
idx =
17
bestlambda =
0.0059
bestloss =
0.0590
使用最佳的lambda拟合NCA特征选择模型
>> nca = fsrnca(Xtrain,ytrain,'FitMethod','exact', ...
'Solver','lbfgs','Lambda',bestlambda);
绘制特征权重
>> figure
plot(nca.FeatureWeights,'ro')
xlabel('Feature Index')
ylabel('Feature Weight')
grid on
6、特征提取
采用MNIST数据集进行测试。MNIST数据集是一个手写体数据集。
>> load('mnistdata.mat')
rng('default') % For reproducibility
numrows = size(Xtrain,1);
ims = randi(numrows,4,1);
imgs = Xtrain(ims,:);
for i = 1:4
pp{i} = reshape(imgs(i,:),28,28);
end
ppf = [pp{1},pp{2};pp{3},pp{4}];
imshow(ppf);
MNIST数据集有784个特征,特征越多,运算需要的内存和时间越多。但是特征比较少会导致准确率下降。
所以需要选择合适的特征数量,以在时间和准确率之间进行平衡。
>> q = 100; % 指定特征数量
Mdl = sparsefilt(Xtrain,