Это старая версия документа!
Яндекс.Толока — тестирование диктанта
Вводные
Цель: получение текстов разнообразных вариантов написания диктанта для построения тепловой карты ошибок с последующим анализом возможных ошибок/вариантов и корректировки разметки.
Ограничение: цельный текст диктанта под секретом, нельзя его полностью показывать отдельному человеку.
Решение: предлагать пользователям сервиса «Яндекс.Толока» писать отдельные предложения под диктовку, а затем склеивать результаты в единые тексты, затем формировать архив для импорта.
Описание решения
Регистрация
Зарегистрируйтесь в сервисе Яндекс.Толока в качестве заказчика.
Пополнение баланса
Пополните баланс на нужную сумму (в долларах). Примерная экономика: 3 цента за предложение. В диктанте в среднем 15-20 предложений, следовательно, одно написание будет стоить от 45 до 60 центов.
Можно пополнить баланс с расчётного счёта юрлица.
Формирование проекта
Создайте новый проект. Шаблон: «Audio → Transcribing audio recordings».
Name to show Tolokers: «Напишите предложение из школьного диктанта».
Description for Tolokers: «Нужно послушать и записать предложение со всеми знаками препинания, опираясь на собственную грамотность».
Task interface → Template builder → Config: вставить json из поля ниже.
- json
{ "view": { "type": "view.list", "items": [ { "label": "Послушайте предложение из диктанта (это ОДНО предложение)", "type": "view.audio", "url": { "type": "data.input", "path": "audio" }, "validation": { "type": "condition.played-fully", "hint": "Послушайте аудиозапись" } }, { "type": "field.textarea", "label": "Запишите услышанное предложение со всеми знаками препинания, опираясь ТОЛЬКО на собственную грамотность (без словарей, справочников и поисковиков), см. Инструкцию. ", "data": { "type": "data.output", "path": "transcription" }, "validation": { "type": "condition.required", "hint": "Введите услышанное" } } ] }, "plugins": [ { "type": "plugin.toloka", "layout": { "kind": "scroll", "taskWidth": 500 } } ] }
Инструкция для исполнителей
В поле «Instructions for Tolokers» вставляется инструкция:
Используйте наушники для прослушивания аудиозаписи. Внимательно послушайте и запишите предложение орфографически точно, со всеми знаками препинания, но опираясь только на собственную грамотность: без словарей, справочников и поисковиков. Некоторые правила: * Тире (в отличие от дефиса) отделяется пробелами с обеих сторон: "это - тире". * Предложение начинается с заглавной буквы. Задание будет отклонено, если Ваш текст совсем не похож на продиктованный.
После заполнения всех полей нажимается Save.
Создание пула
Создаётся новый пул заданий («Create new pool»), для каждого диктанта отдельный. В поле «Pool type» выбирается опция «General tasks». Называние пишется в поле «Pool name (private)», например, «Диктант 1» (название текущего диктанта). В «Private comment» записывается название проекта.
На странице пула выставляются следующие параметры:
- На странице «Select the audience for your task» убирается галочка «My task may contain shocking or pornographic content», сохраняется опция «Languages» в поле «= Value» выставляется «Russian», ставится галочка «Tolokers who passed the language test». На шкале «Specify the percentage of top-rated Tolokers who can access tasks in the pool» выбирается, например, топ 60% лучших исполнителей.
- На странице «Set up quality control» удаляется окошко с полями «Recent task suites to use… Minimum time per task suite». Через новое «Add a quality control rule» выбирается правило контроля качества «Submitted responses», там проставляются значения:
If submitted tasks suites = 3, then suspend in pool permanently
— для того, чтобы один человек смог увидеть не более трёх предложений диктанта. В «Reason» вписывается «Ответ получен».
- На странице «Set the task price and overlap» в поле «Price per task suite, $» выставляется цена 0,02, в поле «Number of Tolokers per task Overlap» выставляется значение 120.
- На странице «Add optional pool settings» проставляется галочка «Keep task order», остальные параметры оставляются по умолчанию.
Загрузка заданий
Можно взять готовый шаблон или создать таблицу с нуля.
Формируется таблица в гугл.документах (https://sheet.new/) с двумя листами:
- INPUT
- OUTPUT
На листе INPUT добавляется в ячейку A1 строка INPUT:audio
.
Ниже вставляются ссылки на аудиофайлы предложений в прямом порядке. Ссылки на предложения можно получить в Учительской: страница диктанта → Страница диктовки → кнопка «Скачать» → «Скачать предложения».
Примерно так должен выглядеть лист:
Далее с листа копируется первый столбец и вставляется в текстовый файл. Каждая ссылка разделяется пустой строкой:
INPUT:audio https://teacher.dict.orfogrammka.ru/api/media/61f0d7a8a5fd104693b9638c/6235982d9b28050b5b2b8b26.mp3 https://teacher.dict.orfogrammka.ru/api/media/61f0d7a8a5fd104693b9638c/623598f49b28050b5b2b8b33.mp3 https://teacher.dict.orfogrammka.ru/api/media/61f0d7a8a5fd104693b9638c/623599539b28050b5b2b8b3d.mp3
Файл сохраняется с расширением .tsv
и загружается в текущий пул задач (страница «Prepare and upload data»). После «Continue» в окне «Smart mixing» выставляются параметры: «General tasks» — 1, «Control tasks» — 0, «Training tasks» — 0.
У оставшегося окна нажимается «Do it later».
Запуск пула
На открывшейся странице («Overview») нажимается «Start labeling» → «Launch». После модерации Толоки проект будет запущен и откроется толокерам.
Получение результатов написания
После выполнения всех заданий толокерами можно скачать результаты по кнопке «Download results» в пуле. В окне скачивания выбираются статусы «General» и «Accepted» без полей и разделения ответов пустой строкой.
Данные из скачанного файла импортируются в таблицу, на лист OUTPUT так, чтобы в каждой строке была ссылка на аудиофайл и текст результата:
Следует просмотреть глазами все результаты, чтобы вручную удалить пустые и некорректные строки (сочетание Ctrl + Alt + -
).
Итого, готова таблица для работы скрипта по формированию текстов диктанта.
Подготовка скрипта слияния
В среде AppsScript создаётся новый проект (или можно запросить доступ к готовому проекту). Вставляется следующий код ниже.
- js
//-------------------------------------------------------------------------------------------- // ---=== основные параметры скрипта ===--- // // URL таблицы с данными по диктанту в нужном формате: два листа INPUT, OUTPUT. // В первом упорядоченные ссылки на звуковые фрагменты по предложениям, во втором результаты из Толоки const sheetName = 'https://docs.google.com/spreadsheets/d/1fbP4rylF5ryZS905D2xlgA9qhRimD6IxpHPR-bbz3tE/edit'; // // id директории, куда сохранять файлы диктантов (берётся из URL'а https://drive.google.com/drive/folders/%id) const folderSave = '1s9p2RBowh3hou94p_jDdJ1Zv4Ty7fqu-'; // //id диктанта из Учительской (берётся из URL'а диктанта) const dictId = '61f8e9a6a5fd104693b9646d'; //-------------------------------------------------------------------------------------------- function RunImport() { Logger.log("Запуск скрипта формирования текстов диктантов из результатов Яндекс.Толоки..."); //https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app var sheetDict = SpreadsheetApp.openByUrl(sheetName); Logger.log('Получен доступ к гугл.таблице "%s"', sheetDict.getName()); var dictFolder = DriveApp.getFolderById(folderSave); Logger.log('Получен доступ к директории "%s"', dictFolder.getName()); var range = sheetDict.getRange("INPUT!A2:A100"); //задаём название листа и интервал со значениями ссылок на диктовки предложений (задания в Толоке) var sentencesIds = getSentenceIds(range.getValues()); var range = sheetDict.getRange("OUTPUT!A2:B"); //задаём название листа и интервал со значениями результатов Толоки mergeResults(range.getValues(), sentencesIds, dictFolder); Logger.log("Готово!"); }; function saveDict(text, dictFolder){ var fileName = dictId + '_' + createUUID() + '.txt'; dictFolder.createFile(fileName, text); Logger.log('диктант "%s" сохранён (размер %d символов)', fileName, text.length); } function mergeResults(valuesInput, sentencesIds, dictFolder){ var dictText = []; var link = ''; var text = ''; var idx = -1; for (var i = 0,countLines = valuesInput.length; i < countLines; i++) { link = valuesInput[i][0].trim(); text = valuesInput[i][1].trim(); if (link.length > 2 && text.length > 2) { idx = sentencesIds.indexOf(link); if (idx == -1) { Logger.log('В таблице предложений не найден элемент со ссылкой %s', link) } else { if (dictText[idx] == null) { dictText[idx] = text; valuesInput[i][0] = '?'; valuesInput[i][1] = '?'; if (Object.keys(dictText).length == sentencesIds.length) { var fullText = dictText.join(" "); saveDict(fullText, dictFolder); dictText.length = 0; i = 0; } } } } } } // получение массива id предложений по ссылкам на аудиозаписи function getSentenceIds(valuesInput){ var sentencesIds = []; for (var i = 0,countLines = valuesInput.length; i < countLines; i++) { if (valuesInput[i][0].length > 1) { sentencesIds.push(valuesInput[i][0].trim()) } } return (sentencesIds) } function createUUID() { // http://www.ietf.org/rfc/rfc4122.txt var s = []; var hexDigits = "0123456789abcdef"; for (var i = 0; i < 36; i++) { s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); } s[14] = "4"; s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); //s[8] = s[13] = s[18] = s[23] = "-"; var uuid = s.join(""); return uuid; }
В начале, в секции «основные параметры скрипта», прописываются нужные ссылки: на таблицу с результатами, директорию сохранения текстовых файлов, идентификатора диктанта. Подробные пояснения в комментариях скрипта.
После заполнения нужных параметров нажимается команда «Выполнить».
Получение архива с текстами диктантов
Через некоторое время появляются результаты в указанной папке на Гугл.Диске. Внутри папки выделяются все файлы и через контекстное меню скачивается архив:
Архив импортируется в Учительскую в формате для импорта.
Сохранение артефактов
В комментарии к Редмайн-задаче даётся ссылка на гугл-таблицу, ссылка на «Тепловую карту», прикрепляется zip-архив с текстами из Толоки.