FA: Выбор матрицы вращения, основанной на «Критериях простой структуры» - PullRequest
2 голосов
/ 26 января 2010

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

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

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

Критерии простой структуры:

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

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

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

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

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

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

P.S. Вышеприведенную формулировку Simple Structure Criteria можно найти в книге "Осмысление факторного анализа" от PETT, M., LACKEY, N., SULLIVAN, J.

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

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

1 Ответ

1 голос
/ 27 января 2010

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

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...