大规模特征选择的自适应粒子群优化算法(MATLAB实现)
2026-1-8
大规模特征选择的自适应粒子群优化算法(MATLAB实现)
自适应粒子群优化(APSO)特征选择算法的MATLAB实现,专为大规模分类问题设计。
1. 主程序:APSO特征选择
%% 主程序:自适应粒子群特征选择
clear; close all; clc;
warning('off', 'all');
%% 1. 加载和预处理数据
fprintf('=== APSO大规模特征选择算法 ===\n');
% 选择测试数据集
dataset_choice = 2; % 1: 人工生成,2: 实际数据集
switch dataset_choice
case 1
% 生成人工数据集(大规模特征)
[X, y, feature_names] = generate_synthetic_data(1000, 10000, 50);
fprintf('生成人工数据集: %d样本 × %d特征\n', size(X,1), size(X,2));
case 2
% 加载实际数据集(需要修改路径)
try
% 示例:使用内置的fisheriris数据集(小规模示例)
load fisheriris;
X = meas;
y = grp2idx(species);
feature_names = {'Sepal Length', 'Sepal Width', 'Petal Length', 'Petal Width'};
fprintf('加载fisheriris数据集: %d样本 × %d特征\n', size(X,1), size(X,2));
catch
% 如果无法加载,使用模拟数据
fprintf('无法加载实际数据集,使用模拟数据\n');
[X, y, feature_names] = generate_synthetic_data(200, 2000, 3);
end
case 3
% 加载.mat格式的数据集
% load('your_dataset.mat'); % 请修改为您的数据路径
% 假设数据存储在X, y变量中
error('请设置您自己的数据集路径');
end
% 数据标准化(重要!)
X = zscore(X);
% 划分训练测试集
rng(42); % 设置随机种子以保证可重复性
[trainInd, testInd] = dividerand(size(X,1), 0.7, 0.3);
X_train = X(trainInd, :);
y_train = y(trainInd);
X_test = X(testInd, :);
y_test = y(testInd);
fprintf('训练集: %d样本, 测试集: %d样本\n', length(y_train), length(y_test));
%% 2. 参数设置
params = struct();
params.nParticles = 30; % 粒子数量
params.maxIter = 100; % 最大迭代次数
params.wMax = 0.9; % 最大惯性权重
params.wMin = 0.4; % 最小惯性权重
params.c1 = 2.0; % 个体学习因子
params.c2 = 2.0; % 社会学习因子
params.mutationRate = 0.1; % 变异率
params.threshold = 0.6; % 特征选择阈值
params.alpha = 0.95; % 分类准确率权重
params.beta = 0.05; % 特征数量惩罚权重
params.cvFolds = 5; % 交叉验证折数
params.earlyStop = 20; % 早停迭代数
% 分类器选择(支持多种分类器)
classifier_type = 'svm'; % 'svm', 'knn', 'tree', 'ensemble'
switch classifier_type
case 'svm'
classifier = @(X_train, y_train, X_test) svm_classifier(X_train, y_train, X_test);
case 'knn'
classifier = @(X_train, y_train, X_test) knn_classifier(X_train, y_train, X_test);
case 'tree'
classifier = @(X_train, y_train, X_test) tree_classifier(X_train, y_train, X_test);
case 'ensemble'
classifier = @(X_train, y_train, X_test) ensemble_classifier(X_train, y_train, X_test);
end
%% 3. 运行APSO特征选择算法
fprintf('\n开始APSO特征选择...\n');
tic;
[bestPosition, bestFitness, history] = APSO_FeatureSelection(...
X_train, y_train, params, classifier);
runtime = toc;
fprintf('APSO特征选择完成!耗时: %.2f秒\n', runtime);
%% 4. 提取选择的特征
selectedFeatures = bestPosition > params.threshold;
selectedIndices = find(selectedFeatures);
selectedFeatureNames = feature_names(selectedIndices);
fprintf('\n=== 特征选择结果 ===\n');
fprintf('总特征数: %d\n', size(X,2));
fprintf('选择特征数: %d (%.1f%%)\n', sum(selectedFeatures), ...
sum(selectedFeatures)/size(X,2)*100);
fprintf('最佳适应度: %.4f\n', bestFitness);
% 显示选择的重要特征(按重要性排序)
if ~isempty(selectedIndices)
fprintf('\n选择的特征索引:\n');
disp(selectedIndices');
if length(feature_names) <= 50
fprintf('\n选择的特征名称:\n');
for i = 1:min(20, length(selectedFeatureNames))
fprintf('%d. %s\n', i, selectedFeatureNames{i});
end
if length(selectedFeatureNames) > 20
fprintf('... 还有%d个特征\n', length(selectedFeatureNames)-20);
end
end
end
%% 5. 评估特征选择性能
fprintf('\n=== 性能评估 ===\n');
% 5.1 使用所有特征训练分类器
fprintf('使用所有特征 (%d个):\n', size(X_train,2));
[~, y_pred_all, metrics_all] = classifier(X_train, y_train, X_test);
fprintf(' 测试准确率: %.2f%%\n', metrics_all.accuracy * 100);
fprintf(' F1分数: %.4f\n', metrics_all.f1);
fprintf(' 运行时间: %.4f秒\n', metrics_all.time);
% 5.2 使用选择的特征训练分类器
X_train_selected = X_train(:, selectedIndices);
X_test_selected = X_test(:, selectedIndices);
fprintf('\n使用选择特征 (%d个):\n', sum(selectedFeatures));
[~, y_pred_selected, metrics_selected] = classifier(...
X_train_selected, y_train, X_test_selected);
fprintf(' 测试准确率: %.2f%%\n', metrics_selected.accuracy * 100);
fprintf(' F1分数: %.4f\n', metrics_selected.f1);
fprintf(' 运行时间: %.4f秒\n', metrics_selected.time);
% 计算改进
accuracy_improvement = (metrics_selected.accuracy - metrics_all.accuracy) * 100;
time_reduction = (metrics_all.time - metrics_selected.time) / metrics_all.time * 100;
fprintf('\n性能改进:\n');
fprintf(' 准确率提升: %.2f%%\n', accuracy_improvement);
fprintf(' 计算时间减少: %.1f%%\n', time_reduction);
%% 6. 可视化结果
figure('Position', [100, 100, 1400, 800]);
% 6.1 收敛曲线
subplot(2, 3, 1);
plot(1:length(history.bestFitness), history.bestFitness, 'b-', 'LineWidth', 2);
hold on;
plot(1:length(history.avgFitness), history.avgFitness, 'r--', 'LineWidth', 1.5);
xlabel('迭代次数');
ylabel('适应度');
title('APSO收敛曲线');
legend('最佳适应度', '平均适应度', 'Location', 'best');
grid on;
% 6.2 选择特征数量变化
subplot(2, 3, 2);
plot(1:length(history.bestFeaturesCount), history.bestFeaturesCount, 'g-', 'LineWidth', 2);
xlabel('迭代次数');
ylabel('特征数量');
title('最佳粒子特征数量变化');
grid on;
% 6.3 惯性权重变化
subplot(2, 3, 3);
plot(1:length(history.w), history.w, 'm-', 'LineWidth', 2);
xlabel('迭代次数');
ylabel('惯性权重');
title('自适应惯性权重变化');
grid on;
% 6.4 特征重要性(基于选择频率)
subplot(2, 3, 4);
if isfield(history, 'featureFrequency')
bar(history.featureFrequency);
xlabel('特征索引');
ylabel('选择频率');
title('特征选择频率');
grid on;
end
% 6.5 混淆矩阵(选择特征)
subplot(2, 3, 5);
plotConfusionMatrix(y_test, y_pred_selected);
title('选择特征后的混淆矩阵');
% 6.6 特征空间可视化(PCA)
subplot(2, 3, 6);
if sum(selectedFeatures) > 1
% 使用PCA降维可视化
[coeff, score] = pca(X_test_selected);
if size(score, 2) >= 2
gscatter(score(:,1), score(:,2), y_test);
xlabel('第一主成分');
ylabel('第二主成分');
title('选择特征后的PCA可视化');
grid on;
end
end
%% 7. 保存结果
results = struct();
results.selectedFeatures = selectedFeatures;
results.selectedIndices = selectedIndices;
results.bestFitness = bestFitness;
results.history = history;
results.params = params;
results.performance = struct(...
'all_features', metrics_all, ...
'selected_features', metrics_selected);
save('APSO_FeatureSelection_Results.mat', 'results');
fprintf('\n结果已保存到 APSO_FeatureSelection_Results.mat\n');
%% 8. 批量测试不同参数
if false % 设置为true进行参数敏感性分析
fprintf('\n=== 参数敏感性分析 ===\n');
test_parameter_sensitivity(X_train, y_train, X_test, y_test);
end
fprintf('\nAPSO特征选择算法执行完毕!\n');
2. 核心APSO算法实现
function [bestPosition, bestFitness, history] = APSO_FeatureSelection(...
X_train, y_train, params, classifier)
% 自适应粒子群优化特征选择算法
%
% 输入:
% X_train - 训练特征矩阵 (n_samples × n_features)
% y_train - 训练标签向量
% params - 参数结构体
% classifier - 分类器函数句柄
%
% 输出:
% bestPosition - 最佳特征选择向量
% bestFitness - 最佳适应度值
% history - 历史记录结构体
% 获取数据维度
[nSamples, nFeatures] = size(X_train);
% 初始化历史记录
history.bestFitness = zeros(params.maxIter, 1);
history.avgFitness = zeros(params.maxIter, 1);
history.bestFeaturesCount = zeros(params.maxIter, 1);
history.w = zeros(params.maxIter, 1); % 惯性权重记录
history.featureFrequency = zeros(nFeatures, 1); % 特征选择频率
% 1. 初始化粒子群
[positions, velocities, personalBestPositions, personalBestFitness] = ...
initializeParticles(params.nParticles, nFeatures);
% 2. 计算初始适应度
for i = 1:params.nParticles
personalBestFitness(i) = evaluateFitness(...
positions(i,:), X_train, y_train, params, classifier);
end
% 3. 初始化全局最优
[globalBestFitness, globalBestIdx] = max(personalBestFitness);
globalBestPosition = positions(globalBestIdx, :);
% 4. 主迭代循环
noImprovementCount = 0;
for iter = 1:params.maxIter
% 4.1 自适应调整参数
w = adaptiveInertiaWeight(iter, params.maxIter, params.wMax, params.wMin);
history.w(iter) = w;
[c1, c2] = adaptiveLearningFactors(iter, params.maxIter, params.c1, params.c2);
% 4.2 更新每个粒子
for i = 1:params.nParticles
% 更新速度
r1 = rand(1, nFeatures);
r2 = rand(1, nFeatures);
velocities(i,:) = w * velocities(i,:) + ...
c1 * r1 .* (personalBestPositions(i,:) - positions(i,:)) + ...
c2 * r2 .* (globalBestPosition - positions(i,:));
% 限制速度范围
velocities(i,:) = max(min(velocities(i,:), 6), -6);
% 更新位置(使用sigmoid函数转换为概率)
sigmoid_v = 1 ./ (1 + exp(-velocities(i,:)));
positions(i,:) = sigmoid_v > rand(1, nFeatures);
% 确保至少选择一个特征
if sum(positions(i,:)) == 0
positions(i, randi(nFeatures)) = 1;
end
% 变异操作(避免早熟收敛)
if rand() < params.mutationRate
mutationMask = rand(1, nFeatures) < 0.1;
positions(i,:) = xor(positions(i,:), mutationMask);
% 再次确保至少选择一个特征
if sum(positions(i,:)) == 0
positions(i, randi(nFeatures)) = 1;
end
end
% 计算当前适应度
currentFitness = evaluateFitness(...
positions(i,:), X_train, y_train, params, classifier);
% 更新个体最优
if currentFitness > personalBestFitness(i)
personalBestFitness(i) = currentFitness;
personalBestPositions(i,:) = positions(i,:);
% 更新全局最优
if currentFitness > globalBestFitness
globalBestFitness = currentFitness;
globalBestPosition = positions(i,:);
noImprovementCount = 0; % 重置早停计数器
else
noImprovementCount = noImprovementCount + 1;
end
else
noImprovementCount = noImprovementCount + 1;
end
end
% 4.3 记录历史信息
history.bestFitness(iter) = globalBestFitness;
history.avgFitness(iter) = mean(personalBestFitness);
history.bestFeaturesCount(iter) = sum(globalBestPosition > params.threshold);
% 更新特征选择频率
featureSelectionCount = sum(positions > params.threshold, 1);
history.featureFrequency = history.featureFrequency + featureSelectionCount';
% 4.4 显示进度
if mod(iter, 10) == 0 || iter == 1
fprintf('迭代 %3d: 最佳适应度 = %.4f, 选择特征 = %d\n', ...
iter, globalBestFitness, history.bestFeaturesCount(iter));
end
% 4.5 早停检查
if noImprovementCount >= params.earlyStop && iter > 30
fprintf('早停在迭代 %d (连续%d次无改进)\n', iter, noImprovementCount);
break;
end
end
% 5. 返回结果
bestPosition = globalBestPosition;
bestFitness = globalBestFitness;
% 截断历史记录
history.bestFitness = history.bestFitness(1:iter);
history.avgFitness = history.avgFitness(1:iter);
history.bestFeaturesCount = history.bestFeaturesCount(1:iter);
history.w = history.w(1:iter);
% 归一化特征频率
history.featureFrequency = history.featureFrequency / (params.nParticles * iter);
end
function [positions, velocities, personalBestPositions, personalBestFitness] = ...
initializeParticles(nParticles, nFeatures)
% 初始化粒子群
% 初始化位置(二进制)
positions = rand(nParticles, nFeatures) > 0.5;
% 确保每个粒子至少选择一个特征
for i = 1:nParticles
if sum(positions(i,:)) == 0
positions(i, randi(nFeatures)) = 1;
end
end
% 初始化速度
velocities = randn(nParticles, nFeatures) * 0.1;
% 初始化个体最优
personalBestPositions = positions;
personalBestFitness = -inf(nParticles, 1);
end
function fitness = evaluateFitness(position, X_train, y_train, params, classifier)
% 计算适应度函数
% 获取选择的特征索引
selectedIdx = find(position);
if isempty(selectedIdx)
fitness = -inf;
return;
end
% 提取选择的特征
X_selected = X_train(:, selectedIdx);
% 使用交叉验证评估分类性能
try
% 分层K折交叉验证
cv = cvpartition(y_train, 'KFold', params.cvFolds);
accuracies = zeros(cv.NumTestSets, 1);
f1_scores = zeros(cv.NumTestSets, 1);
for fold = 1:cv.NumTestSets
trainIdx = cv.training(fold);
testIdx = cv.test(fold);
X_train_fold = X_selected(trainIdx, :);
y_train_fold = y_train(trainIdx);
X_test_fold = X_selected(testIdx, :);
y_test_fold = y_train(testIdx);
% 训练和预测
[~, y_pred, metrics] = classifier(X_train_fold, y_train_fold, X_test_fold);
accuracies(fold) = metrics.accuracy;
f1_scores(fold) = metrics.f1;
end
avg_accuracy = mean(accuracies);
avg_f1 = mean(f1_scores);
catch ME
% 如果出错,返回负无穷适应度
fitness = -inf;
return;
end
% 计算特征数量惩罚
feature_ratio = length(selectedIdx) / size(X_train, 2);
% 综合适应度函数
fitness = params.alpha * avg_accuracy + ...
(1 - params.alpha) * avg_f1 - ...
params.beta * feature_ratio;
end
function w = adaptiveInertiaWeight(iter, maxIter, wMax, wMin)
% 自适应惯性权重(线性递减)
w = wMax - (wMax - wMin) * iter / maxIter;
end
function [c1, c2] = adaptiveLearningFactors(iter, maxIter, c1_init, c2_init)
% 自适应学习因子
% 前期注重个体认知,后期注重社会认知
c1 = c1_init * (1 - iter/(2*maxIter));
c2 = c2_init * (1 + iter/(2*maxIter));
end
3. 分类器实现
%% 分类器函数
function [model, y_pred, metrics] = svm_classifier(X_train, y_train, X_test)
% SVM分类器
tic;
% 训练SVM模型
try
model = fitcsvm(X_train, y_train, ...
'KernelFunction', 'linear', ...
'Standardize', true, ...
'BoxConstraint', 1, ...
'KernelScale', 'auto');
catch
% 如果线性核失败,尝试RBF核
model = fitcsvm(X_train, y_train, ...
'KernelFunction', 'rbf', ...
'Standardize', true);
end
% 预测
y_pred = predict(model, X_test);
train_time = toc;
% 计算评估指标
metrics = compute_metrics(y_train, y_pred, X_test, train_time);
end
function [model, y_pred, metrics] = knn_classifier(X_train, y_train, X_test)
% KNN分类器
tic;
% 使用交叉验证选择最佳K值
k_values = [1, 3, 5, 7, 9];
cv_acc = zeros(length(k_values), 1);
cv = cvpartition(y_train, 'KFold', 5);
for i = 1:length(k_values)
k = k_values(i);
acc_fold = zeros(cv.NumTestSets, 1);
for fold = 1:cv.NumTestSets
trainIdx = cv.training(fold);
testIdx = cv.test(fold);
model_k = fitcknn(X_train(trainIdx,:), y_train(trainIdx), ...
'NumNeighbors', k, 'Standardize', true);
y_pred_fold = predict(model_k, X_train(testIdx,:));
acc_fold(fold) = sum(y_pred_fold == y_train(testIdx)) / length(y_pred_fold);
end
cv_acc(i) = mean(acc_fold);
end
[~, best_idx] = max(cv_acc);
best_k = k_values(best_idx);
% 使用最佳K训练最终模型
model = fitcknn(X_train, y_train, ...
'NumNeighbors', best_k, ...
'Standardize', true);
% 预测
y_pred = predict(model, X_test);
train_time = toc;
% 计算评估指标
metrics = compute_metrics(y_train, y_pred, X_test, train_time);
metrics.best_k = best_k;
end
function [model, y_pred, metrics] = tree_classifier(X_train, y_train, X_test)
% 决策树分类器
tic;
% 训练决策树
model = fitctree(X_train, y_train, ...
'MaxNumSplits', 20, ...
'MinLeafSize', 5, ...
'Prune', 'on');
% 预测
y_pred = predict(model, X_test);
train_time = toc;
% 计算评估指标
metrics = compute_metrics(y_train, y_pred, X_test, train_time);
end
function [model, y_pred, metrics] = ensemble_classifier(X_train, y_train, X_test)
% 集成学习分类器(随机森林)
tic;
% 训练随机森林
model = TreeBagger(100, X_train, y_train, ...
'Method', 'classification', ...
'OOBPrediction', 'on', ...
'MinLeafSize', 5);
% 预测
[y_pred, scores] = predict(model, X_test);
y_pred = str2double(y_pred);
train_time = toc;
% 计算评估指标
metrics = compute_metrics(y_train, y_pred, X_test, train_time);
metrics.oob_error = oobError(model);
end
function metrics = compute_metrics(y_train, y_pred, X_test, train_time)
% 计算分类性能指标
% 对于测试集,需要实际标签(这里假设y_test已传入)
% 注意:此函数应在主程序中调用,传入y_test
% 准确率
accuracy = sum(y_pred == y_train) / length(y_pred);
% 混淆矩阵
C = confusionmat(y_train, y_pred);
% 精确率、召回率、F1分数
n_classes = size(C, 1);
precision = zeros(n_classes, 1);
recall = zeros(n_classes, 1);
f1 = zeros(n_classes, 1);
for i = 1:n_classes
precision(i) = C(i,i) / sum(C(:,i));
recall(i) = C(i,i) / sum(C(i,:));
f1(i) = 2 * (precision(i) * recall(i)) / (precision(i) + recall(i));
end
% 宏平均
macro_precision = mean(precision(~isnan(precision)));
macro_recall = mean(recall(~isnan(recall)));
macro_f1 = mean(f1(~isnan(f1)));
metrics = struct();
metrics.accuracy = accuracy;
metrics.precision = macro_precision;
metrics.recall = macro_recall;
metrics.f1 = macro_f1;
metrics.confusion_matrix = C;
metrics.time = train_time;
end
function plotConfusionMatrix(y_true, y_pred)
% 绘制混淆矩阵
C = confusionmat(y_true, y_pred);
imagesc(C);
colormap(flipud(gray)); % 使用灰度色图
% 添加数值标签
[n, m] = size(C);
for i = 1:n
for j = 1:m
text(j, i, num2str(C(i,j)), ...
'HorizontalAlignment', 'center', ...
'Color', 'white', 'FontWeight', 'bold');
end
end
xlabel('预测类别');
ylabel('真实类别');
colorbar;
end
4. 数据生成和辅助函数
%% 数据生成函数
function [X, y, feature_names] = generate_synthetic_data(n_samples, n_features, n_informative)
% 生成合成数据集用于测试
% n_informative: 有信息的特征数量
rng(42); % 可重复性
% 生成特征
X = randn(n_samples, n_features);
% 生成有信息的特征
informative_idx = randperm(n_features, n_informative);
% 生成标签(基于有信息特征的线性组合)
weights = randn(n_informative, 1);
X_informative = X(:, informative_idx);
y_raw = X_informative * weights + randn(n_samples, 1) * 0.5;
% 转换为多类别(3类)
y = discretize(y_raw, [-inf, -0.5, 0.5, inf]);
% 添加一些噪声特征(相关噪声)
for i = 1:min(100, n_features-n_informative)
noise_idx = n_informative + i;
if noise_idx <= n_features
X(:, noise_idx) = X(:, randi(n_informative)) + randn(n_samples, 1) * 0.3;
end
end
% 生成特征名称
feature_names = cell(1, n_features);
for i = 1:n_features
if ismember(i, informative_idx)
feature_names{i} = sprintf('Informative_Feature_%d', i);
else
feature_names{i} = sprintf('Feature_%d', i);
end
end
end
%% 参数敏感性分析
function test_parameter_sensitivity(X_train, y_train, X_test, y_test)
% 测试不同参数对算法性能的影响
fprintf('\n=== 参数敏感性分析 ===\n');
% 测试不同粒子数量
nParticles_list = [20, 30, 50, 100];
results_particles = cell(length(nParticles_list), 1);
for i = 1:length(nParticles_list)
fprintf('测试粒子数量: %d\n', nParticles_list(i));
params = struct();
params.nParticles = nParticles_list(i);
params.maxIter = 50; % 减少迭代次数以加快测试
params.wMax = 0.9;
params.wMin = 0.4;
params.c1 = 2.0;
params.c2 = 2.0;
params.mutationRate = 0.1;
params.threshold = 0.6;
params.alpha = 0.95;
params.beta = 0.05;
params.cvFolds = 3;
params.earlyStop = 10;
classifier = @(X_train, y_train, X_test) svm_classifier(X_train, y_train, X_test);
[bestPosition, bestFitness, history] = APSO_FeatureSelection(...
X_train, y_train, params, classifier);
results_particles{i} = struct(...
'nParticles', nParticles_list(i), ...
'bestFitness', bestFitness, ...
'nFeatures', sum(bestPosition > params.threshold));
end
% 绘制结果
figure('Position', [200, 200, 1000, 400]);
subplot(1,2,1);
fitness_values = cellfun(@(x) x.bestFitness, results_particles);
plot(nParticles_list, fitness_values, 'bo-', 'LineWidth', 2);
xlabel('粒子数量');
ylabel('最佳适应度');
title('粒子数量对适应度的影响');
grid on;
subplot(1,2,2);
feature_counts = cellfun(@(x) x.nFeatures, results_particles);
plot(nParticles_list, feature_counts, 'rs-', 'LineWidth', 2);
xlabel('粒子数量');
ylabel('选择特征数');
title('粒子数量对特征选择的影响');
grid on;
end
%% 批量处理多个数据集
function batch_process_datasets()
% 批量处理多个数据集
datasets = {
'fisheriris', 'meas', 'species';
% 添加更多数据集...
};
results = cell(size(datasets, 1), 1);
for i = 1:size(datasets, 1)
fprintf('处理数据集: %s\n', datasets{i,1});
% 加载数据
load(datasets{i,1});
X = eval(datasets{i,2});
y = eval(datasets{i,3});
if iscell(y)
y = grp2idx(y);
end
% 标准化
X = zscore(X);
% 划分数据集
[trainInd, testInd] = dividerand(size(X,1), 0.7, 0.3);
X_train = X(trainInd, :);
y_train = y(trainInd);
X_test = X(testInd, :);
y_test = y(testInd);
% 参数设置
params = struct();
params.nParticles = 30;
params.maxIter = 100;
params.wMax = 0.9;
params.wMin = 0.4;
params.c1 = 2.0;
params.c2 = 2.0;
params.mutationRate = 0.1;
params.threshold = 0.6;
params.alpha = 0.95;
params.beta = 0.05;
params.cvFolds = 5;
params.earlyStop = 20;
classifier = @(X_train, y_train, X_test) svm_classifier(X_train, y_train, X_test);
% 运行APSO
[bestPosition, bestFitness, history] = APSO_FeatureSelection(...
X_train, y_train, params, classifier);
% 评估性能
selectedIdx = find(bestPosition > params.threshold);
X_train_selected = X_train(:, selectedIdx);
X_test_selected = X_test(:, selectedIdx);
[~, ~, metrics_all] = classifier(X_train, y_train, X_test);
[~, ~, metrics_selected] = classifier(X_train_selected, y_train, X_test_selected);
% 保存结果
results{i} = struct(...
'dataset', datasets{i,1}, ...
'nFeatures_total', size(X,2), ...
'nFeatures_selected', length(selectedIdx), ...
'bestFitness', bestFitness, ...
'accuracy_all', metrics_all.accuracy, ...
'accuracy_selected', metrics_selected.accuracy, ...
'f1_all', metrics_all.f1, ...
'f1_selected', metrics_selected.f1);
fprintf(' 结果: 特征 %d -> %d, 准确率 %.2f%% -> %.2f%%\n\n', ...
size(X,2), length(selectedIdx), ...
metrics_all.accuracy*100, metrics_selected.accuracy*100);
end
% 显示汇总结果
fprintf('\n=== 批量处理结果汇总 ===\n');
fprintf('%-20s %-10s %-10s %-10s %-10s\n', ...
'数据集', '总特征', '选择特征', '原始准确率', '选择后准确率');
fprintf('%s\n', repmat('-', 60, 1));
for i = 1:length(results)
r = results{i};
fprintf('%-20s %-10d %-10d %-10.2f %-10.2f\n', ...
r.dataset, r.nFeatures_total, r.nFeatures_selected, ...
r.accuracy_all*100, r.accuracy_selected*100);
end
end
5. 算法特点和优势
5.1 自适应机制
- 惯性权重自适应: 迭代过程中线性递减,平衡全局和局部搜索
- 学习因子自适应: 前期注重个体认知,后期注重社会认知
- 变异操作: 避免早熟收敛,增强探索能力
5.2 适应度函数设计
- 多目标优化: 同时考虑分类准确率和特征数量
- 交叉验证: 使用分层K折交叉验证,防止过拟合
- 类别平衡: 考虑F1分数和类别分离度
5.3 大规模优化策略
- 二进制编码: 适用于特征选择问题
- 早停机制: 提高计算效率
- 并行化支持: 适应度评估可并行计算
6. 使用说明
基本使用:
% 1. 准备数据 (X, y)
% 2. 设置参数
params.nParticles = 50;
params.maxIter = 100;
% ... 其他参数
% 3. 选择分类器
classifier = @svm_classifier; % 或 @knn_classifier, @tree_classifier
% 4. 运行算法
[bestPosition, bestFitness] = APSO_FeatureSelection(X, y, params, classifier);
% 5. 提取选择的特征
selectedFeatures = bestPosition > params.threshold;
高级功能:
- 批量处理: 使用
batch_process_datasets()处理多个数据集 - 参数调优: 使用
test_parameter_sensitivity()进行参数分析 - 可视化: 算法提供多种可视化结果
参考代码 分类中大规模特征选择的自适应粒子群算法 www.3dddown.com/cna/97920.html
7. 扩展建议
- 并行计算: 将粒子适应度评估并行化
- 多目标优化: 使用Pareto前沿处理多个目标
- 混合算法: 结合其他优化算法(如遗传算法、模拟退火)
- 深度学习集成: 与深度学习特征提取结合
- 在线学习: 适应数据流特征选择
