He aquí un breve tutorial. Primero creamos una matriz de sus variables ocultas (o "factores"). Tiene 100 observaciones y hay dos factores independientes.
>> factors = randn(100, 2);
Ahora cree una matriz de cargas. Esto va a mapear las variables ocultas en sus variables observadas. Supongamos que las variables observadas tienen cuatro características. Luego, su matriz de cargas debe ser 4 x 2
>> loadings = [
1 0
0 1
1 1
1 -1 ];
que te dice que las primeras cargas variables observadas en el primer factor, la segunda carga en el segundo factor, la tercera cargas variables sobre la suma de los factores y la cuarta variable cargas sobre la diferencia de los factores.
Ahora crear sus observaciones:
>> observations = factors * loadings' + 0.1 * randn(100,4);
que añade una pequeña cantidad de ruido aleatorio para simular el error experimental. Ahora realizamos la PCA utilizando la función pca
de la caja de herramientas estadísticas:
>> [coeff, score, latent, tsquared, explained, mu] = pca(observations);
La variable score
es la matriz de los principales puntuaciones de los componentes. Estos serán ortogonal por construcción, que se puede comprobar -
>> corr(score)
ans =
1.0000 0.0000 0.0000 0.0000
0.0000 1.0000 0.0000 0.0000
0.0000 0.0000 1.0000 0.0000
0.0000 0.0000 0.0000 1.0000
La combinación score * coeff'
se reproduce la versión centrada de sus observaciones. La media mu
se resta antes de realizar PCA. Para reproducir sus observaciones originales que hay que añadir de nuevo en,
>> reconstructed = score * coeff' + repmat(mu, 100, 1);
>> sum((observations - reconstructed).^2)
ans =
1.0e-27 *
0.0311 0.0104 0.0440 0.3378
para obtener una aproximación a los datos originales, se puede comenzar a caer las columnas de los componentes principales calculadas.Para tener una idea de las columnas que se caen, se examinan las variables explained
>> explained
explained =
58.0639
41.6302
0.1693
0.1366
Las entradas que indican qué porcentaje de la varianza explicada por cada uno de los componentes principales. Podemos ver claramente que los primeros dos componentes son más importantes que los dos segundos (explican más del 99% de la varianza entre ellos). El uso de los dos primeros componentes para reconstruir las observaciones da el rango-2 aproximación,
>> approximationRank2 = score(:,1:2) * coeff(:,1:2)' + repmat(mu, 100, 1);
Ahora podemos probar el trazado:
>> for k = 1:4
subplot(2, 2, k);
hold on;
grid on
plot(approximationRank2(:, k), observations(:, k), 'x');
plot([-4 4], [-4 4]);
xlim([-4 4]);
ylim([-4 4]);
title(sprintf('Variable %d', k));
end
obtenemos una reproducción casi perfecta del original observaciones. Si quisiéramos una aproximación gruesa, podríamos utilizar el primer componente principal:
>> approximationRank1 = score(:,1) * coeff(:,1)' + repmat(mu, 100, 1);
y la trama que,
>> for k = 1:4
subplot(2, 2, k);
hold on;
grid on
plot(approximationRank1(:, k), observations(:, k), 'x');
plot([-4 4], [-4 4]);
xlim([-4 4]);
ylim([-4 4]);
title(sprintf('Variable %d', k));
end
Esta vez, la reconstrucción no es tan buena. Eso es porque deliberadamente construimos nuestros datos para tener dos factores, y solo lo estamos reconstruyendo a partir de uno de ellos.
Tenga en cuenta que a pesar de la similitud entre la sugerente forma en que construimos los datos originales y su reproducción,
>> observations = factors * loadings' + 0.1 * randn(100,4);
>> reconstructed = score * coeff' + repmat(mu, 100, 1);
no hay necesariamente ninguna correspondencia entre factors
y score
, o entre loadings
y coeff
. El algoritmo PCA no sabe nada sobre la forma en que se construyen sus datos; simplemente trata de explicar la mayor varianza posible con cada componente sucesivo.
El usuario @Mari preguntó en los comentarios cómo podría trazar el error de reconstrucción en función del número de componentes principales. Usar la variable explained
arriba es bastante fácil. Voy a generar algunos datos con una estructura de factores más interesante para ilustrar el efecto -
>> factors = randn(100, 20);
>> loadings = chol(corr(factors * triu(ones(20))))';
>> observations = factors * loadings' + 0.1 * randn(100, 20);
Ahora todas las observaciones carga en un factor común significativa, con otros factores de importancia decreciente. Podemos obtener la descomposición PCA como antes
>> [coeff, score, latent, tsquared, explained, mu] = pca(observations);
y trazar el porcentaje de varianza explicada de la siguiente manera,
>> cumexplained = cumsum(explained);
cumunexplained = 100 - cumexplained;
plot(1:20, cumunexplained, 'x-');
grid on;
xlabel('Number of factors');
ylabel('Unexplained variance')
muy gran respuesta, sólo quería darle las gracias. –
Awesome answer. Gracias Chris! – rayryeng
Genial para aprender. Muchas gracias. Sin embargo, tengo una pequeña duda, ¿por qué tenemos que crear variables ocultas al principio? ¿Puedo comenzar con '[w pc ev] = princomp (X);' para analizar mis datos originales? Gracias de nuevo. – Mari