2011-11-08 13 views
6

Ho una dimensione 5000,1 (matrice), che contiene numeri interi compresi tra 1 e 10. Voglio espandere quegli indici in un vettore 1-di-10. Vale a dire, y contiene 1,2,3 ... e lo voglio a "espandere" a:Matlab/Octave rappresentazione 1-of-K

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

Qual è il modo migliore per farlo?

ho provato:

Y = zeros(5000,10); Y(y) = 1; 

ma non ha funzionato.

Si lavora per i vettori però:

se y = [2 5 7], e Y = zeros(1,10), quindi Y(y) = [0 1 0 0 1 0 1 0 0 0].

+0

possibile duplicato del [Creazione Indicatore Matrice] (http://stackoverflow.com/questions/6150174/creating-indicator-matrix) – Amro

risposta

6
n=5 
Y = ceil(10*rand(n,1)) 
Yexp = zeros(n,10); 
Yexp(sub2ind(size(Yexp),1:n,Y')) = 1 

Inoltre, si consiglia di utilizzare sparse, come in: Creating Indicator Matrix.

+0

Are ther e relativi meriti/demeriti a bsxfun v. sub2ind? – Frank

+0

@Frank: questo è basato sull'indicizzazione, il mio implica fare confronti di uguaglianza ... Sarebbe interessante vedere come si confrontano in termini di prestazioni – Amro

+0

Ho controllato la performance. La soluzione sub2ind è leggermente più veloce della soluzione bsxfun. – cyborg

-2

Credo che si intende:

y = [2 5 7]; 
Y = zeros(5000,10); 
Y(:,y) = 1; 

Dopo la modifica domanda, dovrebbe essere questo, invece:

y = [2,5,7,9,1,4,5,7,8,9....]; //(size (1,5000)) 
for i = 1:5000 
    Y(i,y(i)) = 1; 
end 
+0

Questo imposterà tutte le colonne y a 1. – cyborg

+0

Volevo evitare di scrivere il ciclo, che è la soluzione più ovvia :-) – Frank

+0

la domanda non era molto chiara fino a quando Amro l'ha modificata :), assicurati di accettare l'altro risposta – Smash

6

Si consideri il seguente:

y = randi([1 10],[5 1]);  %# vector of 5 numbers in the range [1,10] 
yy = bsxfun(@eq, y, 1:10)'; %# 1-of-10 encoding 

Esempio:

>> y' 
ans = 
    8  8  4  7  2 
>> yy 
yy = 
    0  0  0  0  0 
    0  0  0  0  1 
    0  0  0  0  0 
    0  0  1  0  0 
    0  0  0  0  0 
    0  0  0  0  0 
    0  0  0  1  0 
    1  1  0  0  0 
    0  0  0  0  0 
    0  0  0  0  0 
+0

Questo è quello che sto cercando, dare o prendere una trasposizione :-) Grazie! – Frank

+0

@Frank: Credo anche che la casella degli strumenti di statistica abbia una funzione in qualche modo simile [DUMMYVAR] (http://www.mathworks.com/help/toolbox/stats/dummyvar.html) – Amro

2

Mentre sparse può essere più veloce e salvare la memoria, un occhio risposta che coinvolge() sarebbe più elegante in quanto è più veloce di un ciclo ed è stato introdotto durante la lezione ottava di quella classe

Ecco un esempio per 1 a 4

V = [3;2;1;4]; 
I = eye(4); 
Vk = I(V, :); 
+0

Ciò che funziona per me è l'occhio (K) (V, :) che è simile al tuo ma condensa le linee 2 e 3 in un'unica riga. Più utile però, K è il numero di possibili classi, non classi effettivamente presenti, quindi per esempio se ci fossero 10 risultati possibili di cui 4 erano effettivamente presenti, avrebbe funzionato in modo più corretto e più affidabile. –

0

Si può provare operazioni cellfun:

function vector = onehot(vector,decimal) 
    vector(decimal)=1; 
end 
aa=zeros(10,2); 
dec=[5,6]; 
%split into columns 
C=num2cell(aa,1); 
D=num2cell(dec,1); 
onehotmat=cellfun("onehot",C,D,"UniformOutput",false); 
output=cell2mat(onehotmat);