working_helen
[데이터 전처리] 설명변수 PCA 본문
데이터 전치리 과정에서 학습한 내용 중 두 번째로 PCA에 대해 공부해본다. 본 프로젝트에서는 변수의 개수가 많고, 상관관계와 VIF를 보았을 때 다중공선성 문제가 존재한다고 판단되어 변수 선택 + PCA 전처리 과정을 진행했다.
1. 주성분 분석 PCA
1) 차원 축소
2) 주성분 분석
2. 주성분 분석 과정
3. 파이썬 코드
(4. 주성분 분석 수학적 이해)
1. 주성분 분석 PCA (Principal Component Analysis)
1) 데이터의 차원 = 설명변수(feature)의 개수
- 하나의 feature가 추가될 때마다 데이터의 차원이 하나씩 증가한다.
- feature가 너무 많아져 차원이 증가하면 데이터를 표현하는 Feature Space의 부피가 기하 급수적으로 증가한다.
- 이로 인해 데이터의 양과 노이즈는 많아지지만 데이터 밀도는 매우 희소해져 학습 속도가 느려진다. 또한 중요하지 않은 feature들로 인해 과적합되거나 모델 성능이 저하될 수 있다.
=> Feature selection, Dimensionality Reduction 등이 필요하다.
- Feature selection(변수 선택) : y에 유의미한 영향을 미치는 feature만 선택하고, 불필요한 feature를 제거한다.
- Dimensionality Reduction(차원 축소) : 고차원 데이터의 특징을 최대한으로 유지하면서 데이터를 저차원화시킨다.
2) 주성분 분석
주성분 PC (Principal Component)
= 분산이 가장 큰 성분
= 전체 데이터의 분포를 가장 잘 설명하는 성분
- 주성분 분석은 차원 축소의 한 방법
- 전체 변수가 아닌 주성분 변수들만 사용하여 기존의 데이터를 표현함으로써 차원을 줄인다.
- 기존의 변수들로부터 데이터의 분포를 가장 잘 설명하는, 서로 연관성이 없는 새로운 주성분 변수 PC로 변환한다.
- 더 적은 개수의 변수로 데이터를 충분히 잘 설명하는 축을 생성한다.
- 설명변수가 너무 많아 중요한 일부 변수만으로 모델링을 하려는 경우 PCA를 사용한다.
- 데이터가 겹칠수록 점들 간 거리가 줄어 전체 분산이 작아진다. 따라서 분산을 최대화하는, 점들간 거리를 최대한 멀리하는 축을 이용한다.
2. 주성분 분석 과정
1) 변수 Scaling (Mean centering)
- Scaling을 하지 않으면 각 설명변수(feature)의 값의 범위나 분포에 따라 주성분이 설명하는 분산량 계산에 영향을 미칠 수 있다. 이는 모델의 성능 저하로 이어지기 때문에 주성분 분석시 반드시 표준화를 해주어야 한다.
- 예를 들어, 단위가 크고 분포가 넓은 변수는 실제 사실 여부와 관계없이 단순히 스케일에 의해 단위가 작고 분포가 좁은 변수보다 주성분 추출에 더 많은 영향을 줄 수 있다.
- Mean centering, 평균이 0, 분산이 1인 분포로 스케일링한다.
2) 공분산행렬 => 고유벡터 + 고유값
- 스케일링 된 feature들을 이용해 공분산행렬(Covariance Matrix)을 계산한다.
- 공분산행렬로부터 고유벡터(Eigen vector) + 고유값(Eigen value)을 추출한다.
- 고유값 분해(eigenvalue-decomposition), 특이값 분해(SVD, Singular Value Decomposition) 등 이용
3) 주성분 추출
: 원본 데이터로부터 n개의 주성분을 추출한다.
= 데이터의 분산을 가장 잘 설명하고 + 주성분들 사이에는 연관성이 없는 n개의 축을 찾는다.
- 데이터의 분산을 가장 잘 설명한다 = 고유값이 크다
- 주성분들 사이에는 연관성이 없는 = 다른 주성분들과 직교를 이루는 = 다른 주성분으로 생성 될 수 없는 축
- PC1 (제1 주성분 축) : 원본 Feature Space에서 데이터의 분산을 최대로 설명하는 축을 찾아 PC1으로 잡는다.
- PC2 (제2 주성분 축) : PC1과 직교(orthogonal)하면서, 데이터의 분산을 최대로 설명하는 축을 찾아 PC2로 잡는다.
- PC3 (제3 주성분 축) : PC1, PC2와 직교하면서, 데이터의 분산을 최대로 설명하는 축을 찾아 PC3로 잡는다.
- n개의 PC : 동일한 방법으로 서로 직교하면서, 데이터의 분산을 최대로 설명하는 축 n개를 찾는다.
4) 축 회전
: 새롭게 생성한 주성분 축을 기준으로 분포를 변환한다.
3. 파이썬 코드
- sklearn에서 제공하는 PCA 클래스로 구현할 수 있다.
from sklearn.decomposition import PCA
# PCA 객체 생성
pca = PCA(n_components = n 주성분 개수)
pca.fit(df)
pca.transform(df)
# fit + transform 한번에
pca.fit_transform(df)
1) PC값 확인
- pca.components_ : 고유 벡터 출력
# 주성분에 해당하는 고유벡터 가져오기
pca_components = pca.components_
# 주성분을 행으로, 기존 feature을 열로 하는 테이블 생성
pca_table = pd.DataFrame(data=pca_components.T, columns=['PC1', 'PC2', 'PC3',,, 'PCn'])
pca_table.index = df.columns
2) PC의 설명 정도 확인
- pca.explained_variacne_ : 각 PC 값의 설명력 정도를 확인, PC값이 클수록 설명력이 높다.
- pca.explained_variance_ratio_ : 각 PC의 explained_variance를 비율 = 전체 데이터의 분산을 설명하는 비율을 확인
# pca.explained_variance_ratio_의 출력 예시
# 순서대로 PC1, PC2, PC3의 설명 비율을 의미
[0.32493417 0.14920236 0.11900259]
=> PC1이 32%, PC2가 15%, PC3가 12%의 설명력을 가지고 있다.
PC1은 이 데이터의 32%를 설명할 수 있고, PC2는 이 데이터의 15%를 설명할 수 있다.
3) 적정 주성분 pc 개수 확인
- plotly.express.area 함수를 이용해 누적 영역 plot을 생성한다.
- x축 = pc의 개수 | y축 = pc가 설명하는 분산의 비율
- 몇 개의 PC를 사용할 때 원하는 만큼 원래 데이터를 표현할 수 있을지 확인할 수 있다.
- 일반적으로 70% 이상을 권장하며, 90% 이상을 권장하는 경우도 있다.
- 후반 PC로 갈수록 분산을 설명하는 비율은 감소하기 때문에 위로 볼록한 그래프가 그려진다.
pca = PCA()
pca.fit(df)
# 각 PC의 설명 비율을 누적합한 array 생성
np.cumsum(pca.explained_variance_ratio_)
# PC의 설명 비율 누적 합 그래프 생성
px.area(
x=range(1, exp_var_cumul.shape[0] + 1),
y=exp_var_cumul,
labels={"x": "# Components", "y": "Explained Variance"},
width=700, height=400
)
4) 주성분으로 변환된 Dafaframe 생성
- 원래 데이터에서 구한 주성분으로 이루어진 데이터 프레임으로 변환한다.
- 각 feature에 해당하는 값이 아닌 주성분에 해당하는 값으로 채워진다.
# 기존 데이터를 주성분으로 표현한 새로운 Dafaframe 정의
pd.DataFrame(pca.fit_transform(df))
4. 주성분 분석 수학적 이해
PC의 수학적 의미 : http://matrix.skku.ac.kr/math4ai-intro/W12/
분산 행렬과 고유값의 수학적 의미 : https://angeloyeo.github.io/2019/07/27/PCA.html
Jupyter Notebook
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import plotly.express as px
from plotly.subplots import make_subplots
plt.rc('font', family='NanumBarunGothic')
import warnings
warnings.filterwarnings(action='ignore')
모델링 전 전처리¶
- 행정동명 encoding
- PCA : PCA 두가지 방법으로 진행
PCA1 : 특성을 사전에 직접 나누어서 PCA
PCA2 : 특성 사전 구분없이 바로 PC
변수 삭제 여부 x 3가지 PCA 진행 방법
- 기초 EDA => 상관관계, 모델 복잡도 기반으로 모델에 포함하지 않을 변수 결정
- PCA 3가지 버전 (안한거, PCA!, PCA2)
=> 총 6가지의 X 전처리 파일 생성
- 미삭제 > 바로 모델 : 미삭제_PCA안함.csv
- 미삭제 > PCA 1 > 모델 : 미삭제_PCA1.csv
- 미삭제 > PCA 2 > 모델 : 미삭제_PCA2.csv
- 삭제 > 바로 모델 : 삭제_PCA안함.csv
- 삭제 > PCA 1 > 모델 : 삭제_PCA1.csv
- 삭제 > PCA 2 > 모델 : 삭제_PCA2.csv
원본 학습데이터 불러오기
final = pd.read_csv(path+'/데이터 전처리/찐찐최종.csv', encoding = 'cp949')
final.head(3)
Unnamed: 0.1 | Unnamed: 0 | 상호명 | 시군구명 | 행정동명 | 도로명주소 | 위도 | 경도 | 폐업여부 | 소득분위 | ... | 반경500_대학개수 | 반경1000_대학개수 | index | 상권활성화지수등급 | 상권활성화지수 | 매출지수 | 인프라지수 | 가맹점지수 | 인구지수 | 금융지수 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | (주)도피오커피서남병원인 | 양천구 | 신정3동 | 서울특별시 양천구 신정이펜1로 20(신정동, 서남병원) | 37.511895 | 126.833157 | y | 7 | ... | 0 | 0 | 24 | 9.26 | 1 | 3.00 | 6.45 | 0.36 | 12.50 | 2.51 |
1 | 1 | 1 | 커피나무 | 강남구 | 논현2동 | 서울특별시 강남구 언주로148길 14(논현동,2층) | 37.520407 | 127.036095 | y | 8 | ... | 0 | 0 | 415 | 26.56 | 10 | 10.82 | 14.35 | 2.04 | 17.63 | 8.70 |
2 | 2 | 2 | (주)프라빈 | 강남구 | 역삼1동 | 서울특별시 강남구 테헤란로22길 11(지상9층 역삼동) | 37.499232 | 127.035300 | y | 7 | ... | 0 | 0 | 423 | 31.32 | 10 | 14.21 | 17.25 | 4.66 | 21.81 | 8.82 |
3 rows × 35 columns
final.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20886 entries, 0 to 20885
Data columns (total 35 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Unnamed: 0.1 20886 non-null int64
1 Unnamed: 0 20886 non-null int64
2 상호명 20886 non-null object
3 시군구명 20886 non-null object
4 행정동명 20886 non-null object
5 도로명주소 20886 non-null object
6 위도 20886 non-null float64
7 경도 20886 non-null float64
8 폐업여부 20886 non-null object
9 소득분위 20886 non-null int64
10 가구수 20886 non-null int64
11 1년 생존율 20886 non-null float64
12 3년 생존율 20886 non-null float64
13 5년 생존율 20886 non-null float64
14 최근 10년 기준 평균영업기간 20886 non-null float64
15 최근 30년 기준 평균영업기간 20886 non-null float64
16 임대시세 20886 non-null float64
17 유동인구 20886 non-null int64
18 주거인구 20886 non-null int64
19 직장인구 20886 non-null int64
20 방범지수 20886 non-null int64
21 반경500_카페개수 20886 non-null int64
22 반경500_지하철역개수 20886 non-null int64
23 반경500_정류장개수 20886 non-null int64
24 반경500_공공기관개수 20886 non-null int64
25 반경500_대학개수 20886 non-null int64
26 반경1000_대학개수 20886 non-null int64
27 index 20886 non-null int64
28 상권활성화지수등급 20886 non-null float64
29 상권활성화지수 20886 non-null int64
30 매출지수 20886 non-null float64
31 인프라지수 20886 non-null float64
32 가맹점지수 20886 non-null float64
33 인구지수 20886 non-null float64
34 금융지수 20886 non-null float64
dtypes: float64(14), int64(16), object(5)
memory usage: 5.6+ MB
1. 행정동명 encoding¶
"행정동명" 범주형 열 > 8가지의 더미변수로 표현하는 행정동 encoder로 변환¶
#!pip install category_encoders
import category_encoders as ce
encoder = ce.BinaryEncoder(cols=["행정동명"])
df_binary = encoder.fit_transform(final["행정동명"])
#final = pd.concat([final, df_binary], axis=1)
encoder
BinaryEncoder(cols=['행정동명'],
mapping=[{'col': '행정동명',
'mapping': 행정동명_0 행정동명_1 행정동명_2 행정동명_3 행정동명_4 행정동명_5 행정동명_6 행정동명_7 행정동명_8
1 0 0 0 0 0 0 0 0 1
2 0 0 0 0 0 0 0 1 0
3 0 0 0 0 0 0 0 1 1
4 0 0 0 0 0 0 1 0 0
5 0 0 0 0 0 0 1 0 1
... ... ... ... ... ... ... ... ... ...
420 1 1 0 1 0 0 1 0 0
421 1 1 0 1 0 0 1 0 1
422 1 1 0 1 0 0 1 1 0
-1 0 0 0 0 0 0 0 0 0
-2 0 0 0 0 0 0 0 0 0
[424 rows x 9 columns]}])
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
BinaryEncoder(cols=['행정동명'],
mapping=[{'col': '행정동명',
'mapping': 행정동명_0 행정동명_1 행정동명_2 행정동명_3 행정동명_4 행정동명_5 행정동명_6 행정동명_7 행정동명_8
1 0 0 0 0 0 0 0 0 1
2 0 0 0 0 0 0 0 1 0
3 0 0 0 0 0 0 0 1 1
4 0 0 0 0 0 0 1 0 0
5 0 0 0 0 0 0 1 0 1
... ... ... ... ... ... ... ... ... ...
420 1 1 0 1 0 0 1 0 0
421 1 1 0 1 0 0 1 0 1
422 1 1 0 1 0 0 1 1 0
-1 0 0 0 0 0 0 0 0 0
-2 0 0 0 0 0 0 0 0 0
[424 rows x 9 columns]}])
df_binary
행정동명_0 | 행정동명_1 | 행정동명_2 | 행정동명_3 | 행정동명_4 | 행정동명_5 | 행정동명_6 | 행정동명_7 | 행정동명_8 | |
---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
4 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
20881 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 |
20882 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 |
20883 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
20884 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
20885 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |
20886 rows × 9 columns
final에 행정동 encoder 8가지 열이 추가되었다.
final.head(3)
Unnamed: 0.1 | Unnamed: 0 | 상호명 | 시군구명 | 행정동명 | 도로명주소 | 위도 | 경도 | 폐업여부 | 소득분위 | ... | 금융지수 | 행정동명_0 | 행정동명_1 | 행정동명_2 | 행정동명_3 | 행정동명_4 | 행정동명_5 | 행정동명_6 | 행정동명_7 | 행정동명_8 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | (주)도피오커피서남병원인 | 양천구 | 신정3동 | 서울특별시 양천구 신정이펜1로 20(신정동, 서남병원) | 37.511895 | 126.833157 | y | 7 | ... | 2.51 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
1 | 1 | 1 | 커피나무 | 강남구 | 논현2동 | 서울특별시 강남구 언주로148길 14(논현동,2층) | 37.520407 | 127.036095 | y | 8 | ... | 8.70 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
2 | 2 | 2 | (주)프라빈 | 강남구 | 역삼1동 | 서울특별시 강남구 테헤란로22길 11(지상9층 역삼동) | 37.499232 | 127.035300 | y | 7 | ... | 8.82 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
3 rows × 44 columns
DF 정리 : 학습용 칼럼만 남기고 정리
기초 EDA를 통해 선정한 모델에 포함시키지 않을 변수를 삭제
final : 변수 미삭제 상태
final1 : 변수 삭제 상태
final.drop(['Unnamed: 0.1','Unnamed: 0','index','상호명','시군구명','행정동명','도로명주소','위도','경도'],axis=1,inplace=True)
# 상권 활성화 관련 지표 칼럼명 병경
final.rename(columns={'상권활성화지수등급' : 'tmp'}, inplace=True)
final.rename(columns={'상권활성화지수' : '상권활성화지수등급'}, inplace=True)
final.rename(columns={'tmp' : '상권활성화지수'}, inplace=True)
최종 final Datraframe
final.head(3)
폐업여부 | 소득분위 | 가구수 | 1년 생존율 | 3년 생존율 | 5년 생존율 | 최근 10년 기준 평균영업기간 | 최근 30년 기준 평균영업기간 | 임대시세 | 유동인구 | ... | 반경500_공공기관개수 | 반경500_대학개수 | 반경1000_대학개수 | 상권활성화지수 | 상권활성화지수등급 | 매출지수 | 인프라지수 | 가맹점지수 | 인구지수 | 금융지수 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | y | 7 | 16957 | 75.0 | 75.0 | 25.0 | 2.8 | 3.3 | 167322.0 | 33003 | ... | 0 | 0 | 0 | 9.26 | 1 | 3.00 | 6.45 | 0.36 | 12.50 | 2.51 |
1 | y | 8 | 11676 | 72.3 | 29.8 | 21.3 | 2.6 | 3.9 | 166981.0 | 80595 | ... | 1 | 0 | 0 | 26.56 | 10 | 10.82 | 14.35 | 2.04 | 17.63 | 8.70 |
2 | y | 7 | 23983 | 67.6 | 42.6 | 33.3 | 2.7 | 4.0 | 182473.0 | 72621 | ... | 5 | 0 | 0 | 31.32 | 10 | 14.21 | 17.25 | 4.66 | 21.81 | 8.82 |
3 rows × 26 columns
최종 final1 Datraframe
final1 = final.drop(['1년 생존율','5년 생존율','최근 30년 기준 평균영업기간', '주거인구','직장인구',
'반경500_대학개수','상권활성화지수등급','매출지수','인프라지수','가맹점지수','인구지수','금융지수'],axis=1)
final1.head(3)
폐업여부 | 소득분위 | 가구수 | 3년 생존율 | 최근 10년 기준 평균영업기간 | 임대시세 | 유동인구 | 방범지수 | 반경500_카페개수 | 반경500_지하철역개수 | 반경500_정류장개수 | 반경500_공공기관개수 | 반경1000_대학개수 | 상권활성화지수 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | y | 7 | 16957 | 75.0 | 2.8 | 167322.0 | 33003 | 2 | 10 | 0 | 27 | 0 | 0 | 9.26 |
1 | y | 8 | 11676 | 29.8 | 2.6 | 166981.0 | 80595 | 3 | 79 | 0 | 15 | 1 | 0 | 26.56 |
2 | y | 7 | 23983 | 42.6 | 2.7 | 182473.0 | 72621 | 4 | 140 | 1 | 13 | 5 | 0 | 31.32 |
2. PCA¶
- 범주형 변수 소득분위, 상권활성화지수등급 제외하고 PCA 진행
(상권활성화지수등급은 여기서부터 변수에서 제외)
x_cat_cols = final[['소득분위','상권활성화지수등급']].columns
x_num_cols = final.drop(final[x_cat_cols], axis=1).columns
x1_cat_cols = final1[['소득분위']].columns
x1_num_cols = final1.drop(final1[x1_cat_cols], axis=1).columns
표준화 Scaling¶
from sklearn.preprocessing import StandardScaler
# final version
x = final.drop(['폐업여부'],axis=1)
x_scaler = StandardScaler().fit_transform(x) #표준화
x_scaled = pd.DataFrame(data=x_scaler, index=x.index, columns = x.columns)
# final1 version
x1 = final1.drop(['폐업여부'],axis=1)
x1_scaler = StandardScaler().fit_transform(x1)
x1_scaled = pd.DataFrame(data=x1_scaler, index=x1.index, columns = x1.columns)
#폐업여부 "y"를 1로 변환
y = final['폐업여부'].eq('y').mul(1)
다중공선성 확인 > PCA의 필요성 확인¶
- vif가 10이상 (혹은 5이상) 변수가 많으면 다중공선성 문제가 존재
- vif 계산 결과 x와 x1 모두에서 vif가 10이상, 5이상인 변수가 다수 존재했다. 특히 x의 경우 100을 넘어갈 정도로 높은 값을 보이는 변수도 존재했다.
x.columns
Index(['소득분위', '가구수', '1년 생존율', '3년 생존율', '5년 생존율', '최근 10년 기준 평균영업기간',
'최근 30년 기준 평균영업기간', '임대시세', '유동인구', '주거인구', '직장인구', '방범지수',
'반경500_카페개수', '반경500_지하철역개수', '반경500_정류장개수', '반경500_공공기관개수',
'반경500_대학개수', '반경1000_대학개수', '상권활성화지수', '상권활성화지수등급', '매출지수', '인프라지수',
'가맹점지수', '인구지수', '금융지수'],
dtype='object')
from statsmodels.stats.outliers_influence import variance_inflation_factor
vif_x = pd.DataFrame()
vif_x["Features"] = x.columns
vif_x["VIF"] = [variance_inflation_factor(x.values, i) for i in range(x.shape[1])]
print(vif_x.sort_values(by='VIF', ascending=False))
Features VIF
18 상권활성화지수 1915.934807
21 인프라지수 245.408011
24 금융지수 189.941300
5 최근 10년 기준 평균영업기간 172.496870
23 인구지수 154.672328
6 최근 30년 기준 평균영업기간 117.247997
20 매출지수 110.051676
0 소득분위 62.515647
2 1년 생존율 42.558925
19 상권활성화지수등급 40.877961
3 3년 생존율 27.408990
9 주거인구 24.110381
7 임대시세 20.785255
4 5년 생존율 14.105581
8 유동인구 13.087146
11 방범지수 10.662542
14 반경500_정류장개수 9.910956
22 가맹점지수 9.291396
1 가구수 9.112836
12 반경500_카페개수 6.052737
10 직장인구 5.261444
13 반경500_지하철역개수 3.015144
17 반경1000_대학개수 2.308871
15 반경500_공공기관개수 1.988401
16 반경500_대학개수 1.677894
x1.columns
Index(['소득분위', '가구수', '3년 생존율', '최근 10년 기준 평균영업기간', '임대시세', '유동인구', '방범지수',
'반경500_카페개수', '반경500_지하철역개수', '반경500_정류장개수', '반경500_공공기관개수',
'반경1000_대학개수', '상권활성화지수'],
dtype='object')
vif_x1 = pd.DataFrame()
vif_x1["Features"] = x1.columns
vif_x1["VIF"] = [variance_inflation_factor(x1.values, i) for i in range(x1.shape[1])]
print(vif_x1.sort_values(by='VIF', ascending=False))
Features VIF
3 최근 10년 기준 평균영업기간 64.379095
0 소득분위 51.400093
12 상권활성화지수 26.788981
4 임대시세 18.352918
6 방범지수 9.978897
2 3년 생존율 8.545776
9 반경500_정류장개수 8.113052
1 가구수 7.534201
7 반경500_카페개수 5.045898
5 유동인구 3.941574
8 반경500_지하철역개수 2.766401
10 반경500_공공기관개수 1.616284
11 반경1000_대학개수 1.466066
ver1 모든변수 사용한 모델 X (미삭제 > PCA 1)¶
: 변수 제거가 되지 않은 dataframe인 final의 x 이용
상권특성_pca
임대시세, 방범지수, 반경500_지하철역개수, 반경500_정류장개수, 반경500_공공기관개수, 반경500_대학개수, 반경1000_대학개수, 매출지수, 인프라지수, 금융지수, 상권활성화지수
경쟁업체특성_pca
1년 생존율, 3년 생존율, 5년 생존율, 최근 10년 기준 평균영업기간, 최근 30년 기준 평균영업기간, 반경500_카페개수, 가맹점지수
소비자특성_pca
가구수, 유동인구, 주거인구, 직장인구, 인구지수
- 상권특성 PCA 수행
from sklearn.decomposition import PCA
상권특성_v1 = x_scaled[['임대시세','방범지수','반경500_지하철역개수','반경500_정류장개수','반경500_공공기관개수','반경500_대학개수','반경1000_대학개수','매출지수','인프라지수','금융지수','상권활성화지수']]
pca = PCA()
pca.fit(상권특성_v1)
적정 주성분 pc 개수 확인¶
print(pca.explained_variance_ratio_)
exp_var_cumul = np.cumsum(pca.explained_variance_ratio_)
print(exp_var_cumul)
[0.32493417 0.14920236 0.11900259 0.09056076 0.07908398 0.07017893
0.0571783 0.04310278 0.03918219 0.02619895 0.00137499]
[0.32493417 0.47413653 0.59313912 0.68369988 0.76278386 0.83296278
0.89014109 0.93324387 0.97242606 0.99862501 1. ]
- 70% above를 보통 권장 > pc 5개면 충분
- 90% above를 권장하는 경우도 있음 > pc 8개면 충분
px.area(
x=range(1, exp_var_cumul.shape[0] + 1),
y=exp_var_cumul,
labels={"x": "# Components", "y": "Explained Variance"},
width=700, height=400
)
성분 개수 결정 => pc 8로 설정하여 상권특성 PCA 수행¶
11개 -> 8개 변수 개수 감소
pca = PCA(n_components=8)
pca.fit(상권특성_v1)
PCA(n_components=8)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
PCA(n_components=8)
주성분 벡터값 Dataframe 생성 + 주성분 벡터의 의미 추론¶
# 주성분에 해당하는 고유벡터 가져오기
pca_components = pca.components_
# 주성분을 행으로, 변수를 열로 하는 테이블 생성
pca_table = pd.DataFrame(data=pca_components.T, columns=['PC1', 'PC2', 'PC3', 'PC4', 'PC5','PC6','PC7','PC8'])
pca_table.index = 상권특성_v1.columns
# 소수 넷째 자리에서 반올림
pca_table_rounded = pca_table.round(4)
pca_table_rounded
PC1 | PC2 | PC3 | PC4 | PC5 | PC6 | PC7 | PC8 | |
---|---|---|---|---|---|---|---|---|
임대시세 | 0.3581 | -0.0728 | 0.0582 | 0.0403 | 0.4912 | 0.1272 | -0.4309 | 0.5885 |
방범지수 | -0.0277 | -0.1833 | -0.1222 | 0.9351 | -0.1469 | -0.1574 | 0.0794 | 0.1080 |
반경500_지하철역개수 | 0.2904 | 0.0391 | -0.2399 | -0.1508 | 0.2309 | -0.7114 | 0.4642 | 0.2130 |
반경500_정류장개수 | 0.0961 | 0.1704 | -0.6218 | -0.1231 | -0.5632 | 0.0681 | -0.2642 | 0.3721 |
반경500_공공기관개수 | 0.3349 | -0.0585 | -0.1929 | -0.0328 | -0.0424 | 0.5701 | 0.6404 | 0.0451 |
반경500_대학개수 | 0.0113 | 0.6583 | 0.0997 | 0.2044 | 0.1385 | 0.0952 | 0.0824 | 0.0951 |
반경1000_대학개수 | 0.0388 | 0.6787 | 0.0251 | 0.1304 | 0.0696 | 0.0361 | 0.0150 | -0.0862 |
매출지수 | 0.4476 | -0.1328 | 0.1651 | 0.1247 | 0.0232 | 0.2047 | 0.0006 | -0.0579 |
인프라지수 | 0.4201 | 0.0859 | -0.2571 | 0.0205 | 0.0068 | -0.1651 | -0.2975 | -0.5587 |
금융지수 | 0.1955 | 0.0856 | 0.6072 | -0.0890 | -0.5565 | -0.2026 | 0.0644 | 0.2730 |
상권활성화지수 | 0.4986 | -0.0286 | 0.1666 | 0.0475 | -0.1752 | -0.0519 | -0.1138 | -0.2226 |
- PC1 : 직장가 카페 (공공기관 다수 포진, 임대시세 높음, 매출지수와 인프라지수 높음)
- PC2 : 대학가 카페 (대학개수 높음)
- PC3 : 주거밀집지역 카페(교통 접근성이 낮고 소비자들의 잠재구매력이 높은 카페)
- PC4 : 치안이 좋은 지역 카페
- PC5 : 임대시세 거품이 심한 지역 카페(임대시세에 반해 버스의 접근성 낮음, 소비자의 잠재구매력 낮음)
- PC6 : 역세권 아닌 직장가 카페(지하철역개수 낮음)
- PC7 : 임대세시가 낮은 직장가 카페
- PC8 : 역세권 아닌 대학가 카페(대학내부 카페로 추정)
주성분으로 변환된 새로운 Dafaframe 정의¶
상권특성_fit_v1 = pd.DataFrame(pca.fit_transform(상권특성_v1))
상권특성_fit_v1
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
---|---|---|---|---|---|---|---|---|
0 | -2.426608 | -0.523301 | -0.726663 | -0.980566 | 0.863790 | 1.092991 | -0.475605 | 0.385616 |
1 | 1.511599 | -0.901957 | 2.131754 | 0.212383 | -0.942215 | 0.688106 | -0.143229 | -0.752065 |
2 | 4.282256 | -1.370018 | 1.273765 | 0.986497 | -0.790961 | 1.496123 | 2.567555 | -0.626966 |
3 | 4.272688 | -1.386975 | 1.335651 | 0.998752 | -0.734907 | 1.489347 | 2.593857 | -0.664005 |
4 | -0.223221 | -1.053488 | 1.322419 | 0.859992 | 0.381269 | -0.820396 | 0.572076 | 0.304210 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
20881 | -1.175663 | -0.442537 | 0.053964 | -0.955066 | 0.205493 | 0.697194 | -0.777169 | -0.125157 |
20882 | -1.023557 | -0.234801 | -1.311454 | -0.509566 | -0.725323 | -0.605678 | -0.054391 | 0.582330 |
20883 | -1.266637 | -0.570430 | -2.054841 | 0.348516 | 0.571653 | -1.661671 | 1.033384 | 0.507070 |
20884 | 0.606184 | -0.463084 | 1.300935 | -0.328451 | -1.302406 | -1.015271 | 0.150279 | 0.346828 |
20885 | -1.348815 | -1.084753 | -0.773362 | 1.700076 | 0.560396 | -0.669234 | 0.592225 | 0.198011 |
20886 rows × 8 columns
- 경쟁업체 특성 pc
적정 주성분 pc 개수 확인¶
# 경쟁업체 특성
경쟁업체특성_v1 = x_scaled[['1년 생존율','3년 생존율','5년 생존율','최근 10년 기준 평균영업기간','최근 30년 기준 평균영업기간','반경500_카페개수', '가맹점지수']]
pca = PCA()
pca.fit(경쟁업체특성_v1)
exp_var_cumul = np.cumsum(pca.explained_variance_ratio_)
px.area(
x=range(1, exp_var_cumul.shape[0] + 1),
y=exp_var_cumul,
labels={"x": "# Components", "y": "Explained Variance"},
width=700, height=400
)
#70% above > pc 3개면 충분
#90% above > pc 5개면 충분
주성분 개수 결정 => pc 5로 설정하여 상권특성 PCA 수행¶
7개 -> 5개 변수 개수 감소
pca = PCA(n_components=5)
pca.fit(경쟁업체특성_v1)
pca_components = pca.components_
pca_table = pd.DataFrame(data=pca_components.T, columns=['PC1', 'PC2', 'PC3', 'PC4','PC5'])
pca_table.index = 경쟁업체특성_v1.columns
pca_table_rounded = pca_table.round(4)
pca_table_rounded
PC1 | PC2 | PC3 | PC4 | PC5 | |
---|---|---|---|---|---|
1년 생존율 | 0.4495 | -0.1528 | -0.3068 | 0.7772 | 0.0506 |
3년 생존율 | 0.5581 | -0.1024 | -0.2246 | -0.1925 | -0.0599 |
5년 생존율 | 0.5344 | -0.0652 | -0.1803 | -0.5615 | -0.0520 |
최근 10년 기준 평균영업기간 | 0.3353 | 0.3956 | 0.4738 | 0.1660 | 0.2446 |
최근 30년 기준 평균영업기간 | 0.2491 | 0.5422 | 0.3612 | -0.0167 | -0.0111 |
반경500_카페개수 | -0.1417 | 0.4397 | -0.5674 | -0.0938 | 0.6746 |
가맹점지수 | -0.0794 | 0.5640 | -0.3820 | 0.0834 | -0.6900 |
- PC1 : 일반적인 상권 카페 (카페수와 가맹점지수 0에 가까움)
- PC2 : 경쟁 치열한 상권의 카페(가맹점 다수, 생존율 낮음)
- PC3 : 경쟁 적은 상권의 카페(카페와 가맹점 음수, 생존율 낮지만 영업기간 높음)
- PC4 : 상권이 자주 바뀌는 카페(1년 생존율만 높고 그외 수치는 낮음)
- PC5 : 개인카페 위주 상권의 카페(카페개수 많음, 가맹점지수 낮음)
주성분으로 변환된 새로운 Dafaframe 정의¶
경쟁업체특성_fit_v1 = pd.DataFrame(pca.fit_transform(경쟁업체특성_v1))
경쟁업체특성_fit_v1
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
0 | 0.836520 | -1.393711 | 0.728871 | 0.232352 | -0.042931 |
1 | -1.024110 | 0.427385 | 0.191099 | 0.557118 | -0.119721 |
2 | -0.567230 | 2.207935 | -1.190457 | -0.101424 | -0.792500 |
3 | -0.636744 | 2.423623 | -1.468795 | -0.147441 | -0.461620 |
4 | -1.888814 | -0.183862 | 0.066579 | 0.350720 | -0.744393 |
... | ... | ... | ... | ... | ... |
20881 | 1.055803 | -1.499739 | -0.836683 | 1.790218 | -0.767993 |
20882 | 0.296880 | -0.536598 | -1.179413 | -0.080245 | -0.336997 |
20883 | -3.948965 | 0.237523 | 1.666183 | -0.590876 | -0.128630 |
20884 | -1.568180 | 0.095330 | 0.339291 | -0.180331 | 0.396378 |
20885 | -0.608794 | -0.403459 | 1.462047 | 0.671536 | 0.309012 |
20886 rows × 5 columns
- 소비자 특성 pca
# 소비자 특성
소비자특성_v1 = x_scaled[['가구수','유동인구','주거인구','직장인구','인구지수']]
pca = PCA()
pca.fit(소비자특성_v1)
exp_var_cumul = np.cumsum(pca.explained_variance_ratio_)
px.area(
x=range(1, exp_var_cumul.shape[0] + 1),
y=exp_var_cumul,
labels={"x": "# Components", "y": "Explained Variance"},
width=700, height=400
)
#70% above > pc 2개면 충분
#90% above > pc 3개면 충분
주성분 개수 결정 => pc 8로 설정하여 상권특성 PCA 수행¶
5개 -> 3개 변수 개수 감소
pca = PCA(n_components=3)
pca.fit(소비자특성_v1)
pca_components = pca.components_
pca_table = pd.DataFrame(data=pca_components.T, columns=['PC1', 'PC2', 'PC3'])
pca_table.index = 소비자특성_v1.columns
pca_table_rounded = pca_table.round(4)
pca_table_rounded
PC1 | PC2 | PC3 | |
---|---|---|---|
가구수 | 0.2517 | -0.2261 | -0.9302 |
유동인구 | 0.5731 | -0.0803 | 0.2692 |
주거인구 | 0.5622 | -0.2664 | 0.2034 |
직장인구 | 0.0472 | 0.8458 | -0.1346 |
인구지수 | 0.5385 | 0.3951 | -0.0523 |
- PC1 : 주거지역 카페
- PC2 : 직장가 카페
- PC3 : 인구수가 상대적으로 적은 지역 카페 (주택가)
주성분으로 변환된 새로운 Dafaframe 정의¶
소비자특성_fit_v1 = pd.DataFrame(pca.transform(소비자특성_v1))
소비자특성_fit_v1
0 | 1 | 2 | |
---|---|---|---|
0 | -0.597521 | -0.882719 | -1.142003 |
1 | 0.621241 | 1.353794 | -0.115682 |
2 | 1.839192 | 2.682422 | -2.834992 |
3 | 1.839192 | 2.682422 | -2.834992 |
4 | 1.716347 | -0.278187 | -0.651161 |
... | ... | ... | ... |
20881 | 0.539384 | -0.600838 | 0.155794 |
20882 | 0.588643 | -0.728765 | 0.504993 |
20883 | -0.180802 | -0.044807 | 0.914517 |
20884 | -0.298688 | 1.052266 | 0.214400 |
20885 | -1.319473 | -0.563154 | -1.189460 |
20886 rows × 3 columns
ver2 선택한 변수만 사용한 모델 X1 (삭제 > PCA 1)¶
: 변수 제거가 완료된 dataframe인 final1의 x1 이용
상권특성_pca
임대시세, 방범지수, 반경500_지하철역개수,반경500_정류장개수, 반경500_공공기관개수,반경1000_대학개수,상권활성화지수
경쟁업체특성_pca
3년 생존율, 최근 10년 기준 평균영업기간,반경500_카페개수
소비자특성_pca
가구수, 유동인구
- 상권특성 pca
주성분 개수 결정 => pc 6로 설정하여 상권특성 PCA 수행¶
7개 -> 6개 변수 개수 감소
pca = PCA(n_components=6)
pca.fit(상권특성_v2)
PCA(n_components=6)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
PCA(n_components=6)
주성분 벡터값 Dataframe 생성 + 주성분 벡터의 의미 추론¶
pca_components = pca.components_
pca_table = pd.DataFrame(data=pca_components.T, columns=['PC1', 'PC2', 'PC3','PC4','PC5','PC6'])
pca_table.index = 상권특성_v2.columns
pca_table_rounded = pca_table.round(4)
pca_table_rounded
PC1 | PC2 | PC3 | PC4 | PC5 | PC6 | |
---|---|---|---|---|---|---|
임대시세 | 0.4843 | -0.2416 | -0.2398 | 0.1761 | 0.1239 | -0.6161 |
방범지수 | -0.0632 | -0.4088 | 0.7151 | 0.5580 | -0.0516 | 0.0234 |
반경500_지하철역개수 | 0.4318 | 0.0764 | 0.0146 | -0.0175 | -0.8517 | 0.2430 |
반경500_정류장개수 | 0.1637 | 0.5647 | 0.6063 | -0.3231 | 0.0268 | -0.4260 |
반경500_공공기관개수 | 0.4785 | 0.0153 | 0.1756 | -0.1731 | 0.4822 | 0.6052 |
반경1000_대학개수 | 0.0530 | 0.6566 | -0.1772 | 0.7165 | 0.1018 | 0.1006 |
상권활성화지수 | 0.5625 | -0.1359 | -0.0336 | 0.0983 | 0.1138 | -0.0538 |
- PC1 : 직장가카페 (임대시세 높음, 공공기관 다수, 상권활성화지수 높음, 역세권)
- PC2 : 상대적으로 낙후된 대학가카페 (정류장 많음, 대학 많음, 방범지수 낮음, 임대료 낮음)
- PC3 : 치안 좋은 지역의 카페 (방범지수 높고 정류장 다수)
- PC4 : 대학가카페 (대학가 많음, 교통 특성이 안좋은 이유 확인 필요)
- PC5 : 역세권이 아닌 직장가카페 (지하철역 음수, 공공기관 높음)
- PC6 : 임대시세 낮은 직장가카페
주성분으로 변환된 새로운 Dafaframe 정의¶
상권특성_fit_v2 = pd.DataFrame(pca.fit_transform(상권특성_v2))
상권특성_fit_v2
0 | 1 | 2 | 3 | 4 | 5 | |
---|---|---|---|---|---|---|
0 | -1.462765 | 0.212006 | -0.546074 | -1.089663 | 0.565356 | -0.574840 |
1 | 0.435298 | -1.272699 | -0.508299 | -0.000253 | 1.258079 | 0.328409 |
2 | 3.306183 | -1.802535 | 0.626060 | 0.113568 | 1.722921 | 2.725095 |
3 | 3.289889 | -1.858739 | 0.565708 | 0.145727 | 1.720253 | 2.767495 |
4 | -0.211566 | -1.630473 | -0.153358 | 0.685777 | -0.690207 | 0.363747 |
... | ... | ... | ... | ... | ... | ... |
20881 | -0.928882 | -0.044222 | -0.712384 | -0.921229 | 0.676113 | -0.576119 |
20882 | -0.458687 | 0.616701 | 1.013118 | -0.962894 | -0.736583 | -0.394370 |
20883 | -0.331305 | -0.019358 | 1.313934 | -0.252694 | -2.193026 | 0.459209 |
20884 | 0.260140 | -0.427793 | 0.062802 | -0.325983 | -0.576292 | -0.023455 |
20885 | -0.932622 | -1.210065 | 1.319422 | 0.726084 | -0.894521 | 0.341237 |
20886 rows × 6 columns
- 경쟁업체 특성 pca
주성분 개수 결정 => pc 2로 설정하여 상권특성 PCA 수행¶
3개 -> 2개 변수 개수 감소
pca = PCA(n_components=2)
pca.fit(경쟁업체특성_v2)
PCA(n_components=2)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
PCA(n_components=2)
주성분 벡터값 Dataframe 생성 + 주성분 벡터의 의미 추론¶
pca_components = pca.components_
pca_table = pd.DataFrame(data=pca_components.T, columns=['PC1', 'PC2'])
pca_table.index = 경쟁업체특성_v2.columns
pca_table_rounded = pca_table.round(4)
pca_table_rounded
PC1 | PC2 | |
---|---|---|
3년 생존율 | 0.6658 | 0.1542 |
최근 10년 기준 평균영업기간 | 0.6229 | 0.4236 |
반경500_카페개수 | -0.4107 | 0.8926 |
- PC1 : 주변 카페가 적어 오래생존하는 카페
- PC2 : 장수하는 카페
주성분으로 변환된 새로운 Dafaframe 정의¶
경쟁업체특성_fit_v2 = pd.DataFrame(pca.fit_transform(경쟁업체특성_v2))
경쟁업체특성_fit_v2
0 | 1 | |
---|---|---|
0 | 1.804961 | -0.593486 |
1 | -0.779552 | -0.139219 |
2 | -0.558937 | 1.099113 |
3 | -0.760370 | 1.536949 |
4 | -0.737201 | -0.688611 |
... | ... | ... |
20881 | 1.384633 | -1.013510 |
20882 | -0.123238 | -0.082820 |
20883 | -2.120761 | -1.029913 |
20884 | -1.090726 | -0.034783 |
20885 | 0.932553 | -0.215443 |
20886 rows × 2 columns
- 소비자특성 pca
두 변수를 하나로 줄였을때 분산의 약 57%를 설명
주성분 벡터값 Dataframe 생성 + 주성분 벡터의 의미 추론¶
pca_components = pca.components_
pca_table = pd.DataFrame(data=pca_components.T, columns=['PC1'])
pca_table.index = 소비자특성_v2.columns
pca_table_rounded = pca_table.round(4)
pca_table_rounded
PC1 | |
---|---|
가구수 | 0.7071 |
유동인구 | 0.7071 |
- PC1 : 가구수 + 유동인구 지표
주성분으로 변환된 새로운 Dafaframe 정의
소비자특성_fit_v2 = pd.DataFrame(pca.transform(소비자특성_v2))
소비자특성_fit_v2
0 | |
---|---|
0 | 0.346849 |
1 | 0.478407 |
2 | 2.132443 |
3 | 2.132443 |
4 | 0.861172 |
... | ... |
20881 | -0.169584 |
20882 | 0.462878 |
20883 | -0.965194 |
20884 | -0.357369 |
20885 | -0.245533 |
20886 rows × 1 columns
ver3 선택한 변수 특성 나누지 않고 pca (삭제 > PCA 2)¶
: 변수 제거가 완료된 dataframe인 final1의 x1 이용
주성분 개수 결정 => pc 8로 설정하여 상권특성 PCA 수행¶
13개 -> 10개 변수 개수 감소
pca = PCA(n_components=10)
pca.fit(x1_scaled)
PCA(n_components=10)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
PCA(n_components=10)
주성분 벡터값 Dataframe 생성 + 주성분 벡터의 의미 추론¶
pca_components = pca.components_
pca_table = pd.DataFrame(data=pca_components.T, columns=['PC1', 'PC2', 'PC3', 'PC4','PC5','PC6','PC7','PC8','PC9','PC10'])
pca_table.index = x1_scaled.columns
pca_table_rounded = pca_table.round(4)
pca_table_rounded
PC1 | PC2 | PC3 | PC4 | PC5 | PC6 | PC7 | PC8 | PC9 | PC10 | |
---|---|---|---|---|---|---|---|---|---|---|
소득분위 | 0.2869 | 0.3359 | -0.2785 | -0.1095 | 0.1152 | -0.2885 | 0.1001 | -0.0052 | -0.3296 | 0.4318 |
가구수 | -0.2192 | -0.1818 | -0.4284 | 0.2771 | 0.0643 | 0.0602 | 0.5392 | -0.3913 | -0.3588 | -0.1338 |
3년 생존율 | 0.0325 | 0.3485 | 0.0971 | 0.5504 | 0.1876 | 0.4497 | -0.3174 | -0.3979 | 0.1028 | 0.0151 |
최근 10년 기준 평균영업기간 | 0.2674 | 0.3984 | 0.1422 | 0.2676 | 0.0739 | 0.0112 | 0.3659 | 0.1751 | 0.0281 | 0.2300 |
임대시세 | 0.4382 | 0.0430 | -0.1664 | -0.2170 | 0.1210 | -0.0124 | -0.2702 | -0.1725 | 0.0531 | 0.0622 |
유동인구 | -0.0931 | -0.5039 | 0.0760 | 0.0675 | 0.4070 | 0.2327 | 0.1475 | 0.1680 | 0.2864 | 0.5119 |
방범지수 | -0.0712 | -0.0987 | -0.4640 | 0.5060 | 0.1896 | -0.4461 | -0.3613 | 0.3340 | 0.1257 | -0.0893 |
반경500_카페개수 | 0.3429 | -0.3920 | -0.0466 | -0.0764 | 0.0280 | -0.0251 | -0.2486 | -0.3922 | -0.1432 | -0.1306 |
반경500_지하철역개수 | 0.3322 | -0.1502 | 0.0777 | 0.1390 | 0.0877 | 0.3937 | -0.0264 | 0.5393 | -0.5254 | -0.2977 |
반경500_정류장개수 | 0.1055 | -0.2932 | 0.3535 | 0.4007 | -0.5219 | -0.2413 | -0.1011 | -0.0994 | -0.2529 | 0.3927 |
반경500_공공기관개수 | 0.3718 | -0.0367 | -0.0410 | 0.1929 | -0.3577 | -0.0731 | 0.3409 | 0.0461 | 0.4992 | -0.3357 |
반경1000_대학개수 | 0.0696 | -0.0283 | 0.5445 | 0.0779 | 0.5448 | -0.4811 | 0.1512 | -0.1495 | -0.0689 | -0.2929 |
상권활성화지수 | 0.4573 | -0.2098 | -0.1706 | 0.0016 | 0.1420 | 0.0823 | 0.1657 | -0.0963 | 0.1901 | 0.1012 |
주성분으로 변환된 새로운 Dafaframe 정의¶
전체특성_fit = pd.DataFrame(pca.fit_transform(x1_scaled))
전체특성_fit
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | -1.563254 | 1.870616 | 0.129862 | 0.606852 | -0.655081 | 0.804491 | 0.384749 | -1.314080 | -0.268109 | 0.449488 |
1 | 0.536604 | -0.315821 | -1.400854 | -1.154912 | 0.356824 | -0.352989 | 0.887787 | -0.098443 | 1.186293 | 0.757745 |
2 | 2.464573 | -1.606750 | -2.936435 | 1.288034 | -0.165102 | 0.331304 | 2.650371 | -0.572907 | 1.741114 | -1.857688 |
3 | 2.622283 | -1.769856 | -2.994477 | 1.210654 | -0.099408 | 0.343038 | 2.538498 | -0.755406 | 1.696056 | -1.960850 |
4 | -0.958985 | -0.687667 | -1.563122 | -0.363064 | 0.663972 | 0.389348 | 0.194714 | 0.836313 | 0.103171 | -0.950324 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
20881 | -1.592584 | 1.039658 | 0.462968 | 0.553935 | -0.331921 | 1.801694 | -1.290235 | -1.910693 | 0.798904 | -0.087112 |
20882 | -0.900418 | -1.140850 | 0.716889 | 0.865156 | -0.737887 | 0.852798 | -0.954468 | 0.028700 | -0.294554 | 0.404075 |
20883 | -0.016999 | -0.406427 | -0.618636 | -1.097262 | -0.944213 | -1.437091 | -0.477481 | 2.944198 | -2.122378 | 0.189434 |
20884 | 0.515268 | -0.453937 | -0.616189 | -0.930829 | -0.189108 | -0.179604 | -0.153470 | 0.620994 | -0.550296 | 0.484792 |
20885 | -0.849030 | 1.226157 | -1.391987 | 1.281906 | -0.106792 | -0.624137 | -0.011719 | 1.223740 | -0.727451 | -0.646029 |
20886 rows × 10 columns
PCA결과 하나의 df로 합치기¶
미삭제 X > PCA1¶
'소득분위'열 + 상권특성_fit_v1 + 경쟁업체특성_fit_v1 + 소비자특성_fit_v1
# x(모든변수사용)
x_pca1 = pd.concat([x_scaled['소득분위'], 상권특성_fit_v1, 경쟁업체특성_fit_v1, 소비자특성_fit_v1], axis=1)
new_columns = ['소득분위','상권PC1','상권PC2','상권PC3','상권PC4','상권PC5','상권PC6','상권PC7','상권PC8',
'경쟁PC1','경쟁PC2','경쟁PC3','경쟁PC4','경쟁PC5',
'소비자PC1','소비자PC2','소비자PC3']
x_pca1.columns = new_columns
#소득분위 + 16개 변수 -> 17개
x_pca1.info()
'소득분위'열 + 상권특성_fit_v2 + 경쟁업체특성_fit_v2 + 소비자특성_fit_v2
# x1(선택변수 특성 나누어 사용)
x1_pca1 = pd.concat([x1_scaled['소득분위'],상권특성_fit_v2, 경쟁업체특성_fit_v2, 소비자특성_fit_v2], axis=1)
new_columns = ['소득분위','상권PC1','상권PC2','상권PC3','상권PC4','상권PC5','상권PC6',
'경쟁PC1','경쟁PC2',
'소비자PC1']
x1_pca1.columns = new_columns
#소득분위 + 9개변수 -> 10개
x1_pca1.info()
#x1 특성 안나누고 그냥 pca만 진행
x1_pca2 = 전체특성_fit.copy()
new_columns = ['PC1','PC2','PC3','PC4','PC5','PC6','PC7','PC8','PC9','PC10']
x1_pca2.columns = new_columns
x1_pca2.info()
PCA + Binary Encoding 결과 데이터 파일 생성¶
PCA 진행 Dataframe에 '행정동명' 바이너리 인코딩 결과 8개의 열 추가
미삭제_PCA1 = pd.concat([x_pca1, df_binary], axis=1)
삭제_PCA1 = pd.concat([x1_pca1, df_binary], axis=1)
삭제_PCA2 = pd.concat([x1_pca2, df_binary], axis=1)
# 미삭제_PCA1.to_csv(path + '/미삭제_PCA1.csv')
# 삭제_PCA1.to_csv(path + '/삭제_PCA1.csv')
# 삭제_PCA2.to_csv(path + '/삭제_PCA2.csv')
최종 생성 파일
미삭제 x > 바로 모델 : 미삭제_PCA안함.csv
미삭제 x > PCA 1 진행 : 미삭제_PCA1.csv
미삭제 x > PCA 2 진행 : 미삭제_PCA2.csv
삭제 x1 > 바로 모델 : 삭제_PCA안함.csv
삭제 x1 > PCA 1 진행 : 삭제_PCA1.csv
삭제 x1 > PCA 2 진행 : 삭제_PCA2.csv
Reference
https://m.blog.naver.com/tjdrud1323/221720259834
https://rfriend.tistory.com/751
https://chancoding.tistory.com/53
https://chancoding.tistory.com/52
https://deep-learning-study.tistory.com/812
https://deep-jin.tistory.com/entry/PCA-Principal-Component-Analysis
'TAVE > 뿌스팅 project' 카테고리의 다른 글
[애플리케이션] streamlit 웹 구현 (0) | 2023.08.07 |
---|---|
[모델링] 예측 모델 모델링 및 성능 평가 (0) | 2023.08.07 |
[데이터 전처리] Encoding 인코딩 (0) | 2023.08.07 |
[데이터 전처리] EDA 및 변수 선택 (0) | 2023.08.07 |
[데이터 수집] 데이터 수집 Workflow (0) | 2023.08.07 |