머신러닝 10. 비지도학습: 주성분분석(PCA)
Written on October 22nd , 2019 by MJ 목차
1. 데이터셋 로딩
(1) 데이터셋 로딩
(2) 데이터셋 간단조회: head() / str() / tibble::glimpse()
2. 기술통계분석
(1) 기술통계: summary() / skimr::skim()
3. 각 변수 간 기본적 관련성 파악
(1) 공분산분석: cov() / cov2cor()
(2) 상관관계분석: cor() / Hmisc::rcorr()
(3) 변수 간 상관관계 그래프: plot() / PerformanceAnalytics::chart.Correlation() / psych::pairs.panels()
(4) 변수 간 상관성 파악: corrplot::corrplot() / gplots::heatmap() / d3heatmap::d3heatmap()
4. 데이터 전처리
(1) 성분으로 결합될 가능성 높은 변수컬럼 기준으로 컬럼 순서 재구성
5. 주성분분석: psych::principal()
(1) 적정한 주성분 / 요인 개수 산정: fa.parallel() / fa = “pc” / fa = “fa” / fa = “both”
(2) 주성분분석1 & 무회전 방식 성분추출: psych::principal(rotate=”none”) / str() / $loadings / $weights / $scores
(3) 주성분분석2 & 직교회전 방식 성분추출: psych::principal(rotate=”varimax”)
(4) 주성분분석3 & 사각회전 방식 성분추출: psych::principal(rotate=”promax”)
(5) 주성분분석 후 각 변수와 성분점수와의 상관성 재확인
(6) 주성분 개수 정하기: 누적기여율 / 고유값(eigenvalue) / Scree plot
6. 기타 주성분분석 함수: stats::prcomp() / stats::princomp() 이용 외 이하 동일
7. 기타 주성분분석 함수: FactoMineR::PCA() / summary() / $eig / barplot()
8. 기타 주성분분석 함수: factoextra::fviz_screeplot() / plot.PCA() / fviz_pca_ind() / plot() / fviz_pca_var()
019
-
요인분석과 주성분으로 컬럼을 묶어주기 위해서는 주로 공분산과 상관성의 개념을 이용해 분석.
-
공분산은 방향은 알 수 있으나 크기의 비교가 힘들어서(제곱으로 인해 숫자가 커서) 표준화한 것이 상관계수의 개념.
-
변수마다 평균을 구한 후 각 데이터가 어느 정도의 폭을 가지고 움직이는지를 알기 위해서는 편차 구하고 분산을 구한다. 그리고 표준편차를 구한다. 일반적으로는 편차가 크면 분산이 크다고 이야기한다. 그러면 전반적으로 데이터의 변동폭을 알 수 있다.
-
다중공선성이 존재할 경우 해결 방법 중의 하나가 바로 상관도가 높은 변수들을 하나의 주성분 혹은 요인으로 축소하여 모형개발에 활용하는 것입니다.
각 변수간 기본적 관련성 파악
(1) 공분산 분석(corvariance analysis)
-
두 변수 간에 상호 관련성을 파악하는 기법
-
하나의 변수가 양/음으로 변화될 때 다른 변수도 같은 방향으로 변하는지, 다른방향으로 변하는지 경향성을 파악함
-
그러나 두 변수간의 상호관련성의 크기를 절대적으로 판단할 수 있는 기준은 아님
-
이를 표준화해서 만든 것이 상관계수임
● 상관계수는 제곱 등으로 덩치 커져버린 공분산을 표준편차로 나눠서 표준화시킨 것.
(2). 상관관계 분석(correlation analysis)
-
두 변수 간에 상호 관련성(선형성)을 파악하는 기법
-
관련성의 크기를 상관계수(correlation coefficient)로 나타냄
-
선형성이 있다면 방향성은 정·양(+)인지, 부·음(-)인지, 그 관계는 얼마나 큰지를 나타내는 판단기준
-
상관계수값은 -1 ~ +1 사이로 표준화 되어 있음 0: 상관관계가 없음, ±1은 상관관계가 매우 강함
-
어떤 변수가 원인이고, 결과인지 알 수 없음
-
두 변수가 등간/비율/양적 척도이면, pearson 상관관계
-
서열/등간 척도이면, spearman/kendall 서열상관관계
(3) 축소분석 대상인 여러개 변수들간의 관계를 공분산행렬과 상관계수 행렬중 어떤 것을 사용할 것인가?
주성분 분석의 경우 변수들간의 선형결합을 유도할 때
-
분산을 이용하기 때문에 공분산 행렬로부터 유도된 주성분은 각 변수들의 측정단위에 영향을 많이 받음
-
설문조사처럼 모든 변수들이 같은 수준으로 측정된 데이터는 공분산 행렬을 사용해도 무방함
-
변수들의 scale이 서로 많이 다른 경우에는 측정단위가 큰 특정 변수의 영향으로 도출된 주성분에 오류가 있을 가능성이 크므로 상관계수 행렬을 사용해 추출함
—————코딩——————————————————————————————————
문제시나리오: 온라인 쇼핑몰 쿠폰이벤트 사용자만족도 조사분석
- 쿠폰을 통한 프로모션 진행후 이용고객들에게 사용자만족도를 조사함
- 이용자들이 쿠폰프로모션에 대해서 생각하는 다양한 평가기준(관리포인트)를 대표하는 요소는 무엇인지?
- 이 요소들 중에서 상대적으로 중요한 것은 무엇인가?
사용자만족도 조사변수
- quality: 쿠폰을 통해 판매하는 제품은 품질이 높다.
- refund: 쿠폰을 통해 구매한 제품은 쉽게 환불이 가능하다.
- value: 쿠폰을 통해 판매하는 제품은 대체로 값어치가 있다.
- simple: 쿠폰을 통해 구매하면 매우 간편하다.
- equal: 쿠폰을 통해 구매해 배달되는 제품은 광고제품과 동일하다.
- time: 쿠폰을 통해 구매하면 시간을 절약할 수 있다.
- lost: 쿠폰을 통해 구매하면 분실염려가 없다.
- brand: 쿠폰을 통해 판매하는 제품은 대부분 유명브랜드 제품이다.
- delivery: 쿠폰을 통해 구매한 제품은 원하는 장소에 배달된다.
1. 데이터셋 로딩
(1) 데이터셋 로딩
(2) 데이터셋 간단조회: head() / str() / tibble::glimpse()
2. 기술통계분석
(1) 기술통계: summary() / skimr::skim()
3. 각 변수 간 기본적 관련성 파악
(1) 공분산분석: cov() / cov2cor()
● 원래는 cov() 함수 안에 두 개 데이터 있어야 하나 얘는 벡터연산 가능.
● use = “complete.obs” 옵션은 완벽한 데이터만 써달라는 설정, 즉 NA가 하나라도 들어있다면 빼라는 설정.
● pearson 방식은 양적데이터일 때를 감안한 방법.
● 환불 가능성은 -가 나왔고, 품질변수와 값어치, 브랜드 변수는 대체로 숫자가 + 방향이고, 1이 넘는다.
(2) 상관관계분석: cor() / Hmisc::rcorr()
● 대각선 방향은 1.0인데 완벽히 방향성 일치에 똑같이 움직인다는 뜻으로 얘네는 자기 변수.
● 0.6 ~ 0.7은 매우 강한 상관관계
● 0.4 ~ 0.5는 보통의 상관관계
● 0.3 이상이면 두 변수가 관련성 있게 움직이는 패턴이 있다고 볼 수 있다.
● 퀄리티에서 0.4보다 큰 상관계수가 있는 변수는 품질과 브랜드 정도.
● 나머지는 상관관계가 미미하고, 배달 정도만 관계가 약간 있는 정도. 그러나 배달은 심플과는 큰 관련성이 있어 나중에 요인 분석 시 심플과 결합될 가능성이 있다.
● 심플은 타임과 관련성이 좀 있고 나머지와 거의 관련성이 없다. 걱정하는 측면의 변수들(로스트,..)과는 별로 관련없다.
● 상관성을 보면 잠재변수의 구조가 보인다.
● 만약 이 상관관계가 우리의 생각과 다르게 묶였다면, 질문 자체가 소비자들이 분석가의 의도를 오해하도록 설정되었다거나, 의사 소통이 잘 안됐을 가능성 있는 것.
● refund 변수를 보면, equal과 lost와 묶인다.
● rcorr: 상관관계 확인하는 변수
● p-value: 이 데이터의 결과는 불과 80명에 대한 결과다, 즉 표본이다. 그래서 이 내용이 앞으로도 이런 패턴으로 유지될건지, 표본 크기 변하거나 표본 변하면 결과가 어떻게 될지 모른다. 모집단 대상으로 같은 조사를 했을 때도 동일한 결과가 나올지 판단하기 위한 기준이 p-value. (probability value)
● 주어진 데이터를 가지고 특성을 비교하는 걸 기술통계라고 하는데, 변수간의 관계인 상관성을 보는 것, 그리고 이 패턴이 모집단이나 실제 시장을 대상으로 진행했을 때도 유사하게 나올지 분속하는 걸 추론통계라고 부른다.
● p-value 값이 0.05 보다 낮으면 모집단 대상으로 했을 때도 같은 결과 나올 거라고 예상해도 무방. (허용가능치가 0.05) 즉 오류 가능성이 적다.
● 아마 대체로 상관성 0.4 이상 나오는 변수들이 p-value(유의확률) 값이 0.05 허들보다 작게 나올 것.
(3) 변수 간 상관관계 그래프: plot() / PerformanceAnalytics::chart.Correlation() / psych::pairs.panels()
- 어떤 변수들간에 데이터변화량이 상관성이 있는지 윤곽을 보고 결합될 수 있는 성분/요인을 미리 파악함
● 별표 개수에 따라 관계의 강약이 드러나는데 요인분석 하면 퀄리티와 이퀄은 묶이지 않을 것. 우선순위에서 밀려서.
(4) 변수 간 상관성 파악: corrplot::corrplot() / gplots::heatmap() / d3heatmap::d3heatmap()
4. 데이터 전처리
(1) 성분으로 결합될 가능성 높은 변수컬럼 기준으로 컬럼 순서 재구성
5. 주성분분석: psych::principal() / stats::prcomp()
(1) 적정한 주성분 / 요인 개수 산정: fa.parallel() / fa = “pc” / fa = “fa” / fa = “both”
● n.obs: number of observations. 관찰한 표본 크기
● fa 옵션 : factor analysis.pc: 주성분분석. principle component ( 아래에 나올 fc는 상관있는 것만 가지고 작성하는 요인분석. )
(2) 주성분분석1 & 무회전 방식 성분추출: psych::principal(rotate=”none”) / str() / $loadings / $weights / $scores
● nfactors = 4: 요인을 4개 정도로 묶어본다는 의미. 대표 변수를 4개로 축약하겠다는 설정.
● rotate = “none” : 요인들을 만들 때 전혀 관련 없게 만드는 방법이 있고, 어느 정도 상관성 허용하면서 만드는 방법이 있는데, 이건 무회전 방식으로 요인 간에 90도 각 지게 해서 만드는 방법. 나중에 다시 설명. 개별 변수들간의 선형성을 결합해서 성분을 구성하라는 설정.
● 결과 표에서는 개별 변수 별로 새로운 성분 만들 때 어느정도 가져다 썼는지 ㅅ수 있다. brand 변수에서는 0.79 정도 갖다 썼다는 의미. PC1을 구성하는 데이터의 적재량은 brand, value,….,등등에서 다음과 같이 가져온 것을 알 수 있음. 위에서 많이 가져왔고, time 부터는 절반 이하를 가져와 썼다는 것을 알 수 있다.
● PC2를 보면, PC1을 쓰고 난 나머지 변동성을 가지고 만들었는데, PC1 과 반대되었다. 분산의 양과 움직임이 공분산을 이용해 계산해보니 다르게 움직이고 있다는 것을 알 수 있다. PC2는 equal, lost, refund에서 주로 가져왔다.
● PC3는 가운데에서 많이 가져옴.
● PC4는 전반적으로 적재한 데이터가 산재되어 있다. 아까 스크리더 표에서도 간당간당했고, 상대적으로 대표성이 덜하다.
● h2, u2 이용해서 알 수 있는 것은 brand의 86%정도만 가져와서 사용했고 14% 버려졌다는 것, 손실된 데이터가 조금 있다는 것을 의미.
● 상대적으로 아래쪽은 h2가 80%가 안 된다. 대표 패턴이 75%정도나 그 이하. 그 정도만 활용되고 있다는 의미.
● com은 작으면 작을 수록 좋은 것. 이건 복잡도. 이게 작으면 어느 한쪽에서 비중있게 많이 쓰이고 있다는 의미. 성분을 구성할 때 영향을 많이 끼칠수록 복잡도가 높다.
● delivery 보면 복잡도가 높다. 얘는 데이터 패턴이 어느 한쪽으로 명확하게 나오지 않고 여러 성분 구성할 때 같이 나온다. PC1 에서 0.61, PC3에서 0.47.
● SSloadings은 성분을 구성하는 고유한 분산의 양이라고 보면 된다.
● 이게 1.0이상이 되어야 대표성을 가지고 있는 변수로서 볼 수 있다.
● PC4은 0.79이기 때문에 대표성이라고 보긴 힘들다.
● Proportion Var : 비율면에서 볼 때 이정도의 중요도 차이가 있다는 것. 32%, 22% 이렇게. PC4는 9%라 상대적으로 취약.
● Cumulative Var: 누적 분산량. 오른쪽으로 쭉쭉 가면 81% 정도로 떨어진다. 전체 아홉개 변수를 1.0으로 치자면, 4개 변수로 축약했을 때 데이터 양이 19%정도 손실된 것으로 판단할 수 있다.
● Proportion Explained: 누적분산 설명력. PC1이 80명의 9개 변수 움직임을 40%정도 설명할 수 있는 대표성을 지녔다. PC2가 27%,…. 누적분산 설명력은 85%정도까지가 적당하다고 판단.
● 대표할 수 있는 변수는 3개 정도로 보는 게 적당할 듯. PC4는 너무 산재되어 있다. 이 표를 봤을 때는 3개가 적정.
● 주성분분석은 변수를 줄이려는 게 목적이므로 4개보다는 3개로 적은 게 좋다.
● 논문같은 거 쓸때는 $loadings 즉 제일 밑의 loadings, SS loadings 같은 거 꼭 적어줘야하는 중요한 거.
(3) 주성분분석2 & 직교회전 방식 성분추출: psych::principal(rotate=”varimax”)
● 90도 각도가 나오게 위치 잡아달라, 요인 간의 적재되는 데이터 양이 어정쩡하거나 더많이 벌어지는 타입 아니라, 대표하는 성분 간의 구성된 데이터의 변동량이 방향성이 90도로 만들어달라 는 옵션.
● 아까하고 주요한 내용은 비슷하다.
● 아까하고 요인별 적재된 양은 조금씩 다르다.
● com: complexity. 거의 1점대다. 아까는 3점대도 있었는데.
● value보면 RC1에 거의 90%.
● simple은 좀 어정쩡하네. RC3에 0.63, RC4에 0.64. 이럴 땐 가급적 숫자가 큰 쪽으로 보면 된다. 아무튼 그래서 복잡도도 상대적으로 높다.
● 다중공선성(?)을 피하려면 분산의 변동성이 많은 변수를 살리고 나머지를 없애는 것도 하나의 방법. 그러나 이런 방식보다는 주성분방식이나 요인분석 방식 이용해서 컬럼 묶는 방식 쓰면 데이터 손실이 덜하다.
(4) 주성분분석3 & 직교회전 방식 성분추출: psych::principal(rotate=”promax”)
● weighgts: 가중치. 어떤 변수에 어느 정도로 가져왔는지 확인.
● scores: 실무에서 중요한 내용. 이걸 가지고 군집분석, 회귀분석에 쓰면 된다.
(5) 주성분분석 후 각 변수와 성분점수와의 상관성 재확인
(6) 주성분 개수 정하기: 누적기여율 / 고유값(eigenvalue) / Scree plot
6. 기타 주성분분석 함수: stats::prcomp() / stats::princomp() 이용 외 이하 동일
7. 기타 주성분분석 함수: FactoMineR::PCA() / summary() / $eig / barplot()
8. 기타 주성분분석 함수: factoextra::fviz_screeplot() / plot.PCA() / fviz_pca_ind() / plot() / fviz_pca_var()
<참고 문헌="">참고>
- 최점기 박사님 강의
- 통계학개론 (영지출판사)
- https://rfriend.tistory.com/61