Una de las cuestiones más importantes al usar el análisis factorial es su interpretación. El análisis factorial a menudo usa la rotación de factores para mejorar su interpretación. Después de una rotación satisfactoria, el factor de carga girada matriz L' tendrá la misma capacidad para representar la matriz de correlación y puede ser utilizado como la matriz de factor de carga, en vez de la matriz sin girar L .
El propósito de la rotación es hacer que la matriz de carga del factor rotado tenga algunas propiedades deseables. Uno de los métodos utilizados es rotar la matriz de carga de factores de manera que la matriz rotada tenga una estructura simple .
LL Thurstone presentó el Principio de Estructura Simple, como una guía general para la rotación de factores:
Criterios de estructura simple:
- Cada fila de la matriz de factores debe contener al menos un cero
- Si hay m factores comunes, cada columna de la matriz de factores debe tener al menos m ceros
- Para cada par de columnas en la matriz de factores, debe haber varias variables para las cuales las entradas se acercan a cero en una columna pero no en la otra
- Para cada par de columnas en la matriz de factores, una gran proporción de las variables debe tener entradas cercanas a cero en ambas columnas cuando hay cuatro o más factores
- Para cada par de columnas en la matriz de factores, debe haber solo un pequeño número de variables con entradas distintas de cero en ambas columnas
La estructura simple ideal es tal que:
- cada elemento tiene una carga alta o significativa solo en un factor y
- cada factor tiene cargas altas o significativas para solo algunos de los elementos.
El problema es que, al probar varias combinaciones de métodos de rotación junto con los parámetros que cada uno acepta (especialmente para los oblicuos), aumenta el número de matrices candidatas y es muy difícil ver cuál cumple mejor los criterios anteriores.
Cuando me enfrenté a ese problema por primera vez, me di cuenta de que no podía seleccionar la mejor coincidencia simplemente "mirándolos" y que necesitaba un algoritmo que me ayudara a decidir. Bajo el estrés de los plazos del proyecto, lo máximo que pude hacer fue escribir el siguiente código en MATLAB, que acepta una matriz de rotación a la vez y devuelve (bajo algunos supuestos) si cada criterio se cumple o no. Una nueva versión (si alguna vez intentara actualizarla) aceptaría una matriz 3d (un conjunto de matrices 2d) como argumento, y el algoritmo debería devolver la que mejor se ajuste a los criterios anteriores.
¿Cómo extraerías un algoritmo de esos criterios? Solo pido sus opiniones (también creo que ha habido críticas sobre la utilidad del método en sí mismo) y quizás mejores enfoques para el problema de selección de la matriz de rotación.
Además, me gustaría saber qué software prefiere realizar FA. Si es R, ¿qué paquete usas? (Debo admitir que si tuviera que hacer FA, volvería a SPSS nuevamente). Si alguien quiere proporcionar algún código, preferiría R o MATLAB.
PD La formulación de Criterios de Estructura Simple anterior se puede encontrar en el libro "Making Sense of Factor Analysis" de PETT, M., LACKEY, N., SULLIVAN, J.
PS2 (del mismo libro): "Una prueba de análisis factorial exitoso es la medida en que puede reproducir la matriz corr original. Si también usó soluciones oblicuas, entre todas seleccione la que generó la mayor cantidad de factor más alto y más bajo cargas ". Esto suena como otra restricción que el algoritmo podría usar.
PS3 Esta pregunta también se ha hecho aquí . Sin embargo, creo que encaja mejor en este sitio.
function [] = simple_structure_criteria (my_pattern_table)
%Simple Structure Criteria
%Making Sense of Factor Analysis, page 132
disp(' ');
disp('Simple Structure Criteria (Thurstone):');
disp('1. Each row of the factor matrix should contain at least one zero');
disp( '2. If there are m common factors, each column of the factor matrix should have at least m zeros');
disp( '3. For every pair of columns in the factor matrix, there should be several variables for which entries approach zero in the one column but not in the other');
disp( '4. For every pair of columns in the factor matrix, a large proportion of the variables should have entries approaching zero in both columns when there are four or more factors');
disp( '5. For every pair of columns in the factor matrix, there should be only a small number of variables with nonzero entries in both columns');
disp(' ');
disp( '(additional by Pedhazur and Schmelkin) The ideal simple structure is such that:');
disp( '6. Each item has a high, or meaningful, loading on one factor only and');
disp( '7. Each factor have high, or meaningful, loadings for only some of the items.');
disp('')
disp('Start checking...')
%test matrix
%ct=[76,78,16,7;19,29,10,13;2,6,7,8];
%test it by giving: simple_structure_criteria (ct)
ct=abs(my_pattern_table);
items=size(ct,1);
factors=size(ct,2);
my_zero = 0.1;
approach_zero = 0.2;
several = floor(items / 3);
small_number = ceil(items / 4);
large_proportion = 0.30;
meaningful = 0.4;
some_bottom = 2;
some_top = floor(items / 2);
% CRITERION 1
disp(' ');
disp('CRITERION 1');
for i = 1 : 1 : items
count = 0;
for j = 1 : 1 : factors
if (ct(i,j) < my_zero)
count = count + 1;
break
end
end
if (count == 0)
disp(['Criterion 1 is NOT MET for item ' num2str(i)])
end
end
% CRITERION 2
disp(' ');
disp('CRITERION 2');
for j = 1 : 1 : factors
m=0;
for i = 1 : 1 : items
if (ct(i,j) < my_zero)
m = m + 1;
end
end
if (m < factors)
disp(['Criterion 2 is NOT MET for factor ' num2str(j) '. m = ' num2str(m)]);
end
end
% CRITERION 3
disp(' ');
disp('CRITERION 3');
for c1 = 1 : 1 : factors - 1
for c2 = c1 + 1 : 1 : factors
test_several = 0;
for i = 1 : 1 : items
if ( (ct(i,c1)>my_zero && ct(i,c2)<my_zero) || (ct(i,c1)<my_zero && ct(i,c2)>my_zero) ) % approach zero in one but not in the other
test_several = test_several + 1;
end
end
disp(['several = ' num2str(test_several) ' for factors ' num2str(c1) ' and ' num2str(c2)]);
if (test_several < several)
disp(['Criterion 3 is NOT MET for factors ' num2str(c1) ' and ' num2str(c2)]);
end
end
end
% CRITERION 4
disp(' ');
disp('CRITERION 4');
if (factors > 3)
for c1 = 1 : 1 : factors - 1
for c2 = c1 + 1 : 1 : factors
test_several = 0;
for i = 1 : 1 : items
if (ct(i,c1)<approach_zero && ct(i,c2)<approach_zero) % approach zero in both
test_several = test_several + 1;
end
end
disp(['large proportion = ' num2str((test_several / items)*100) '% for factors ' num2str(c1) ' and ' num2str(c2)]);
if ((test_several / items) < large_proportion)
pr = sprintf('%4.2g', (test_several / items) * 100 );
disp(['Criterion 4 is NOT MET for factors ' num2str(c1) ' and ' num2str(c2) '. Proportion is ' pr '%']);
end
end
end
end
% CRITERION 5
disp(' ');
disp('CRITERION 5');
for c1 = 1 : 1 : factors - 1
for c2 = c1 + 1 : 1 : factors
test_number = 0;
for i = 1 : 1 : items
if (ct(i,c1)>approach_zero && ct(i,c2)>approach_zero) % approach zero in both
test_number = test_number + 1;
end
end
disp(['small number = ' num2str(test_number) ' for factors ' num2str(c1) ' and ' num2str(c2)]);
if (test_number > small_number)
disp(['Criterion 5 is NOT MET for factors ' num2str(c1) ' and ' num2str(c2)]);
end
end
end
% CRITERION 6
disp(' ');
disp('CRITERION 6');
for i = 1 : 1 : items
count = 0;
for j = 1 : 1 : factors
if (ct(i,j) > meaningful)
count = count + 1;
end
end
if (count == 0 || count > 1)
disp(['Criterion 6 is NOT MET for item ' num2str(i)])
end
end
% CRITERION 7
disp(' ');
disp('CRITERION 7');
for j = 1 : 1 : factors
m=0;
for i = 1 : 1 : items
if (ct(i,j) > meaningful)
m = m + 1;
end
end
disp(['some items = ' num2str(m) ' for factor ' num2str(j)]);
if (m < some_bottom || m > some_top)
disp(['Criterion 7 is NOT MET for factor ' num2str(j)]);
end
end
disp('')
disp('Checking completed.')
return