Сегодня я погрузился в новый набор данных WikiReading, который команда Google выпустила вместе с увлекательной статьей, в которой описывается, как они используют его для оценки своих достижений в области глубокого обучения для понимания естественного языка.

В наборе данных почти 19 миллионов экземпляров (документ, свойство, значения), где документ - это полный текст статьи в Википедии, а свойство и значения - это факты из соответствующего элемента WikiData. Например. Статья для Барака Обамы содержит следующее заявление о ее элементе WikiData:

На приведенном выше снимке экрана «супруга» - это собственность, а «Мишель Обама» - это стоимость. Набор данных не включает квалификаторы WikiData (например, время начала) или ссылки. Да, и у элемента может быть несколько значений одного и того же свойства:

Итак, в выпущенных файлах каждый из этих экземпляров (документ, свойство, значения) представляет собой объект JSON в отдельной строке. В несжатом виде он весит 208 ГБ. Он разделен на ~ 180 различных файлов, а также разделен на обучение, тестирование и проверку.

Каждый объект содержит кучу ненужных переформулировок одной и той же информации - насколько я могу понять, это всего лишь артефакт рабочего процесса машинного обучения, который Google использовал для создания своей статьи. Например, у каждого объекта есть 16 полей, тогда как их, вероятно, должно быть только три. Но это нормально, я могу уменьшить его с помощью небольшой обработки (см. Ниже или ознакомьтесь с этим фрагментом jqplay).

На данный момент я вижу более серьезную проблему с набором данных, заключающуюся в том, что как количество экземпляров, так и их распределение по наборам для обучения / проверки / тестирования значительно отличается от цифр, которые они приводят в своей статье. Я поднял вопрос на GitHub, так что посмотрим, что они скажут. Но сейчас похоже, что будет сложно провести честное сравнение между их алгоритмами и другими методами понимания естественного языка, и это основная причина, по которой я хотел погрузиться в это в первую очередь.

Чтобы преобразовать JSON в формат, более подходящий для моих нужд (более тонкий и с необработанным текстом, а не с массивами токенов), я использовал инструмент командной строки jq.

Изначально я использовал Cloud Dataflow, управляемый библиотекой datasplash в Clojure. Было интересно учиться, и мне нравилось наблюдать, как целая куча компьютеров в облаке запускается для работы с моими данными, но меня также раздражали долгие минуты между началом работы и получением последних данных - это было похоже на противоположный интерактивному процессу, который я обычно использую в REPL.

В то же время я наткнулся на статью, аргументирующую использование простых инструментов UNIX, если только вам действительно, действительно не нужно привлекать тяжеловесов. Это убедительно.

Итак, я взглянул на jq:

Я не буду здесь подробно рассказывать об этом, но если вы хотите увидеть, как я преобразую данные, посмотрите этот интерактивный фрагмент jqplay.

Мне понравилось, как легко было выразить трансформацию, но это было медленнее, чем я ожидал:

150 секунд для файла объемом 1,3 ГБ и 100 000 строк. Есть 180 файлов. На запуск потребуется около 7,5 часов. Как мне его ускорить?

Что ж, когда я взглянул на htop, я увидел, что только одно из 16 ядер на моей машине находится под нагрузкой:

Тот факт, что он установлен на 100%, означает, что мы можем с уверенностью предположить, что он ограничен ЦП. Так как же я получил его на другие ядра?

Параллель GNU. Это инструмент для ввода данных и автоматического распределения их между новыми командами, чтобы они выполнялись на нескольких ядрах. У него есть опция pipe, которая позволяет вам направлять входные данные в него (в данном случае путем запуска cat для всех файлов JSON, которые нам нужны), и он разбивает входные данные на фрагменты размером 1 МБ и передает каждый фрагмент в отдельный процесс. Свидетель:

Это ускорение почти в восемь раз. На самом деле я понятия не имею, почему это не шестнадцать раз, учитывая, что он перешел от работы на одном ядре к работе на шестнадцати. Кто-нибудь может просветить меня?

Даже после моего jq-преобразования для удаления раздувания размер файла всего примерно в четыре раза меньше (~ 50 ГБ). Все еще немного великоват, чтобы просто погрузиться в Clojure и начать играть с данными на моем ноутбуке, что является для меня самым быстрым способом исследования.

Я считаю, что большая часть размера файла связана с тем, что полный текст статьи повторяется для каждого отдельного утверждения (свойство, значения), связанного с элементом. Следующим шагом будет преобразование ее в двухуровневую карту {document - ›{property -› value}}.

Но уже немного поздно, и я займусь этим завтра.

Я был поклонником WikiData много лет. Приятно видеть, как большие исследовательские группы обращают на это внимание и используют его для развития современного состояния.

Моя цель на следующие несколько дней - запустить классификатор fastText Facebook для набора данных и сравнить его эффективность при классификации текста с методами глубокого обучения, используемыми в статье Google.