Общий кодбук для качественного кодирования
Как задать, кто может добавлять, переименовывать, объединять и выводить из употребления коды, как изменение затрагивает уже закодированные фрагменты и где Potato записывает определения кодов и изменения.
Кодбук в Potato — это список кодов, которые применяют кодировщики проекта. Potato хранит кодбук в базе данных проекта, а не в YAML-конфигурации. Схема подключается к кодбуку через codebook: true, и после этого варианты схемы берутся из кодбука. Кодировщик может добавить код посреди сессии, и никому не нужно править конфигурацию или перезапускать сервер. Коды могут располагаться под родительским кодом, а запись каждого кода состоит из типизированных полей, среди которых определение, правила включения и исключения и примеры. Potato помечает каждую сохранённую разметку номером ревизии кодбука, действовавшей в момент сохранения. Кодбук появился вместе с QDA Mode в Potato 2.6.0 и работает в обычной разметке, в Solo Mode и в QDA Mode.
Кодбук в качественном исследовании перечисляет коды, которые применяет команда, и указывает, когда применяется каждый код. MacQueen и соавторы (1998) утверждают, что кодбук с одной и той же фиксированной структурой для каждого кода даёт команде кодировщиков устойчивую рамку и повышает согласованность между кодировщиками. Potato даёт каждому коду один и тот же набор типизированных полей, от краткого определения до контрпримеров. Руководство по разработке кодбука описывает, как команда пишет и пересматривает эти записи.
Хранение и начальное заполнение кодбука
- Хранение. Коды хранятся в
<task_dir>/project.sqlite. Заметки и кейсы используют ту же базу данных проекта. YAML содержит только начальные метки. - Начальное заполнение. При первом запуске сервера Potato копирует
labelsкаждой схемы с пометкойcodebook: trueв пустой кодбук. С этого момента источником истины служит база данных, и сервер игнорирует последующие правки меток в YAML. - Один кодбук на проект. Каждая схема с пометкой
codebook: trueпоказывает одни и те же коды. В проекте со схемойthemesи схемойquotesобе схемы берут коды из одного списка. - Типы схем.
radio,multiselect,selectиspanпринимаютcodebook: true. - Ревизии. Добавление, переименование, смена цвета, перемещение, удаление, объединение или разделение кода увеличивает номер ревизии кодбука проекта на единицу. Potato записывает ревизию в каждую разметку, сохранённую после этого.
- Где кодировщики видят кодбук. Переключатель Codebook у правого края страницы разметки открывает боковую панель со списком кодов и кратким определением каждого кода. Страница
/codebookпоказывает полный кодбук со всеми полями всех кодов.
Конфигурация
Конфигурация ниже настраивает кодирование интервью для команды в режиме extensible. Кодировщики могут добавлять коды по ходу чтения, а переименовывать и удалять коды может только арбитр. Две начальные метки записаны в объектной форме, и метка в объектной форме задаёт коду цвет и краткое определение.
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
user_config:
allow_all_users: true
codebook_mode: extensible
annotation_schemes:
- annotation_type: span
name: codes
description: Highlight a passage and apply a code
codebook: true
labels:
- name: access barriers
color: "#4682b4"
description: Anything the speaker names as standing between them and care they wanted.
- name: cost concerns
color: "#b44682"
description: Money, insurance, or the fear of a bill.| Параметр | По умолчанию | Описание |
|---|---|---|
annotation_schemes[].codebook | false | Берёт варианты схемы из кодбука проекта. |
annotation_schemes[].labels | (нет) | Заполняет пустой кодбук при первом запуске. Метка может быть строкой или объектом с name, color и description (или tooltip). Описание становится кратким определением кода. |
codebook_mode | open, если qda_mode.enabled или solo_mode.enabled равно true, иначе fixed | Кто может менять коды: fixed, extensible или open. Имеет приоритет над codebook.mode, если заданы оба. Любое другое значение не проходит валидацию. |
codebook.mode | как у codebook_mode | Вложенная запись codebook_mode. |
codebook.enabled | не задано | Включает или выключает боковую панель, страницу /codebook и API кодбука. Если параметр не задан, кодбук включается, когда какая-либо схема задаёт codebook: true, а также в QDA Mode или Solo Mode. В конфигурации, где задан codebook_mode, кодбук включён независимо от значения codebook.enabled. |
codebook.distiller.include (или include_types) | short_def, definition, use_when, avoid_when, example, counter_example | Какие поля каждого кода попадают в текст, который Potato добавляет в промпты разметки с ICL. |
codebook.distiller.include_doc_sections | preamble, general_instructions | Какие разделы уровня всего кодбука попадают в тот же текст промпта. |
codebook.distiller.scope | per_code | per_code добавляет поля каждого кода. whole_doc добавляет только разделы уровня всего кодбука. |
codebook.distiller.procedure | concat | Как собирается текст промпта. llm_summarize и select_icl_examples принимаются, но в 2.13.1 дают тот же результат, что и concat. |
codebook.distiller.max_chars | без ограничения | Обрезает текст промпта до заданного числа символов. |
codebook_invivo_key | i | Клавиша, которая открывает окно кодирования in vivo, пока в схеме span на основе кодбука выделен текст. Учитывается только первый символ. |
qda_mode.codebook.mode проходит валидацию. Potato 2.13.1 не читает этот ключ, когда решает, кто может редактировать коды. В QDA Mode задайте codebook_mode, чтобы изменить значение по умолчанию open.
Кто может менять коды
Что может делать вошедший в систему кодировщик, зависит от режима. Арбитр может вносить любые структурные изменения в режимах extensible и open. В режиме fixed ни кодировщики, ни арбитры не могут добавлять, переименовывать, перекрашивать, перемещать или удалять коды. Администраторы и арбитры по-прежнему могут объединять и разделять коды в разделе Curate боковой панели.
| Режим | Кодировщики могут | Типичное применение |
|---|---|---|
fixed | только применять коды | раунд проверки надёжности, краудсорсинг, кодбук, согласованный до начала кодирования |
extensible | добавлять коды | командное кодирование с согласованным ядром и местом для новых кодов |
open | добавлять, переименовывать, перекрашивать, перемещать и удалять коды, а также править определения | один аналитик или небольшая команда, которая разрабатывает кодбук вместе |
Для любой краудсорсинговой конфигурации Potato фиксирует режим fixed и записывает предупреждение в журнал, если конфигурация запрашивала больше. Potato вводит эту блокировку, чтобы набранные разметчики не перекраивали общий кодбук. Блокировка действует при crowdsourcing.provider с любым значением, кроме expert, при верхнеуровневом блоке prolific: или mturk: и при login.type: prolific или mturk. Нераспознанное имя провайдера и пустое значение провайдера тоже блокируют режим.
crowdsourcing.provider: expert сохраняет запрошенный режим, потому что экспертов приглашают поимённо. login.type: url_direct сам по себе сохраняет запрошенный режим и записывает предупреждение. Любой, у кого есть ссылка на такое исследование, может зарегистрироваться и затем редактировать открытый кодбук.
В 2.13.1 у каждого вида изменений свой путь:
| Изменение | В браузере | Через API | Кто |
|---|---|---|---|
| Добавить код | поле "Add a code" в боковой панели или клавиша in vivo | POST /api/codebook | extensible или open |
| Переименовать, перекрасить или переместить под родителя | в 2.13.1 элемента управления нет | PATCH /api/codebook/<id> | open или арбитр в extensible |
| Удалить код | в 2.13.1 элемента управления нет | DELETE /api/codebook/<id> | open или арбитр в extensible |
| Объединить один код с другим | раздел Curate боковой панели | POST /api/codebook/admin/merge | администратор или арбитр, в любом режиме |
| Разделить код по кодировщику | раздел Curate боковой панели | POST /api/codebook/admin/split | администратор или арбитр, в любом режиме |
| Изменить определение или добавить пример | карандаш у кода в боковой панели или /codebook | PUT /api/codebook/blocks | open или арбитр в extensible. Правка любого другого пользователя встаёт в очередь на подтверждение администратором или арбитром. |
Поле добавления в боковой панели создаёт код верхнего уровня. Код помещается под родителя через поле parent_id запроса POST или PATCH.
Кодирование in vivo по выделенному тексту
В схеме span с пометкой codebook: true кодировщик выделяет фрагмент и нажимает клавишу in vivo. Открывается небольшое окно с названием, взятым из выделенных слов (до 60 символов), и кнопка "Create & code" за один шаг добавляет код и выделяет фрагмент новым кодом. Пока кодировщик вводит название, существующие коды с похожими названиями появляются в виде плашек. Кодировщик, который выбирает плашку, применяет существующий код вместо того, чтобы создавать почти дубликат, например cost рядом с cost concerns.
Изменения, предложенные моделью
Модель никогда не меняет общий кодбук напрямую. Агент или модель в Solo Mode ставит изменение в очередь через POST /api/codebook/proposals с actor_kind: "model". Изменение ждёт в разделе Curate в виде фразы, например "Merge «cost» into «cost concerns»". Администратор или арбитр подтверждает или отклоняет предложение. Подтверждённое предложение проходит тот же путь, что и правка человека, и помечается в журнале изменений как исходящее от модели.
Вложенность кодов
Код с parent_id располагается под этим родителем, а родитель может располагаться под другим родителем. Перемещение, которое поместило бы код под одного из потомков этого же кода, завершается ошибкой. Добавление второго кода с тем же названием под одним родителем завершается такой же ошибкой. Удаление родителя удаляет все коды под этим родителем.
Боковая панель и /codebook показывают дерево. Форма разметки показывает коды одним плоским списком в порядке дерева, родители перед потомками. Вариант формы и сохранённая разметка хранят только название кода. Поэтому одно и то же название под двумя родителями появляется в форме дважды, и потом эти два кода невозможно различить. Делайте названия кодов уникальными во всём кодбуке.
В 2.13.1 CSV-экспорт codebook и экспорт .qdpx записывают коды схемы на основе кодбука плоским списком. Столбцы parent и color в CSV для этих кодов пусты. Иерархию кодов, нужную в другой программе, придётся восстановить в той программе или записать в названиях кодов.
Как изменения кодов влияют на сохранённое кодирование
Potato сохраняет каждое применение кода с названием кода в качестве метки в файле user_state.json кодировщика. Объединение или разделение никогда не удаляет строки из базы данных. Potato применяет каждое изменение кодбука только к самому кодбуку и никогда не переписывает сохранённую разметку:
- Добавление кода не меняет сохранённое кодирование.
- Переименование кода меняет форму с этого момента. Применения, сохранённые под старым названием, сохраняют старое название, и экспорт и статистика согласованности учитывают эти применения под старым названием. Переименовывайте код до начала раунда кодирования или перекодируйте затронутые фрагменты.
- Удаление кода убирает из формы этот код и все коды под ним. Сохранённые применения сохраняют название, и журнал изменений сохраняет название удалённого кода.
- Объединение архивирует исходный код. Архивированный код исчезает из формы, а строка кода и его история остаются в базе данных. Применения, сохранённые с исходным кодом, сохраняют название исходного кода.
- Разделение по кодировщику указывает одного кодировщика и новый или существующий целевой код. Разделение предназначено для случая, когда два кодировщика использовали одно название кода для разных вещей, и задумано так, чтобы переносить только применения указанного кодировщика. В 2.13.1 форма разметки не записывает связи по кодировщикам, которые переносит разделение. Поэтому разделение создаёт целевой код и архивирует исходный код для всех кодировщиков всякий раз, когда у исходного кода нет дочерних кодов. Сохранённые применения сохраняют название, выбранное каждым кодировщиком.
Potato сообщает кодировщикам об изменениях двумя способами. Во-первых, на фрагменте, сохранённом до добавления новых кодов, появляется баннер с названиями новых кодов. Во-вторых, список Review в боковой панели содержит каждый фрагмент, который кодировщик сохранил до последнего изменения любого рода. У каждого фрагмента в списке есть кнопка Go. Оба сигнала можно закрыть, и Potato никогда не заставляет перекодировать. Администратор или арбитр видит тот же список для всего проекта по адресу GET /api/codebook/admin/stale.
У правок определений отдельный счётчик. Правка краткого определения, определения, поля "Use when" или "Avoid when" кода повышает семантическую ревизию, и Potato записывает семантическую ревизию в каждую разметку, сохранённую после этого. Аналитик затем может разделить применения кодов, сделанные до и после изменения определения. Отметка Minor edit (no re-review) в редакторе /codebook сохраняет формулировку без повышения семантической ревизии. В 2.13.1 список Review отслеживает только структурные изменения.
Для раунда проверки надёжности задайте codebook_mode: fixed, потому что Potato вычисляет согласованность по сохранённым названиям кодов, и код, переименованный посреди раунда, превращается в два кода. Коэффициенты описаны на странице Согласованность разметчиков. Временная шкала согласованности на /admin/iaa отмечает каждую ревизию кодбука на графике согласованности во времени. Страница Дрейф согласованности объясняет, как читать эту шкалу.
Типизированные поля в записи каждого кода
Запись каждого кода — это список типизированных полей. /codebook — полностраничный редактор с историей версий для каждого кода, сравнением версий и восстановлением, которое сохраняет старую версию как новую версию. Кнопка "Paste markdown" превращает вставленный текст кодбука в поля по заголовкам и просит пользователя выбрать тип для любого раздела, который парсер не распознал. Два человека, одновременно сохраняющие один и тот же код, не перезаписывают правки друг друга. Второе сохранение завершается ошибкой и возвращает текущий текст для сверки.
| Поле | Заголовок в редакторе | Семантическое |
|---|---|---|
short_def | Short definition | да |
definition | Definition | да |
use_when | Use when | да |
avoid_when | Avoid when | да |
example | Examples | нет |
counter_example | Counter-examples | нет |
rationale | Rationale | нет |
background | Background | нет |
downstream_usage | Downstream usage | нет |
keywords | Keywords | нет |
notes | Notes | нет |
custom | собственный заголовок пользователя | нет |
У кодбука в целом есть четыре раздела вне кодов, с заголовками Preamble, General instructions, Background и How codes are used downstream. Боковая панель показывает краткое определение каждого кода, урезанное до двух строк. Если у кода нет краткого определения, боковая панель показывает полное определение.
Дистиллятор (distiller) превращает выбранные поля в текст, который Potato добавляет в промпты разметки с ICL, и пересобирает этот текст после каждого изменения кодбука. GET /api/codebook/distilled возвращает текст, который модель получает сейчас. Чтобы выбрать поля, добавьте блок codebook.distiller в конфигурацию выше:
codebook:
distiller:
include: [definition, use_when, avoid_when, example]
procedure: concatЗаполнение и перенос через CLI
potato codebook добавляет код для каждой метки каждой схемы codebook: true, которой ещё нет в кодбуке, и не трогает существующие коды:
potato codebook config.yamlКоманда печатает, сколько кодов создано и сколько уже было. Коды, созданные через CLI, получают одинаковый ID на любой машине, потому что CLI вычисляет каждый ID из названия проекта, родителя и названия кода. Запускайте CLI до первого запуска сервера, если ID должны совпадать между копиями проекта, потому что коды, созданные сервером при начальном заполнении, получают случайные ID. CLI копирует только названия. Цвета и определения из меток в объектной форме попадают в кодбук только при начальном заполнении сервером при первом запуске.
Поскольку сервер заполняет только пустой кодбук, добавить новые метки из YAML в кодбук, где уже есть коды, можно через CLI. Чтобы посмотреть результат без записи, запустите модуль напрямую. В 2.13.1 potato codebook --dry-run отбрасывает флаг и записывает коды.
python -m potato.codebook_cli config.yaml --dry-runAPI
Все маршруты находятся под /api/codebook и требуют сессии вошедшего пользователя. Административные маршруты принимают администратора или арбитра.
| Метод | Путь | Назначение |
|---|---|---|
| GET | /api/codebook | дерево, плоский список меток, ревизия, схемы на основе кодбука и значения can_add и can_edit вызывающего |
| GET | /api/codebook/version | структурная ревизия и ревизия содержимого для дешёвого опроса |
| GET | /api/codebook/similar?name= | существующие коды с названиями, близкими к name |
| GET | /api/codebook/provenance?instance_id= | предшествует ли кодирование одного объекта вызывающим текущей ревизии и какие коды добавлены с тех пор |
| GET | /api/codebook/stale | список Review вызывающего |
| POST | /api/codebook | добавить код (name, необязательные color и parent_id) |
| PATCH | /api/codebook/<id> | переименовать (name), перекрасить (color) или переместить (parent_id) |
| DELETE | /api/codebook/<id> | удалить код и все коды под ним |
| POST | /api/codebook/proposals | поставить изменение в очередь (op, payload, actor_kind) |
| GET | /api/codebook/admin/stale | список Review для каждого кодировщика (администратор) |
| POST | /api/codebook/admin/merge | объединить src_id с dst_id (администратор) |
| POST | /api/codebook/admin/split | перенести связи annotator с src_id на target_id или на новый код с названием new_name (администратор) |
| GET | /api/codebook/admin/changes | журнал изменений (администратор) |
| GET | /api/codebook/admin/proposals | ожидающие предложения (администратор) |
| POST | /api/codebook/admin/proposals/<id>/confirm | выполнить предложение (администратор) |
| POST | /api/codebook/admin/proposals/<id>/reject | отклонить предложение (администратор) |
Редактор определений использует GET /api/codebook/document, GET и PUT /api/codebook/blocks, POST /api/codebook/parse, GET /api/codebook/history, GET /api/codebook/history/<id>, POST /api/codebook/restore и GET /api/codebook/distilled. В QDA Mode /qda/codebook возвращает кодбук в режиме только для чтения.
Экспорт кодбука и история изменений
Экспорт codebook записывает codebook.csv, по одной строке на код для каждой схемы на основе кодбука, со столбцами schema, annotation_type, code, parent, description, color и n_uses. Экспорт читает базу данных кодбука. Коды, добавленные во время кодирования, включаются, а объединённые коды не включаются. description содержит краткое определение кода или полное определение, если у кода нет краткого. n_uses подсчитывает сохранённые применения по названию. Применение, сохранённое под названием, которого в кодбуке больше нет, не учитывается ни в одной строке.
python -m potato.export -c config.yaml --format codebook -o ./export/Экспорт quotation_report перечисляет каждый закодированный фрагмент вместе с кодом фрагмента. Экспорт qdpx передаёт коды и кодирование в другую программу QDA. Оба экспорта описаны на странице QDA Mode, а столбцы перечислены на странице Форматы экспорта.
История хранится в project.sqlite. Таблица codebook_change записывает каждое переименование, смену цвета, перемещение, удаление, объединение, разделение и подтверждённое или отклонённое предложение со старым и новым значениями, исполнителем, признаком того, был ли исполнитель человеком или моделью, и ревизией. В 2.13.1 переименование, смена цвета, перемещение или удаление через PATCH или DELETE записывается с исполнителем system, а добавленные коды появляются не в журнале, а в таблице codes с именем пользователя-создателя. GET /api/codebook/admin/changes возвращает журнал изменений в формате JSON.
codebook_snapshot хранит каждую сохранённую версию каждого определения, а codebook_revision_history записывает, когда произошла каждая ревизия. И снимок проекта, и архив из potato deploy pull включают project.sqlite. Любой из этих архивов служит журналом аудита кодбука для раздела о методах.
Запустите прилагаемый пример из checkout-копии Potato:
python potato/flask_server.py start examples/advanced/codebook-example/config.yaml -p 8000Пример кодирует пять комментариев пациентов о доступе к клинике с помощью открытого кодбука с множественным выбором из четырёх тем. examples/advanced/codebook-document-example/ добавляет блок дистиллятора. Откройте /codebook в этом примере, чтобы увидеть редактор определений.
Дополнительные материалы
- QDA Mode — кодбук вместе с заметками, кейсами и поиском
- Заметки — аналитические записи рядом с кодами
- Разработка кодбука для качественного исследования — как писать определения и пересматривать коды командой
- Надёжность кодирования в качественном исследовании — когда сообщать согласованность и какой коэффициент использовать
- Дрейф согласованности — согласованность во времени на фоне ревизий кодбука
Литература
MacQueen, K. M., McLellan, E., Kay, K., & Milstein, B. (1998). Codebook Development for Team-Based Qualitative Analysis. CAM Journal, 10(2), 31-36. https://doi.org/10.1177/1525822X980100020301
Подробности реализации см. в исходной документации.