Up

因子分析: 変量に対する最小2乗法

簡単な解説とプログラム(実行形式ファイルソースコードファイル

 

 因子分析は、因子という潜在変数の1次式によってデータ(変量)の変動を説明するモデルであり、次式(1)

(1)                 

によって表わされ、多くのものが提案されている。よく用いられるものとして、主因子解および最尤法による解があげられる。主因子解では、残差項の独立性の仮定のもとで、相関係数の対角要素を共通性の推定値で置き換えたものに対して最小2乗法の基準で解が求められる。最尤法では、多変量正規分布に従うという仮定の下で最尤法を適用して、相関行列から解が求められる。これらに対して、残差項の独立性あるいは多変量正規分布などの仮定をおくことなく直接(1)式に最小2乗法を適用する方法がある(Okamoto (2005),"On the Special Type of Principal Component Analysis: It should belong to factor analysis")。この方法をここでは因子分析の直接最小2乗解と呼んでおく。

 直接最小2乗解では次式

(2)                 

を最小にするものとして因子の値と因子パターンAを求める。これらは、行列に対する特異値分解による近似として求めることができる(岡本安晴(2009)「統計学を学ぶための数学入門[下]」培風館; Pp. 100 – 101 参照)。すなわち、データを行列

                           

で、因子得点を行列

                           

で、因子パターンを行列

                           

で表わすとき、次式

(3)                 

を最小にするFAは、Xの特異値分解

                           

から求めることができる。いま、因子分析における慣例に従い、データは、平均値0、分散1に標準化されているものとする(本ウェブサイトに用意されているプログラムでは、素データを入力として読み込み、プログラム内で素データの標準化を行っている)。また、因子得点も平均値0、分散1に標準化されたものを求めるものとする。このとき、FAは次式で与えられる。

(4)                 

ここで、は、特異値分解において特異値の大きいものに対応するものをからq組を選んだものである。

 プログラムでは

 

                 SVD( x, rnk, U, V, lambda );           //              特異値分解

 

と特異値分解を行って、

 

         for (int i = 0; i < p; i++)

                 for (int j = 0; j < q; j++)

                         A[i][j] = V[i][j] * lambda[j][0] / Math::Sqrt(n);              //              パターン行列

         for (int i = 0; i < n; i++)

                 for (int j = 0; j < q; j++)

                         F[i][j] = U[i][j] * Math::Sqrt(n);                             //              因子得点

 

とパターン行列Aと因子得点行列Fを求めている。

 式(3)を最小にするものとして与えられる式(4)の値は、Xの主成分分析から得られる式と同じである。しかし、数式の表面的な類似性から実質科学的解釈を行うことは危険である。物理学において、数式の表面的類似に基づいて議論を展開することの危険が指摘されている(サイフェ(著)・林大(訳)「宇宙を復号する」早川書房,2007p. 100)。因子分析の場合の因子は潜在変数として想定されているものであり、主成分分析における主成分は射影によって得られる(別の観点からいえば重み付き)合成量であるという実質科学的に異なる性質の量であることに注意しなければならない。

なお、次元を圧縮する最適な正射影を求めるという観点からの主成分分析の説明は、別のウェブサイトで行っている。

 

 プログラムfa_lse.exeは、式(2)すなわち式(3)の値を最小にするものとして因子の値と因子パターンAを求めるものである。プログラムは.NET Framework3.5対応の実行形式のファイルであるので、ファイル名fa_lse.exeをクリックしてダウンロード・実行することができる。実行すると図1のフォームが表示される。

図1

 

ラジオボタンは、「PrintData」にチェックが入っていると、読み込んだデータがファイルに出力される。出力されたファイルを見ることによって、データが正しく読み込まれているか確認することができる。因子数は、求める因子の数qを設定する。rはプロマックス回転におけるパラメータである。通常はでよいが、他の値を試すこともできる。「GO」ボタンをクリックすると、図1のフォームに設定された条件で因子分析が行われる。まず、入力データファイル名の設定を求めるダイアログウィンドウが表示される(図2)。

図2

 

入力データファイルは、以下のような形式で用意する。

======================= 入力データファイルの例 ===========================

 

     No of variables = 12

 

/

             12

   ID     Var_1    Var_12     Var_2    Var_11     Var_3    Var_10     Var_4     Var_9     Var_5     Var_8     Var_6     Var_7

    1     0.290    -2.523     0.779    -2.322     0.310    -2.796     0.968     0.253     0.144     0.102     0.198     0.222

    2    -1.271    -1.003    -1.378    -0.841    -1.137    -0.968    -1.398    -1.635    -1.294    -1.836    -1.897    -1.979

    3     0.553    -0.180     0.135     0.213     0.948    -0.177     0.796     0.750     0.551     0.630     0.959     0.887

    4     0.090    -0.799     0.363    -1.224    -0.150    -0.817    -0.157     1.176    -0.073     1.087     1.184     1.251

    5     1.476     0.398     1.480     0.715     1.397     0.634     1.235     0.439     1.425     0.661     0.434     0.741

     ・

     ・

     ・

  198     0.203     0.569     0.198     1.006     0.169     0.603     0.135    -3.055     0.179    -3.449    -3.113    -3.456

  199     0.114     0.309    -0.231     0.429     0.362     0.525     0.180     0.901     0.148     1.131     0.935     1.378

  200    -0.785     0.851    -0.682     1.054    -1.269     0.721    -0.650    -0.184    -0.773    -0.698    -0.428    -0.833

/

 

======================== 入力データファイルの例  =========================

 

データは、スラッシュ「/」で始まる行で挟む。最初のスラッシュ「/」で始まる行の次の行に、因子分析を行うデータの変量の数pを書く。次の行に各変量のラベルを空白で区切って書く。データはその次の行から、1行に1ケースのデータを書いていく。各行の第1変量はデータのケース番号を書く。このケース番号は分析には用いられないが、データの入力を解りやすくするための番号である。また、ケース番号は文字列として読み込まれているので、英字などを含んだ「abc123」のようなものでもよい。ケース番号は区切り文字を含まないものであるが、区切り文字は次のコードで指定されている。

 

        array<wchar_t> ^ separator = { ' ', '\t', ',',' ','/' };

 

詳しい説明は<岡本安晴「大学生のための心理学VC++プログラミング入門」勁草書房p. 209 >を参照されたい。

各ケースのデータの変量の値は2番目から書く。データの最終行の次の行は、スラッシュ「/」で始まる行を置く。この2つのスラッシュで始まる行で挟まれた部分以外はプログラムでは無視されるのでコメントなどを書くことができる。

 図2の入力ファイル名を設定するダイアログウィンドウでファイル名を設定して「開く」ボタンをクリックすると、次に出力ファイル名の設定を求めるダイアログウィンドウが表示される(図3)。

図3

 

適当なテキストファイル名を設定して「保存」ボタンをクリックする。「保存」ボタンをクリックすると計算が始まり、計算が終了すると計算結果を出力ファイルに保存したことを知らせるダイアログウィンドウが表示される(図4)。

図4

 

図4の「OK」ボタンのクリックでプログラムの実行が終了する。実行後、出力ファイルを開くと以下のようになっている。

まず、入力ファイル名が出力されている。

 

Data File = F:\yasuharu\www\LaCoocan\VCpp\fa_lse\fa_lse\fa_lse\DataCor200.txt

 

入力ファイル名の出力に続いて、スラッシュで始まる行まで、読み込んだ行がそのまま出力されている。

 

     No of variables = 12

 

/

 

次に、読み込んだ変量名と読み込んだケース数nが出力される。変量名の順序は、データを作成するときに昇順と降順が混在するように作成されている。これは、プログラムの出力においてパターン行列が見やすくなるように並べ替えが行われているかどうかをチェックするためである。入力データファイルでの変量名の並びがわざと入れ替えた形になっているということである。変量Var_1からVar_5までが1つのグループ、Var_6からVar_9までが第2グループ、Var_10からVar_12までが第3グループとなるようにデータが作成されている。バリマックス回転およびプロマックス回転後のパターン行列の出力が、これらのグループごとにまとめられて出力されることを確認する。

 

Vars =      Var_1    Var_12     Var_2    Var_11     Var_3    Var_10     Var_4     Var_9     Var_5     Var_8     Var_6     Var_7

n = 200

 

各変量の平均値と標準偏差が出力される。

 

                mean        sd

Var_1          0.036     1.331

Var_12         0.002     1.101

Var_2          0.059     1.320

Var_11         0.001     1.093

Var_3          0.050     1.299

Var_10         0.009     1.098

Var_4          0.059     1.330

Var_9          0.076     1.466

Var_5          0.056     1.338

Var_8          0.094     1.467

Var_6          0.096     1.477

Var_7          0.108     1.455

 

eigen valueとして、特異値の2乗をケース数nで割った値が出力される。これは、和が変量の数になるように調整したもので、各特異値に対応する因子がデータの変動量の説明率になるようにしたものである。

 

Eigen values...

Eigen value(1) = 6.60509

Eigen value(2) = 2.91881

Eigen value(3) = 2.26891

Eigen value(4) = 0.03812

Eigen value(5) = 0.03225

Eigen value(6) = 0.02605

Eigen value(7) = 0.02282

Eigen value(8) = 0.02133

Eigen value(9) = 0.01857

Eigen value(10) = 0.01807

Eigen value(11) = 0.01561

Eigen value(12) = 0.01436

Sum = 12

 

特異値分解から算出される因子パターン が出力される。

 

因子パターン

            Factor-1  Factor-2  Factor-3

Var_1        0.89775   0.09664  -0.41142

Var_12      -0.12354   0.97822   0.08995

Var_2        0.89048   0.09503  -0.42421

Var_11      -0.11485   0.97908   0.08148

Var_3        0.89666   0.10057  -0.41168

Var_10      -0.10794   0.97612   0.10273

Var_4        0.89231   0.09724  -0.41959

Var_9        0.79888  -0.04203   0.58815

Var_5        0.90163   0.09262  -0.40007

Var_8        0.79975  -0.00994   0.58979

Var_6        0.80070  -0.03397   0.58648

Var_7        0.79623  -0.03071   0.59252

 

上のパターンをバリマックス回転(直交回転)したものが次に出力される。

 

バリマックス回転後の因子パターン

            Factor-1  Factor-2  Factor-3  Communalities

Var_2       -0.96507   0.22384  -0.02196        0.98195

Var_4       -0.96392   0.22852  -0.01943        0.98174

Var_1       -0.96301   0.23830  -0.01961        0.98456

Var_3       -0.96283   0.23730  -0.01566        0.98360

Var_5       -0.95849   0.24970  -0.02272        0.98156

Var_7       -0.24756   0.96107  -0.03265        0.98601

Var_8       -0.25465   0.96049  -0.01263        0.98755

Var_9       -0.25086   0.95968  -0.04454        0.98589

Var_6       -0.25434   0.95926  -0.03687        0.98623

Var_12       0.02591  -0.03788   0.98902        0.98026

Var_11       0.01383  -0.03907   0.98829        0.97844

Var_10       0.02198  -0.01809   0.98702        0.97502

Contri.        4.889     3.968     2.936

 

バリマックス回転は、次のようにクラス型VariMaxによって行っている。

 

         VariMax Rot( A, p, q, commu, Contri );

         Rot.Rotate();                                  //              バリマックス回転

 

この回転後のパターンは、見やすくするために以下のコードで並べ替えられている。

 

/***   因子の並べ替え   ***/

        for (int j = 0; j < q-1; j++){

                int k = j;

                for (int j1 = j+1; j1 < q; j1++)

                        if (Contri[k] < Contri[j1])

                                k = j1;

                if (j < k){

                        swap( Contri[j], Contri[k] );

                        for (int j1 = 0; j1 < p; j1++)

                                swap( F[j1][j], F[j1][k] );

                }

        }

 

 

/***   変数の並べ替え     ***/

        for (int i = 0; i < p-1; i++){

                int k = i;

                for (int j = i+1; j < p; j++)

                        if (RhLargerLh(j, k)) k = j;

                if (i < k){

                        SwapString( VLabel[i], VLabel[k] );

                        for (int j1 = 0; j1 < q; j1++)

                                swap( F[i][j1], F[k][j1] );

                        swap( h[i], h[k] );

                }

        }

 

バリマックス回転の次に、プロマックス回転(斜交回転)されたパターン行列と因子相関行列が出力される。

 

プロマックス回転後の因子パターン

            Factor-1  Factor-2  Factor-3

Var_2       -0.99542  -0.00987  -0.00242

Var_4       -0.99287  -0.00433   0.00023

Var_3       -0.98924   0.00576   0.00426

Var_1       -0.98910   0.00670   0.00034

Var_5       -0.98087   0.02037  -0.00250

Var_7        0.00040   0.99310  -0.00100

Var_8       -0.00782   0.99118   0.01913

Var_9       -0.00345   0.99033  -0.01291

Var_6       -0.00750   0.98918  -0.00520

Var_12       0.00412  -0.00539   0.98949

Var_11      -0.00947  -0.00993   0.98888

Var_10       0.00542   0.01532   0.98812

 

因子相関行列...

                      Factor-1       Factor-2       Factor-3

Factor-1               1.00000       -0.47012        0.04764

Factor-2              -0.47012        1.00000       -0.06804

Factor-3               0.04764       -0.06804        1.00000

 

 

プロマックス回転は次のようにクラス型ProMaxによって行っている。

 

         ProMax promax( Rot.Ftemp, p, q, r );

         promax.Rotate();                       //              プロマックス回転

 

 

 プログラムについての詳しい内容はソースコードを参照されたい。ソースコードファイルなどは圧縮ファイルfa_lse.zipとしてまとめた。圧縮ファイル名fa_lse.zipをクリックしてダウンロードすることができる。ダウンロードした圧縮ファイルは、Windows VistaあるいはWindows7の場合は、マウスの右ボタンクリックで表示されるメニュから「展開」あるいは「解凍」を選んで解凍することができる。解凍したファイルはVisual C++2008などで開くことができる。

 

岡本安晴

Up