如何在Matlab中编码?

时间:2016-08-15 00:45:46

标签: matlab neural-network octave deep-learning

通常会给出一个表示标签(也就是类)的整数值向量,例如

[2; 1; 3; 3; 2]

并且你想对这个向量进行编码,这样每个值在标签向量的每一行中由值指示的列中用1表示,例如

[0 1 0;
 1 0 0;
 0 0 1;
 0 0 1;
 0 1 0]

5 个答案:

答案 0 :(得分:19)

为了节省速度和内存,您可以使用bsxfun结合eq来完成同样的事情。虽然您的eye解决方案可能有效,但您的内存使用量会随着X中唯一值的数量呈二次方式增长。

Y = bsxfun(@eq, X(:), 1:max(X));

如果您愿意,可以使用匿名函数:

hotone = @(X)bsxfun(@eq, X(:), 1:max(X));

或者,如果您使用Octave(或MATLAB版本R2016b及更高版本),您可以利用自动广播,只需按照@Tasos的建议执行以下操作。

Y = X == 1:max(X);

基准

以下是一个快速基准,显示各种答案的效果,X上的元素数量不同,X中的唯一值数量不同。

function benchit()

    nUnique = round(linspace(10, 1000, 10));
    nElements = round(linspace(10, 1000, 12));

    times1 = zeros(numel(nUnique), numel(nElements));
    times2 = zeros(numel(nUnique), numel(nElements));
    times3 = zeros(numel(nUnique), numel(nElements));
    times4 = zeros(numel(nUnique), numel(nElements));
    times5 = zeros(numel(nUnique), numel(nElements));

    for m = 1:numel(nUnique)
        for n = 1:numel(nElements)
            X = randi(nUnique(m), nElements(n), 1);
            times1(m,n) = timeit(@()bsxfunApproach(X));

            X = randi(nUnique(m), nElements(n), 1);
            times2(m,n) = timeit(@()eyeApproach(X));

            X = randi(nUnique(m), nElements(n), 1);
            times3(m,n) = timeit(@()sub2indApproach(X));

            X = randi(nUnique(m), nElements(n), 1);
            times4(m,n) = timeit(@()sparseApproach(X));

            X = randi(nUnique(m), nElements(n), 1);
            times5(m,n) = timeit(@()sparseFullApproach(X));
        end
    end

    colors = get(0, 'defaultaxescolororder');

    figure;

    surf(nElements, nUnique, times1 * 1000, 'FaceColor', colors(1,:), 'FaceAlpha', 0.5);
    hold on
    surf(nElements, nUnique, times2 * 1000, 'FaceColor', colors(2,:), 'FaceAlpha', 0.5);
    surf(nElements, nUnique, times3 * 1000, 'FaceColor', colors(3,:), 'FaceAlpha', 0.5);
    surf(nElements, nUnique, times4 * 1000, 'FaceColor', colors(4,:), 'FaceAlpha', 0.5);
    surf(nElements, nUnique, times5 * 1000, 'FaceColor', colors(5,:), 'FaceAlpha', 0.5);

    view([46.1000   34.8000])

    grid on
    xlabel('Elements')
    ylabel('Unique Values')
    zlabel('Execution Time (ms)')

    legend({'bsxfun', 'eye', 'sub2ind', 'sparse', 'full(sparse)'}, 'Location', 'Northwest')
end

function Y = bsxfunApproach(X)
    Y = bsxfun(@eq, X(:), 1:max(X));
end

function Y = eyeApproach(X)
    tmp = eye(max(X));
    Y = tmp(X, :);
end

function Y = sub2indApproach(X)
    LinearIndices = sub2ind([length(X),max(X)], [1:length(X)]', X);
    Y = zeros(length(X), max(X));
    Y(LinearIndices) = 1;
end

function Y = sparseApproach(X)
    Y = sparse(1:numel(X), X,1);
end

function Y = sparseFullApproach(X)
    Y = full(sparse(1:numel(X), X,1));
end

结果

如果您需要非稀疏输出bsxfun表现最佳,但如果您可以使用sparse矩阵(无需转换为完整矩阵),那么这是最快且效率最高的内存选项。

enter image description here

答案 1 :(得分:5)

您可以使用输入/标签向量使用单位矩阵和索引,例如,如果标签向量X是一些随机整数向量

X = randi(3,5,1)

ans =

   2
   1
   2
   3
   3

然后,以下将热门编码X

eye(max(X))(X,:)

可以使用

方便地定义为函数
hotone = @(v) eye(max(v))(v,:)

修改

虽然上面的解决方案适用于Octave,但您可以按照以下方法修改Matlab,

I = eye(max(X));
I(X,:)

答案 2 :(得分:2)

我认为这在矩阵维度增长时特别快:

Y = sparse(1:numel(X), X,1);

Y = full(sparse(1:numel(X), X,1));

答案 3 :(得分:1)

只是发布sub2ind解决方案,以满足您的好奇心:) 但我更喜欢你的解决方案:p

>> X = [2,1,2,3,3]'
>> LinearIndices = sub2ind([length(X),3], [1:length(X)]', X);
>> tmp = zeros(length(X), 3); 
>> tmp(LinearIndices) = 1
tmp =

     0     1     0
     1     0     0
     0     1     0
     0     0     1
     0     0     1

答案 4 :(得分:0)

以防有人正在寻找2D案例(就像我一样):

X = [2 1; ...
     3 3; ...
     2 4]
Y = zeros(3,2,4)
for i = 1:4
    Y(:,:,i) = ind2sub(X,X==i)
end

沿第3维提供单热编码矩阵。