Skip to content

Croksuter/Qi-Ai-2026-Winter-TeamE

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

7 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

KKBox Churn Prediction Project

KKBox μŒμ•… 슀트리밍 μ„œλΉ„μŠ€μ˜ 고객 μ΄νƒˆ(Churn) 예츑 ν”„λ‘œμ νŠΈμž…λ‹ˆλ‹€.

ν”„λ‘œμ νŠΈ κ°œμš”

λ°°κ²½

KKBoxλŠ” μ•„μ‹œμ•„ μ΅œλŒ€μ˜ μŒμ•… 슀트리밍 μ„œλΉ„μŠ€μž…λ‹ˆλ‹€. 이 ν”„λ‘œμ νŠΈλŠ” μ‚¬μš©μžμ˜ ꡬ독 행동 데이터λ₯Ό λΆ„μ„ν•˜μ—¬ λ‹€μŒ 달에 ꡬ독을 ν•΄μ§€ν•  κ°€λŠ₯성이 μžˆλŠ” μ‚¬μš©μžλ₯Ό μ˜ˆμΈ‘ν•˜λŠ” 것을 λͺ©ν‘œλ‘œ ν•©λ‹ˆλ‹€.

λΉ„μ¦ˆλ‹ˆμŠ€ κ°€μΉ˜

  • μ΄νƒˆ 예츑: μ΄νƒˆ κ°€λŠ₯성이 높은 고객을 사전에 νŒŒμ•…
  • νƒ€κ²Ÿ λ§ˆμΌ€νŒ…: 예츑된 μ΄νƒˆ κ³ κ°μ—κ²Œ λ§žμΆ€ν˜• ν”„λ‘œλͺ¨μ…˜ 제곡
  • 수읡 보호: 고객 μ΄νƒˆλ‘œ μΈν•œ 맀좜 손싀 λ°©μ§€

데이터 좜처

Kaggle - KKBox Churn Prediction Challenge


λΉ λ₯Έ μ‹œμž‘

1. ν™˜κ²½ μ„€μ •

# μ €μž₯μ†Œ 클둠
git clone <repository-url>
cd KKBox

# Python 버전 확인 (3.13 이상 ν•„μš”)
python --version

# μ˜μ‘΄μ„± μ„€μΉ˜ (uv μ‚¬μš©)
uv sync

2. 데이터 μ€€λΉ„

Kaggleμ—μ„œ 데이터λ₯Ό λ‹€μš΄λ‘œλ“œν•˜μ—¬ data/csv/ 폴더에 λ°°μΉ˜ν•©λ‹ˆλ‹€:

data/csv/
β”œβ”€β”€ raw_train_v1.csv
β”œβ”€β”€ raw_train_v2.csv
β”œβ”€β”€ raw_transactions_v1.csv
β”œβ”€β”€ raw_transactions_v2.csv
β”œβ”€β”€ raw_user_logs_v1.csv
β”œβ”€β”€ raw_user_logs_v2.csv
└── raw_members_v3.csv

3. 데이터 νŒŒμ΄ν”„λΌμΈ μ‹€ν–‰

# μ „μ²˜λ¦¬ νŒŒμ΄ν”„λΌμΈ μ‹€ν–‰
uv run python src/main.py

# ν”Όμ²˜ μ—”μ§€λ‹ˆμ–΄λ§ μ‹€ν–‰
uv run python src/feature-engineer.py

ν”„λ‘œμ νŠΈ ꡬ쑰

KKBox/
β”œβ”€β”€ README.md                 # ν”„λ‘œμ νŠΈ μ„€λͺ…μ„œ (ν˜„μž¬ 파일)
β”œβ”€β”€ pyproject.toml           # ν”„λ‘œμ νŠΈ μ„€μ • 및 μ˜μ‘΄μ„±
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ main.py              # 데이터 μ „μ²˜λ¦¬ νŒŒμ΄ν”„λΌμΈ
β”‚   β”œβ”€β”€ feature-engineer.py  # ν”Όμ²˜ μ—”μ§€λ‹ˆμ–΄λ§ νŒŒμ΄ν”„λΌμΈ
β”‚   └── code-guide.md        # μ½”λ“œ μŠ€νƒ€μΌ κ°€μ΄λ“œ
β”œβ”€β”€ data/
β”‚   β”œβ”€β”€ csv/                 # 원본 CSV 파일 (gitignore)
β”‚   β”œβ”€β”€ parquet/             # 처리된 Parquet 파일 (gitignore)
β”‚   β”œβ”€β”€ analysis/            # 뢄석 κ²°κ³Ό (히트맡, 차트 λ“±)
β”‚   └── data.duckdb          # DuckDB λ°μ΄ν„°λ² μ΄μŠ€ (gitignore)
└── .venv/                   # Python κ°€μƒν™˜κ²½ (gitignore)

데이터 νŒŒμ΄ν”„λΌμΈ 상세

전체 흐름도

[CSV νŒŒμΌλ“€]
     β”‚
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  1. CSV β†’ DuckDB λ‘œλ“œ                                        β”‚
β”‚     β€’ λŒ€μš©λŸ‰ CSVλ₯Ό 청크 λ‹¨μœ„λ‘œ 읽어 DuckDB ν…Œμ΄λΈ”λ‘œ μ €μž₯      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  2. ν…Œμ΄λΈ”λͺ… μ •κ·œν™”                                          β”‚
β”‚     β€’ train β†’ train_v1 (버전 λͺ…μ‹œ)                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  3. v1/v2 병합                                               β”‚
β”‚     β€’ train_v1 + train_v2 β†’ train_merge                     β”‚
β”‚     β€’ transactions, user_logs, members λ™μΌν•˜κ²Œ 처리        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  4. user_id λ§€ν•‘ 생성                                        β”‚
β”‚     β€’ msno(λ¬Έμžμ—΄ ν•΄μ‹œ) β†’ user_id(μ •μˆ˜) λ³€ν™˜                 β”‚
β”‚     β€’ λ©”λͺ¨λ¦¬ 효율 및 쑰인 μ„±λŠ₯ ν–₯상                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  5. 데이터 필터링                                            β”‚
β”‚     β€’ 5-1. 곡톡 user_id ꡐ집합 필터링                        β”‚
β”‚     β€’ 5-2. κΈ°μ€€ ν…Œμ΄λΈ” 기반 필터링                           β”‚
β”‚     β€’ 5-3. Churn 전이 기반 필터링 (v1=0 β†’ v2=0/1)           β”‚
β”‚     β€’ 5-4. 쀑볡 νŠΈλžœμž­μ…˜ μœ μ € μ œμ™Έ                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  6~8. 데이터 λ³€ν™˜                                            β”‚
β”‚     β€’ gender: male/female β†’ 0/1 μ •μˆ˜ λ³€ν™˜                   β”‚
β”‚     β€’ λ‚ μ§œ: YYYYMMDD μ •μˆ˜ β†’ DATE νƒ€μž… λ³€ν™˜                  β”‚
β”‚     β€’ 컬럼λͺ…: msno β†’ user_id 톡일                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  9. Parquet 내보내기                                         β”‚
β”‚     β€’ μ••μΆ•λœ Parquet 포맷으둜 μ €μž₯ (zstd)                    β”‚
β”‚     β€’ ML λͺ¨λΈ ν•™μŠ΅μ— λ°”λ‘œ μ‚¬μš© κ°€λŠ₯                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

μ£Όμš” ν…Œμ΄λΈ” μ„€λͺ…

ν…Œμ΄λΈ”λͺ… μ„€λͺ… μ£Όμš” 컬럼
train_merge ν•™μŠ΅ λ ˆμ΄λΈ” (μ΄νƒˆ μ—¬λΆ€) user_id, is_churn
transactions_merge 결제 νŠΈλžœμž­μ…˜ 기둝 user_id, payment_method_id, plan_list_price, transaction_date
user_logs_merge 일별 μ‚¬μš© 둜그 user_id, date, num_25, num_50, num_75, num_100, total_secs
members_merge νšŒμ› 정보 user_id, city, bd (λ‚˜μ΄), gender, registered_via

뢄석 ν•¨μˆ˜

ν•¨μˆ˜λͺ… μ„€λͺ… 좜λ ₯
analyze_churn_transition() v1β†’v2 μ΄νƒˆ μƒνƒœ 전이 뢄석 3x3 히트맡
analyze_duplicate_transactions() 쀑볡 νŠΈλžœμž­μ…˜ μœ μ € 뢄석 파이 차트
analyze_feature_correlation() ν”Όμ²˜ κ°„ 상관관계 뢄석 상관관계 히트맡

핡심 κ°œλ… μ„€λͺ… (λΉ„μ „κ³΅μžμš©)

Churn (μ΄νƒˆ)μ΄λž€?

  • ꡬ독 μ„œλΉ„μŠ€μ—μ„œ 고객이 ꡬ독을 ν•΄μ§€ν•˜λŠ” 것
  • is_churn = 1: μ΄νƒˆν•¨ (ꡬ독 ν•΄μ§€)
  • is_churn = 0: μœ μ§€ν•¨ (ꡬ독 지속)

μ™œ v1, v2κ°€ μžˆλ‚˜μš”?

  • v1: 2017λ…„ 2μ›” κΈ°μ€€ 데이터
  • v2: 2017λ…„ 3μ›” κΈ°μ€€ 데이터
  • 2μ›”(v1)에 μœ μ§€ν–ˆλ˜ 고객이 3μ›”(v2)에 μ΄νƒˆν•˜λŠ” νŒ¨ν„΄μ„ 예츑

user_logs의 num_25, num_50 등은 λ¬΄μ—‡μΈκ°€μš”?

  • num_25: 곑의 25% 미만 μž¬μƒ ν›„ μŠ€ν‚΅ν•œ 횟수
  • num_50: 곑의 25~50% μž¬μƒ ν›„ μŠ€ν‚΅ν•œ 횟수
  • num_75: 곑의 50~75% μž¬μƒ ν›„ μŠ€ν‚΅ν•œ 횟수
  • num_985: 곑의 75~98.5% μž¬μƒ ν›„ μŠ€ν‚΅ν•œ 횟수
  • num_100: 곑을 λκΉŒμ§€ μž¬μƒν•œ 횟수
  • num_unq: μž¬μƒν•œ 고유 곑 수
  • total_secs: 총 μž¬μƒ μ‹œκ°„ (초)

DuckDBλž€?

  • 파일 기반 λΆ„μ„μš© λ°μ΄ν„°λ² μ΄μŠ€
  • SQLite처럼 κ°€λ³μ§€λ§Œ λŒ€μš©λŸ‰ 뢄석에 μ΅œμ ν™”
  • 별도 μ„œλ²„ μ„€μΉ˜ 없이 파일 ν•˜λ‚˜λ‘œ λ™μž‘

기술 μŠ€νƒ

ꡬ뢄 기술 버전
Language Python 3.13+
Package Manager uv -
Database DuckDB 1.4+
Data Processing Pandas 2.3+
Visualization Matplotlib, Seaborn -
Progress Bar tqdm -

개발 κ°€μ΄λ“œ (νŒ€μ›μš©)

μ½”λ“œ μŠ€νƒ€μΌ

ν”„λ‘œμ νŠΈμ˜ μ½”λ“œ μŠ€νƒ€μΌμ€ src/code-guide.mdλ₯Ό μ°Έκ³ ν•˜μ„Έμš”.

μ£Όμš” κ·œμΉ™:

  • νƒ€μž… 힌트 ν•„μˆ˜
  • Google μŠ€νƒ€μΌ Docstring μ‚¬μš©
  • λ‘œκΉ…: μž‘μ—… μ‹œμž‘/μ™„λ£Œ μ‹œ === μž‘μ—…λͺ… === ν˜•μ‹
  • 숫자 포맷: {value:,} (천 λ‹¨μœ„ 콀마)

νŒŒμ΄ν”„λΌμΈ 단계별 μ‹€ν–‰

src/main.py의 __main__ λΈ”λ‘μ—μ„œ 주석을 ν•΄μ œν•˜μ—¬ νŠΉμ • λ‹¨κ³„λ§Œ μ‹€ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

if __name__ == "__main__":
    DB_PATH = "data/data.duckdb"

    # 1λ‹¨κ³„λ§Œ μ‹€ν–‰ν•˜λ €λ©΄:
    load_csv_to_duckdb(...)

    # λ‚˜λ¨Έμ§€λŠ” 주석 처리
    # rename_tables_add_v1_suffix(...)
    # create_merge_tables(...)

μƒˆ ν•¨μˆ˜ μΆ”κ°€ μ‹œ

  1. μ μ ˆν•œ μ„Ήμ…˜ 번호 λΆ€μ—¬ (예: 5-8, 6 λ“±)
  2. ꡬ뢄선 μΆ”κ°€:
    # ============================================================================
    # μ„Ήμ…˜λ²ˆν˜Έ. ν•¨μˆ˜ μ„€λͺ…
    # ============================================================================
  3. νƒ€μž… νžŒνŠΈμ™€ Docstring μž‘μ„±
  4. μž‘μ—… μ „/ν›„ 둜그 좜λ ₯

뢄석 κ²°κ³Ό μ €μž₯ μœ„μΉ˜

  • 이미지: data/analysis/
  • CSV: data/analysis/

μ•Œλ €μ§„ 데이터 이슈

1. total_secs μ˜€λ²„ν”Œλ‘œμš°

  • 문제: 일뢀 ν–‰μ—μ„œ total_secsκ°€ INT64 μ΅œλŒ€κ°’ (9.22e+15)
  • 원인: 원본 데이터 였λ₯˜ λ˜λŠ” μ˜€λ²„ν”Œλ‘œμš°
  • ν•΄κ²°: nullify_out_of_range() ν•¨μˆ˜λ‘œ 0~86400 λ²”μœ„ λ°– 값을 NULL 처리

2. bd (λ‚˜μ΄) 컬럼의 잘λͺ»λœ 해석

  • 주의: bdλŠ” 생년(birth year)이 μ•„λ‹ˆλΌ λ‚˜μ΄(age)
  • bd = 0: λ‚˜μ΄ 정보 μ—†μŒ (κ²°μΈ‘)
  • bd = 27: 27μ„Έ

3. gender κ²°μΈ‘ ν‘œμ‹œ

  • gender = -1: 성별 정보 μ—†μŒ
  • gender = 0: μ—¬μ„±
  • gender = 1: 남성

자주 λ¬»λŠ” 질문 (FAQ)

Q: 데이터 μ²˜λ¦¬μ— μ–Όλ§ˆλ‚˜ κ±Έλ¦¬λ‚˜μš”?

전체 νŒŒμ΄ν”„λΌμΈ μ‹€ν–‰ μ‹œ μ•½ 30λΆ„~1μ‹œκ°„ μ†Œμš” (ν•˜λ“œμ›¨μ–΄μ— 따라 닀름)

Q: DuckDB 파일이 λ„ˆλ¬΄ ν°λ°μš”?

처리된 data.duckdb νŒŒμΌμ€ μ•½ 35GBμž…λ‹ˆλ‹€. SSD μ‚¬μš©μ„ ꢌμž₯ν•©λ‹ˆλ‹€.

Q: νŠΉμ • λ‹¨κ³„λ§Œ λ‹€μ‹œ μ‹€ν–‰ν•˜κ³  μ‹Άμ–΄μš”

src/main.pyμ—μ„œ ν•΄λ‹Ή ν•¨μˆ˜μ˜ μ£Όμ„λ§Œ ν•΄μ œν•˜κ³  μ‹€ν–‰ν•˜μ„Έμš”.

Q: λ©”λͺ¨λ¦¬κ°€ λΆ€μ‘±ν•΄μš”

  • chunksize νŒŒλΌλ―Έν„°λ₯Ό μ€„μ΄μ„Έμš” (κΈ°λ³Έ 1,000,000 β†’ 500,000)
  • sample_size μ˜΅μ…˜μœΌλ‘œ μƒ˜ν”Œλ§ν•˜μ—¬ 뢄석

λΌμ΄μ„ μŠ€

이 ν”„λ‘œμ νŠΈλŠ” ꡐ윑 및 연ꡬ λͺ©μ μœΌλ‘œ μ‚¬μš©λ©λ‹ˆλ‹€. λ°μ΄ν„°λŠ” Kaggle Competition Rulesλ₯Ό λ”°λ¦…λ‹ˆλ‹€.


κΈ°μ—¬μž

  • 2026 QI AI Winter νŒ€

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages