FA: Выбор матрицы вращения на основе "простых структурных критериев"

79
13

Одной из наиболее важных проблем при использовании факторного анализа является его интерпретация. Факторный анализ часто использует поворот факторов, чтобы улучшить его интерпретацию. После удовлетворительного вращения матрица с вращающимся коэффициентом загрузки L ' будет иметь одинаковую способность представлять корреляционную матрицу и может использоваться как матрица загрузки факторов вместо невращающейся матрицы L.


Цель вращения состоит в том, чтобы заставить матрицу загрузки вращающегося фактора иметь некоторые желательные свойства. Один из используемых методов состоит в том, чтобы повернуть матрицу загрузки факторов таким образом, чтобы вращающаяся матрица имела простую структуру.


л. Л. Турстон ввел принцип простой структуры как общий справочник по вращению факторов:


Простые структурные критерии:


    Каждая строка фактор-матрицы должна содержать по крайней мере один нуль
    Если есть m общих факторов, каждый столбец фактор-матрицы должен иметь не менее m нулей
    Для каждой пары столбцов в фактор-матрице должно быть несколько переменных, для которых записи приближаются к нулю в одном столбце, но не в другом
    Для каждой пары столбцов в фактор-матрице значительная часть переменных должна иметь записи, приближающиеся к нулю в обоих столбцах, когда есть четыре или более факторов.
    Для каждой пары столбцов в фактор-матрице должно быть только небольшое число переменных с ненулевыми элементами в обоих столбцах

Идеальная простая структура такова, что:


    каждый элемент имеет высокую или значимую нагрузку только на один фактор и
    каждый фактор имеет высокие или значимые нагрузки только для некоторых элементов.

Проблема заключается в том, что, пробуя несколько комбинаций методов вращения вместе с параметрами, которые каждый принимает (особенно для косых), количество матриц-кандидатов увеличивается, и очень сложно понять, какой из них лучше соответствует указанным выше критериям.


Когда я впервые столкнулся с этой проблемой, я понял, что мне не удалось выбрать лучшее совпадение, просто "взглянув" на них, и мне нужен алгоритм, который поможет мне решить. Под стрессом крайних сроков проекта я мог бы написать следующий код в MATLAB, который принимает одну матрицу вращения за раз и возвращает (при некоторых предположениях), соблюден ли каждый критерий или нет.
Новая версия (если бы я когда-либо пытался ее обновить) приняла бы в качестве аргумента 3d-матрицу (набор матриц 2d), и алгоритм должен вернуть тот, который лучше соответствует указанным выше критериям.


Я просто прошу вашего мнения (я также считаю, что критика в отношении полезности метода сама по себе) и, возможно, лучшие подходы к проблеме выбора матрицы вращения. Если кто-то хочет предоставить какой-то код, я бы предпочел R или MATLAB.


P.S. Вышеуказанный Простая формулировка критериев структуры можно найти в книге "Сознание анализа факторов" PETT, M., LACKEY, N., Сулливан, Дж.


PS2 (из той же книги): "Тест успешного анализа факторов - это то, в какой степени он может воспроизводить исходную матрицу корра. Если вы также использовали наклонные решения, среди всех выберите тот, который генерировал наибольшее количество наивысшая и низкая факторная нагрузка".
Это звучит как другое ограничение, которое может использовать алгоритм.


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

спросил(а) 2021-01-19T18:10:06+03:00 6 месяцев, 1 неделя назад
1
Решение
64

Я знаю, что это не то, что вы просите, но вы можете найти это полезным даже в других случаях:


MATLAB должен использовать циклы только тогда, когда это действительно неизбежно. например, ваш код


%// 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 6
disp(' ');
disp('CRITERION 6');
ct_lg_meaningful = sum(ct > meaningful,2) %// check where ct>meaningful, and sum along 2nd axis - gives a column vector of number of times each row was larger than meaningful.
criteria_not_met = find((ct_lg_meaningful == 0)|(ct_lg_meaningful>1)) %// in this vector find elements that are 0 or >1
if length(criteria_not_met)>0 %// if we found any elements, display them.
disp(['Criterion 6 is NOT MET for items ' num2str(criteria_not_met')]) %' <- to fix SO syntax highlighting
end

ответил(а) 2021-01-19T18:10:06+03:00 6 месяцев, 1 неделя назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема