2

因子分析を使用する上で最も重要な問題の1つは、その解釈です。因子分析では、多くの場合、因子ローテーションを使用してその解釈を強化します。十分な回転の後、回転された因子負荷行列L'は、相関行列を表す同じ能力を持ち、回転されていない行列Lの代わりに、因子負荷行列として使用できます。

回転の目的は、回転した因子負荷行列にいくつかの望ましい特性を持たせることです。使用される方法の1つは、回転された行列が単純な構造になるように因子負荷行列を回転させることです。

LL Thurstoneは、因子回転の一般的なガイドとして、単純構造の原理を紹介しました。

単純な構造基準:

  1. 因子行列の各行には、少なくとも1つのゼロが含まれている必要があります
  2. m個の共通因子がある場合、因子行列の各列には少なくともm個の零点が必要です。
  3. 因子行列の列のペアごとに、一方の列ではエントリがゼロに近づき、もう一方の列ではエントリがゼロに近づく変数がいくつかあるはずです。
  4. 因子行列の列のすべてのペアについて、4つ以上の因子がある場合、変数の大部分は両方の列でゼロに近づくエントリを持つ必要があります
  5. 因子行列の列のすべてのペアについて、両方の列にゼロ以外のエントリを持つ変数は少数である必要があります

理想的な単純な構造は次のようなものです。

  1. 各アイテムには、1つの要素のみに高い、または意味のある負荷がかかり、
  2. 各要素には、一部のアイテムに対してのみ高い、または意味のある負荷があります。

問題は、回転方法のいくつかの組み合わせを、それぞれが受け入れるパラメーター(特に斜めの方法)と一緒に試してみると、候補行列の数が増え、どれが上記の基準をよりよく満たすかを判断するのが非常に難しいことです。

その問題に最初に直面したとき、私はそれらを単に「見る」だけでは最適なものを選択することができず、決定するのに役立つアルゴリズムが必要であることに気づきました。プロジェクトの締め切りのストレスの下で、私ができることは、MATLABで次のコードを書くことでした。これは、一度に1つの回転行列を受け入れ、各基準が満たされているかどうかを(いくつかの仮定の下で)返します。新しいバージョン(アップグレードしようとした場合)は、引数として3d行列(2d行列のセット)を受け入れ、アルゴリズムは上記の基準により適したものを返す必要があります。

私はあなたの意見を求めています(私はまた、この方法自体の有用性についての批判もあったと思います)そしておそらく回転行列選択問題へのより良いアプローチです。誰かがコードを提供したいのなら、私はRかMATLABを好むでしょう。

PS上記の単純構造基準の定式化は、PETT、M.、LACKEY、N.、SULLIVAN、J.による著書「MakingSenseofFactorAnalysis」に記載されています。

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
4

1 に答える 1

1

これはあなたが求めているものではないことはわかっていますが、他の場合でもこれが役立つ場合があります。

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
于 2010-01-27T06:49:23.217 に答える