rによるprincomp関数を使わない主成分分析

6
2012.12 作成 princomp 関数を使わない主成分分析 主成分分析の種類 A. 相関行列から算出するもの <= データを標準化する場合 B. 共分散行列から算出するもの <= データを標準化しない場合 主成分分析の流れ データを標準化 [A(相関行列出発)の場合のみ] 相関行列、または共分散行列の計算 データが標準化されていれば、共分散行列=相関行列となる。 相関行列/共分散行列から固有ベクトルと固有値を算出 大きい固有値に対応する固有ベクトルから、第一主成分、第二主成分・・・になる。 固有値から寄与率を算出し、何番目の主成分まで採用するか決める。 主成分負荷量及び主成分得点の計算 A. 標準化したデータと固有ベクトルとの内積 B. 主成分を標準化し、中心化したデータと内積 [デモ]R によるあやめデータの主成分分析 ステップ 1 : 前処理 まず R を起動し、組込のあやめのデータセットを呼び出す。[a] データセット名の iris と入力すると、データの内容が表示される。[b] このデータは、三つの異なる品種のあやめの花弁の寸法を測ったもので、 5 変数 150 データ(品種 50 データずつ)14 変数までが量的変数で、第 5 変数は品種名。データはリスト属性で、 データ番号・変数名つき。縦がデータ数、横が変数。 サンプルデータ(データ番号 1, 51, 101リスト属性のデータは、そのまま計算に使うのは不都合なので、行列(matrix)属性データに変 換し、さらに数量項目ではない第 5 変数を落とし、作業用の dat というデータを作る。[c] 通常データは scale 関数などを用いて標準化することが多いが[d]、今回は標準化しない例を取 り上げる。 Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa 51 7.0 3.2 4.7 1.4 versicolor 101 6.3 3.3 6.0 2.5 virginic

Upload: wada-kazumi

Post on 14-Jul-2015

2.273 views

Category:

Education


5 download

TRANSCRIPT

Page 1: Rによるprincomp関数を使わない主成分分析

2012.12 作成

princomp 関数を使わない主成分分析

主成分分析の種類

A. 相関行列から算出するもの <= データを標準化する場合

B. 共分散行列から算出するもの <= データを標準化しない場合

主成分分析の流れ

① データを標準化 [A(相関行列出発)の場合のみ]

② 相関行列、または共分散行列の計算

※ データが標準化されていれば、共分散行列=相関行列となる。

③ 相関行列/共分散行列から固有ベクトルと固有値を算出

④ 大きい固有値に対応する固有ベクトルから、第一主成分、第二主成分・・・になる。

⑤ 固有値から寄与率を算出し、何番目の主成分まで採用するか決める。

⑥ 主成分負荷量及び主成分得点の計算

A. 標準化したデータと固有ベクトルとの内積

B. 主成分を標準化し、中心化したデータと内積

[デモ]R によるあやめデータの主成分分析

ステップ 1 : 前処理

まずR を起動し、組込のあやめのデータセットを呼び出す。[a]

データセット名の iris と入力すると、データの内容が表示される。[b]

このデータは、三つの異なる品種のあやめの花弁の寸法を測ったもので、5 変数 150 データ(各

品種 50データずつ)、1~4変数までが量的変数で、第 5 変数は品種名。データはリスト属性で、

データ番号・変数名つき。縦がデータ数、横が変数。

サンプルデータ(データ番号 1, 51, 101)

リスト属性のデータは、そのまま計算に使うのは不都合なので、行列(matrix)属性データに変

換し、さらに数量項目ではない第 5変数を落とし、作業用の datというデータを作る。[c]

通常データは scale関数などを用いて標準化することが多いが[d]、今回は標準化しない例を取

り上げる。

Sepal.Length Sepal.Width Petal.Length Petal.Width Species

1 5.1 3.5 1.4 0.2 setosa

51 7.0 3.2 4.7 1.4 versicolor

101 6.3 3.3 6.0 2.5 virginic

Page 2: Rによるprincomp関数を使わない主成分分析

あやめデータの散布図

data(iris) #[a]

iris #[b]

dat<- as.matrix(iris[,1:4]) #[c]

# dat<- scale(as.matrix(iris[,1:4])) #[d]

fg1 <- as.numeric(iris[,5]) # 品種別フラグ

pairs(dat, pch=21, bg=c("red", "green", "blue")[fg1]) # 散布図

Sepal.Length

2.0 3.0 4.0 0.5 1.5 2.5

4.5

5.5

6.5

7.5

2.0

3.0

4.0

Sepal.Width

Petal.Length1

23

45

67

4.5 5.5 6.5 7.5

0.5

1.5

2.5

1 2 3 4 5 6 7

Petal.Width

Page 3: Rによるprincomp関数を使わない主成分分析

ステップ 2 : 固有値計算

共分散行列を求め[e]、これから固有値・固有ベクトルを算出する。[f]

固有ベクトルが主成分(主成分得点の係数)で、固有値は主成分得点の分散にあたる。

データが 4 変数なので、共分散行列は四行四列。

4 つの固有値は大きい順に並んだ一つのベクトル(下の例では eg$value)、固有ベクトルは

対応する固有値が大きい順に上から並んだ 4 行 4 列の行列が返される。

寄与率は、4つの固有値の合計で各固有値を割った値になる。[g]

上の例では、eigen 関数による固有値・固有ベクトルの計算結果を変数 eg1 に代入している

ので、eg1 とタイプすると結果が表示される。

$values が固有値、$vectors が固有ベクトル。それぞれ eg1$value, eg1$vector で個別にこれ

らの内容が参照できる。第 1主成分は、eg1$vectors[1,]、これに対応する固有値が eg1$values[1]、

寄与率 ct の計算結果を見れば、この第一主成分だけでデータ全体の 92%が説明できることが

わかる。

[結果出力のコンソール画面]

主成分分析を行う目的が次元縮約(たくさんある変数の数を減らすこと)であれば、主成

分採用の目安は経験的に累積寄与率が 70~80%以上とされているので、このデータの場合は

第一主成分だけを採用すればよいことになる。

cv <- cov(dat) #[e]

eg1 <- eigen(cv, symmetric=TRUE) #[f]

eg1a <- eg1$value # eg1から固有値を eg1aに取り出す

eg1v <- eg1$vectors # eg1から固有ベクトルを eg1vに取り出す

ct1 <- eg1a / sum(eg1a) #[g]

> eg1

$values

[1] 4.22824171 0.24267075 0.07820950 0.02383509

$vectors

[,1] [,2] [,3] [,4]

[1,] 0.36138659 0.65658877 0.58202985 0.3154872

[2,] -0.08452251 0.73016143 -0.59791083 -0.3197231

[3,] 0.85667061 -0.17337266 -0.07623608 -0.4798390

[4,] 0.35828920 -0.07548102 -0.54583143 0.7536574

> ct1

[1] 0.924618723 0.053066483 0.017102610 0.005212184

> eg1$vectors[1,]

[1] 0.3613866 0.6565888 0.5820299 0.3154872

> eg1

$values[1]

[1] 4.228242

Page 4: Rによるprincomp関数を使わない主成分分析

ステップ 3 : 主成分得点と主成分負荷量の計算

ステップ 2 で、固有値分解により、固有値 ega と固有ベクトル egv を算出した。次に、主成分

得点(データの各主成分に対する値)と、主成分負荷量(構造係数とも呼ばれ、主成分と各変

量の間の相関係数と一致する)を計算してみる。

主成分得点は、データポイントから各主成分に射影したときのデータの重心(=平均)から

の影の長さになる。[図 1参照]

まず各データから平均値ベクトルを引き、データの中心を原点に持ってくる(中心化)。[k]

データを標準化せず、共分散行列から出発した場合、主成分も標準化されていないので、固

有値の平方根(=各主成分の標準偏差)で割って標準化する。[l]

(※中心化と主成分の標準化は、最初にデータを標準化した場合は必要がない。)

主成分得点(上の青いベクトル)は、標準化済主成分と中心化したデータの内積。[m]

主成分負荷量は、もとのデータと主成分得点との相関係数にあたる。

図 1. 主成分と主成分得点

cdat<- t(t(dat) - colMeans(dat, 2)) # [k]

spca<- eg1v %*% diag(1/sqrt(eg1a)) # [l] 主成分を標準化

tok<- cdat %*% spca # [m] 主成分得点

dev.new()

plot(tok[,1:2], pch=21, bg=c("red", "green", "blue")[fg1])

# 第 1・2主成分を x, y軸としてプロット

xpca<- solve(spca) # 主成分の逆行列

xpca<- solve(spca) # 主成分の逆行列 =>もとの軸を示すものになる

arrows(0, 0, x1=xpca[,1], y1=xpca[,2], col="red")

# あまり見栄えがよくないが、主成分得点プロットに元の軸を矢印で表示してみた

-1.5 -1.0 -0.5 0.0 0.5 1.0 1.5

-3-2

-10

12

tok[, 1:2][,1]

tok[,

1:2

][,2

]

Page 5: Rによるprincomp関数を使わない主成分分析

princomp 関数との比較

princomp 関数による結果と比較してみる。ccr=FALSE指定で先と同じデータを標準化しな

い形での分析になる。結果は変わらないが、見栄えの良い biplotを出力することができる。

[結果出力のコンソール画面]

図 1 散布図

prc1 <- princomp(dat, cor=FALSE)

summary(prc1)

prc1$loadings # 因子負荷量表示

dev.new()

biplot(prc1)

> prc1 <- princomp(dat, cor=FALSE)

> summary(prc1)

Importance of components:

Comp.1 Comp.2 Comp.3 Comp.4

Standard deviation 2.0494032 0.49097143 0.27872586 0.153870700主成分標準偏差

Proportion of Variance 0.9246187 0.05306648 0.01710261 0.005212184寄与率

Cumulative Proportion 0.9246187 0.97768521 0.99478782 1.000000000累積寄与率

> prc1$loadings 因子負荷量のはずだが表示されているのは固有ベクトル(未標準化)

Loadings:

Comp.1 Comp.2 Comp.3 Comp.4

Sepal.Length 0.361 -0.657 -0.582 0.315

Sepal.Width -0.730 0.598 -0.320

Petal.Length 0.857 0.173 -0.480

Petal.Width 0.358 0.546 0.754

Comp.1 Comp.2 Comp.3 Comp.4

SS loadings 1.00 1.00 1.00 1.00

Proportion Var 0.25 0.25 0.25 0.25

Cumulative Var 0.25 0.50 0.75 1.00

-0.2 -0.1 0.0 0.1 0.2

-0.2

-0.1

0.0

0.1

0.2

Comp.1

Com

p.2

1

23

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

202122

23 24

2526

27

2829

3031

32

33

34

35

36

37

38

39

4041

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

6768

6970

7172

73

74

75

767778

79

80

8182

8384

85

86

87

8889

9091

92

93

94

95

9697

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116117

118

119

120

121

122

123

124

125

126

127128

129

130131

132

133134

135

136

137138

139

140

141

142

143

144145146

147

148149

150

-20 -10 0 10 20

-20

-10

010

20

Sepal.LengthSepal.Width

Petal.LengthPetal.Width

Page 6: Rによるprincomp関数を使わない主成分分析

結果を比較するかぎり、どうも princomp は主成分を標準していないと思われる。先の spca

は標準化した主成分で、これが上の因子負荷量と同じになるはずだが、上の$loadings で表示

されているのは eg1v、つまり生の固有ベクトルと同じもの。

このままこれを用いてスコア計算すれば、標準偏差が 1にならないはずなので、以下は検証。

> eg1v

[,1] [,2] [,3] [,4]

[1,] 0.36138659 -0.65658877 -0.58202985 0.3154872

[2,] -0.08452251 -0.73016143 0.59791083 -0.3197231

[3,] 0.85667061 0.17337266 0.07623608 -0.4798390

[4,] 0.35828920 0.07548102 0.54583143 0.7536574

>spca

[,1] [,2] [,3] [,4]

[1,] 0.1757487 -1.3328606 -2.0812081 2.043494

[2,] -0.0411048 -1.4822115 2.1379949 -2.070931

[3,] 0.4166141 0.3519427 0.2726031 -3.108044

[4,] 0.1742424 0.1532248 1.9517707 4.881638

>apply(prc1$scores, 2, sd) # やっぱり princompのスコアは標準化されていない

Comp.1 Comp.2 Comp.3 Comp.4

2.0562689 0.4926162 0.2796596 0.1543862

>tokx<- cdat %*% eg1v # 主成分を標準化せずにスコア計算

>apply(tokx, 2, sd) # 標準化しないときのスコアの分散と同じ

[1] 2.0562689 0.4926162 0.2796596 0.1543862

# 今度は個々のデータのスコアの比較。

> tail(prc1$scores) # princompの主成分得点

Comp.1 Comp.2 Comp.3 Comp.4

[145,] 2.418746 -0.30479820 0.5044827 0.2410910

[146,] 1.944110 -0.18753230 0.1778251 0.4261959

[147,] 1.527167 0.37531698 -0.1218982 0.2543674

[148,] 1.764346 -0.07885885 0.1304816 0.1370013

[149,] 1.900942 -0.11662796 0.7232516 0.0445953

[150,] 1.390189 0.28266094 0.3629096 -0.1550386

> tail(tokx) # 標準化しないいで計算した主成分得点

[,1] [,2] [,3] [,4]

[145,] 2.418746 -0.30479820 0.5044827 0.2410910

[146,] 1.944110 -0.18753230 0.1778251 0.4261959

[147,] 1.527167 0.37531698 -0.1218982 0.2543674

[148,] 1.764346 -0.07885885 0.1304816 0.1370013

[149,] 1.900942 -0.11662796 0.7232516 0.0445953

[150,] 1.390189 0.28266094 0.3629096 -0.1550386

> tail(tok) #標準化した主成分得点

[,1] [,2] [,3] [,4]

[145,] 1.1762791 -0.6187336 1.8039168 1.5616100

[146,] 0.9454550 -0.3806864 0.6358626 2.7605835

[147,] 0.7426882 0.7618851 -0.4358805 1.6476050

[148,] 0.8580326 -0.1600817 0.4665730 0.8873934

[149,] 0.9244616 -0.2367522 2.5861852 0.2888555

[150,] 0.6760735 0.5737954 1.2976834 -1.0042261