[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -2,61 +2,163 @@
|
||||
id: wiki-2026-0508-ordinal-data-analysis
|
||||
title: Ordinal Data Analysis
|
||||
category: 10_Wiki/Topics
|
||||
status: needs_review
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [DATA-ORD-001]
|
||||
aliases: [Ordinal Analysis, Ordinal Regression, Ordered Categorical Analysis, Likert Analysis]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 1.0
|
||||
tags: ["Statistics|[Statistics", data-Analysis, ordinal-data, categorical-data, machine-learning, Feature-Engineering]
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [statistics, ordinal, regression, survey, likert]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-04-26
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
|
||||
tech_stack: { language: python, framework: scipy/statsmodels/sklearn }
|
||||
---
|
||||
|
||||
# Ordinal Data Analysis (순서형 데이터 분석)
|
||||
# Ordinal Data Analysis
|
||||
|
||||
## 📌 한 줄 통찰 (The Karpathy Summary)
|
||||
> "데이터 사이의 상대적인 '순서'와 '계층'을 보존하되, 그 간격이 일정하지 않음을 인정하며 통계적 질서를 세우라" — 범주(Category)들 사이에 명확한 순위나 등급이 존재하지만, 각 단계 사이의 수치적 거리가 일정하지 않은 데이터를 분석하고 처리하는 통계적 방법론.
|
||||
## 한 줄
|
||||
순서 정보는 있으나 간격은 정의되지 않은 데이터를 다루는 통계·ML 기법(Spearman, Kendall, ordinal regression).
|
||||
|
||||
## 📖 구조화된 지식 (Synthesized Content)
|
||||
- **추출된 패턴:** "Order-preserving Encoding and Rank Statistics" — '매우 만족(5), 만족(4), 보통(3)...'과 같이 순서 정보가 중요한 데이터를 처리할 때, 단순 범주형으로 취급하여 순서를 잃지 않으면서도 수치형처럼 거리 연산을 오용하지 않도록 순위 기반의 통계 기법(Spearman's Rho 등)이나 서열 인코딩(Ordinal Encoding)을 적용하는 패턴.
|
||||
- **주요 특징:**
|
||||
- **Relative Ranking:** 순서 관계($1 < 2 < 3$)는 명확함.
|
||||
- **Variable Intervals:** $2-1$의 의미와 $3-2$의 의미가 수학적으로 동일하지 않음.
|
||||
- **의의:** 고객 만족도 조사, 신용 등급 분류, 질병의 중증도 단계 등 실생활에서 흔히 접하는 계층적 정보를 AI 모델이 왜곡 없이 학습하게 하는 필수 전처리 지식.
|
||||
## 핵심
|
||||
- **Ordinal scale**: order O, distance X (예: 1=Poor … 5=Excellent).
|
||||
- 평균 사용 금지 — 중앙값/사분위수/mode 사용.
|
||||
- **상관**: Spearman ρ, Kendall τ (rank-based, 비모수).
|
||||
- **회귀**: ordinal logit (Proportional Odds), ordinal probit, ordinal forest.
|
||||
- **거리**: Manhattan on rank, Earth Mover's Distance.
|
||||
- 평가: MAE on rank, QWK(Quadratic Weighted Kappa).
|
||||
- 모델링 시 `OrdinalEncoder`는 단순 정수 → 잠재공간 가정 강함, 주의.
|
||||
|
||||
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
|
||||
- **과거 데이터와의 충돌:** 순서형 데이터를 단순히 수치형으로 변환하여 평균을 내는 오류를 범하기 쉬우나, 현대 분석에서는 누적 로짓 모델(Cumulative Logit Model) 등을 사용하여 순서형 데이터의 본질적 특성을 보존하는 모델링을 수행함.
|
||||
- **정책 변화:** Antigravity 프로젝트는 에이전트의 작업 결과에 대한 사용자 피드백(1~5점 척도)을 분석할 때, 산술 평균뿐만 아니라 순위 기반의 분포 분석을 병행하여 정교한 성능 개선 지표를 도출함.
|
||||
## 💻 패턴
|
||||
|
||||
## 🔗 지식 연결 (Graph)
|
||||
- Pre-Processing-Data-for-AI, [[One-Hot-Encoding|One-Hot-Encoding]], [[Exploratory-Data-Analysis|Exploratory-Data-Analysis]], Feature-Engineering-Best-Practices
|
||||
- **Raw Source:** 10_Wiki/Topics/AI/Ordinal-Data-Analysis.md
|
||||
```python
|
||||
# 1. Spearman / Kendall 상관
|
||||
from scipy.stats import spearmanr, kendalltau
|
||||
import numpy as np
|
||||
|
||||
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
|
||||
x = np.array([1, 2, 3, 4, 5, 5, 4, 3]) # 만족도 (1~5)
|
||||
y = np.array([10, 25, 40, 70, 95, 90, 60, 30]) # 사용 시간(분)
|
||||
|
||||
**언제 이 지식을 쓰는가:**
|
||||
- *(TODO)*
|
||||
rho, p1 = spearmanr(x, y)
|
||||
tau, p2 = kendalltau(x, y)
|
||||
print(f"Spearman ρ={rho:.3f} (p={p1:.4f})")
|
||||
print(f"Kendall τ={tau:.3f} (p={p2:.4f})")
|
||||
```
|
||||
|
||||
**언제 쓰면 안 되는가:**
|
||||
- *(TODO)*
|
||||
```python
|
||||
# 2. Ordinal Logistic Regression (statsmodels)
|
||||
import pandas as pd
|
||||
from statsmodels.miscmodels.ordinal_model import OrderedModel
|
||||
|
||||
## 🧪 검증 상태 (Validation)
|
||||
df = pd.DataFrame({
|
||||
"satisfaction": [1, 2, 3, 4, 5, 4, 3, 2, 5, 4], # ordinal target
|
||||
"age": [22, 35, 41, 28, 50, 33, 45, 24, 60, 39],
|
||||
"premium": [0, 0, 1, 0, 1, 1, 0, 0, 1, 1],
|
||||
})
|
||||
|
||||
- **정보 상태:** needs_review
|
||||
- **출처 신뢰도:** A
|
||||
- **검토 이유:** *(P-Reinforce Phase 1 자동 정규화. 본문 검증 필요.)*
|
||||
model = OrderedModel(
|
||||
df["satisfaction"],
|
||||
df[["age", "premium"]],
|
||||
distr="logit", # or "probit"
|
||||
)
|
||||
res = model.fit(method="bfgs", disp=False)
|
||||
print(res.summary())
|
||||
```
|
||||
|
||||
## 🧬 중복 검사 (Duplicate Check)
|
||||
```python
|
||||
# 3. sklearn-style: mord (ordinal regression)
|
||||
# pip install mord
|
||||
from mord import LogisticAT
|
||||
import numpy as np
|
||||
|
||||
- **기존 유사 문서:** *(TODO: 인덱서 클러스터 리포트 참조)*
|
||||
- **처리 방식:** UPDATE (자동 정규화)
|
||||
- **처리 이유:** Phase 1 정규화 — 옛 템플릿/누락 필드 보강.
|
||||
X = np.random.randn(200, 4)
|
||||
y = np.random.randint(1, 6, size=200) # 1..5 ordinal
|
||||
|
||||
## 🕓 변경 이력 (Changelog)
|
||||
clf = LogisticAT(alpha=1.0)
|
||||
clf.fit(X, y)
|
||||
print("Train acc:", clf.score(X, y))
|
||||
print("Pred:", clf.predict(X[:5]))
|
||||
```
|
||||
|
||||
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|
||||
|------|-----------|-----------|--------|
|
||||
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
|
||||
```python
|
||||
# 4. Quadratic Weighted Kappa (대표 ordinal 평가)
|
||||
from sklearn.metrics import cohen_kappa_score
|
||||
|
||||
y_true = [1, 2, 3, 4, 5, 3, 2, 4]
|
||||
y_pred = [1, 2, 4, 4, 5, 2, 2, 5]
|
||||
qwk = cohen_kappa_score(y_true, y_pred, weights="quadratic")
|
||||
print(f"QWK = {qwk:.3f}") # 1.0 = perfect, 0 = chance
|
||||
```
|
||||
|
||||
```python
|
||||
# 5. Likert 5점 척도 분포 시각화 (Diverging Bar)
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
likert = pd.DataFrame({
|
||||
"Q1": [10, 20, 15, 30, 25],
|
||||
"Q2": [5, 15, 25, 35, 20],
|
||||
"Q3": [40, 25, 10, 15, 10],
|
||||
}, index=["Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree"])
|
||||
|
||||
likert.T.plot(kind="barh", stacked=True, colormap="RdYlGn", figsize=(8, 3))
|
||||
plt.xlabel("% respondents")
|
||||
plt.tight_layout()
|
||||
```
|
||||
|
||||
```python
|
||||
# 6. Ordinal Encoder (주의: 거리 가정 강함)
|
||||
from sklearn.preprocessing import OrdinalEncoder
|
||||
|
||||
cats = [["Low"], ["Medium"], ["High"], ["High"], ["Low"]]
|
||||
enc = OrdinalEncoder(categories=[["Low", "Medium", "High"]])
|
||||
codes = enc.fit_transform(cats)
|
||||
print(codes.ravel()) # [0. 1. 2. 2. 0.]
|
||||
```
|
||||
|
||||
```python
|
||||
# 7. Mann-Whitney U (두 그룹 ordinal 비교)
|
||||
from scipy.stats import mannwhitneyu
|
||||
|
||||
group_a = [3, 4, 5, 4, 5, 5] # 신제품 평점
|
||||
group_b = [2, 3, 3, 4, 2, 3] # 구제품 평점
|
||||
|
||||
stat, p = mannwhitneyu(group_a, group_b, alternative="greater")
|
||||
print(f"U={stat}, p={p:.4f}")
|
||||
```
|
||||
|
||||
## 결정 기준
|
||||
|
||||
| 상황 | 권장 기법 |
|
||||
|---|---|
|
||||
| 두 ordinal 변수 상관 | Spearman ρ |
|
||||
| 동순위 많을 때 | Kendall τ-b |
|
||||
| ordinal target 회귀 | OrderedModel(logit) / mord LogisticAT |
|
||||
| 다중 그룹 비교 | Kruskal-Wallis |
|
||||
| 두 그룹 비교 | Mann-Whitney U |
|
||||
| 평가 지표 | QWK (대회 표준) |
|
||||
| 단순 ML feature 변환 | OrdinalEncoder + tree 모델 |
|
||||
|
||||
## 🔗 Graph
|
||||
- Related: `[[Statistics-Foundations]]`, `[[Regression-Models]]`, `[[Encoding-Categorical-Variables]]`, `[[Survey-Analysis]]`, `[[Likert-Scale]]`
|
||||
- Tools: `[[scipy]]`, `[[statsmodels]]`, `[[sklearn]]`
|
||||
|
||||
## 🤖 LLM 활용
|
||||
- 설문 자유응답 → LLM이 "5점 만족도"로 ordinal 정규화 → 통계 분석 결합.
|
||||
- 모델 평가에서 LLM 응답 품질을 1~5 ordinal로 라벨링한 뒤 QWK로 평가.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- ordinal에 mean 사용 (4.2 같은 평균은 해석 모호).
|
||||
- ordinal target에 일반 회귀(Linear/MSE) — 거리 비대칭 무시.
|
||||
- one-hot 인코딩으로 순서 정보 손실.
|
||||
- Pearson 상관으로 ordinal 비교 (선형성 가정 위배).
|
||||
|
||||
## 🧪 검증
|
||||
- Spearman/Kendall로 두 ordinal 컬럼 합리적 양의 상관 확인.
|
||||
- OrderedModel 추정 후 PR(predicted) vs actual confusion matrix가 대각 집중.
|
||||
- QWK > 0.6면 강한 ordinal agreement.
|
||||
|
||||
## 🕓 Changelog
|
||||
- 2026-05-08 Phase 1: 초안.
|
||||
- 2026-05-10 Manual cleanup: 코드 7개 패턴, QWK/diverging bar 추가.
|
||||
|
||||
Reference in New Issue
Block a user