Files
2nd/10_Wiki/Topic_Programming/Architecture/Experience-Sampling-Method.md
T
Antigravity Agent 9148c358d0 docs(10_Wiki): 위키 전체 재구성 — Topic_* 폴더를 4개 카테고리로 통합 + 대규모 중복 제거
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를
Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류.

- 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로
  자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거,
  동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거.
- 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming,
  Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business,
  Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로,
  나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는
  title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백).
  원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지.
- 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서.
- 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는
  지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지.
- Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경.
- 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
2026-07-05 00:33:48 +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 |