spdiags和功能缩放

时间:2015-03-10 18:53:34

标签: matlab scaling libsvm

根据libsvm faqs,以下单行代码将每个特征缩放到Matlab中[0,1]的范围

(data - repmat(min(data,[],1),size(data,1),1))*spdiags(1./(max(data,[],1)-min(data,[],1))',0,size(data,2),size(data,2))

所以我正在使用这段代码:

v_feature_trainN=(v_feature_train - repmat(mini,size(v_feature_train,1),1))*spdiags(1./(maxi-mini)',0,size(v_feature_train,2),size(v_feature_train,2));
 v_feature_testN=(v_feature_test - repmat(mini,size(v_feature_test,1),1))*spdiags(1./(maxi-mini)',0,size(v_feature_test,2),size(v_feature_test,2));

我用第一个训练分类器,第二个用来分类......

在我的拙见中,缩放应该通过以下方式执行:

enter image description here

即:

v_feature_trainN2=(v_feature_train -min(v_feature_train(:)))./(max(v_feature_train(:))-min((v_feature_train(:))));
v_feature_test_N2=(v_feature_test  -min(v_feature_train(:)))./(max(v_feature_train(:))-min((v_feature_train(:))));

现在我使用这两种缩放方法比较分类结果,第一种方法优于第二种方法。 问题是: 1)第一种方法究竟是什么?我不明白。 2)为什么libsvm建议的代码优于第二个代码(例如80%vs 60%)? 非常感谢你提前

2 个答案:

答案 0 :(得分:1)

首先: libsvm中描述的代码与您的代码有所不同:

它将每列独立地映射到区间[0,1]。 但是,您的代码使用全局minmax来映射所有列,使用相同的仿射转换而不是每列的单独转换。


第一个代码按以下方式工作:

  • (data - repmat(min(data,[],1),size(data,1),1))
    这会从整列中减去每列的最小值。它通过计算最小值min(data,[],1)的行向量来实现这一点,然后将其复制以构建与data大小相同的矩阵。然后从data

  • 中扣除
  • spdiags(1./(max(data,[],1)-min(data,[],1))',0,size(data,2),size(data,2))
    这会生成对角矩阵。此矩阵的条目(i,i)为1除以i列的最大值和最小值之差:max(data(:,i))-min(data(:,i))

  • 此对角矩阵的右乘意味着:将左矩阵的每一列与对应的对角线条目相乘。这有效地将列i除以max(data(:,i))-min(data(:,i))


使用bsxfun可以更有效地执行此操作,而不是使用稀疏对角矩阵:

bsxfun(@rdivide, ...
       bsxfun(@minus, ...
              data, min(data,[],1)), ...
       max(data,[],1)-min(data,[],1))

这是matlab的写作方式:

  • 鸿沟:
    • 区别:
      • 每列及其各自的最小值
    • 由每列maxmin
    • 的差异决定

答案 1 :(得分:0)

我知道这已经得到了正确回答,但我想提出另一个我认为也正确的解决方案,我发现knedlsepp提供的解决方案更直观/更简洁。我是matlab的新手,当我研究knedlsepp解决方案时,我发现用以下公式解决这个问题更直观:

function [ output ] = feature_scaling( y)

output = (y - repmat(min(y),size(y,1),1)) * diag(1./(max(y) - min(y)));

end

我发现使用diag这种方式而不是spdiags更容易,但我相信它会产生与此练习相同的结果。

将第一项乘以第二项,有效地将矩阵的每个成员(Y-min(Y))除以标量值1 /(max(y)-min(y)),从而获得所需的结果。

如果有人喜欢较短的版本,也许这会有所帮助。