Files
2nd/10_Wiki/Topics/Architecture/Experience-Sampling-Method.md
T
Antigravity Agent f8b21af4be Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리:
- 오류 캡처/미완성 stub 문서 227개 제거
- 교차폴더 중복 43클러스터 병합 (63파일 → redirect)
- 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건
- 카테고리 MOC 6개 신규 생성
- Graph 섹션 미해결 related-keyword 링크 10,058건 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:52:15 +09:00

211 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: wiki-2026-0508-experience-sampling-method
title: Experience Sampling Method
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [ESM, EMA, Ecological Momentary Assessment, Diary Studies]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [research-methodology, psychology, ux-research, mobile]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: react-native
---
# Experience Sampling Method
## 매 한 줄
> **"매 retrospection bias 의 in-the-moment self-report 의 replace"**. Experience Sampling Method (ESM, Csikszentmihalyi & Larson 1987) 매 participants 의 day 의 multiple times 의 random/scheduled prompt, 매 current activity/affect/context 의 record. Mobile-era 매 EMA (Ecological Momentary Assessment) 의 generalize — 매 mental health, UX, productivity research 의 gold standard.
## 매 핵심
### 매 Why ESM
- **Retrospection bias**: 매 "지난주 어땠나" 매 peak-end bias, mood-congruent recall 의 distort.
- **Ecological validity**: 매 in-context 매 lab 의 not-replicate.
- **Within-subject variance**: 매 person × situation 의 interaction 의 capture.
### 매 Sampling schedules
- **Signal-contingent**: 매 random beep 매 day 매 6-8 prompts.
- **Interval-contingent**: 매 fixed times (9am/12pm/3pm/6pm).
- **Event-contingent**: 매 specific event (meal, exercise) 의 trigger.
- **Hybrid**: 매 baseline random + event triggers.
### 매 응용
1. Mood / affect tracking (depression, bipolar).
2. Pain studies (chronic pain).
3. UX product research — feature use in-context.
4. Flow state research (Csikszentmihalyi original).
5. LLM agent behavior tracking — analog 매 process.
## 💻 패턴
### Mobile prompt scheduler (React Native)
```typescript
import * as Notifications from 'expo-notifications';
interface ESMConfig {
startHour: number; endHour: number;
promptsPerDay: number;
minIntervalMinutes: number;
}
async function schedulePrompts(cfg: ESMConfig, days = 7) {
const slots = generateRandomSlots(cfg, days);
for (const slot of slots) {
await Notifications.scheduleNotificationAsync({
content: {
title: 'Quick check-in (30s)',
body: 'How are you feeling right now?',
data: { promptId: slot.id, scheduledFor: slot.time.toISOString() },
},
trigger: { date: slot.time },
});
}
}
function generateRandomSlots(cfg: ESMConfig, days: number) {
const slots = [];
for (let d = 0; d < days; d++) {
const dayStart = new Date();
dayStart.setDate(dayStart.getDate() + d);
const windowMs = (cfg.endHour - cfg.startHour) * 3600_000;
const minGap = cfg.minIntervalMinutes * 60_000;
const times: number[] = [];
while (times.length < cfg.promptsPerDay) {
const candidate = Math.random() * windowMs;
if (times.every(t => Math.abs(t - candidate) >= minGap)) {
times.push(candidate);
}
}
times.sort((a, b) => a - b).forEach((offset, i) => {
const t = new Date(dayStart);
t.setHours(cfg.startHour, 0, 0, 0);
t.setTime(t.getTime() + offset);
slots.push({ id: `${d}-${i}`, time: t });
});
}
return slots;
}
```
### Brief response form (PANAS-short, 30s budget)
```typescript
interface ESMResponse {
promptId: string;
respondedAt: Date;
latencyMs: number;
affect: {
valence: number; // -3..+3
arousal: number; // -3..+3
};
activity: string; // dropdown: work | social | rest | exercise | other
social: 'alone' | 'with_others';
freeText?: string;
}
```
### Compliance tracking
```typescript
function complianceMetrics(responses: ESMResponse[], scheduled: number) {
const completed = responses.length;
const onTime = responses.filter(r => r.latencyMs < 15 * 60_000).length;
const meanLatency = responses.reduce((s, r) => s + r.latencyMs, 0) / completed;
return {
completionRate: completed / scheduled, // target > 0.7
onTimeRate: onTime / scheduled, // target > 0.5
meanLatencyMin: meanLatency / 60_000,
};
}
```
### Multilevel analysis (within vs between)
```python
import statsmodels.formula.api as smf
# 매 each row 매 prompt response, 매 participant_id 매 grouping
model = smf.mixedlm(
'valence ~ activity + social + time_of_day',
data=df,
groups=df['participant_id'],
re_formula='~time_of_day',
).fit()
print(model.summary())
# 매 within-person variance (situation) 매 between-person (trait) 의 separate
```
### Sliding-window mood detection
```typescript
function detectMoodEpisode(responses: ESMResponse[], windowDays = 7, threshold = -1.5) {
const sorted = [...responses].sort((a, b) =>
a.respondedAt.getTime() - b.respondedAt.getTime());
const episodes = [];
for (let i = 0; i < sorted.length; i++) {
const start = sorted[i].respondedAt;
const end = new Date(start.getTime() + windowDays * 86400_000);
const window = sorted.filter(r =>
r.respondedAt >= start && r.respondedAt <= end);
if (window.length < 5) continue;
const meanV = window.reduce((s, r) => s + r.affect.valence, 0) / window.length;
if (meanV < threshold) episodes.push({ start, end, meanV, n: window.length });
}
return mergeOverlapping(episodes);
}
```
### Privacy: 매 on-device aggregation
```typescript
// 매 raw responses 매 device 의 stay, 매 weekly summary 만 의 server 의 send
async function uploadWeeklySummary(responses: ESMResponse[]) {
const summary = {
week: getCurrentWeek(),
n: responses.length,
valenceMean: mean(responses.map(r => r.affect.valence)),
valenceStd: std(responses.map(r => r.affect.valence)),
activityHistogram: histogram(responses.map(r => r.activity)),
};
await api.post('/esm/summary', summary);
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Trait measurement (depression baseline) | 매 ESM unnecessary — 매 single questionnaire 매 fine |
| Within-day variation 의 question | 매 ESM signal-contingent |
| Specific event 매 rare | 매 event-contingent |
| Compliance fragile | 매 prompt count 의 reduce, 매 incentive |
| Privacy-sensitive (clinical) | 매 on-device aggregation 또는 federated |
**기본값**: 매 6-8 prompts/day, 매 14 days, 매 30s response — 매 compliance > 70% 의 target.
## 🔗 Graph
- 부모: [[Research-Methodology]]
- 변형: [[Ecological-Momentary-Assessment]]
- 응용: [[Flow_State|Flow-State]]
## 🤖 LLM 활용
**언제**: 매 in-the-moment subjective state 의 measure. Within-person variance 의 study. Retrospective bias 의 likely.
**언제 X**: 매 stable trait. 매 single-shot decision study. 매 intrusive sampling 매 acceptable 의 X.
## ❌ 안티패턴
- **Too many prompts**: 매 12+/day 매 fatigue → compliance crash.
- **Long forms**: 매 5min response 매 ecological 의 break.
- **Ignoring missing-not-at-random**: 매 prompts during depressive episode 매 skipped — 매 selection bias.
- **Cross-sectional analysis 의 hierarchical data**: 매 multilevel model 의 use, 매 OLS 의 std error 의 underestimate.
## 🧪 검증 / 중복
- Verified (Csikszentmihalyi & Larson 1987 JNMD; Shiffman et al. 2008 Ann Rev Clin Psych).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — ESM scheduler + analysis + privacy patterns |