Skip to content

Latest commit

 

History

26 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

서울시 생활 인프라 기반 법정동 군집 분석

서울 452개 법정동의 교육·상업 인프라 밀도를 K-Means 클러스터링으로 분류하고, PCA로 시각화하며, Decision Tree로 판별 규칙을 도출합니다.


목차

  1. 사용 알고리즘
  2. 1단계 — 문제 정의
  3. 2단계 — 데이터 수집 및 설명
  4. 3단계 — 데이터 전처리
  5. 4단계 — 모델 설계 및 적용
  6. 5단계 — 성능 평가
  7. 6단계 — 결과 분석 및 해석
  8. 실행 방법
  9. 프로젝트 구조

사용 알고리즘

수업에서 다룬 알고리즘 중 이 프로젝트에서 실제로 적용한 항목입니다.

분류 알고리즘 적용 목적
군집화 (Clustering) K-Means Clustering 서울 법정동을 인프라 특성 기준으로 4개 그룹으로 분류
차원 축소 Principal Component Analysis (PCA) 3차원 데이터를 2차원으로 압축해 군집 분포 시각화
분류 (Classification) Decision Tree K-Means 군집 레이블을 학습해 동네 유형 판별 규칙 도출 및 군집 유효성 검증

이 외에도 StandardScaler(정규화), Silhouette Score(군집 품질 평가), Elbow Method(최적 K 탐색), 5-Fold Cross Validation(트리 깊이 최적화), Ridge Regression(집값 예측 보조 분석)이 활용되었습니다.


1단계 — 문제 정의

핵심 질문

"서울 동네들은 어떤 기준으로 나눌 수 있을까? 그리고 그 기준을 명확한 규칙으로 표현할 수 있을까?"

우리는 흔히 "교육 특구는 집값이 높다", "상업지는 주거 선호도가 낮다"고 말합니다. 하지만 이를 데이터로 객관적으로 검증한 사례는 많지 않습니다.

이 프로젝트는 다음 세 가지 질문에 답합니다.

  • 서울 동네들은 인프라 특성(소상공인·학교·학원 밀도)에 따라 어떻게 나뉘는가?
  • 각 동네 유형을 구분하는 인프라 밀도 기준값은 얼마인가?
  • 인프라 유형과 실거래가 사이에는 어떤 관계가 있는가?

분석 범위

  • 대상: 서울시 전체 452개 법정동
  • 입력 변수: 동별 소상공인 수 / 면적(km²), 학교 수 / 면적, 학원 수 / 면적 (밀도 기준)
  • 비교 지표: 아파트 실거래가 (2025.04 ~ 2026.03)

2단계 — 데이터 수집 및 설명

모든 데이터는 공공데이터포털에서 수집하였습니다.

파일명 설명 활용
소상공인.csv 서울시 전체 소상공인 사업장 목록 (주소 포함) 클러스터링 변수
학교.csv 서울시 초·중·고·대학교 목록 클러스터링 변수
학원.csv 서울시 등록 학원 중 개원 중인 곳 클러스터링 변수
토지 면적.csv 법정동별 면적 (km²) 밀도 계산 기준
인구밀도.csv 서울시 읍면동별 인구 현황 유효 법정동 452개 선정 기준
서울시_실거래가.csv 아파트 실거래가 (2025.04 ~ 2026.03) 집값 비교 분석

주요 변수 기술통계

변수 평균 표준편차 최솟값 최댓값 비고
소상공인 밀도 (개/km²) 63.9 91.0 0.0 814.5 명동(814) 극단값
학교 밀도 (개/km²) 5.5 17.8 0.0 288.8 right-skewed
학원 밀도 (개/km²) 32.3 51.6 0.0 430.5 대치동(430) 극단값

변수 선택 근거: 인구밀도·지하철역 추가 시 Silhouette Score가 0.49 → 0.39로 하락(noise 증가)해 제외하고, 생활 인프라 핵심 3축만 사용합니다.


3단계 — 데이터 전처리

처리 흐름

원본 데이터 (소상공인 / 학교 / 학원 / 면적)
         │
         ▼
법정동별 개수 집계 → 면적(km²)으로 나누어 밀도 계산
         │
         ▼
Log1p 변환  →  right-skewed 분포 완화
  (예: 대치동 학원밀도 430 → log(431)=6.07 / 전체 평균 log(33)=3.53)
         │
         ▼
StandardScaler  →  평균 0, 표준편차 1로 정규화
         │
         ▼
Z-score 기반 이상치 제거 (|Z| > 3인 동네 3개 제거)
  단, 분석상 중요한 대치동·신사동은 강제 보존
         │
         ▼
최종 입력 데이터: 449개 법정동 × 3개 변수

왜 Log1p 변환인가?

밀도 데이터는 극단적으로 치우쳐 있습니다. 명동의 소상공인 밀도(814/km²)는 평균(64/km²)의 12배입니다. 이대로 클러스터링하면 알고리즘이 극단값에 끌려가 의미 있는 군집이 만들어지지 않습니다. Log1p 변환으로 극단값을 완화하면서도 동네 간 상대적 차이는 유지합니다.

이상치 처리

처리 방법 대상 결과
Z-score > 3 제거 종로구 숭인동, 중구 흥인동, 마포구 아현동 3개 동 제거
화이트리스트 보존 강남구 대치동, 강남구 신사동 분석 중요 동네 강제 포함

4단계 — 모델 설계 및 적용

K-Means 클러스터링

K-Means는 군집 수(K)를 미리 정해야 합니다. Elbow Method(관성값 감소 추이)와 Silhouette Score(군집 응집도)를 함께 확인해 K=4를 선택했습니다.

km = KMeans(n_clusters=4, random_state=42, n_init=10)
labels = km.fit_predict(X)
  • 입력: 449개 법정동 × 3개 변수 (소상공인·학교·학원 정규화 밀도)
  • 출력: 각 법정동에 클러스터 번호(0~3) 부여

K 탐색 결과 (data/processed/k_selection.png):

K Silhouette Score 해석
2 0.476 분리 과도
3 0.420
4 0.446 최적 (Elbow + Silhouette 동시 고려)
5 0.381 과분할

PCA 차원 축소 (시각화)

3차원 데이터를 그래프로 나타내기 어렵기 때문에 PCA로 2차원으로 압축해 군집 분포를 시각화했습니다.

pca = PCA(n_components=2, random_state=42)
coords = pca.fit_transform(X)
  • PC1: 교육 인프라 축 (학원·학교 밀도 반영, 설명 분산 ~70%)
  • PC2: 상권 집중 축 (소상공인 밀도 반영, 설명 분산 ~20%)
  • 누적 설명 분산 ~90% → 3개 변수의 정보를 거의 손실 없이 보존

PCA 주성분 로딩 표

Decision Tree — 군집 판별 규칙 도출

K-Means가 만든 클러스터 레이블(0~3)을 target으로 놓고, 인프라 밀도로 분류하는 Decision Tree를 학습합니다.

입력(X): 소상공인_밀도, 학교_밀도, 학원_밀도
출력(y): K-Means 클러스터 번호 (0, 1, 2, 3)

두 가지 목적으로 활용합니다.

  1. 규칙 도출: "학원 밀도 > X이면 교육 특화, 소상공인 밀도 > Y이면 상업 특화"와 같은 명확한 기준값 추출
  2. 군집 유효성 검증: 정확도가 높을수록 K-Means 군집이 인프라로 잘 설명되는 실제 패턴임을 의미

최적 트리 깊이는 5-Fold Cross Validation으로 탐색합니다.

dt = DecisionTreeClassifier(max_depth=best_depth, random_state=42)
dt.fit(X_train, y_train)

트리 깊이별 정확도 변화:

트리 깊이 탐색


5단계 — 성능 평가

K-Means — Silhouette Score

지표 해석
Silhouette Score 0.4458 군집 간 분리가 뚜렷하며 신뢰할 수 있는 수준

일반적으로 Silhouette Score 0.4 이상이면 의미 있는 군집 구조가 존재한다고 봅니다.

클러스터별 법정동 수

클러스터 이름 법정동 수
C0 상업·학원 복합 119개
C1 교육·주거 밀집 128개
C2 저밀도 주거 71개
C3 상업 특화 131개

PCA 설명 분산

주성분 설명 분산 해석
PC1 ~70% 교육 인프라 축 (학원·학교 밀도 반영)
PC2 ~20% 상권 집중 축 (소상공인 밀도 반영)
합계 ~90% 3개 변수의 정보를 90% 이상 보존

Decision Tree — 분류 성능

지표 해석
Test 정확도 98.9% 449개 법정동 중 단 1개만 오분류
5-Fold CV 정확도 95.8% 과적합 없이 안정적으로 높은 성능
최적 트리 깊이 5 Cross Validation으로 탐색

6단계 — 결과 분석 및 해석

클러스터별 인프라 프로파일 (레이더 차트)

4개 클러스터가 소상공인·학교·학원 밀도에서 어떻게 다른지 한눈에 비교합니다.

레이더 차트

클러스터 이름 주요 특징 대표 동네
C0 상업·학원 복합 소상공인과 학원 밀도가 모두 높음 신사동, 역삼동, 서교동, 인사동
C1 교육·주거 밀집 학원·학교 밀도가 압도적으로 높음 대치동, 중계동, 반포동, 잠실동
C2 저밀도 주거 모든 지표가 낮음 (조용한 주거지) 이촌동, 세곡동, 율현동, 자곡동
C3 상업 특화 소상공인 밀도만 극단적으로 높음 명동, 소공동, 충무로, 을지로

PCA 2D 시각화 (군집 분포)

3개 변수를 2개의 주성분으로 압축해 서울 449개 법정동의 분포를 시각화했습니다. 같은 색상의 점들이 비슷한 인프라 특성을 가진 동네들입니다.

PCA 산점도


PCA 주성분 해석

PC1과 PC2가 각각 어떤 변수를 얼마나 반영하는지 분석합니다.

PCA 해석 슬라이드

주성분 해석 의미
PC1 (교육 인프라 축) 학원·학교 변수에 높은 양의 가중치 PC1이 높을수록 교육 특화 지역
PC2 (상권 집중 축) 소상공인에 양, 학교에 음의 가중치 PC2가 높을수록 상업 특화 지역

Decision Tree 결과

트리 시각화 — 동네 유형 판별 규칙

인프라 밀도 기준값으로 어떻게 4개 유형이 나뉘는지 트리로 표현합니다.

트리 시각화

혼동 행렬 (Confusion Matrix)

449개 법정동 중 단 1개만 오분류. 4개 클러스터 모두 높은 정밀도·재현율을 보입니다.

혼동 행렬

Feature Importance — 어떤 인프라가 동네 유형을 가장 잘 구분하는가?

Feature Importance

K-Means 레이더 차트와 Decision Tree Feature Importance가 같은 변수를 중요하게 본다면, 분석 결론이 두 모델에서 일관되게 지지되는 것을 의미합니다.


클러스터별 아파트 실거래가 비교

인프라 유형이 실제 집값에 어떤 영향을 미치는지 확인합니다.

집값 비교

클러스터 이름 거래건수 평균가 중앙값
C0 상업·학원 복합 17,443건 12.22억 11.00억
C1 교육·주거 밀집 44,721건 11.68억 9.28억
C2 저밀도 주거 2,025건 13.43억 10.55억
C3 상업 특화 6,932건 12.48억 10.75억

핵심 인사이트:

  • 교육·주거 밀집(C1) 클러스터가 거래량 44,721건으로 전체의 63%를 차지합니다. 학원·학교 밀도가 높은 지역에 서울 아파트 거래가 집중됩니다.
  • 단, 평균가(11.68억)와 중앙값(9.28억) 모두 4개 클러스터 중 가장 낮습니다. 대치동·반포동 같은 고가 지역과 노원·강북·은평 등 중저가 교육 지역이 같은 군집에 혼재하기 때문입니다.
  • 저밀도 주거(C2) 클러스터는 거래량(2,025건)이 가장 적지만 평균가(13.43억)는 가장 높습니다. 이촌동처럼 조용하고 희소한 고급 주거지의 프리미엄이 반영됩니다.
  • 상업 특화(C3) 클러스터(명동·충무로 등)의 평균가는 12.48억으로, 상권 활성화가 반드시 주거 비선호를 의미하지 않음을 보여줍니다.

클러스터 요약 카드

각 클러스터의 핵심 지표와 대표 동네를 한눈에 정리합니다.

클러스터 요약


최종 인사이트 정리

"서울에서 교육 인프라가 집중된 동네가 거래량은 압도적 1위지만, 가격이 가장 높은 곳은 오히려 조용한 저밀도 주거지입니다."

  1. 교육 인프라 = 최고의 주거 수요: C1의 거래량이 44,721건으로 전체 거래의 63%를 차지합니다. 학원·학교 밀도가 높은 동네에 서울 아파트 거래가 집중됩니다.
  2. 교육 접근성은 모든 가격대에 걸쳐 있다: C1은 평균가 11.68억으로 4개 클러스터 중 가장 낮습니다. 대치동(고가)과 중계동·노원·강북(중저가)이 같은 '교육 특화' 군집에 함께 속해 평균을 끌어내립니다.
  3. 조용한 저밀도 주거지가 실제 가격은 가장 높다: C2(저밀도 주거)는 거래량(2,025건)이 가장 적지만 평균 13.43억으로 집값 1위입니다. 이촌동처럼 밀도가 낮고 희소한 주거지에 프리미엄이 붙습니다.
  4. 같은 강남도 다르다: 신사동(C0, 상업·학원 복합)과 대치동(C1, 교육 특화)은 같은 강남구지만 완전히 다른 클러스터에 속합니다. 인프라 구성이 다르면 동네 성격도 다릅니다.
  5. PCA로 본 서울의 두 축: 서울 동네의 특성은 크게 '교육 인프라 축'과 '상권 집중 축' 두 가지로 설명할 수 있습니다.
  6. Decision Tree로 검증: 정확도 98.9%로, K-Means 군집이 임의로 나뉜 게 아니라 인프라 밀도로 설명되는 실제 패턴임을 확인했습니다.

실행 방법

환경 설정

git clone <repo-url>
cd DataMining-Project
pip install -r requirements.txt

노트북 실행 순서

1. notebooks/02_preprocessing/kmeans_prep.ipynb
   → 소상공인·학교·학원 밀도 계산, Log1p 변환, StandardScaler 정규화
   → 출력: data/processed/df_scaled.csv, df_density.csv

2. notebooks/03_modeling/kmeans.ipynb
   → Elbow Method + Silhouette Score로 최적 K 탐색 (K=4 선택)
   → K-Means 클러스터링 수행
   → 출력: data/processed/kmeans_result.csv
   → 시각화: notebooks/result/kmeans/k_selection.png, cluster_radar_k5.png, notebooks/result/pca/cluster_pca_k5.png

3. notebooks/03_modeling/price_cluster.ipynb
   → 아파트 실거래가 데이터와 클러스터 결과 병합 및 통계 분석
   → 출력: notebooks/result/kmeans/cluster_price.png, cluster_price_box.png

4. notebooks/03_modeling/cluster_decision_tree.ipynb
   → K-Means 군집 레이블로 Decision Tree 학습
   → 군집 판별 규칙 도출 및 유효성 검증
   → 출력: notebooks/result/decision_tree/dt_*.png

5. notebooks/04_visualization/viz_presentation.ipynb
   → 레이더 차트, 집값 비교, PCA 시각화, 요약 카드 생성
   → 출력: notebooks/result/kmeans/ (pres_radar, pres_price, pres_summary)
           notebooks/result/pca/       (pres_pca, pres_pca_explained, pres_pca_table)

notebooks/01_eda/ 노트북(store, school, academy, people)은 변수 탐색 참고용으로, 위 순서와 무관하게 실행 가능합니다.

notebooks/03_modeling/predict.ipynb은 인프라 밀도 → 집값 Ridge 회귀 보조 분석입니다.

경로 설정

모든 노트북은 .git 폴더를 기준으로 프로젝트 루트를 자동 탐색합니다. 별도의 경로 수정 없이 어느 위치에서 Jupyter를 실행해도 동작합니다.


프로젝트 구조

DataMining-Project/
├── data/
│   ├── raw/                          # 원본 CSV 데이터 (수정 금지)
│   │   ├── 소상공인.csv
│   │   ├── 학교.csv
│   │   ├── 학원.csv
│   │   ├── 토지 면적.csv
│   │   ├── 인구밀도.csv
│   │   └── 서울시_실거래가.csv
│   └── processed/                    # 전처리 결과물 (CSV만 유지)
│       ├── df_scaled.csv             # 정규화된 피처 데이터
│       ├── df_density.csv            # 법정동별 밀도 데이터
│       └── kmeans_result.csv         # 클러스터링 결과
├── notebooks/
│   ├── 01_eda/                       # 변수별 탐색적 분석 (참고용)
│   │   ├── store.ipynb
│   │   ├── school.ipynb
│   │   ├── academy.ipynb
│   │   └── people.ipynb
│   ├── 02_preprocessing/             # 전처리 및 스케일링
│   │   └── kmeans_prep.ipynb
│   ├── 03_modeling/                  # 모델링
│   │   ├── kmeans.ipynb              # K-Means 클러스터링
│   │   ├── price_cluster.ipynb       # 집값-군집 비교
│   │   ├── cluster_decision_tree.ipynb  # Decision Tree 분류
│   │   └── predict.ipynb             # Ridge 회귀 (집값 예측 보조)
│   ├── 04_visualization/             # 발표용 시각화
│   │   └── viz_presentation.ipynb
│   ├── common/                       # 공통 유틸리티
│   └── result/                       # 알고리즘별 시각화 결과
│       ├── kmeans/                   # K-Means 관련 이미지
│       │   ├── k_selection.png       # Elbow + Silhouette 그래프
│       │   ├── cluster_radar_k5.png  # 클러스터별 레이더 차트 (중간)
│       │   ├── cluster_price.png     # 클러스터별 평균·중앙값 집값
│       │   ├── cluster_price_box.png # 클러스터별 집값 박스플롯
│       │   ├── pres_radar.png        # 발표용 레이더 차트
│       │   ├── pres_price.png        # 발표용 집값 비교
│       │   └── pres_summary.png      # 클러스터 요약 카드
│       ├── pca/                      # PCA 관련 이미지
│       │   ├── cluster_pca_k5.png    # K-Means PCA 산점도 (중간)
│       │   ├── pres_pca.png          # 발표용 PCA 산점도
│       │   ├── pres_pca_explained.png # PCA 해석 슬라이드
│       │   └── pres_pca_table.png    # PCA 로딩 테이블
│       └── decision_tree/            # Decision Tree 관련 이미지
│           ├── dt_depth.png          # 트리 깊이 탐색
│           ├── dt_tree.png           # Decision Tree 시각화
│           ├── dt_confusion.png      # 혼동 행렬
│           └── dt_importance.png     # Feature Importance
├── requirements.txt
└── README.md

사용 라이브러리

라이브러리 용도
pandas 데이터 로드 및 처리
numpy 수치 연산, Log1p 변환
scikit-learn KMeans, PCA, DecisionTreeClassifier, StandardScaler, Ridge, silhouette_score
matplotlib 레이더 차트, 산점도, 트리 시각화 등

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages