基于ReliefF算法的分类数据特征选择算法 matlab代码,输出为选择的特征序号
·
基于ReliefF算法的分类数据特征选择算法 matlab代码,输出为选择的特征序号

三伏天最适合躲在空调房搞特征选择。今天手把手教你们用Matlab实现ReliefF算法,专治分类数据里那些没用的特征。这个算法像老中医把脉,通过特征与样本的亲近程度判断谁是真爱。

先上主菜,核心代码也就二十来行:
function selected_features = reliefF_categorical(X, y, K, m)
[n_samples, n_features] = size(X);
weights = zeros(1, n_features);
for i = 1:m
rand_idx = randi(n_samples);
target = X(rand_idx, :);
same_class = find(y == y(rand_idx));
diff_class = find(y ~= y(rand_idx));
% 找邻居要算两次账
hit_neighbors = nearest_neighbors(target, X(same_class, :), K);
miss_neighbors = nearest_neighbors(target, X(diff_class, :), K);
% 更新权重就像给特征打分
for f = 1:n_features
diff_hit = sum(target(f) ~= X(hit_neighbors, f)) / K;
diff_miss = sum(target(f) ~= X(miss_neighbors, f)) / K;
weights(f) = weights(f) - diff_hit/(m*K) + diff_miss/(m*K);
end
end
[~, selected_features] = sort(weights, 'descend');
end
function neighbors = nearest_neighbors(target, pool, K)
distances = sum(target ~= pool, 2); % 分类数据用海明距离
[~, sorted_idx] = sort(distances);
neighbors = sorted_idx(1:min(K, length(sorted_idx)));
end
重点来了,这个算法怎么挑邻居的?看nearest_neighbors函数里那行sum(target ~= pool, 2),这可不是简单的数数。比如某个特征颜色有红黄蓝三种,两个样本在这个特征上不同就直接记1,管你是红黄还是红蓝,简单粗暴但有效。

权重更新更有意思,每次随机抓个样本当裁判。对同类的邻居,特征值不同就扣分(diffhit);对异类邻居,特征不同反而加分(diffmiss)。就像相亲时,介绍人总喜欢找条件相似的,但真正合适的可能互补。

基于ReliefF算法的分类数据特征选择算法 matlab代码,输出为选择的特征序号

跑完算法后,sort(weights, 'descend')这一句把特征按权重降序排列。想要前N个重要特征?直接取前N个索引就行。

举个栗子,假设我们有个水果数据集:
% 颜色(1红2黄3绿), 形状(1圆2长), 重量(1轻2中3重)
X = [1,1,1; 2,2,2; 3,2,3; 1,1,2; 2,2,3];
y = [1;1;2;1;2]; % 1苹果, 2香蕉
selected = reliefF_categorical(X, y, 2, 100);
disp('重要特征排序:');
disp(selected);
跑完可能会发现颜色特征排第一,毕竟黄色既出现在苹果(黄苹果)又出现在香蕉,区分度反而没有形状特征高。这时候就该怀疑是不是采样次数不够,或者K值需要调整了。
最后提醒,别迷信算法结果。有一次我用这个挑患者特征,结果血型排第一。后来发现数据里O型血样本占了70%,这哪是特征重要,分明是抽样偏差。好算法也得配上好数据,就像再好的厨子也做不好馊掉的食材。
更多推荐


所有评论(0)