Dementia Personalized Search
Personalized movement prediction and area-budgeted search alerts for dementia missing-person research.
치매 실종자 수색을 위한 개인화 이동 예측·면적 제한 알림 구역 선택 코드입니다. 서비스 가입이나 모델 API 없이 시작할 수 있는 작은 오프라인 예제를 제공합니다.
This is an Apache-2.0 code release, not model weights or a diagnostic model. It exposes the verified prediction-related source used in the Doraogil (돌아오길) service so researchers and developers can inspect, reuse and improve individual modules without knowing that application. Full production operation requires separately authorized models, RAG sources and map inputs.
Start with a guardian story / 보호자 설명부터 이해하기
**“보호자가 알려준 평소 행동을, 수색할 때 사용할 이동 가설과 조건별 행동 규칙으로 바꾸는 코드”**입니다. 지도 숫자는 그 뒤의 결과입니다.
합성 보호자 설명
“요즘도 집 근처 산책공원에 거의 매일 혼자 걸어가세요. 늘 다니던 길이에요. 예전 작업장은 오래전에 그만두셨고 요즘은 가지 않아요. 집 근처에서 짧게 걷고, 연속 12분 걸으면 다리가 아파 앉아서 4분 쉬어야 해요. 길을 잃었다고 알아차리면 가족이 올 때까지 그 자리에서 기다렸어요. 제가 데리러 갔어요. 어느 시장이든 시끄러우면 멀어지셨고, 조용할 때 반응은 잘 모르겠어요.”
예제의 검증 범위: 위 문장과 아래 의미 해석은 이해를 돕기 위해 직접 작성한 합성 예시입니다. K-EXAONE을 새로 호출해 받은 응답이 아닙니다. 아래 숫자 변환·규칙 컴파일·7개 상황의 규칙 판정 결과는 공개된 실제 코드로 실행했습니다. 보호자 문장을 수정하는 것만으로 새 해석이 생성되지는 않습니다.
English: This walkthrough connects an authored caregiver story to authored semantic interpretations, then to real deterministic compiler outputs. It makes zero model calls. It does not claim that the model generated these interpretations, that they are clinically validated, or that this offline script runs the full service.
1. 원문 → 의미 해석 → 실행 입력
| 보호자 근거 | 의미 해석 예시: K-EXAONE이 담당하는 단계 | 코드에 반영되는 입력 |
|---|---|---|
| “요즘도 공원에 거의 매일 혼자, 늘 다니던 길” | habitual_visit, routine_independent |
공원의 끌림 가중치, 경로 익숙함, 목적지 탐색 전략 비율 |
| “예전 작업장은 요즘 가지 않음” | historical_only; 경로 경험은 unknown |
지금의 반복 목적지로 승격하지 않음. 후보 장소에서 자동 삭제되는 뜻은 아님 |
| “집 근처 짧게 걷고, 12분 후 4분 휴식” | 보행 능력 B + 조건부 rest |
이동 능력·거리 분포 보정 + 보행 중 12분에 도달하면 4분 휴식 규칙 |
| “길 잃음을 인지하면 가족 올 때까지 대기” | 조건부 wait |
lost_awareness and not family_present; 가족 도착 시 이 대기 규칙 해제 |
| “제가 데리러 갔어요” | 이동 주체는 보호자 | 대상자가 가족에게 걸어가는 seek 규칙을 만들지 않음 |
| “시끄러운 시장을 피함; 조용할 때는 모름” | 조건부 시장 회피, 조용할 때 unknown |
시장 근처에서 소음이 참일 때 회피. 시장 위치만으로 소음이 있다고 가정하지 않음 |
원문은 질문·답변과 N0~N4 근거 ID로 연결합니다. 모델이 의미·조건을 해석하고, 코드는 허용된 필드를 검증해 수치와 실행 규칙으로 변환합니다. 문장에서 키워드만 찾아 파라미터를 정하는 예제가 아닙니다. 원문·의미 계약 전체는 guardian_input.json에 있습니다.
2. 개인화 파라미터: 실제 코드의 전후 결과
이 예제의 시작 분포는 설명용으로 직접 지정한 숫자입니다. SAR LoRA 실응답이나 논문에서 추출한 수치가 아닙니다. 운영에서는 SAR 초기 수치와 저장된 개인 해석이 이 단계에 연결됩니다.
| 파라미터 | 설명용 초기값 | 개인 해석 적용 후 실제 출력 | 뜻 |
|---|---|---|---|
landmark_seeking |
0.200000 | 0.333333 | 반복 목적지 근거로 목적지 탐색 비중을 높이고 전체 전략을 재정규화 |
random_walk |
0.250000 | 0.208333 | 전체 전략을 재정규화한 결과 |
route_following |
0.150000 | 0.125000 | 경로 익숙함 0.9와 별개의 전략 분포; 익숙함 상승이 이 비율 상승을 뜻하지 않음 |
direction_keeping |
0.100000 | 0.083333 | 같은 방향 유지 관찰을 새로 만들지 않음 |
backtracking |
0.150000 | 0.125000 | 재정규화 결과 |
staying_put |
0.150000 | 0.125000 | 조건부 대기를 모든 상황의 고정 대기 성향으로 바꾸지 않음 |
attraction_weights: 공원 / 예전 작업장 |
0.5 / 0.5 | 0.6 / 0.4 | 후보 간 상대 끌림. 한 장소 독식을 제한하는 기존 상한 적용 |
공원 route_familiarity.score |
미지정 | 0.9 | 익숙한 경로의 독립 이동이라는 등급의 코드 매핑 |
mobility_transport_capacity |
미지정 | 0.3 | 보행 등급 B의 코드 매핑. 30%의 보행 성공률이 아님 |
radius_lognormal |
μ=0.0, σ=0.8 | μ=-0.4, σ=0.8 | 이 예제 기준 거리 중앙값은 약 0.67032배. 수색 면적 상한과 다른 값 |
이 수치들은 엔진의 잠정 변환 규약이며 임상 점수·발견 확률이 아닙니다. 작업장 0.4도 실제 방문 확률 40%라는 뜻이 아닙니다. 축 채점 기능 OFF여도 개인 해석의 보행 등급이 이동 능력 입력으로 연결되는 경로는 남습니다. 근거가 없는 다른 축을 새로 채점하지 않습니다.
3. 마음 행동 규칙: 언제 무엇을 실행하나
아래 JSON은 합성 의미 해석 파일의 authored_mind_interpretation.rules입니다. 설명용으로 작성한 모델 출력 형식이며, 모델의 실제 생성 응답은 아닙니다.
[
{
"action": "rest",
"goal_place": "",
"applies_only_at": [],
"condition": "is_walking and continuous_walk_minutes >= 12",
"hold_minutes": 4,
"note_ids": [
"N2"
]
},
{
"action": "wait",
"goal_place": "",
"applies_only_at": [],
"condition": "lost_awareness and not family_present",
"hold_minutes": 0,
"note_ids": [
"N3"
]
},
{
"action": "avoid_market",
"goal_place": "",
"applies_only_at": [],
"condition": "market.noisy",
"hold_minutes": 0,
"note_ids": [
"N4"
]
}
]
실제 컴파일러는 이를 when 조건 배열과 rest·wait·avoid 명령으로 바꾸고, 각 규칙에 근거 답변 원문을 연결합니다. hold_minutes: 0은 컴파일 후 null로, 시간 미지정을 뜻합니다. wait는 가족 도착 등 조건 변화로 해제되며 0분 대기라는 뜻이 아닙니다.
| 합성 상황: 나머지 조건은 비활성으로 지정 | 실제 규칙 판정 결과 |
|---|---|
| 평상시 5분 보행 | 발동 규칙 없음; 기본 개인화 보행 유지 |
| 계속 걷는 중 12분에 도달 | a_0: rest, hold_minutes=4 |
| 이미 쉬는 중 | 새 보행 휴식 조건은 비활성. 진행 중인 휴식 유지·종료는 별도 보행 실행기가 관리 |
| 길 잃음 인지 + 가족 없음 | a_1: wait |
| 길 잃음 인지 + 가족 도착 | 이 대기 규칙 비활성; 관찰되지 않은 후속 목적지를 만들어 내지 않음 |
| 시장 근처 + 소음 관측 참 | a_2: avoid, feature=market |
| 시장 근처 + 소음 미확인 | 확정 발동 없음, a_2는 가능한 규칙으로 보존 |
이 실행은 규칙의 컴파일과 발동 조건 판정까지 확인합니다. 4분 동안의 실제 입자 보행이나 전체 경로 시뮬레이션은 이 스크립트에서 실행하지 않습니다. 조건 미확인은 거짓과 다르며, 전체 엔진은 가능한 분기와 그 가중 규약을 따로 처리합니다. 지도상 시장이라는 사실은 실제 소음·혼잡 관측이 아닙니다. 마음 규칙은 이후 보행 중 코드로 평가하며 매 걸음 모델을 호출하지 않습니다.
4. 이 결과가 지도와 30:70으로 이어지는 위치
보호자 문답·원문 근거
↓ 서비스에서는 K-EXAONE 의미 해석·규칙 준비
↓ 이 오프라인 예제에서는 그 형식의 합성 해석을 직접 제공
SAR 초기 수치 + 개인 해석 → 개인화 파라미터
조건부 마음 규칙 → 보행 상황에 따라 휴식·대기·회피
↓ 도로·시간·사건 시작점이 있어야 보행 지도 계산 가능
개인화 보행 지도 30% + 독립 문헌 거리 지도 70%
↓ 결합 확률을 면적당 밀도로 평가
res9 / 실제 알림 구역 면적 최대 5.8 km²
30% 안에는 개인화 파라미터와 마음 규칙의 영향이 함께 들어갑니다. 70%는 개인 파라미터를 넣지 않은 독립 문헌 거리 지도입니다. 30:70은 두 지도의 혼합 비율입니다. 위 전략 비율·장소 끌림 가중치와는 서로 다른 층의 숫자입니다.
이 예제는 도로망·SAR 가중치·K-EXAONE 서비스를 포함하지 않으므로 아래 지도 예제와 자동으로 연결된 E2E 실행은 아닙니다. 아래 지도 예제의 확률 숫자 역시 별도로 작성한 합성 입력입니다.
직접 실행 / Run the compiler example
저장소를 내려받은 뒤 실행합니다. Python 3.14 / Pydantic 2.13.4에서 확인했습니다.
python -m pip install -r requirements-guardian-example.txt
python examples/guardian_example.py --check
- 질문·답변, 의미 해석, 시작 파라미터, 7개 상황
- 실제로 생성한 파라미터·규칙·상황별 출력 전체
- 재현 스크립트
- 실제 변환 코드: person_projection.py, mind_policy_guarded_core.py, mind_policy.py
--check는 저장된 기대 출력과 다시 계산한 결과의 일치를 확인합니다. 의미 해석의 정확성을 평가하는 테스트는 아닙니다. 모델 실호출 예제로 확장하려면 출처와 공개 권한이 확인된 모델·검색 자료를 연결하고, 실제 입력·모델 버전·실행 조건·출력·오류를 별도로 기록해야 합니다.
Next: offline area selection
git clone https://huggingface.co/Damisoda/Dementia-Personalized-Search
cd Dementia-Personalized-Search
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements-example.txt
python examples/offline_selection.py
The example creates an illustrative H3 grid around the public KINTEX study region, combines a toy personal map (30%) and toy background map (70%), and calls the unchanged production area selector with res9 and a 5.8 km² cap. It prints selected cell count, actual selected area and captured toy probability mass. It performs no API calls, model inference, road download or notification delivery. The toy distributions are for learning the interface; they are not the evaluated SAR/literature priors, real patient data or a performance benchmark. Python 3.14 with the pinned example dependencies was checked in the release environment.
The source files are directly browsable in src/; source-snapshot.zip is an optional frozen download of the same source and example.
Input → output examples / 입출력 예시
Synthetic, executable examples of the map-combination and area-selection modules. These inputs are already-computed probability maps, not guardian conversations or actual SAR/K model responses. All example H3 cells are near the public KINTEX study region. No patient data, external calls, model inference or real push delivery is used.
python examples/io_examples.py --check
# Supply the same list-of-cases JSON format for your own offline maps:
python examples/io_examples.py --input examples/io_inputs.json
Input: a small area budget
The tight_budget fixture below uses 0.15 km² only to make cell exclusion visible. The documented service setting remains 5.8 km² / res9 / personal 30% + independent literature 70%.
{
"personal_map": {
"8930e0b5b13ffff": 0.8,
"8930e0b5b03ffff": 0.15,
"8930e0b5b17ffff": 0.05
},
"background_map": {
"8930e0b5b13ffff": 0.1,
"8930e0b5b03ffff": 0.3,
"8930e0b5b17ffff": 0.6
},
"weights": [
0.3,
0.7
],
"target_res": 9,
"area_cap_km2": 0.15,
"max_cells": 3
}
| Input | Meaning |
|---|---|
personal_map |
H3 cell → probability from personalized walking; toy values here |
background_map |
H3 cell → independent background probability; toy values, not the actual literature fit |
weights |
[personal, background]; two finite nonnegative values summing to 1 |
target_res |
H3 delivery resolution; fixtures use 9 and require input cells at that resolution |
area_cap_km2 |
Upper bound on actual delivery coverage in square kilometres |
max_cells |
Maximum number of selected source cells; a count, not square kilometres |
Each map must be nonempty, use valid H3 cells and have finite nonnegative probabilities summing to 1. A cell absent from one map contributes zero from that map. The example wrapper validates this narrow input contract; it is not a documented HTTP endpoint or a replacement for the complete service schemas.
Actual output from the frozen production modules
{
"status": "ok",
"combined_map": {
"8930e0b5b03ffff": 0.255,
"8930e0b5b13ffff": 0.31,
"8930e0b5b17ffff": 0.435
},
"selected_source_cells": [
"8930e0b5b17ffff",
"8930e0b5b13ffff"
],
"delivery_cells": [
"8930e0b5b13ffff",
"8930e0b5b17ffff"
],
"area_km2": 0.14423,
"captured_probability_mass": 0.745,
"excluded_cells": [
"8930e0b5b03ffff"
]
}
For cell 8930e0b5b13ffff, the mixed probability is 0.3 × 0.8 + 0.7 × 0.1 = 0.31. The selector ranks probability per square kilometre, accounting for actual cell area. In this fixture, two cells fit in 0.15 km² and the third is excluded.
| Output | Meaning |
|---|---|
combined_map |
Normalized 30:70 probability distribution; values rounded to six decimals in this wrapper |
selected_source_cells |
Cells returned by the production selector, in selection order |
delivery_cells |
Sorted union of target-resolution coverage used to calculate the area |
area_km2 |
Actual selected coverage, not the requested maximum |
captured_probability_mass |
Sum of the toy input distribution inside selected cells; not accuracy, recall, a patient-finding rate or calibrated confidence |
excluded_cells |
Candidate cells not in delivery coverage; they receive no eligibility from this example's selection |
The production alpha_pool(...) returns a dictionary and select(...) returns a cell list. The JSON object shown above is produced by the teaching wrapper examples/io_examples.py; it is not a model-generated answer. See the exact inputs and all expected outputs.
Four runnable cases
| Case | Area cap | Expected result |
|---|---|---|
normal_budget |
5.8 km² | All three toy cells, area 0.216347 km², toy mass 1.0; a cap need not be filled |
tight_budget |
0.15 km² | Two cells, area 0.144230 km², toy mass 0.745 |
zero_budget |
0 km² | No selected/delivery cells, area and captured mass 0 |
invalid_negative_budget |
-1 km² | ValueError: area budget must be finite and nonnegative |
--check reruns the real map combiner and selector and compares every result with the committed output file. Error cases are serialized by the example wrapper; production select raises the exception directly. The examples use six-decimal output rounding and the pinned dependencies in requirements-example.txt.
Larger offline example: actual console output
python examples/offline_selection.py produces:
{
"example_only": true,
"not_a_performance_benchmark": true,
"source_cells": 331,
"selected_delivery_cells": 80,
"area_km2": 5.770239942512572,
"area_cap_km2": 5.8,
"captured_toy_probability_mass": 0.5340048014828218,
"model_calls": 0,
"map_downloads": 0,
"notifications": 0
}
Tiny last-digit floating-point differences may occur across environments. These are module examples, not the separately evaluated final-system benchmark. Guardian evidence → K-EXAONE interpretation → walking requires the external components described below; invented model responses are not presented as tested end-to-end outputs here.
What can I reuse?
Module under src/app/ |
Role |
|---|---|
phase2/combine.py |
Combine probability maps; the example uses linear pooling |
phase3/area_budget.py + geo/h3cover.py |
Select cells by probability density under actual alert coverage area |
phase2/literature_distance.py |
Independent distance-based background prior |
phase0/person_preparation.py + phase2/person_projection.py |
Preserve personal interpretation and project it into movement parameters |
phase0/mind_preparation.py + llm/mind_policy.py |
Prepare and validate conditional behavior rules |
phase2/person_walk.py, phase2/persistent_context_walk.py, phase2/continuous_prediction.py |
Personalized walking and checkpoint reuse |
The snapshot includes 84 source files, including supporting/legacy imports. Presence of a module is not proof it runs in the demonstrated path. See the deployment provenance, source hashes, and demo configuration.
What does 30:70 mean?
In the documented service configuration, SAR generates initial numeric values. Saved K-EXAONE personal interpretation and conditional behavior rules affect the personal walking map (30%). The independent literature-distance map (70%) has no personal parameters. The maps are mixed before selecting alert cells at H3 res9 within 5.8 km². These are probability-map mixture weights, not percentages of users, model accuracy, or proportions of code.
Axis scoring is OFF. Prepared behavior rules execute in code while walking; they do not require a model call per particle. Live model failures and unsupported map areas can trigger fallback paths. Full pipeline setup is an integration task; the quick start only demonstrates the reusable selector.
Contribute
See CONTRIBUTING.md. Useful first contributions include documented input contracts, edge-case tests for geographic area accounting, portable offline examples, and clearer uncertainty explanations. Use the Community tab for issues and pull requests. Keep the frozen service source identifiable when proposing improvements.
Evidence and limitations
The source files match the final service snapshot byte-for-byte; adding documentation and this example does not change that engine. This repository does not distribute the SAR adapter, training QA, RAG papers, full road graph or evaluation maps because they have separate publication-rights checks. It does not claim that the entire model-to-walk evaluation can be regenerated from this code-only release.
This is research software, not a dementia diagnosis tool, clinical validation or a guarantee of locating a missing person. Synthetic evaluation is not a real-world recovery rate. Any use involving people requires appropriate validation, lawful data access and operational oversight. Do not upload personal profiles, precise live locations, credentials, or patient records to community issues.
License and origin
Team-owned source, this example and accompanying original documentation are licensed under Apache-2.0. NOTICE retains attribution; dependencies and external data keep their own terms. Model weights and provider services are not covered by the code license. The original deployment is the Come-back-home project, documented here as provenance rather than a requirement to use its service.