Ловушки, которых следует избегать

Зачем кодировать наборы данных

Code AI недавно стал общей темой; будь то классификация темы кода, поиск уязвимостей в ней, обобщение ее или даже угадывание следующего токена с учетом предыдущих. Что делает это возможным, так это недавние достижения НЛП и повышение доступности богатых и разнообразных наборов данных исходного кода. При наличии таких сервисов, как Github, Gitlab и Bitbucket, создание наборов данных исходного кода может рассматриваться как тривиальная задача - просканировать Github и начать обучение модели. На самом деле эта простота охватывает довольно сложную область, в которой нужно избегать множества ловушек. Подробное объяснение ниже.

Тематическое исследование - прогнозирование темы

Предположим, наша задача - построить модель, которая предсказывает, связан ли исходный код с сервером. Есть много способов подойти к этому: от ручного сбора функций (таких как тип файла, тестовый код, импорт в нем и т. Д.) До глубоких нейронных сетей, которые автоматически генерируют набор функций для просмотра. Независимо от того, какой путь мы выберем, первым делом необходимо собрать соответствующий набор данных. Распространенный (наивный !!) предлагаемый план будет заключаться в случайном выборке репозиториев из общедоступной службы хостинга кода (например, Github) с использованием некоторых соответствующих критериев поиска (например, репозиториев Node.js) и присвоение им меток на основе наличие соответствующих терминов («связанный с сервером» VS «нет»). Следуя по этому пути, мы, скорее всего, обнаружим, что наша модель переоснащается поверхностным характеристикам набора данных. Что может пойти не так?

Почему случайный код выборки нетривиален

Основная проблема с нашим первоначальным планом - это присущие набору данных исходного кода неявные предубеждения, которые могут повлиять на обобщение модели для разных языков и типов кода. Сообщается, что Github, который является одним из наиболее распространенных сервисов хостинга кода, страдает длинным хвостом языков; некоторые из них очень распространены (например, Javascript и Java), в то время как большинство (например, C) довольно редки. Если вернуться к нашему плану, случайная выборка Github приведет к получению прокси их длиннохвостого распределения. Может стать еще хуже из-за того, что некоторые темы связаны с языком; Например, Java более актуальна для серверных приложений, чем Clojure. Учитывая, что Java также чаще встречается в нашем наборе данных, модель может прийти к выводу, что Clojure вообще не имеет отношения к серверам (всегда отрицательно для прогнозов нашей модели, что неверно). Решение должно заключаться в том, чтобы наш набор данных более равномерно распределялся по языкам и классам.

Почему расслоение кода выборки нетривиально

Распространенным способом достижения равномерного распределения является стратифицированная выборка. В наборах данных кода обычно применяется выборка на уровне репо, чтобы убедиться, что сгенерированные разбиения на поезд-тест-валидацию являются взаимоисключающими (чтобы избежать риска переобучения одних и тех же файлов репо). Попытка выбрать языки на уровне репо может быть трудной, поскольку некоторые языки, такие как Json и Yaml, в целом распространены; независимо от того, какая политика выборки будет применяться, они, вероятно, в конечном итоге станут (слишком) общими в нашем наборе данных. Другой вопрос, как настроить таргетинг на соответствующие файлы; чтобы убедиться, что в наборе данных будет достаточно примеров, связанных с сервером, мы предложили выполнять поиск в Github, используя термины, связанные с сервером (например, котенок на Java, колба на Python и экспресс на Javascript), но проблема в том, что такой поиск слишком специфичен для технологии (может привести к переобучению), и в целом может быть сложно убедиться, что это приведет к тому же количеству примеров для каждого языка. Если полагаться на нормализованные поисковые запросы (например, на само слово сервер), многие потенциально релевантные примеры для таргетинга будут проигнорированы. Как обеспечить равномерное распределение нашего набора данных при сохранении его богатства и разнообразия?

Поэтапная выборка для настройки распределения

Следуя упомянутым характеристикам набора данных кода, наш набор данных, вероятно, будет иметь смещения. Стратифицированная выборка может только частично решить эту проблему из-за неявных отношений класса к языку. Решение должно быть отбором по фазам; Что касается положительного класса (который обычно более редок), недостаточная выборка может привести к потере дорогостоящих примеров, в то время как избыточная выборка может позволить запомнить менее распространенные примеры. Для отрицательного класса (который обычно более доступен) стратифицированная выборка может скрыть разнообразие классов. Наше решение будет заключаться в том, чтобы начать с недостаточной выборки слишком общих языков положительного класса и продолжить чрезмерную выборку языков с длинным хвостом. Наконец, мы сделаем выборку отрицательного класса, чтобы он соответствовал только что сгенерированному положительному распределению языков. В результате получится выборка данных, в которой мы сохраним как можно больше положительных примеров, при этом убедившись, что общая популяция распределена почти равномерно. Важное примечание: какую бы стратегию выборки мы ни выбрали, мы должны всегда отслеживать; обязательно следите как за общей, так и за языковой эффективностью. Выявление потенциальных скрытых предубеждений.

Активное обучение, чтобы восполнить пробел

В предложенном нами решении некоторые примеры будут проигнорированы (при выборке слишком общих положительных и в целом отрицательных), а некоторые будут дублироваться (избыточная выборка для положительного длинного хвоста). Чтобы сделать выборку более разумной, чем простая случайная выборка, мы можем использовать слабую модель, чтобы определить, каким отрицательным примерам следует отдать более высокий приоритет (те, которые правильно определены более слабой моделью, менее важны), и заменить дублирование избыточной выборки активным нацеливанием на страты. представляет интерес. Сосредоточение внимания на «слабых» областях набора данных позволит нам лучше тратить нашу рабочую силу на улучшение модели.

Создавайте с осторожностью

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