데이터 변환 방법으로서

(1) 표준화

(2) 정규분포화

(3) 범주화

    - 이산형화

    - 이항변수화

(4) 개수 축소

(5) 차원 축소

   - (5-1) 주성분분석

   - (5-2) 요인분석

(6) 시그널 데이터 압축

의 6개 구분 중에서

 

등간척도(혹은 비율척도)로 측정한 두 개 이상의 다수의 변수들에 잠재되어 있는 공통인자를 찾아내는 (5-2) 요인분석(Factor Analysis)에 대해서 알아보겠습니다. 

 

요인분석은 통계학자 Spearman이 학생들의 여러개의 시험 성적(예: Classic, French, English, Math...) 간에 상관관계 행렬을 보다가 "어떻게 하면 연관성있는 변수들을 묶어주는 내재하는 속성을 찾을 수 있을까?"를 가지고 고민하다가 유래되었다고 합니다.

 

요인분석을 왜 하는지에 대해서는 이전에 포스팅한 (5-1) 주성분분석의 초반부를 참고하시기 바랍니다. (바로가기 ☞ 주성분분석)

 

 

 

 

대신에 요인분석과 주성분분석의 공통점과 차이점에 대해서 정리한 다른 분의 블로그(http://ai-times.tistory.com/112) 내용을 소개하겠습니다.

 

요인분석 과 주성분분석의 관계는?

많은 경우 (많은 사람들이) 요인분석과 주성분분석을 혼동한다.
두 용어를 같은 것으로 이해하는 사람들도 많다. ( 요인분석 = 주성분분석 ? ) 그러나 이것은 요인분석이나 주성분 분석을 잘 이해하지 못한 것이다. (참고는 요인분석은 Factor Analysis 이고, 주성분 분석은 Principle Component Analysis 이며 보통 PCA 라고 불린다.)

요인분석과 주성분분석은 물론 깊은 관계가 있다. 그러나 엄밀하게는 같은 것은 아니다.
요인분석을 수행하기 위해서 즉, 몇 개의 요인(잠재된 변수)들을 추출하기 위해서 여러 가지 방법이 사용될 수 있으나 그 중에 가장 많이 사용되는 방법이 <주성분 분석>이다. (그렇다고, 요인분석이 주성분분석의 상위 개념에 있는 것이라고 할 수는 없다. 집합으로 볼 때 포함 관계 아님)

 

* 공통점
[1] 모두 데이터를  축소한다. 
[2] 원래 데이터의 새로운 몇 개의 변수들로 만들어 낸다.


* 차이점
(아래에 정리해보았다. 요인분석은 FA 로, 주성분분석은 PCA 로 표현하였다.)

[1] 생성되는 변수의 수
FA  : 몇 개라고 지정할 수 없다. 데이터의 의미에 따라 다르다. 3개가 될 수도 있고, 또는 4개도 있고, ...
데이터에 서로 성관성을 갖는 변수들의 군집의 개수로 나뉘어질 것이다.
PCA : 주성분이라고 하며, 보통 2개를 찾는다. 제1주성분, 제2주성분 이라고 불린다.

[2] 생성되는 변수의 의미 (이름)
FA : 위에서 학생들의 성적데이터를 가지고 설명했듯이 분석가가 적절한 이름을 붙일 수 있다. 자동적으로 이름을 만들어주지는 않는다.
PCA : 보통 2개의 변수를 채택한다. 첫번째 것은 제1주성분, 제2주성분 이라고 부른다. (원래 데이터의 입력변수가 p라고 하면, ... 제p주성분까지 만들수 있다. 그러나 보통 2개 정도만 사용한다. 이걸로 보통 충분하다.)
요인분석에서는 서로 상관있는 변수들의 이름을 지을 수 있으나 제n주성분의 경우는 그게 좀 힘들다. (의미 중심으로 묶였다기 보다는 분류 결정력이 높은 임의의 변수를 만든 것이기 때문이다.)

[3] 생성된 변수들의 관계
FA : 새 (잠재)변수들은 기본적으로 대등한 관계를 갖는다. 어떤 것이 더 중요하다 라는 의미는 요인분석에서는 없다. 단, 분류/예측에 그 다음 단계로 사용된 다면 그 때 중요성의 의미가 부여될 것이다.  
PCA : 제1주성분이 가장 중요하고, 그 다음 제2주성분이 중요하게 취급된다. 그 다음은 제3주성분 ... 이런 식이다. 즉, 변수들 간의 중요성의 순위가 존재한다.

[4] 분석방법의 의미
FA : 목표 필드를 고려하지 않는다. 그냥 데이터가 주어지면 변수들을 비슷한 성격들로 묶어서 새로운 [잠재]변수들을 만들어 낸다.
PCA : 목표 변수를 고려한다. 목표 변수를 잘 예측/분류하기 위하여 원래 변수들의 선형 결합으로 이루어진 몇 개의 주성분(변수)들을 찾아낸다 

 

* 출처: http://ai-times.tistory.com/112

 

 

요인 추출 방법으로 주성분분석이 활용됩니다. 요인분석을 할 때 초기값 m을 어떻게 잡아주느냐에 따라서 계산 속도가 많이 영향을 받게 됩니다. 이때 보통은 반응변수들이 가지고 있는 변동량의 대부분들을 설명해줄 수 있는 고유값(eigenvalue)와 고객벡터(engenvector)의 수는 몇 개인가를 결정할 수 있는 주성분분석(Principal Component Analysis, PCA)를 활용해서 초기값 m을 잡게 됩니다. (지난 주성분분석 포스팅의 Scree Plot 참조)

 

 

[참고: 용어설명]

- 요인점수 (Factor Score) : 각 관측치의 요인 점수는 요인 점수 계수(Standardized Scoring Coefficients)와 실제 (표준화된) 관측치의 값의 곱으로 구하며, 요인별로 이를 summation하면 요인별 요인점수가 됨.

- 요인패턴 (Factor Loading) :  각 요인이 각 변수에 미치는 효과.  변수와 요인의 상관 행렬

- 공통 분산치 (Communality) : 요인에 의해 설명될 수 있는 변수의 분산량

- 요인회전 (Factor Rotation) : p개의 변수들을 m개의 요인(factor)로 묶어주기 편리하게 혹은 해석하기 쉽게하도록 축을 회전시키는 것. 직교회전에 varimax, transvarimax 등이 있고 비직교회전방법도 있으며, 보통 분산을 최대화하는 직교회전방법 varimax 를 많이 씀.

 

한국신용평가정보에서 나온 '국내 증권회사의 주요 재무제표' (2007.3.31 기준)를 가지고 요인분석을 R로 해보도록 하겠습니다. (지난번 포스팅에서는 똑같은 데이터에 대해 주성분분석을 해보았습니다)

 

이 데이터는 18개 증권사별로 V1.총자본순이익율, V2.자기자본순이익율, V3.자기자본비율, V4.부채비율, V5.자기자본회전율 재무지표 변수로 구성되어 있습니다.

 

예제 데이터('국내 증권회사의 주요 재무제표' (2007.3.31 기준)) 다운로드 ☞

secu_com_finance_2007.csv

 

R로 외부 csv 데이터 불러오기, 표준화 변환, 부채비율 방향 변환, 변수 선택, 상관계수분석, 산포도행렬은 아래와 같습니다. (지난 포스팅 주성분분석 설명과 동일)

 

주성분분석처럼 요인분석도 변수별 scale 영향을 없애기 위해서 표준화(standardization)한 관측값을 사용합니다.

 

> # csv 파일 불러오기 (file importing)
> secu_com_finance_2007 <- read.csv("C:/Users/user/Documents/R/secu_com_finance_2007.csv",
+                                   header = TRUE, 
+                                   stringsAsFactors = FALSE)
> # V1 : 총자본순이익율
> # V2 : 자기자본순이익율
> # V3 : 자기자본비율
> # V4 : 부채비율
> # V5 : 자기자본회전율
> 
> 
> # 표준화 변환 (standardization)
> secu_com_finance_2007 <- transform(secu_com_finance_2007, 
+                                    V1_s = scale(V1), 
+                                    V2_s = scale(V2), 
+                                    V3_s = scale(V3), 
+                                    V4_s = scale(V4),
+                                    V5_s = scale(V5))
> 
> # 부채비율(V4_s)을 방향(max(V4_s)-V4_s) 변환
> secu_com_finance_2007 <- transform(secu_com_finance_2007, 
+                                    V4_s2 = max(V4_s) - V4_s)
> 
> # variable selection
> secu_com_finance_2007_2 <- secu_com_finance_2007[,c("company", "V1_s", "V2_s", "V3_s", "V4_s2", "V5_s")]
> 
> 
> # Correlation analysis
> cor(secu_com_finance_2007_2[,-1])
            V1_s       V2_s       V3_s      V4_s2        V5_s
V1_s  1.00000000  0.6165153  0.3239780  0.3553930  0.01387883
V2_s  0.61651527  1.0000000 -0.5124351 -0.4659444  0.42263462
V3_s  0.32397800 -0.5124351  1.0000000  0.9366296 -0.56340782
V4_s2 0.35539305 -0.4659444  0.9366296  1.0000000 -0.53954570
V5_s  0.01387883  0.4226346 -0.5634078 -0.5395457  1.00000000
> 
> round(cor(secu_com_finance_2007_2[,-1]), digits=3) # 반올림
       V1_s   V2_s   V3_s  V4_s2   V5_s
V1_s  1.000  0.617  0.324  0.355  0.014
V2_s  0.617  1.000 -0.512 -0.466  0.423
V3_s  0.324 -0.512  1.000  0.937 -0.563
V4_s2 0.355 -0.466  0.937  1.000 -0.540
V5_s  0.014  0.423 -0.563 -0.540  1.000
> 
> 
> # Scatter plot matrix
> plot(secu_com_finance_2007_2[,-1])

 

 

 

factanal()함수를 활용해서 R로 요인분석을 해보도록 하겠습니다.

- secu_com_finance_2007_2 : 데이터를 지정해주고 (표준화된 숫자형 변수들)

- factors = 2 : 요인의 개수 지정

- ratation = "varimax" : 회전방법 지정

- scores = "regression" :  요인점수 계산 방법 지정

해주면 되겠습니다.

 

지난번 포스팅의 주성분분석에서는 동일한 데이터로 했을 때 주성분을 3개(Scree plot 보고서 결정)로 해서 분석 결과 해석을 했었는데요,

 

> # Scree Plot
> plot(prcomp(secu_com_finance_2007_2[,c(2:6)]), type="l",
+      sub = "Scree Plot")

 

 

 

 

 

 

요인분석에서 요인 개수를 3개로 집어넣었더닌 변수 5개밖에 안되는데 요인을 3개씩이나 한다고 경고메시지가 뜨네요. ^^;  그래서 요인 2개로 집어넣었습니다.

 

> # 요인분석(maximum likelihood factor analysis)
> # rotation = "varimax"
> secu_factanal <- factanal(secu_com_finance_2007_2[,2:6], 
+                           factors = 2, 
+                           rotation = "varimax", # "varimax", "promax", "none" 
+                           scores="regression") # "regression", "Bartlett"
> 
> print(secu_factanal)

Call:
factanal(x = secu_com_finance_2007_2[, 2:6], factors = 2, scores = "regression",     rotation = "varimax")

Uniquenesses:
 V1_s  V2_s  V3_s V4_s2  V5_s 
0.005 0.026 0.036 0.083 0.660 

Loadings:
      Factor1 Factor2
V1_s   0.252   0.965 
V2_s  -0.588   0.792 
V3_s   0.979         
V4_s2  0.950   0.120 
V5_s  -0.562   0.155 

               Factor1 Factor2
SS loadings      2.586   1.604
Proportion Var   0.517   0.321
Cumulative Var   0.517   0.838

Test of the hypothesis that 2 factors are sufficient.
The chi square statistic is 1.59 on 1 degree of freedom.
The p-value is 0.207 

 

 

 

위에 Loadings 에 보면 Factor2의 V3_s가 숫자가 비어있는데요, 아래처럼 cutoff 를 조정해주면 모두 볼 수 있습니다.

 

> print(secu_factanal$loadings, cutoff=0) # display every loadings

Loadings:
      Factor1 Factor2
V1_s   0.252   0.965 
V2_s  -0.588   0.792 
V3_s   0.979   0.080 
V4_s2  0.950   0.120 
V5_s  -0.562   0.155 

               Factor1 Factor2
SS loadings      2.586   1.604
Proportion Var   0.517   0.321
Cumulative Var   0.517   0.838 

 

요인1(Factor1)은 자기자본비율(V3_s)과 (방햔변환 후의) 부채비율(V4_s2) 이 같이 묶였으며, 요인2(Factor2)는 총자본순이익율(V1_s)과 자기자본순이익율(V2_s)이 함께 묶었습니다.  V5_s가 두 요인 중에서 어디에 속한다고 할지 좀 애매한데요, 요인1하고는 부호가 다르므로 요인2에 묶인다고 하겠습니다.

 

 

 

 

다음으로, 요인분석 Biplot을 그려보도록 하겠습니다.  주성분분석할 때는 prcomp() 함수로 분석하고 biplot()함수로 단 한번에 아주 쉽게 Biplot을 그렸었는데요, 요인분석에서는 biplot을 단번에 그릴 수 있는 함수를 못찾았습니다. (혹시 이 포스팅 보시는 분중에 요인분석 biplot 그릴 수 있는 패키지, 함수 알고 계신분은 댓글로 공유해주시면 감사하겠습니다. 미리 꾸벅~ ☞_☜)

 

> # factor scores plotting
> secu_factanal$scores
          Factor1     Factor2
 [1,] -1.01782141 -0.28535410
 [2,] -0.17230586  0.08808775
 [3,] -0.13294211 -0.71511403
 [4,] -1.03557284  2.77950626
 [5,] -0.34416962 -1.21841127
 [6,] -0.01993668  0.44223954
 [7,] -0.62177426  1.26909067
 [8,]  1.79002399  0.28314793
 [9,]  1.60353334  0.52158445
[10,] -0.55591603 -0.12331881
[11,]  0.55387868 -1.03939155
[12,] -0.93740279 -0.74332879
[13,]  0.45680247  0.06433085
[14,] -1.13490535 -0.63034122
[15,]  1.36209539 -0.98147959
[16,]  1.57141053  0.89812864
[17,] -0.56190944  0.38006982
[18,] -0.80308800 -0.98944656
> 
> plot(secu_factanal$scores, main="Biplot of the first 2 factors")
> 
 

 

 
 
> # 관측치별 이름 매핑(rownames mapping)
> text(secu_factanal$scores[,1], secu_factanal$scores[,2], 
+      labels = secu_com_finance_2007$company, 
+      cex = 0.7, pos = 3, col = "blue")
> 
 

 

 
 
> # factor loadings plotting
> points(secu_factanal$loadings, pch=19, col = "red")
>
 

 

> text(secu_factanal$loadings[,1], secu_factanal$loadings[,2], + labels = rownames(secu_factanal$loadings), + cex = 0.8, pos = 3, col = "red") >
> # plotting lines between (0,0) and (factor loadings by Var.)
> segments(0,0,secu_factanal$loadings[1,1], secu_factanal$loadings[1,2])
> segments(0,0,secu_factanal$loadings[2,1], secu_factanal$loadings[2,2])
> segments(0,0,secu_factanal$loadings[3,1], secu_factanal$loadings[3,2])
> segments(0,0,secu_factanal$loadings[4,1], secu_factanal$loadings[4,2])
> segments(0,0,secu_factanal$loadings[5,1], secu_factanal$loadings[5,2])

 

 

 

 

가로축 Factor1이 '안정성' (자기자본비율, 부채비율) 지표라고 했는데요, Factor1 축의 오른쪽에 위치한 한양증권, 브릿지증권, 부국증권, 유화증권사 등은 안정성이 높은 회사들이라고 해석할 수 있겠습니다.

 

(참고: Factor1 = 0.252*V1_s - 0.588*V2_s + 0.979*V3_s + 0.950*V4_s2 - 0.562*V5_s)

 

 

다음으로, 세로축 Factor2는 '수익성'(총자본순이익율, 자기자본순이익율, 자기자본회전율) 지표라고 했는데요, Factor2 축의 위쪽에 위치한 미래애셋증권, 한화증권, 메리츠증권, 교보증권, 삼성증권 등이 수익성이 양호한 증권사라고 해석할 수 있겠습니다.

 

(참고: Factor2 = 0.965*V1_s + 0.792*V2_s + 0.080*V3_s + 1.20*V4-s2 + 0.155*V5_s)

 

 

이처럼 요인분석을 활용하면 다수의 변수를 안정성과 수익성이라는 두 개의 축으로 차원을 축소해서 포지셔닝맵을 그려서 쉽게 전체 상황을 파악할 수 있겠습니다.

 

다음번 포스팅에서는 기계데이터, 신호데이터에서 나오는 신호를 압축 변환하는 방법에 대해서 알아보겠습니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by R Friend R_Friend

데이터 변환 방법으로서

(1) 표준화

(2) 정규분포화

(3) 범주화

   - 이산형화

   - 이항변수화

(4) 개수 축소

(5) 차원 축소

   - (5-1) 주성분분석

   - (5-2) 요인분석

(6) 시그널 데이터 압축

 

의 6개 구분 중에서 (5-1) 주성분분석(Principal Component Analysis, PCA)에 대해서 알아보겠습니다.

 

주성분분석이란 여러 변수들의 변량을 '주성분(Principal Component)'이라고 불리는, 서로 상관성이 높은 여러 변수들의 선형조합으로 만든 새로운 변수들로 요약, 축소하는 기법입니다.  첫번째 주성분으로 전체 변동을 가장 많이 설명할 수 있도록 하고, 두번째 주성분으로는 첫번째 주성분과는 상관성이 없어서(낮아서) 첫번째 주성분이 설명하지 못하는 나머지 변동을 정보의 손실없이 가장 많이 설명할 수 있도록 변수들의 선형조합을 만들게 됩니다.

 

 

 

 

주성분분석이나 요인분석은 다변량통계분석에서 배우게 되는데요, 선형대수(Linear Algebra)에 대한 기본적인 이해가 없으면 이론으로 깊이 들어가는 것이 매우 어렵습니다.  그래서 이번 포스팅에서는 수식이나 행렬 등 어려운 이론은 넘어가도록 하겠으며, 주성분분석이나 요인분석을 왜 하는지 알아보고, 분석을 위한 R script 와 결과 해석에 주안점을 두도록 하겠습니다.

 

(☞ 선형대수학은 본 블로그의 선형대수' 카테고리에 별도로 정리하였으니 참고하시기 바랍니다. (벡터, 행렬, 내적, 외적, 선형독립, 기저, 벡터공간, 부분공간, 생성공간, 차원, 핵, 상공간, 차원정리, 계수, 고유값, 고유벡터 등))

 

 

주성분분석, 요인분석은 왜 하는가?  어떤 분석에 연계활용되나? 

 

1. 여러 변수들 간에 내재하는 상관관계, 연관성을 이용해 소수의 주성분 또는 요인으로 차원을 축소함으로써 데이터를 이해하기 쉽고 관리하기 쉽게 해줍니다.  사람은 1차원, 2차원까지는 그래프로 그려서 직관적으로 이해를 할 수 있지만, 3차원 이상으로만 넘어가도 집단의 모습을 인식하는데 큰 어려움을 겪게 됩니다.(향후 홀로그램이 상용화되면 3차원까지는 그래도 사람이 인지하기 편할수도 있겠네요 ^^;)  만약 변수가 10개 있는데 이를 단 2개의 차원으로 요약을 했는데도 변수들이 가지는 변동을 80~90% 설명할 수 있다면 굳이 변수 10개를 모두 이용할 필요가 없겠지요.

 

 

 

 

2. 회귀분석이나 의사결정나무(decision tree) 등의 모형 개발 시 입력변수들간의 상관관계가 높은 다중공선성(multicollinearity)이 존재할 경우 모형이 잘못만들어지고 따라서 해석에도 문제가 생기게 됩니다.  다중공선성이 존재할 경우 해결 방법 중의 하나가 바로 상관도가 높은 변수들을 하나의 주성분 혹은 요인으로 축소하여 모형개발에 활용하는 것입니다.

 

3. 연관성이 높은 변수 간 주성분 또는 요인분석을 통해 차원을 축소한 후에 군집분석을 수행하면 군집화 결과, 연산속도 개선에 기여하게 됩니다.  가령, Benefit 고객세분화를 위해 survey를 하게 되면 소구점들에 대한 다수의 문항(변수)의 답변 결과에 대해서 먼저 요인분석을 한 후에 요인점수(factor score)를 가지고 군집분석(clustering)을 수행하고 세분군집을 명명(naming)하게 됩니다.

 

4. 기계에서 나오는 다수의 센서데이터를 주성분분석이나 요인분석을 하여 차원을 축소한 후에 시계열로 분포나 추세의 변화를 분석하면 기계의 고장(fatal failure) 징후를 사전에 파악하는데 활용하기도 합니다.

 

위의 몇 개 사용예처럼 다른 분석의 입력변수로 주성분분석(주성분점수)나 요인분석(요인점수)를 통해 데이터를 전처리/변환하기도 하며, 아니면 주성분분석이나 요인분석을 바로 그 자체로 바로 활용하기도 합니다. 

 

 

 주성분분석(Principal Component Analysis, PCA) R script

 

주성분분석에서는

 - 상관행렬과 공분산행렬 중 어느 것을 선택할 것인가?

 - 주성분의 개수를 몇 개로 할 것인가?

 - 주성분에 영향을 미치는 변수로 어떤 변수를 선택할 것인가?

에 대해서 결정을 해야 하는데요,

 

한국신용평가정보에서 나온 '국내 증권회사의 주요 재무제표' (2007.3.31 기준)를 가지고 주성분분석을 R로 해보도록 하겠습니다. (다음번 포스팅에서는 똑같은 데이터에 대해 요인분석을 해보겠습니다)

 

이 데이터는 18개 증권사별로 V1.총자본순이익율, V2.자기자본순이익율, V3.자기자본비율, V4.부채비율, V5.자기자본회전율 재무지표 변수로 구성되어 있습니다.

 

예제 데이터('국내 증권회사의 주요 재무제표' (2007.3.31 기준)) 다운로드 ☞

secu_com_finance_2007.csv

 

R로 외부 csv 데이터 불러오기

 

> ##----------------------------------------------------------------------
> ## 차원축소(dimension reduction) : (1) PCA(Principal Component Analysis)
> ##----------------------------------------------------------------------
> 
> # csv 파일 불러오기 (file importing)
> secu_com_finance_2007 <- read.csv("C:/Users/user/Documents/R/secu_com_finance_2007.csv",
+                                   header = TRUE, 
+                                   stringsAsFactors = FALSE)
> # V1 : 총자본순이익율
> # V2 : 자기자본순이익율
> # V3 : 자기자본비율
> # V4 : 부채비율
> # V5 : 자기자본회전율

 

 

주성분분석에서는 변수별로 단위가 다른 raw data를 사용하지 않고 평균과 표준편차를 가지고 표준화(standadization)한 데이터를 사용합니다. 그래야 scale이 다른 문제로 인한 데이터 왜곡을 피할 수 있기 때문입니다.

 

> # 표준화 변환 (standardization) > secu_com_finance_2007 <- transform(secu_com_finance_2007, + V1_s = scale(V1), + V2_s = scale(V2), + V3_s = scale(V3), + V4_s = scale(V4), + V5_s = scale(V5))

 

 

V1.총자본순이익율, V2.자기자본순이익율, V3.자기자본비율, V5.자기자본회전율의 네 개의 변수는 숫자가 클 수록 좋다는 뜻이지만 V4.부채비율는 높을 수록 안 좋다고 해석하게 됩니다.  즉 V1, V2, V3, V5와 V4는 반대방향으로 움직이게 되는데요, 서로 같은 방향으로 움직이게 해서 상관도가 높게 나와 같은 주성분에 반영되도록 하기 위해서 아래와 같이 V4.부채비율의 방향을 변환(표준화된 이후의 max 값에서 표준화된 이후의 관찰값을 뺌)하겠습니다. (부채비율 방향 변환 후에는 숫자가 높을 수록 좋은 회사라고 해석할 수 있습니다)  그리고 주성분분석에 필요한 변수(V4_s가 아니라 V4_s2 가져온거 유의)만 indexing해서 선별하였습니다.

 

> # 부채비율(V4_s)을 방향(max(V4_s)-V4_s) 변환
> secu_com_finance_2007 <- transform(secu_com_finance_2007, 
+                                    V4_s2 = max(V4_s) - V4_s)
> 
> # variable selection
> secu_com_finance_2007_2 <- secu_com_finance_2007[,c("company", "V1_s", "V2_s", "V3_s", "V4_s2", "V5_s")]

 

 

먼저, 변수들간의 상관계수를 분석해보겠습니다.  주성분분석이 변수들 간의 상관관계가 높다는 것을 가정하고 있기 때문에 한번 확인해보도록 하겠습니다.  

 

V1_s.총자본순이익률과 V2_s.자기자본순이익율이 상관관계가 높고(상관계수 0.615), V3_s.자기자본비율과 V4_s2.(방향변환 후의)부채비율이 상관관계가 매우 높게(상관계수 0.936) 나왔습니다.  V5_s.자기자본회전율은 V2_s.자기자본순이익율과 상관관계가 있고, V3_s.자기자본비율과 V4_s2.(방향전환후의 부채비율)과는 역의 상관관계가 나왔네요.

 

> # Correlation analysis
> cor(secu_com_finance_2007_2[,-1])
            V1_s       V2_s       V3_s      V4_s2        V5_s
V1_s  1.00000000  0.6165153  0.3239780  0.3553930  0.01387883
V2_s  0.61651527  1.0000000 -0.5124351 -0.4659444  0.42263462
V3_s  0.32397800 -0.5124351  1.0000000  0.9366296 -0.56340782
V4_s2 0.35539305 -0.4659444  0.9366296  1.0000000 -0.53954570
V5_s  0.01387883  0.4226346 -0.5634078 -0.5395457  1.00000000 
> 
> round(cor(secu_com_finance_2007_2[,-1]), digits=3) # 반올림

 

 

변수들간의 산점도 행렬도 살펴보도록 하죠.

 

> # Scatter plot matrix
> plot(secu_com_finance_2007_2[,-1])

 

 

 

 

이제 prcomp() 함수를 사용해서 주성분분석을 실시합니다.  아래 결과에 보면 누적기여율(Cummulative Proportion)에 제1주성분(PC1)이 55.23%, 제 2주성분(PC1 & PC2)까지의 누적기여율dl 87.34%로 매우 높게 나왔습니다.

 

> # 주성분분석 PCA(Principal Component Analysis) > secu_prcomp <- prcomp(secu_com_finance_2007_2[,c(2:6)]) # 첫번째 변수 회사명은 빼고 분석 > > summary(secu_prcomp) Importance of components: PC1 PC2 PC3 PC4 PC5 Standard deviation 1.6618 1.2671 0.7420 0.25311 0.13512 Proportion of Variance 0.5523 0.3211 0.1101 0.01281 0.00365 Cumulative Proportion 0.5523 0.8734 0.9835 0.99635 1.00000

 

 

아래에 주성분분석 결과를 출력해보았습니다. 제1요인이 표준편차가 1.66으로 가장 크고, 제2요인이 1.26으로 그 다음으로 큰 식으로 순서가 있습니다.

 

그리고 Rotation 후의 고유벡터(eigenvector)의 계수를 보면 제1요인(PC1)은 자기자본비율(V3_s)와 부채비율(V4_s2)와 관련이 있고, 제 2요인(PC2)은 총자본순이익율(V1_s)과 자기자본순이익율(V2_s)와 관련이 있으며, 제 3요인(PC3)은 자기자본회전율(V5_s)와 관련이 있음을 알 수 있습니다.

 

> print(secu_prcomp)
Standard deviations:
[1] 1.6617648 1.2671437 0.7419994 0.2531070 0.1351235

Rotation:
              PC1         PC2           PC3          PC4         PC5
V1_s   0.07608427 -0.77966993  0.0008915975 -0.140755404  0.60540325
V2_s  -0.39463007 -0.56541218 -0.2953216494  0.117644166 -0.65078503
V3_s   0.56970191 -0.16228156  0.2412221065 -0.637721889 -0.42921686
V4_s2  0.55982770 -0.19654293  0.2565972887  0.748094314 -0.14992183
V5_s  -0.44778451 -0.08636803  0.8881182665 -0.003668418 -0.05711464 
 

 

 

 

이처럼 변수와 주성분간 관계를 고려해서 주성분에 이름을 명명(naming)해보자면 PC1은 안정성, PC2는 수익성, PC3는 활동성이라고 할 수 있겠네요. (재무제표 배울 때 배우는 대표적인 재무평가 지표)

 

 

 

 

 

선형대수를 안배우면 용어, 이론 개념이 어려울 수 있는데요, 참고로 고유값(eigenvalue)와 고유벡터(eigenvector)에 대한 정의를 아래에 소개합니다.

 

[참고: 고유값(eigenvalue), 고유벡터(eigenvector) 용어설명]

 

 

 

주성분의 개수를 정할 때 누적기여율을 가지고 하기도 하고, 또는 고유값(eigenvalue)을 가지고 아래 처럼 Scree plot 그래프를 그려서 고유값 곡선이 꺽이는 지점의 바로 앞의 주성분 개수를 선택하기도 합니다.  아래 그래프로 보면 주성분 4개째에서 수평으로 드러누웠으므로 한개를 뺀 (4-1 = 3) 3개 주성분이 적합해 보입니다.

 

> # Scree Plot
> plot(prcomp(secu_com_finance_2007_2[,c(2:6)]), type="l",
+      sub = "Scree Plot")

 

 

 

 

주성분1점수(principal component 1 score)과 주성분2점수(principal component 2 score)를 가지고 Biplot을 그려보겠습니다.  

가로축 PC1(안정성)을 기준으로 보면 오른쪽에 V3_s, V4_s2 화살표가 향하는 쪽에 있는 부국증권, 한양증권, 유화증권사는 안정성이 높은 회사군이라고 해석을 할 수 있게 됩니다.

(참고: PC1 = 0.076*V1_s - 0.394*V2_s + 0.569*V3_s + 0.559*V4_s2 - 0.447*V5_s )

 

세로축 PC2(수익성)을 기준으로 보면 아래쪽에 있는 대우증권, 미래애셋증권사 등이 수익성이 좋은 축에 속합니다. (아래 식 부호가 (-) 라서 숫자 낮은 것이 수익성 좋다는 뜻)

(참고: PC2 = -0.779*V1_s - 0.565*V2_s - 0.162*V3_s - 0.196*V4_s2 - 0.086*V5_s )

 

> # Biplot
> biplot(prcomp(secu_com_finance_2007_2[,c(2:6)]), cex = c(0.7, 0.8))
> 
> # 관측치별 주성분1, 주성분2 점수 계산(PC1 score, PC2 score)
> secu_pc1 <- predict(secu_prcomp)[,1]
> secu_pc2 <- predict(secu_prcomp)[,2]
> 
> 
> # 관측치별 이름 매핑(rownames mapping)
> text(secu_pc1, secu_pc2, labels = secu_com_finance_2007_2$company, 
+      cex = 0.7, pos = 3, col = "blue")
 

 

 

 

 

이렇게 변환한 주성분점수를 가지고 다른 통계모형이나 데이터마이닝 모형 개발 시 input으로 활용해도 되겠습니다.  

 

 

 

참고로, 변수에 대한 설명력의 누적기여율(cummulative proportion)이 80%가 되는 주성분의 개수 k개를 찾아서, 주성분 1번부터 주성분 k번째까지의 주성분점수를 반환하는 사용자 정의함수는 아래와 같습니다. 

(Dr.Kevin 님의 댓글 덕분에 오류 잡아서 프로그램 수정하였습니다. Dr.Kevin님 감사합니다)

 

> ###########################################################
> ## PCA (Principal Component Analysis)
> ## User Defined Function
> ##  - finding PC k which Cummulative Proportion is over 0.8
> ###########################################################
> 
> pca <- function(dataset){
+   pc = prcomp(dataset, scale = TRUE)
+   
+   k = 0
+   R = 0
+ 
+   while(R < 0.8) {
+     k = k + 1
+     R = sum(pc[[1]][1:k]^2)/sum(pc[[1]]^2)
+ 
+     cat("When number of Principal Component(k) is ", k, 
+         ", Cummulative Proportion(R) is ", R, "\n", "\n", sep="")
+   }
+   
+   SelectedDataSet = pc[[5]][,1:k]
+   return(SelectedDataSet)
+ }
> 
> pca(secu_com_finance_2007_2[,c(2:6)])
When number of Principal Component(k) is 1, Cummulative Proportion(R) is 0.5522924

When number of Principal Component(k) is 2, Cummulative Proportion(R) is 0.8734231

             PC1        PC2
 [1,] -1.4870243  0.6066594
 [2,] -0.2063797 -0.0804627
 [3,]  0.1968538  0.9704605
 [4,] -2.3542884 -3.5056480
 [5,] -0.8953707  1.4552899
 [6,] -0.3682082 -0.5976313
 [7,] -0.9354306 -1.4144519
 [8,]  2.4129728 -0.6785064
 [9,]  2.6991862 -0.7596591
[10,] -0.4050098  0.2800099
[11,]  1.3958199  1.1353513
[12,] -1.5381192  1.1576616
[13,]  0.3217681 -0.2378023
[14,] -2.0306806  0.9646122
[15,]  3.0389460  0.8841645
[16,]  2.0064063 -1.2831337
[17,] -0.4211779 -0.2987099
[18,] -1.4302634  1.4017959

 

 

 

다음 포스팅에서는 요인분석(factor analysis)에 대해서 알아보겠습니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

 

 

 

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by R Friend R_Friend

데이터 변환 방법으로서

 

(1) 표준화 (Standardizatio)

(2) 정규분포화

(3) 범주화

   - 이산형화

   - 이항변수화

(4) 개수 축소

(5) 차원 축소

   - 주성분분석

   - 요인분석 

(6) 시그널 데이터 압축

 

중에서 (1) 표준화(Standardization)에 대해서 알아보겠습니다. 

 

 

다양한 소스로 부터 데이터를 R로 불러와서, 결합하고, 결측값과 특이값을 확인 후 처리하고, 필요한 부분의 데이터만 선별적으로 선택 혹은 제거한 후에 분석의 목적과 필요에 따라서, 그리고 데이터의 형태에 따라서 다양한 데이터 변환 (data transformation) 작업을 수행합니다. 

 

고급 분석가와 그렇지 않는 분석가가 나뉘는 부분, 데이터 엔지니어와 데이터 분석가가 나뉘어 지는 부분이 여기서 부터 이지 않을까 싶습니다.  업에 대한 지시과 더불어 분석의 목적과 분석의 기법에 대해서 정확히 알아야 하고, 데이터의 형태가 그에 맞는지, 맞지 않다면 어떻게 변환을 해야 하는지 알아야 하기 때문입니다.  그리고 데이터 변환을 하는데 있어 통계적인 기본 지식이 필요하다보니 여기부터는 프로그래밍을 잘하지만 통계를 잘 모르는 데이터 엔지니어의 경우 어려움을 겪기 시작합니다.

 

이 변환 작업에는 많은 시간과 노력이 필요합니다.  그래서 데이터 분석을 업으로 삼으려고 생각했던 사람이라도 소위 데이터 전처리, 데이터 변환의 지난한 과정에 대해서 재미를 느끼지 못하면 오래 견디지 못하고 다른 커리어로 전향을 하기도 합니다.  그만큼 본격적인 통계/데이터마이닝 과정에 진입하기 위한 전초 단계로 중요하지만 쉽지 많은 않은 과정이라는 얘기입니다. 

 

모델링을 하는데 있어 분석 목적에 유의미하고 적합한 파생변수를 개발하고 input으로 넣는 것이 정말 중요합니다.  개념적 정의, 조작적 정의를 통해 파생변수를 개발하는 과정에 필수로 필요한 이론적 지식이 이번부터 해서 총 6번에 나누어서 진행할 데이터 변환이 되겠습니다. 

 

데이터 변환을 (1) 표준화, (2) 정규분포화, (3) 범주화, (4) 개수 축소(샘플링), (5) 차원 축소, (6) 시그널 데이터 압축 등의 6개 카테고리로 구분하였습니다.  대략적으로 봤을 때 (1) 표준화, (2) 정규분포화, (3) 범주화는 데이터 분포나 속성을 변화시키는 기법이고, (4) 개수 축소(샘플링), (5) 차원 축소, (6) 시그널 데이터 압축은 데이터 크기를 축소하는 기법이 되겠습니다.

 

이번 포스팅에서는 (1) 표준화의 (1-1) z 변환, (1-2) [0-1] 변환에 대해서 알아보겠습니다.  

 

 

데이터 변환 (1) 표준화 

 

 

[ 데이터 변환 구성 ]

 

 

 

 

(1-1) 표준정규분포 z 변환

 

우선 정규분포에 대해서 간략히 짚고 z 변환으로 넘어가겠습니다. 일상 생활 속에서 우리는 다양한 정규분포를 접하고 삽니다.  만약 100명의 수강생을 대상으로 통계와 R 분석 교육을 받고 시험을 치면 아마도 평균을 중심으로 종모양으로 좌우 분포가 비슷한 성적 분포를 띨 것입니다.  수강생 100명의 키와 몸무게를 조사를 해서 히스토그램을 그려보면 이 또한 평균을 중심으로 종모양으로 좌우 대칭인 정규분포를 띨 것입니다.  수강생 얼굴을 아직 본적도 없는데 이렇게 예언을 할 수 있다는거, 이게 참 신기한겁니다. ^^  만약 키의 평균과 표준편차를 저한테 알려주고, 수강생 100명 중에서 한 명의 수강생을 뽑아서 키를 재서 저에게 알려주면 그 수강생이 전체 100명 중에서 상위 몇 % 키에 속할지도 추측할 수 가 있습니다. 놀랍지요?

 

통계학에서는 '중심극한정리(central limit theorem)'이 정말 중요한 역할을 하는데요, 모집단에서 표본을 추출할 때 표본의 크기가 커질 수록 표본 X는 정규분포로 근사한다는 정리입니다.  이 중심극한정리에 근거해서 보통 샘플이 대략 30개 이상이면 정규분포로 근사한다고 가정하고 정규분포 가정에 근거한 다양한 통계분석 기법(추정과 검정 등...)을 적용할 수 있게 됩니다. 

 

이때 두 개 이상의 모집단으로 부터 추출한 샘플 X, Y...가 다수이고, 각 집단의 평균과 표준편차가 다르거나, 혹은 측정 scale 이 다른 경우에는 다수의 집단 간, 변수 간 직접적인 비교가 불가능하게 됩니다.   미국 달러, 유럽의 유로화, 중국의 위안화, 일본의 엔화, 그리고 한국의 원화를 각 각 1000 단위를 가지고 있다고 했을 때, 이게 서로간에 대비해서 얼마나 많은 건지, 값어치가 있는건지 직접 비교하는게 불가능한 것과 같은 이치입니다.  이때 특정 나라의 통화를 기준으로 삼고 다른 나라의 통화를 기준으로 변환을 하면 각 나라별 통화간의 돈의 가치를 비교할 수 있게 됩니다.  이게 표준화의 원리입니다.

 

위에서 정규분포의 중요성에 대해서 설명했는데요, 정규분포 중에서도 평균이 0, 표준편차가 1인 정규분포를 표준정규분포(standadized normal distribution) 이라고 합니다.  평균이 표준편차가 서로 다른 다수의 집합을 표준정규분포로 표준화를 하면 서로 비교를 할 수 있게 됩니다. 

 

그러면, 이제 R로 표준정규화 하는 방법에 대해서 알아보겠습니다.

 

  • 한국 성인 남성 1,000 명의 키가 평균 170cm, 표준편차 10cm의 정규분포
  • 남아프리카 부시맨 성인 남성 1,000명의 키가 평균 150cm, 표준편차 8cm의 정규분포

를 따른 다고 했을 때 두 집단의 키를 평균이 0, 표준편차가 1인 표준정규분포로 표준화를 해보도록 하겠습니다.

 

 

 먼저, 데이터 생성은 아래와 같이 랜덤하게 생성하였습니다.

 

> ## 한국인, 부시맨 각 성인 1000명 키 데이터 생성 > height_korean <- rnorm(n=1000, mean = 170, sd = 10) > height_bushman <- rnorm(n=1000, mean = 150, sd = 8) > > height <- data.frame(height_korean, height_bushman) # 데이터 프레임 생성

> rm(height_korean, height_bushman) # 벡터 삭제

> > head(height) # 상위 6개 데이터 확인 height_korean height_bushman 1 162.7654 132.5271 2 180.5701 135.5497 3 172.6752 142.5168 4 171.8035 156.7872 5 186.5258 154.3027 6 171.4634 156.1118 

 

> ## 한국인, 부시맨 키 히스토그램

> attach(height)
> par( mfrow = c(1,2))
> hist(height_korean, freq = TRUE, main = "한국인 키 빈도 히스토그램")
> hist(height_korean, freq = FALSE, main = "한국인 키 확률밀도함수 그래프")
> 

 

 

> hist(height_bushman, freq = TRUE, main = "부시맨 키 빈도 히스토그램")
> hist(height_bushman, freq = FALSE, main = "부시맨 키 확률밀도함수 그래프")

 

 

> detach(height)

 

 

그리고 표준정규화를 해보겠는데요, (a) scale()함수를 쓰는 방법과 (b) (x-mean(x))/sd(x) 처럼 공식을 직접 입력하는 방법이 있습니다.  결과는 동일합니다.

 

> ## a. scale() 함수
> 
> height <- transform(height, 
+                     z.height_korean = scale(height_korean), 
+                     z.height_bushman = scale(height_bushman)
+                     )
> 
> head(height)
  height_korean height_bushman z.height_korean z.height_bushman
1        179.19         140.60         0.89308         -1.18393
2        164.54         152.70        -0.60892          0.35689
3        184.18         136.76         1.40477         -1.67426
4        196.37         144.26         2.65531         -0.71833
5        162.61         155.72        -0.80706          0.74198
6        158.02         147.19        -1.27775         -0.34510

 

> ## b. z=(x-mean(x))/sd(x)
> height <- transform(height, 
+                     z2.height_korean = (height_korean - mean(height_korean))/sd(height_korean), 
+                     z2.height_bushman = (height_bushman - mean(height_bushman))/sd(height_bushman)
+                     )
> 
> head(height)
  height_korean height_bushman z.height_korean z.height_bushman z2.height_korean z2.height_bushman
1        179.19         140.60         0.89308         -1.18393          0.89308          -1.18393
2        164.54         152.70        -0.60892          0.35689         -0.60892           0.35689
3        184.18         136.76         1.40477         -1.67426          1.40477          -1.67426
4        196.37         144.26         2.65531         -0.71833          2.65531          -0.71833
5        162.61         155.72        -0.80706          0.74198         -0.80706           0.74198
6        158.02         147.19        -1.27775         -0.34510         -1.27775          -0.34510 

 

 

아래 히스토그램은 한국인과 부시맨의 성인 남자 키를 z 표준화 한 값에 대한 히스토그램이 되겠습니다.  둘다 평균이 0, 표준편차가 1인 표준정규분포로 표준화 되었음을 확인할 수 있습니다.

 

> hist(height$z.height_korean, freq=TRUE, main="standized freq. of Korean H")
> hist(height$z.height_bushman, freq=TRUE, main="standized  freq. of Bushman H ")

 

 

 

 

 

(1-2) [0-1] 변환

 

연속형 변수의 값을 '0~1' 사이의 값으로 변환하는 [0-1]변환도 z변환과 함께 많이 쓰이는 표준화 기법입니다.  만약 변수들 간의 scale 이 다른 상태에서 인공신경망 분석을 하려면 [0-1]변환으로 단위를 표준화해준 후에 분석을 시행해야 합니다.  Scale이 다른 두 변수를 [0-1] 변환하게 되면 상호간에 비교가 가능해집니다.

 

[0-1] 변환은  (x-min(x) /(max(x)-min(x)) 의 수식으로 계산하면 됩니다.

 

위의 한국 성인 남성과 부시맨 성인 남성 각 1,000명의 키 데이터를 가지고 이번에는 [0-1] 표준화 변환을 해보도록 하겠습니다.  일단 위 데이터셋 height에서 첫번째와 두번째 변수만 선택하고, 변수명이 너무 길므로 짧게 변수이름을 변경해보겠습니다.

 

> ## [0-1] transformation
> height <- height[,c(1:2)]
> library(reshape)
> height <- rename(height, c(height_korean = "h_kor", height_bushman = "h_bush"))
> head(height)
   h_kor h_bush
1 179.19 140.60
2 164.54 152.70
3 184.18 136.76
4 196.37 144.26
5 162.61 155.72
6 158.02 147.19

 

 

그 다음 [0-1] 변환을 하고 히스토그램을 그려보겠습니다.

 

> height <- transform(height, 
+                     h_kor_01 = (h_kor - min(h_kor))/(max(h_kor) - min(h_kor)), 
+                     h_bush_01 = (h_bush - min(h_bush))/(max(h_bush) - min(h_bush))
+                     )
> 
> head(height)
   h_kor h_bush h_kor_01 h_bush_01
1 179.19 140.60  0.64341   0.27053
2 164.54 152.70  0.41760   0.51072
3 184.18 136.76  0.72034   0.19410
4 196.37 144.26  0.90835   0.34311
5 162.61 155.72  0.38781   0.57074
6 158.02 147.19  0.31705   0.40129
> 
> hist(height$h_kor_01)
> hist(height$h_bush_01)
 
 

 

 

 

한국 성인 남성 키와 부시맨 성인 남성 키가 0~1 사이의 값으로 표준화되었음을 알 수 있습니다.

 

이해가 쉽도록 166cm의 한국 남성과 156cm의 부시맨 남성의 키를 가지고 [0-1] 변환 했을 때의 예시를 개념도로 아래에 작성하였습니다.  참고하시기 바랍니다.

 

 

[0-1] 변환 예시 (한국 남성 166cm, 부시맨 남성 156cm) 

 

 

 

많은 도움 되었기를 바랍니다. 

 

다음번 포스팅에서는 정상화 변환에 대해서 알아보도록 하겠습니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

 

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by R Friend R_Friend


티스토리 툴바