Data Analysis & ML/Python을 활용한 통계분석

[통계분석] 탐색적 요인분석(EFA)

YSY^ 2020. 12. 24. 19:56

탐색적 요인분석(Exploratory factor analysis)

탐색적 요인분석이란

  • 요인 분석 (FA)은 관찰 된 변수 집합에서 영향력있는 기본 요인 또는 잠재 변수를 검색하는 데 사용되는 탐색적 데이터 분석 방법이다.
  • 변수 수를 줄여 데이터 해석에 도움을 준다.
  • 모든 변수에서 최대 공분산을 추출하여 공통 점수에 넣는다.
  • 요인 분석은 시장 조사, 광고, 심리학, 금융 및 운영 연구에 널리 사용됨.
  • 예를 들어, 시장 조사원은 요인 분석을 사용하여 가격에 민감한 고객을 식별하고 소비자 선택에 영향을 미치는 브랜드 기능을 식별하며 유통 채널에 대한 채널 선택 기준을 이해하는 데 도움을 준다.

탐색적 요인 분석의 전제조건

  1. 등간척도, 정규분포, 관찰치가 상호독립적이며 분산이 동일해야한다.
  2. 모상관 행렬이 단위 행렬이라는 가설이 기각되어야함(KMO / Bartleet의 검정)
  3. 최초 요인 추출 단계에서 얻은 고유치를 scree chart로 표현했을 때, 한군데 이상 꺾이는 곳이 있어야함,
  4. 변수간에 높은 상관관계가 있어야한다.(상관관계가 높은 변수들끼리 그룹화 하는 것이기 때문)

탐색적 요인 분석 방법

  1. 변수간의 상관행렬로부터 공통요인을 도출한다.
  2. 도출된 공통요인을 이용해서 변수간의 상관관계를 설명한다.
  3. 요인부하량(factor loading)은 ±0.3 이상이면 유의하다고 본다.

탐색적 요인 분석의 목적

  1. 자료의 요약 : 변수들을 몇개의 공통된 변인으로 묶는다.
  2. 츨정도구 타당성 검정 : 변인들이 동일한 요인으로 묶이는지를 확인.
  3. 변인구조 파악 : 변수들의 상호관계를 파악한다.
  4. 불필요한 변인 제거 : 중요도나 설명력이 낮은 변수를 제거한다.
  5. 회귀분석이나 판별분석의 설명변수 선택

PCA(주성분분석)과의 차이점

  • PCA 성분은 최대 분산 량을 설명하는 반면 요인 분석은 데이터의 공분산을 설명한다.
  • PCA 구성 요소는 서로 완전히 직교하는 반면 요인 분석에서는 요인이 꼭 직교하는 것은 아니다.
  • PCA 성분은 관찰 된 변수의 선형 조합이지만, FA에서 관찰 된 변수는 관찰되지 않은 변수 또는 요인의 선형 조합이다.
  • PCA 구성 요소는 해석 할 수 없지만, FA에서 기본 요소는 라벨링 및 해석할 수 있다.
  • PCA는 일종의 차원 감소 방법이며 요인 분석은 잠재 변수 방법이다.
  • PCA는 관찰이지만 FA는 모델링 기술입니다.

 

탐색적 요인 분석 예시 코드

패키지 import 및 데이터 셋 세팅

아래 링크에서 BFI dataset을 다운 받을 수 있다.

vincentarelbundock.github.io/Rdatasets/datasets.html

 

https://vincentarelbundock.github.io/Rdatasets/datasets.html

 

vincentarelbundock.github.io

# 요인분석을 위한 패키지 설치
pip install factor-analyzer

import pandas as pd
from factor_analyzer import FactorAnalyzer
import matplotlib.pyplot as plt

df = pd.read_csv('bfi.csv', index_col=0)
df.columns

df.drop(['gender', 'education', 'age'],axis=1,inplace=True)
df.dropna(inplace=True)
df.info()

데이터 info 확인
데이터 예시

요인성 평가

  • 요인 분석을 수행하기 전에 데이터 세트의 요인성을 평가해야한다. Factorability는 데이터 세트에서 요인을 찾을 수 있는지를 확인하는 것이다.
  • 인수 분해성 또는 샘플링 적절성을 확인하는 방법에는 아래와 같이 두 가지 방법이 있다.

1. Bartlett의 테스트

from factor_analyzer.factor_analyzer import calculate_bartlett_sphericity
chi_square_value,p_value=calculate_bartlett_sphericity(df)
chi_square_value, p_value
# (18170.966350869236, 0.0)
  • p-value가 0이므로 탐색적 요인분석에 적합한 데이터라고 할 수 있다.

2. Kaiser-Meyer-Olkin (KMO)검정

  • 관측 된 각 변수와 전체 모델에 대한 적절성을 결정한다..
  • KMO는 관측 된 모든 변수 간의 분산 비율을 추정한다.
  • Bartlett와 달리 p값이 없기 때문에 판단의 기준이 따로 있다.
  • 0.6 미만의 KMO 값은 부적절한 것으로 간주되며 0.8이상이면 우수하다고 할 수 있다.
  • 다만 KMO test를 하려면 변수가 최소한 3개 이상이어야 한다.
from factor_analyzer.factor_analyzer import calculate_kmo
kmo_all,kmo_model=calculate_kmo(df)
kmo_model
# 0.848539722194922
  • KMO값이 0.85이므로 우수하다고 할 수 있다.

요인 수 선택

fa = FactorAnalyzer(n_factors=25,rotation=None)
fa.fit(df)
#Eigen값 체크 
ev, v = fa.get_eigenvalues()
ev
plt.scatter(range(1,df.shape[1]+1),ev)
plt.plot(range(1,df.shape[1]+1),ev)
plt.title('Scree Plot')
plt.xlabel('Factors')
plt.ylabel('Eigenvalue')
plt.grid()
plt.show()

  • Eigen값이 1이상일때 까지 or 그래프 기울기가 완만해지기 전까지 나누어야 데이터 결함을 최소화 할 수 있다.
  • 위와 같은 경우 6개로 나누어주는 것이 최선이다.

탐색적 요인분석 실시

fa = FactorAnalyzer(n_factors=6, rotation="varimax") #ml : 최대우도 방법
fa.fit(df)
efa_result= pd.DataFrame(fa.loadings_, index=df.columns)
efa_result

탐색적 요인 분석 결과

plt.figure(figsize=(6,10))
sns.heatmap(efa_result, cmap="Blues", annot=True, fmt='.2f')

  1. 요인 0는 N1, N2, N3, N4 및 N5에 대해 높은 요인 적재량을 가진다.
  2. 요인 1는 E1, E2, E3, E4 및 E5에 대해 높은 요인 적재량을 가진다.
  3. 요인 2에는 C1, C2, C3, C4 및 C5에 대해 높은 요인 적재량을 가진다.
  4. 요인 3에는 A1, A2, A3, A4 및 A5에 대해 높은 요인 적재량을 가진다.
  5. 요인 4에는 O1, O2, O3, O4 및 O5 에 대해 높은 요인 적재량을 가진다.
  6. 요인 5에는 변수에 대해 높은 요인 적재량이 없다고 해석할 수 있다. 따라서 위의 5 가지 요소만 활용하는 것이 좋다.

5개 요인으로 분석

fa = FactorAnalyzer(n_factors=5, rotation="varimax") #ml : 최대우도 방법
fa.fit(df)
# FactorAnalyzer(n_factors=5, rotation='varimax', rotation_kwargs={})
fa.get_factor_variance()
df1 = pd.DataFrame(fa.get_factor_variance())
#행, 열 이름 설정
df1.index = ['SS Loadings', 'Proportion Var','Cumulative Var']
df1

5개 요인 분석 결과

 

신뢰도 계수(크론바흐 알파계수) 확인

신뢰도 계수 함수의 출처는 다음과 같다.

stackoverflow.com/questions/20799403/improving-performance-of-cronbach-alpha-code-python-numpy/20799687#20799687

 

Improving performance of Cronbach Alpha code python numpy

I made some code for calculating Cronbach Alpha that works. But I am not too good using lambda functions. Is there a way to reduce the code and improve efficiency by using lambda instead of the sva...

stackoverflow.com

# 신롸도 계수를 구하는 함수
def CronbachAlpha(itemscores):
    itemscores = np.asarray(itemscores)
    itemvars = itemscores.var(axis=0, ddof=1)
    tscores = itemscores.sum(axis=1)
    nitems = itemscores.shape[1]
    return (nitems / (nitems-1)) * (1 - (itemvars.sum() / tscores.var(ddof=1)))
factors = ['A', 'C', 'E', 'N', 'O']
factors_items_dict = {}
for factor in factors:
    factors_items_dict[factor] = [x for x in df.columns if x[0] == factor]

factors_items_dict

for key, value in factors\_items\_dict.items():  
print(key)  
print(CronbachAlpha(df\[value\]))  
print()

  • N과 A정도가 신뢰도가 높다고 할 수 있다.
728x90
반응형