정성 코딩을 위한 전문 검색
단어를 언급하는 모든 인터뷰 발췌문이나 개방형 응답을 찾고, 코더가 일치하는 항목을 자신의 큐로 가져오게 합니다.
Potato는 서버를 시작할 때 모든 항목의 텍스트에 대해 전문 색인을 만들며, 관리자는 QDA 모드의 유무와 관계없이 어떤 프로젝트에서든 그 색인을 검색할 수 있습니다. copay를 검색하면 "copay"로 시작하는 단어를 포함한 각 인터뷰 발췌문이나 개방형 설문 응답이 반환됩니다. 결과는 관련도순으로 도착하며, 일치하는 단어는 짧은 스니펫에서 강조됩니다. 선택 설정 search.annotator_claim은 코딩 페이지에 Find 패널을 추가합니다. Find 패널에서 코더는 같은 색인을 검색하고 일치하는 항목을 자신의 큐로 청구합니다. 검색과 QDA 모드는 모두 Potato 2.6.0에 도입되었습니다.
FTS5는 SQLite의 전문 검색 확장입니다. SQLite는 Potato의 프로젝트 저장소 뒤에 있는 내장 데이터베이스입니다. Potato는 색인을 <task_dir>/project.sqlite의 테이블로 보관하며, 같은 파일에 메모와 코드북도 있습니다. 색인에는 항목의 단어가 들어 있습니다. 코드, 메모, 어노테이션은 색인 밖에 있으며, 검색은 찾은 구절에 코드를 적용하지 않습니다.
검색은 정성 프로젝트에서 두 가지 일을 합니다.
- 코딩할 구절 찾기. 주제별로 말뭉치를 훑는 코더는 "bus"나 "copay"를 검색하고, 그 단어를 언급하는 항목을 청구하며, span 스킴으로 관련 구절을 코딩합니다.
- 말뭉치 전반에서 용어 확인하기. 코드의 포함 기준을 쓰는 분석가나 판정자는 용어를 검색하여 어떤 항목이 그 용어를 사용하는지 확인합니다. 어떤 코더의 큐도 바뀌지 않습니다.
구성
검색에는 구성이 필요 없습니다. search 블록이 없는 프로젝트는 시작할 때 모든 항목을 색인하고 관리자 검색을 제공합니다. 아래 구성은 코더를 위한 검색 및 청구도 켜는 완전한 QDA 모드 프로젝트입니다.
annotation_task_name: Clinic access interviews
task_dir: .
output_annotation_dir: annotation_output/
data_files:
- data/interviews.json
item_properties:
id_key: id
text_key: text
admin_api_key: change-this-key
qda_mode:
enabled: true
search:
annotator_claim: true
annotation_schemes:
- annotation_type: span
name: codes
description: Highlight a passage and apply a code
codebook: true
labels: [access barriers, cost concerns, provider trust]QDA 모드는 한 명의 코더가 전체 말뭉치를 다룬다고 가정합니다. qda_mode.enabled: true에서 Potato는 어떤 배정 설계와도 annotator_claim을 받아들입니다. admin_api_key를 쓰면 스크립트나 명령줄에서 관리자 검색을 호출할 수 있습니다.
search 블록은 네 개의 키를 받습니다.
| 옵션 | 기본값 | 설명 |
|---|---|---|
search.enabled | true | 시작할 때 색인을 만들고 검색 엔드포인트를 제공합니다. false이면 Potato는 색인을 만들지 않고 관리자 검색은 503으로 응답합니다. |
search.backend | fts5 | 색인 엔진. fts5는 Potato 2.13.1의 유일한 백엔드입니다. 다른 값은 검색을 끄고 경고를 기록합니다. |
search.max_instances | 100000 | 색인되는 항목의 최대 수. Potato는 불러온 순서대로 상한까지 항목을 색인합니다. 상한을 넘은 항목은 색인 밖에 남으며, 서버 로그가 상한을 보고합니다. |
search.annotator_claim | false | 코더에게 Find 패널을 보여 주고 코더 검색 및 청구 엔드포인트를 제공합니다. 설정이 배정 설계와 충돌하면 Potato는 시작을 거부합니다(배정 가드 참조). |
누가 검색할 수 있는가
관리자 검색과 코더 검색은 서로 다른 엔드포인트를 통해 같은 색인을 읽습니다.
| 누가 | 엔드포인트 | 사용 가능한 경우 | 요청당 결과 |
|---|---|---|---|
| 관리자와 판정자 | GET /admin/api/search?q=<query>&limit=<n> | search.enabled가 true | 기본 50개, 최대 500개 |
| 로그인한 모든 코더 | GET /api/search?q=<query>&limit=<n>과 Find 패널 | search.annotator_claim: true | 기본 50개, 최대 200개. Find 패널은 50개를 요청함 |
| 로그인한 모든 코더 | {"instance_id": "<id>"}와 함께 POST /api/search/claim | search.annotator_claim: true | 요청당 항목 하나 |
관리자 접근은 X-API-Key 헤더의 관리자 API 키, 또는 역할이 관리자 대시보드를 허용하는 로그인 사용자를 뜻합니다. adjudication 블록이 활성화된 프로젝트의 판정자도 관리자 검색을 사용할 수 있습니다. 관리자 검색은 읽기 전용이며 어떤 큐도 바꾸지 않습니다. Potato 2.13.1에는 관리자 대시보드에 검색 상자가 없으며 관리자는 엔드포인트로 검색합니다.
curl -H "X-API-Key: change-this-key" \
"http://localhost:8000/admin/api/search?q=copay&limit=20"엔드포인트는 다음 형태의 JSON을 반환합니다.
{
"count": 1,
"query": "copay",
"results": [
{
"id": "P01-03",
"instance_id": "P01-03",
"score": -0.525,
"snippet": "My \u0002copay\u0003 went up again this year, so I skipped the follow…"
}
]
}스니펫은 항목에서 가장 잘 일치하는 부분 주변의 최대 12개 단어에 걸쳐 있으며 일치한 각 단어를 제어 문자 U+0002와 U+0003으로 표시합니다. Find 패널은 이 표시를 강조로 바꿉니다. score는 FTS5 BM25 순위입니다. 점수가 낮을수록 더 잘 일치하며, 결과는 가장 잘 일치하는 것부터 도착합니다. count는 반환된 결과의 수입니다. limit은 개수의 상한을 정하며, 응답은 상한을 넘어 일치하는 항목이 몇 개인지는 보고하지 않습니다.
쿼리 구문
Potato는 쿼리를 글자, 숫자, 밑줄이 아닌 모든 문자에서 나누고, 결과로 나온 모든 단어를 접두사로 포함하는 항목을 반환합니다. Potato는 쿼리를 FTS5에 쿼리 구문으로 전달하지 않습니다. 아래 규칙은 그 한 단계에서 나옵니다.
- 모든 단어가 나타나야 합니다.
bus line은 "bus"와 "line"을 모두 포함하는 항목에 순서와 거리에 관계없이 일치합니다. - 각 단어는 접두사로 일치합니다.
copay는 "copay", "copays", "copayment"와 일치합니다.care는 "care"와 함께 "career"와 "careful"에도 일치합니다. - 대소문자와 악센트는 무시됩니다.
Copay와copay는 같은 항목을 반환하며,cafe는 "café"와 일치합니다. - 문장 부호가 단어를 나눕니다.
self-care는 "self"와 "care"를 검색합니다.cost-of-care는 텍스트 어디에든 "cost", "of", "care"를 포함하는 모든 항목을 반환합니다. - 아포스트로피가 단어를 나눕니다.
couldn't는 "couldn"과 "t"를 검색합니다. "couldn't"를 포함하는 항목이 발견되며, 스니펫은 "t"로 시작하는 다른 단어도 강조합니다. - 연산자는 일반 단어입니다. 따옴표와
*는 제거되며,OR,NOT,NEAR는 항목이 포함해야 하는 단어가 됩니다.cost OR care같은 쿼리는 대개 아무것도 반환하지 않습니다. - 단어 형태는 합쳐지지 않습니다.
run은 접두사 규칙으로 "running"과 일치하며,ran은 "run"과 일치하지 않습니다. 참가자가 쓸 법한 각 형태를 따로 검색하세요.
색인되는 텍스트와 색인 재구축
Potato는 항목당 하나의 문자열을 다음 순서로 선택해 색인합니다.
item_properties.text_key(기본값text)가 지정한 필드.- 턴의 목록으로 저장된 전사본처럼
text_key아래의 목록이나 객체. Potato는 필드 이름을 포함해 코딩 페이지가 보여 주는 JSON 텍스트를 색인합니다. text_key아래에 쓸 만한 값이 없는 항목은caption,description,transcript,prompt,question,title,content,message중 비어 있지 않은 첫 번째 필드.
이 필드가 하나도 없는 항목은 색인 밖에 남으며, 서버 로그가 건너뛴 항목 수를 보고합니다. 캡션이 없는 이미지가 흔한 경우입니다. 항목 ID, participant_id 같은 케이스 필드, 그 밖의 항목 필드는 색인되지 않으며, 참가자 ID를 검색하면 아무것도 찾지 못합니다. 케이스는 발췌문을 참가자별로 묶습니다.
Potato는 서버를 시작할 때마다 색인 전체를 다시 만듭니다. data_directory에서 불러온 연구에서는 디렉터리를 불러온 뒤 Potato가 색인을 다시 만들며, 디렉터리 감시자는 새 파일이 도착하면 다시 색인합니다. Python 빌드의 SQLite에 FTS5가 없으면 Potato는 검색을 끄고, 검색 엔드포인트는 503으로 응답하며, 나머지 Potato는 정상적으로 실행됩니다.
검색 및 청구
Find 패널
search.annotator_claim: true이면 코딩 페이지에 Find 버튼이 나타납니다. Find 패널은 쿼리를 받아 최대 50개의 일치 항목을 나열하며, 각각 스니펫, 항목 ID, Claim 버튼이 있습니다. Claim은 항목을 코더의 큐 맨 끝에 추가하고 버튼을 "In your queue"로 바꿉니다. 이미 코더의 큐에 있는 항목에 대한 청구는 아무것도 바꾸지 않으며, 청구 엔드포인트는 "already_assigned": true를 보고합니다. 패널은 항목을 열지 않으며, 코더는 큐를 따라 앞으로 가면서 청구한 항목에 도달합니다.
청구 엔드포인트는 프로젝트의 모든 항목 ID를 받아들입니다. 다른 코더가 이미 가지고 있는 항목도 청구할 수 있습니다. 알 수 없는 ID는 404를 반환하고, 세션이 없는 요청은 401을, annotator_claim이 없는 프로젝트는 403을 반환합니다.
배정 가드
항목을 청구하는 코더는 표본을 선택하는 것이며, 많은 연구 설계는 Potato가 그 선택을 하는 데 의존합니다. search.annotator_claim: true이면 구성이 다음 중 하나도 설정하면 Potato는 시작을 거부합니다.
| 설정 | Potato가 거부하는 이유 |
|---|---|
assignment_strategy가 random, diversity_clustering, max_diversity, active_learning, llm_confidence, least_annotated, category_based, batch, psychometric, model_review, engine 중 하나 | 전략의 표본이나 순서는 Potato가 각 항목을 선택하는 데 의존합니다. |
1을 넘는 num_annotators_per_item, 1을 넘는 overlap_sample.count, 또는 1을 넘는 이전 키 max_annotations_per_item과 min_annotators_per_instance | Potato는 중복 항목이 여러 코더에게 도달함을 보장할 수 없습니다. |
attention_checks.enabled 또는 gold_standards.enabled | 코더가 확인 항목을 찾아 건너뛸 수 있습니다. |
icl_labeling.enabled | 모델을 위한 블라인드 검증 항목을 찾을 수 있게 됩니다. |
adjudication.enabled | Potato가 판정 큐를 선별합니다. |
expert를 제외한 모든 값의 crowdsourcing.provider, 또는 이전 prolific 또는 mturk 블록이나 로그인 유형 | 유급 작업이 배정 단위이며, 청구는 지급과 범위를 깨뜨립니다. |
가드는 배정 전략 fixed_order와 priority를 허용하며, fixed_order가 Potato의 기본값입니다. assignment_strategy: random과 num_annotators_per_item: 2가 있는 구성은 다음 메시지와 함께 검증에 실패합니다.
ERRORS:
- search.annotator_claim: true is incompatible with this configuration:
- assignment_strategy: random (self-selection breaks sampling/ordering)
- num_annotators_per_item: 2 (inter-annotator overlap cannot be guaranteed under self-selection)qda_mode.enabled: true 또는 solo_mode.enabled: true에서는 Potato가 위 표의 모든 검사를 건너뜁니다. 따라서 코더 간 신뢰도를 위한 중복 표본을 배정하는 QDA 모드 팀 프로젝트는 청구가 켜진 채로 시작하며, 그러면 코더는 Potato가 각 코더에게 배정한 표본 밖의 항목도 청구할 수 있습니다. 팀이 신뢰도 표본을 코딩하는 동안에는 annotator_claim을 꺼 두고, 코더가 자신의 항목을 고르는 것이 설계에 맞는다면 이후에 켜세요. 관리자 검색은 어떤 큐도 바꾸지 않으므로 가드 밖에 있습니다.
QDA 모드에서 코딩하면서 검색하기
말뭉치에서 용어를 검색한 다음 그 용어가 나타나는 각 구절을 코딩하는 연구자는 Potato에서 다음 단계를 따릅니다.
- Find를 열고
transport같은 용어를 검색합니다. 접두사 규칙은 "transportation"과 "transported"도 반환합니다. - 스니펫을 읽고 스니펫이 관련 있어 보이는 각 항목을 청구합니다.
- 청구한 각 항목이 큐에서 나타날 때 코딩합니다. 구절을 강조하고 코드북의 코드를 적용하거나,
i를 눌러 선택한 부분으로 인비보 코드를 만듭니다. - 항목이나 선택에 메모를 붙여 구절이 코드에 맞는 이유, 또는 아슬아슬하게 빗나간 것이 코드 밖에 있는 이유를 기록합니다.
검색은 항목당 하나의 스니펫과 함께 항목을 반환합니다. 용어를 다섯 번 언급하는 항목도 한 번만 나타나며, 전체 항목은 큐에서만 열립니다. Potato 2.13.1에는 모든 출현 위치의 키워드 문맥 목록도, 모든 검색 일치에 코드를 적용하는 단계도 없습니다. 각 코딩 결정은 구절을 읽는 코더에게 남습니다.
한계
- 항목 텍스트만. 코드, 메모, 어노테이션, 항목 ID, 색인된 텍스트 이외의 필드는 검색할 수 없습니다.
- 구문, 불리언, 근접, 어간 검색 없음. 모든 쿼리는 모두 나타나야 하는 접두사의 집합입니다.
- 항목당 하나의 스니펫. 스니펫은 최대 12개 단어이며, 용어가 몇 번 나타나든 항목은 한 번 나타납니다.
- 결과 목록 상한. 관리자 검색은 요청당 최대 500개 항목을, 코더 검색은 최대 200개를, Find 패널은 50개를 반환합니다.
- 띄어쓰기 없이 쓰는 언어. 중국어나 일본어 텍스트는 문장 부호 사이의 문자 연속으로 색인되며, 쿼리는 연속의 시작 부분에서만 일치합니다.
- 텍스트 없는 미디어. 이미지, 오디오, 비디오 항목은
text_key가 지정하거나 대체 필드에서 발견되는 캡션이나 전사 필드를 통해서만 색인됩니다.
업스트림 예제 프로젝트
Potato 체크아웃에서 업스트림 검색 예제를 시작하고 예제의 키로 관리자 엔드포인트를 쿼리하세요.
python potato/flask_server.py start examples/advanced/search-example/config.yaml -p 8000
curl -H "X-API-Key: search-example-key" \
"http://localhost:8000/admin/api/search?q=rare"이 예제는 여섯 개의 짧은 상태 보고서를 불러오며 그중 세 개가 "rare"를 언급합니다. 이 예제는 max_annotations_per_user: 2와 fixed_order 배정에서 검색 및 청구를 켭니다. 인터뷰 발췌문 프로젝트에서 Find 패널을 보려면 대신 examples/advanced/qda-mode-example/config.yaml의 QDA 모드 예제를 시작하세요.
더 읽을거리
- QDA 모드, 검색이 속한 작업 공간
- 코드북, 코더가 검색으로 찾은 구절에 적용하는 코드
- 메모, 항목과 선택에 대한 노트
- 작업 배정, 가드가 확인하는 배정 전략
- 인터뷰 전사문 코딩하기, 녹음부터 코딩된 발췌문까지의 전체 경로
구현 세부 사항은 소스 문서를 참조하세요.