Краудсорсинг позволяет размечать данные для разных задач, но популярнее всего, конечно, задачи классификации объектов — текстов и картинок. Обычно в краудсорсинге несколько человек размечают каждый объект, что требует агрегации — выбора верного ответа из представленных. Под катом я покажу, как агрегировать результат разметки с помощью двух алгоритмов: голоса большинства и алгоритма Дэвида-Скина.
Я буду использовать Crowd-Kit — нашу открытую библиотеку вычислительных методов контроля качества в краудсорсинге, которая предлагает реализации разных методов агрегации ответов, оценки неопределённости и согласованности ответов и т. д. Но вы можете воспользоваться альтернативами: spark-crowd (использует Scala вместо Python), CEKA (Java вместо Python) или Truth Inference (использует Python, но предоставляет только категориальные и числовые ответы).
Писать код буду в Google Colab, но любая другая среда для Python тоже подойдёт. Сначала нужно установить библиотеку Crowd-Kit из PyPI. Кроме того, мне понадобятся размеченные данные — буду использовать открытые данные Толоки о релевантности поисковых ответов с двумя категориями: релевантные и нерелевантные. Загрузчиком данных будет сам Crowd-Kit, чтобы скачать их в виде таблиц pandas. Опять же, вы можете использовать другой источник данных и собрать таблицы самостоятельно.
Итак, данные загружены — прежде чем двинуться дальше, давайте взглянем на них.
475536 rows x 3 columns
Функция load_dataset возвращает пару элементов. Первый элемент — это таблица pandas с данными, полученными из краудсорсинга. Второй элемент (если он имеется) — это данные с верными ответами (ground truth). Таблица
Импортируем три класса агрегации: мнение большинства, Wawa и Дэвид-Скин. Давайте попробуем агрегировать с помощью мнения большинства — простого эвристического метода.
Создадим экземпляр класса с реализацией мнения большинства и вызовем метод
Эта простая эвристика работает очень хорошо, особенно на небольших наборах данных, поэтому применить её — хорошая идея. Обратите внимание, что если две или более метки получили одинаковое количество голосов, то нужно выбрать из них случайную, чтобы избежать смещения в сторону первой встречающейся метки.
Классический метод агрегации с помощью мнения большинства не учитывает навыки исполнителей. Но иногда полезно взвесить вклад каждого исполнителя в конечную метку с учётом их согласованности с агрегированным значением. Этот подход называется Wawa, и он тоже представлен в Crowd-Kit. Он вычисляет мнение большинства, а затем повторно взвешивает голоса исполнителей, используя долю ответов, совпавших с мнением большинства.
Теперь мы выполняем ту же операцию с помощью вероятностной модели Дэвида-Скина, реализованной в Crowd-Kit при помощи EM-алгоритма. Это еще один классический подход к агрегированию в краудсорсинге, который был первоначально разработан в 70-х для вероятностного моделирования медицинских обследований. Код практически тот же: мы создаём экземпляр, задаём количество итераций алгоритма, вызываем
Давайте оценим качество агрегированных данных. Для этого мы используем хорошо известную F1-меру из библиотеки scikit-learn.
В этом наборе данных верные ответы доступны только для подмножества заданий, поэтому оценивать будем только по ним. Это позволяет нам выбрать лучшую модель агрегации с использованием хорошо известных и надёжных инструментов, таких как pandas, scikit-learn и Crowd-Kit.
В нашем эксперименте лучшее качество было достигнуто с помощью модели Дэвида-Скина. Выбрав модель, мы хотим экспортировать все агрегированные данные, что имеет смысл в боевых приложениях.
Теперь с помощью pandas сохраним результаты агрегации в файл TSV, предварительно преобразовав последовательность в таблицу, чтобы указать названия столбцов.
Давайте заглянем внутрь. Данные и ответы на месте, результаты агрегации тоже.
Мы получили агрегированные данные, написав всего несколько строк кода.
Я буду использовать Crowd-Kit — нашу открытую библиотеку вычислительных методов контроля качества в краудсорсинге, которая предлагает реализации разных методов агрегации ответов, оценки неопределённости и согласованности ответов и т. д. Но вы можете воспользоваться альтернативами: spark-crowd (использует Scala вместо Python), CEKA (Java вместо Python) или Truth Inference (использует Python, но предоставляет только категориальные и числовые ответы).
Что ещё есть в Crowd-Kit
Библиотека предлагает хорошо знакомые программистам структуры данных и API: она интегрируется с популярными библиотеками для анализа данных на Python, такими как NumPy, SciPy и pandas. Кроме того, она не зависит от конкретной краудсорсинговой платформы. Нужно только предоставить данные в виде таблицы исполнителей, задач и ответов, а Crowd-Kit выдаст качественные результаты независимо от того, на какой платформе эти данные получены.
Писать код буду в Google Colab, но любая другая среда для Python тоже подойдёт. Сначала нужно установить библиотеку Crowd-Kit из PyPI. Кроме того, мне понадобятся размеченные данные — буду использовать открытые данные Толоки о релевантности поисковых ответов с двумя категориями: релевантные и нерелевантные. Загрузчиком данных будет сам Crowd-Kit, чтобы скачать их в виде таблиц pandas. Опять же, вы можете использовать другой источник данных и собрать таблицы самостоятельно.
!pip install crowd-kit
from crowdkit.datasets import load_dataset
df, df_gt = load_dataset('relevance-2')
Итак, данные загружены — прежде чем двинуться дальше, давайте взглянем на них.
perfomer | task | label | |
0 | w851 | t30685 | 1 |
1 | w6991 | t30008 | 0 |
2 | w2596 | t36316 | 0 |
3 | w5507 | t15145 | 1 |
4 | w2982 | t44785 | 1 |
... | ... | ... | ... |
475531 | w4660 | t62250 | 1 |
475532 | w6630 | t46626 | 0 |
475533 | w4605 | t93513 | 1 |
475534 | w1928 | t29002 | 0 |
475535 | w5375 | t49052 | 1 |
df_gt
task
t30006 0
t33578 0
t22462 1
t52093 0
t26935 0
..
t57345 1
t81052 1
t7189 1
t80463 0
t93643 0
Name: label, Length: 10079, dtype: int64
Функция load_dataset возвращает пару элементов. Первый элемент — это таблица pandas с данными, полученными из краудсорсинга. Второй элемент (если он имеется) — это данные с верными ответами (ground truth). Таблица
df
содержит три столбца: исполнитель, задача и метка. Метка имеет значение 0
, если исполнитель оценил документ как нерелевантный, в противном случае 1
. Таблица df_gt
— это последовательность pandas, которая содержит правильные ответы на задачи, помещенные в индекс. Импортируем три класса агрегации: мнение большинства, Wawa и Дэвид-Скин. Давайте попробуем агрегировать с помощью мнения большинства — простого эвристического метода.
from crowdkit.aggregation import MajorityVote, Wawa, DawidSkene
Создадим экземпляр класса с реализацией мнения большинства и вызовем метод
fit_predict
, чтобы агрегировать наши данные.agg_mv = MajorityVote().fit_predict(df)
agg_mv
task
t0 1
t1 1
t10 1
t100 0
t1000 0
..
t9995 1
t9996 0
t9997 0
t9998 0
t9999 1
Length: 99319, dtype: int64
Эта простая эвристика работает очень хорошо, особенно на небольших наборах данных, поэтому применить её — хорошая идея. Обратите внимание, что если две или более метки получили одинаковое количество голосов, то нужно выбрать из них случайную, чтобы избежать смещения в сторону первой встречающейся метки.
Классический метод агрегации с помощью мнения большинства не учитывает навыки исполнителей. Но иногда полезно взвесить вклад каждого исполнителя в конечную метку с учётом их согласованности с агрегированным значением. Этот подход называется Wawa, и он тоже представлен в Crowd-Kit. Он вычисляет мнение большинства, а затем повторно взвешивает голоса исполнителей, используя долю ответов, совпавших с мнением большинства.
agg_wawa = Wawa().fit_predict(df)
agg_wawa
task
t0 1
t1 1
t10 1
t100 0
t1000 0
..
t9995 1
t9996 0
t9997 0
t9998 0
t9999 1
Length: 99319, dtype: int64
Теперь мы выполняем ту же операцию с помощью вероятностной модели Дэвида-Скина, реализованной в Crowd-Kit при помощи EM-алгоритма. Это еще один классический подход к агрегированию в краудсорсинге, который был первоначально разработан в 70-х для вероятностного моделирования медицинских обследований. Код практически тот же: мы создаём экземпляр, задаём количество итераций алгоритма, вызываем
fit_predict
и получаем агрегированные результаты.agg_ds = DawidSkene(n_iter=10).fit_predict(df)
agg_ds
task
t30685 1
t30008 0
t36316 0
t15145 1
t44785 0
..
t95222 0
t83525 0
t49227 0
t96106 1
t16185 1
Length: 99319, dtype: int64
Давайте оценим качество агрегированных данных. Для этого мы используем хорошо известную F1-меру из библиотеки scikit-learn.
from sklearn.metrics import f1_score
В этом наборе данных верные ответы доступны только для подмножества заданий, поэтому оценивать будем только по ним. Это позволяет нам выбрать лучшую модель агрегации с использованием хорошо известных и надёжных инструментов, таких как pandas, scikit-learn и Crowd-Kit.
f1_score(df_gt, agg_mv[df_gt.index])
0.7621861152141802
f1_score(df_gt, agg_wawa[df_gt.index])
0.7610675039246467
f1_score(df_gt, agg_ds[df_gt.index])
0.7883762200532387
В нашем эксперименте лучшее качество было достигнуто с помощью модели Дэвида-Скина. Выбрав модель, мы хотим экспортировать все агрегированные данные, что имеет смысл в боевых приложениях.
Теперь с помощью pandas сохраним результаты агрегации в файл TSV, предварительно преобразовав последовательность в таблицу, чтобы указать названия столбцов.
agg_ds.to_frame('label').to_csv('test.txt')
Давайте заглянем внутрь. Данные и ответы на месте, результаты агрегации тоже.
Мы получили агрегированные данные, написав всего несколько строк кода.
cadovvl
Вот это я жираф. У толоки есть открытые датасеты с 2019 года, а я только сейчас узнаю. :(