Conversation
ho4040
left a comment
There was a problem hiding this comment.
PR #6 리뷰: Add SD4 files
SD4 (Short Dark Tetrad) 인벤토리 추가 PR을 리뷰했습니다. 전반적으로 기존 인벤토리 패턴(IPIP-NEO, REI)을 잘 따르고 있고, 구조가 깔끔합니다. 아래 몇 가지 피드백을 남깁니다.
잘 된 점
ADDING_INVENTORY.md가이드를 충실히 따른 구현benchmark_config.json,__init__.py, 인벤토리 클래스, 문항 JSON 4개 파일 구성이 정확함- 28개 문항이 4개 도메인(M, N, P, S)에 균등하게 7개씩 분배
@register_inventory("sd4")레지스트리 패턴 정확히 사용
수정 필요 사항
1. _load_config에서 레지스트리 키 하드코딩 문제
# 현재 (sd4.py)
inventory_key = "sd4"다른 인벤토리들은 버전을 포함하는 패턴을 사용합니다:
# ipip_neo.py
inventory_key = f"ipip_neo_{self.version}"
# rei.py
inventory_key = f"rei_{self.version}"그런데 benchmark_config.json의 키는 "sd4"로 되어 있어서 현재 코드는 동작하긴 합니다. 다만 일관성을 위해 둘 중 하나로 맞추는 것이 좋겠습니다:
- 방법 A: config 키를
"sd4_28"로 변경하고 코드에서f"sd4_{self.version}"사용 (다른 인벤토리와 일관됨, 권장) - 방법 B: 현재 상태 유지 (동작은 하지만, 향후 다른 버전 추가 시 문제 가능)
2. calculate_scores의 num_items 타입 불일치
# sd4.py (현재)
"num_items": len(scores), # int 반환
# ipip_neo.py
"num_items": len(scores), # int 반환
# rei.py
"num_items": float(len(scores)), # float 반환BaseInventory.calculate_scores의 반환 타입이 dict[str, dict[str, float]]로 선언되어 있으므로, num_items도 float(len(scores))로 하는 것이 타입 일관성에 맞습니다. (Pyright strict 모드에서 걸릴 수 있음)
3. _normalize_trait에서 .upper() 폴백 문제
# sd4.py (현재)
trait_code = trait_map.get(trait)
if trait_code is None:
trait_code = trait_map.get(trait.upper()) # "machiavellianism" -> "MACHIAVELLIANISM" (매칭 안 됨)trait_map에는 대문자 키("M")와 첫글자 대문자("Machiavellianism"), 소문자("machiavellianism")만 있으므로 .upper() 폴백은 단일 문자("m" -> "M")에만 유효합니다. 기존 인벤토리(REI)는 .lower() 폴백을 사용합니다:
# rei.py (기존 패턴)
trait_code = trait_map.get(trait)
if trait_code is None:
trait_code = trait_map.get(trait.lower()).lower() 폴백으로 변경하면 "MACHIAVELLIANISM", "Machiavellianism", "machiavellianism" 모두 처리됩니다.
선택적 개선 사항
4. 모집단 규준(population norms) 출처 확인
config에 population_mean/std가 설정되어 있는데(M: 3.62/0.65, N: 3.16/0.67 등), 원 논문(Paulhus et al., 2021)의 값과 일치하는지 확인 부탁드립니다. 이 값들이 mean_score 기준인지 raw_score(sum) 기준인지도 명확히 해주시면 좋겠습니다.
현재 calculate_scores에서 raw_score = sum(scores) (7문항 합산, 범위: 7~35)로 계산하는데, population_mean이 3.62 수준이면 이는 문항 평균(mean per item) 기준 값으로 보입니다. z-score 계산 시 raw_score(합계)와 population_mean(문항평균)이 단위가 다르면 결과가 부정확해집니다.
해결 방안:
- population_mean/std를 합산 점수 기준으로 변환 (예: mean = 3.62 * 7 = 25.34, std = 0.65 * sqrt(7) ≈ 1.72)
- 또는
calculate_scores에서mean_score를 기준으로 z-score 계산
5. 테스트 파일 누락
기존 패턴에 따르면 테스트 파일이 있으면 좋겠습니다. 최소한 등록 확인, 문항 수 검증, 점수 계산 테스트를 추가해주시면 좋겠습니다.
요약
| 항목 | 상태 |
|---|---|
| 파일 구조 | OK |
| 레지스트리 등록 | OK |
_load_config 키 일관성 |
수정 권장 |
num_items 타입 |
수정 권장 |
_normalize_trait 폴백 |
수정 필요 |
| population norms 단위 | 확인 필요 |
| 테스트 | 추가 권장 |
전체적으로 잘 작성되었으나 위 3~4가지를 수정하면 머지 가능할 것 같습니다!
ho4040
left a comment
There was a problem hiding this comment.
Changes Requested
전반적으로 잘 작성되었지만, population norms 단위 문제가 실제 점수 계산 정확성에 영향을 줄 수 있어 수정 요청드립니다.
핵심 이슈: population norms 단위 불일치
현재 benchmark_config.json의 population_mean/std 값:
- M: mean=3.62, std=0.65
- N: mean=3.16, std=0.67
- P: mean=2.14, std=0.76
- S: mean=2.88, std=0.81
이 값들은 문항 평균(mean per item) 기준으로 보입니다 (1~5 범위).
그런데 calculate_scores()에서는:
raw_score = sum(scores) # 7문항 합산 → 범위: 7~35
z_score = (raw_score - mean) / std # (25 - 3.62) / 0.65 = 32.9 ??합산 점수(7~35)에서 문항 평균(~3.62)을 빼면 z-score가 비정상적으로 커집니다.
해결 방안 (택 1)
A. config의 norms를 합산 점수 기준으로 변환:
"M": {
"population_mean": 25.34, // 3.62 * 7
"population_std": 1.72 // 0.65 * sqrt(7), 또는 원 논문의 합산 std 사용
}B. z-score 계산을 문항 평균 기준으로 변경:
mean_score = raw_score / len(scores) # 문항 평균
z_score = (mean_score - mean) / std원 논문(Paulhus et al., 2021)에서 어떤 기준으로 보고했는지 확인 후 맞춰주시면 감사하겠습니다.
SD4 관련 py/json 등의 정보를 업데이트하여 PR 드립니다.