主成分分析マクロ
1.主成分分析とは何か
多種類のデータが得られたとき、これらのデータを用いて全体の変動を説明したい場合がしばしばあ
る。しかし、経済・経営分野でのデータの場合、各データ間に相関関係のある(相関係数が1に非常に
近くなる)ことが多く、似た変動を示すデータを同時に使用することは意味がないことになる。
回帰分析の場合で言えば、説明変数相互間に相関関係(多重共線性)が存在することになり、最小二
乗法による推定結果が信用できないものとなる。
このようなとき、互いに相関のある多種類のデータのもつ情報を、互いに無相関な少数のデータに要
約する手法である主成分分析は、有効な手段になるであろう。
2.主成分分析の概念
k種類のデータがn組得られたものとする。
{x1i, x2i, ・・・, xki} (i=1,2,・・・,n)
このとき、これらのデータの総合特性を与えるm(m<k)個の主成分zj (j=1,2,・・・,m)は、k種類のデー
タ xj (j=1,2,・・・,k) の加重平均により求められ、第j主成分は次式で表現することができる。
zj = pj1x1 + pj2x2 + ・・・ + pjkxk (j=1,2,・・・,m) (1)
ただし、係数pjiは各データが第j主成分に与える影響の割合を示しているので
pj12 + pj22 + ・・・ + pjk2 = 1 (j=1,2,・・・,m) (2)
を満たすように定められるものとする。
主成分は、k種類のデータの変動を代表するものにならなければならないことから、各主成分は相互
に無相関であり、その分散が大きいものから順に選ばれなければならない。したがって、各主成分は次
のルールに従って導出される。
@ 第1主成分 z1 の係数 {p11, p12,・・・, p1k} は、(2)式を満たし z1 の分散が最大となるように求め
る。
A 第2主成分 z2 の係数 {p21, p22,・・・, p2k} は、(2)式を満たし z1 と z2 が無相関になるとの条件
の下で、z2 の分散が最大となるように求める。
B 同様にして、第j主成分 zj の係数 {pj1, pj2,・・・, pjk} は、(2)式を満たし z1, z2,・・・,zj が無相
関になるとの条件の下で、zj の分散が最大となるように求める。
3.主成分の導出方法
主成分の導出方法としては、分散共分散行列を用いる方法と相関行列を用いる方法の二種類ある。結
果として得られる主成分には違いがあるため、どちらを使用するかについて考慮する必要がある。しか
し、一般的な分析においては相関行列を用いる方法の方が望ましいとされているので、ここでは相関行
列を用いる方法について主に説明する。以下では証明を省略して手順を中心に説明する。
@ k種類のデータの相関行列Rを求める。
A 相関行列Rの固有値と固有ベクトルを求める。
B 相関行列Rは非負定行列であるので、その固有値もすべて非負となる。固有値を大きさの順に
λ1≧λ2≧・・・≧λk≧0
とし、それぞれの固有値に対応する固有ベクトルをv1, v2, ・・・, vkとする。このとき、第j主成分
zj の係数 {pj1, pj2,・・・, pjk} は
┌ pj1 ┐
│ pj2 │
│ ・ │ = vj
│ ・ │
│ ・ │
└ pjk ┘
|
となり、第j主成分zj の分散はλj となる。
C 相関行列Rの固有値の和(すなわちRの対角和)はデータの個数kに等しくなり
第j主成分 zj の分散 λj
―――――――――― = ――
分散の総和 k
は、第j主成分 zj の寄与率と呼ばれ、寄与率を第1主成分から順に累計したものが累積寄与率と
呼ばれる。選ばれる主成分の個数mは、累積寄与率が90%ないし95%になるまでとされている。
以上のようにして求められる主成分は、元のデータの加重和であり、そのデータの具体的な意味は不
明なものである。したがって、主成分を用いて経済ないし経営分析を行ったとき、得られたモデル等の
解釈が難しくなる。しかし、予測を目的とする場合には、説明変数の将来値を予測する必要があり、
ARMA(自己回帰移動平均)モデル等で予測するのであれば、主成分を同様にして予測することが可能で
ある。
次表のように、Excelのワークシートに主成分を求めるべき系列を入力する。さらに、左上のデータ
の上のセルにデータの個数(この例の場合は15)、その右隣に系列数(この例の場合は5)を入力し、
データ個数を入力したセルをアクティブにして実行したとき、主成分及び寄与率を計算するExcelマク
ロを作成する。
ただし、別項「SUB固有ベクトル計算」で説明した3つのSUBプロシージャeigen、S1、S2が複写され
ているものとする。
↓データ個数 ↓系列数
15 | 5 | | | |
789 | 510 | 590 | 670 | 965 |
759 | 513 | 580 | 686 | 910 |
722 | 495 | 560 | 708 | 895 |
760 | 516 | 565 | 710 | 874 |
886 | 540 | 566 | 784 | 810 |
850 | 553 | 617 | 843 | 836 |
880 | 555 | 610 | 950 | 840 |
910 | 558 | 609 | 960 | 866 |
890 | 565 | 623 | 936 | 891 |
933 | 621 | 637 | 950 | 914 |
976 | 640 | 632 | 923 | 925 |
1010 | 639 | 640 | 902 | 940 |
1000 | 625 | 639 | 923 | 885 |
905 | 571 | 592 | 890 | 888 |
915 | 535 | 610 | 904 | 909 |
【手順−0】データを読み込む。
n = ActiveCell
Call S1(0, 1)
k = ActiveCell
Call S1(1, -1)
ReDim D(n, k), E(n, k)
For i = 1 To n
For j = 1 To k
D(i, j) = ActiveCell: E(i, j) = D(i, j): Call S1(0, 1)
Next j
Call S1(1, -k)
Next i
ただし、ここではデータ個数をn、系列数をkに読み込み、データを配列Dに読み込むと同時に配列
Eにコピーしている。
【手順−1】k種類のデータの相関行列Rを求める。
(1−1)k種類のデータの平均値を求め、配列hに代入する。
ReDim h(k)
For i = 1 To k
s = 0
For j = 1 To n
s = s + D(j, i)
Next j
h(i) = s / n
Next i
(1−2)各データから平均値を引き、偏差データを計算する。
For i = 1 To k
For j = 1 To n
D(j, i) = D(j, i) - h(i)
Next j
Next i
(1−3)k種類のデータの分散共分散行列を計算し、配列Cに代入する。
ReDim C(k, k)
For i = 1 To k: For j = 1 To k
s = 0
For m = 1 To n
s = s + D(m, i) * D(m, j)
Next m
C(i, j) = s / n
Next j, i
(1−4)k種類のデータの標準偏差を計算し、配列hに代入する。
For i = 1 To k
h(i) = Sqr(C(i, i))
Next i
(1−5)分散共分散行列Cを標準偏差で割ることで相関行列を求め、配列Rに代入する。
ReDim R(k, k)
For i = 1 To k: For j = 1 To k
R(i, j) = C(i, j) / h(i) / h(j)
Next j, i
【手順−2】相関行列Rの固有値と固有ベクトルWを求める。
ReDim W(k, k)
Call eigen(R, W, k)
【手順−3】求められた固有値を大きさの順に並べ替え、配列hに代入し、固有ベクトルも並べ替え、
配列Cに代入する
For i = 1 To k
z = -1: g = 0
For j = 1 To k
If R(j, j) > z Then
z = R(j, j): g = j
End If
Next j
h(i) = z: R(g, g) = -1
For j = 1 To k
C(j, i) = W(j, g)
Next j
Next i
【手順−4】求められた固有ベクトルの長さをzに求め、各固有ベクトルをzで割ることで長さを1
にする。
For i = 1 To k
s = 0
For j = 1 To k
s = s + C(j, i) ^ 2
Next j
z = Sqr(s)
For j = 1 To k
C(j, i) = C(j, i) / z
Next j
Next i
【手順−5】配列Eに保存しておいた源データと各固有ベクトルをかけることで主成分を配列Fに求
める。
ReDim F(n, k)
For i = 1 To n: For j = 1 To k
s = 0
For m = 1 To k
s = s + E(i, m) * C(m, j)
Next m
F(i, j) = s
Next j, i
【手順−6】各主成分の寄与率を求め、配列pに代入する。
ReDim p(k)
For i = 1 To k
p(i) = h(i) / k
Next i
【手順−7】固有値h、寄与率p、主成分FをExcelワークシートに出力する。
Call S1(1, 1)
For i = 1 To k
ActiveCell = "第" + i + "主成分": Call S1(0, 1)
Next i
Call S1(1, -k-1)
ActiveCell = "固有値": Call S1(0, 1)
For i = 1 To k
ActiveCell = h(i): Call S1(0, 1)
Next i
Call S1(1, -k-1)
ActiveCell = "寄与率": Call S1(0, 1)
For i = 1 To k
ActiveCell = p(i): Call S1(0, 1)
Next i
Call S1(1, -k-1)
ActiveCell = "主成分": Call S1(0, 1)
For i = 1 To n
For j = 1 To k
ActiveCell = F(i, j): Call S1(0, 1)
Next i
Call S1(1, -k)
Next i
SUBプロシージャeigen、S1、S2を再掲する。
Sub S1(x, y)
ActiveCell.Offset(x, y).Range("A1").Select
End Sub
Sub S2(x, n)
For i = 1 To n
For j = 1 To n
x(i, j) = 0
Next j
x(i, i) = 1
Next i
End Sub
Sub eigen(A, W, n)
ReDim B(n, n), C(n, n), D(n, n)
Call S2(W, n)
'
abc:
z = -1
For i = 1 To n - 1
For j = i + 1 To n
If Abs(A(i, j)) > z Then z = Abs(A(i, j)): ii = i: jj = j
Next j
Next i
If z < 0.0000000001 Then Exit Sub
AA = A(ii, ii) - A(jj, jj)
If Abs(AA) < 0.0000000001 Then
t = 3.1415926538979 / 4
Else
t = Atn(2 * A(ii, jj) / AA) / 2
End If
Call S2(B, n)
B(ii, ii) = Cos(t): B(jj, jj) = Cos(t)
B(ii, jj) = Sin(t): B(jj, ii) = -Sin(t)
For i = 1 To n: For j = 1 To n
s = 0
For p = 1 To n: For q = 1 To n
s = s + B(i, p) * A(p, q) * B(j, q)
Next q, p
C(i, j) = s
Next j, i
For i = 1 To n: For j = 1 To n
s = 0
For p = 1 To n
s = s + W(i, p) * B(j, p)
Next p
D(i, j) = s
Next j, i
For i = 1 To n: For j = 1 To n
A(i, j) = C(i, j)
W(i, j) = D(i, j)
Next j, i
GoTo abc
End Sub
|