Как далеко можно зайти в классическое НЛП? От «мешка слов» до наращивания идентификации возможностей жуткого автора.
Сквозной эксперимент по классической разработке естественного языка в задаче Kaggle «Идентификация жуткого автора».
Делиться
Изображение создано с помощью ChatGPT
Определение авторства — хороший способ определения моделей мышления естественного языка, поскольку он фокусируется не только на содержании предложений, но и на его написании. Конкурс Kaggle «Идентификация жуткого автора» — это компактная версия этой задачи: получить одно предложение из готической или ужасной литературы, модель должна предсказать, было ли оно написано Эдгаром Алланом По (EAP) , Мэри УолстонкрафтШелли (MWS) или Г. П. Лавкрафтом (HPL) .
На первый взгляд, это кажется существенным разделением текста по трем классам. Но на самом деле все гораздо сложнее. Все авторы пишут на схожие темы: страх, тайна, смерть, атмосфера и сверхъестественное. Простых ключевых слов недостаточно, чтобы их различать. В результате этих положений подсказками часто выступают стилистические особенности: служебные слова, пунктуация, особенности написания символов, короткие фразы, ритм предложений и способ построения предложений каждым автором. wp-block-quote-is-layout-flow»>
На сколько далеко может продвинуться классическая НЛП, если мы тщательно выбираем способы представления информации и честно их измеряем?
Я подошел к задаче, создав последовательность классических моделей с возрастающими возможностями:
быстрая базовая линия слов Vowpal Wabbit,
Более функциональная модель VW с пунктуацией и n-граммами символов.
настроенный ансамбль TF-IDF,
ансамбль разреженного текста, построенный стекирования, с использованием прогнозов, выходящих за пределы области сгиба.
Небольшое исследование, сравнительное методы с использованием разреженных признаков, BM25, Word2Vec и FastText.
Цель заключалась не только в улучшении результата, но и в том, что какие способы представления данных помогли, какие показатели были разрешены и на основе какой схемы оценки были получены для каждого результата.
В этой статье большое внимание уделяется методологии проектов, результатам и их эффективности. Я рассматриваю основные решения по реализации и поделюсь ключевыми фрагментами кода, но не буду включать каждый текст из блокнота. Полный завершенный блокнот, включая полную реализацию и выходные данные, доступны в репозитории GitHub, ссылка на которую приведена в конце статьи. <сильных>19 579 размеченных обучающихся предложенийсильных> и <сильных>8 392 неразмеченных тестовых предложений . Распределение классов умеренно несбалансировано:
Рисунок 1. Распределение классов в обучающем наборе. Набор данных слегка несбалансирован: наибольшую долю примера составляет EAP, а наименьшую — HPL.
Я закодировал метки в виде целых чисел, начиная с 1, потому что в многоклассовом режиме библиотеки One-Against-All метки Vowpal Wabbit начинаются с 1.
Для локального Сравнительные модели, которые я использовал, стратифицированное разделительное обучение и валидационные выборки в сравнении 70/30 с фиксированным начальным значением генератора случайных чисел. Это обеспечивает сохранение стабильных пропорций классов и позволяет добиться того, чтобы модель оценивалась на одних и тех же отложенных примерах.train_texts_part, valid_texts = train_test_split( train_texts, test_size=0.3, random_state=17, stratify=train_texts[«author_code»] ) y_part = train_texts_part[«author_code»].values y_valid = valid_texts[«author_code»].values
Я сосредоточился на трех основных показателях:
Точность: понятна, но исследование лишь окончательное решение высших качеств.
Макрос F1: представлено для проверки того, насколько убедительна производительность у трех авторов.
Функция потерь для многоклассовой классификации:официальная метрика Kaggle и наиболее важная метрика для этого проекта, поскольку она оценивает качество прогнозируемых вероятностей, а не только прогнозируемый класс. Это важно на соревнованиях, где в качестве исходных данных используются финансовые вероятности по EAP, HPL и MWS. Хорошо обрабатывает разреженные данные и идеально подходит для линейных текстовых моделей. VW обучает линейные модели в режиме онлайн, хеширует признаки в фиксированном пространстве признаков и обрабатывает многоклассовую классификацию с помощью алгоритма «Один против всех».
Для первого базового уровня я использовал только слова, написанные строчными буквами, четверть три и более символов.
Одна из важных деталей реализации касалась обработки многократных проходов VW. Когда VW считывает файл напрямую, такие параметры, как проходит и cacheработают так, как ожидалось. При ручном включении примеры через API Python мне пришлось самостоятельно перебирать файл в цикле.
N_PASSES = 10 vw = Workspace( oaa=3, loss_function=" логистический", ngram=2, b=28, quiet=True, Final_regressor=f"{OUTPUT_DIR}/spooky_words.vw" ) для _ в диапазоне (N_PASSES): с open(f"{OUTPUT_DIR}/train_words.vw") как f: для строки в f: vw.learn(line) vw.finish()
При разделении голосов 70/30, базовый показатель VW, определяемый только по словам, составил:
Убедительная формулировка модели Vowpal Wabbit, основанной только на словах. Даже при использовании простых слов и биграмм, быстрая линейная модель VW обеспечивает надежную отправную точку.
Это уже был хороший результат для линейной модели, использующей простые определения слов и биграмм. Он также установил полезный базовый уровень: для преодоления этого барьера потребуется любое дополнительное представление или дополнительный слой.
2. Расширенные возможности VW: добавление функций, эффектных стилей.
Определение авторства включает в себя не только классификацию тем. Модели также требуют доступа к внешним, отражающим стиль письмам. Для совершенно болеей модели VW я разделил входные данные на три пространства имен:
|w для слов, включая короткие служебные слова,
|p для пунктуаций,
|c для n-грамм символы.
def char_ngrams(text, ns=(2, 3, 4)): """Н-граммы символов с учетом границ; пробелы/ребра становятся '_'.""" t = "_" + re.sub(r"s+", "_", text.strip()) + "_" return [t[i:i + n] for n in ns for i in range(len(t) - n + 1)] def to_vw_rich(df, is_train=True, char_ns=(2, 3, 4)): """Три пространства имен: |w слова, |p пунктуация, |c символы n-грамм."""lines = [] texts = df["text"].values labels = df["author_code"].values if is_train else Нет для i, текст в enumerate(texts): Safe = str(text).lower().replace("|", " ").replace(":", " ") label = labels[i] if is_train else 1 word = " ".join(re.findall(r"w+", Safe)) punct = " ".join(re.findall(r"[^ws]", Safe)) chars = " ".join(char_ngrams(safe, ns=char_ns)) lines.append(f"{label} |w {words} |p {punct} |c {chars}n") returnlines
Эта модель использовала больше проходов и немного большее хеш-пространство, чем базовая модель, основанная только на словах.
N_PASSES = 15 vw = Workspace( oaa=3, loss_function=" логистический", ngram=2, b=29, quiet=True, Final_regressor=f"{OUTPUT_DIR}/spooky_rich.vw" ) для _ в диапазоне (N_PASSES): с open(f"{OUTPUT_DIR}/train_rich.vw") в качестве f: для строки в f: vw.learn(line) vw.finish()
Это ограничение результата в контрольной группе:
Влияние добавление функций VW, наблюдающих, по эффективности контрольной выборки. Добавление знаков препинания и n-грамм символов Macro-F1 и функций эффективности Macro-F1 по сравнению с базовыми символами VW, основанными только на словах.
Полученный результат значителен: добавление знаков стиля препинания и структура на уровне символов помогла модели уловить стиль, выходящий за рамки простого выбора слов.
3. Характеристики слов и символов TF-IDF
Далее я хотел проверить, можно ли другой классический алгоритм обработки разреженного текста ограничить или превзойти результаты VW. Я построил матрицу признаков TF-IDF, используя два представления текста:
униграммы и биграммы на уровне слов,
2-5-граммовые символы на уровне отдельных символов внутри границ слов.
Словарные характеристики отражают лексические и фразовые особенности. Характеристика включает в себя фрагменты орфографии, суффиксы, префиксы, элементы, расположенные рядом с пунктуацией, и другие мелкие детали, полезные для классификации стилей.
Я научил три взаимодополняющие модели в этом представлении:
Логистическая регрессия,
Логистическая регрессия в стиле NB-SVM.
Дополнение к наивному байесовскому классификатору.
Для логистической регрессии и моделей типа NB-SVM я настроил значения C с помощью внутренней перекрестной проверки только на обучающей выборке, о проведении контрольной выборки без изменений.
def Tune_lr_C(X, y, C_grid=(0.1, 0.3, 1, 3, 10, 30), n_splits=5): cv = StratifiedKFold(n_splits=n_splits, shuffle=True, random_state=42) rows = [] для C в C_grid: oof = np.zeros((X.shape[0], len(CLASSES))) для tr_idx, va_idx в cv.split(X, y): clf = LogisticReгрессия(C=C, max_iter=3000) clf.fit(X[tr_idx], y[tr_idx]) oof[va_idx] = align_proba(clf, X[va_idx]) rows.append({"C": C, "log_loss": log_loss(y, oof, labels=CLASSES)}) return pd.DataFrame(rows)
Наилучшие результаты внутреннего CV были приняты:
Результаты внутренних перекрестных проверок для линейных моделей TF-IDF. Логистическая регрессия в стиле NB-SVM показала более низкую логарифмическую функцию потерь при внутренней перекрестной проверке, что указывает на более сильную настроенную линейную связь. составляющую.
Итоговое среднее значение вероятности по трем моделям достигло следующего результата:
Эффективность усреднения 3 моделей TF-IDF при контрольной выборке. Усреднение вероятностей моделей, отражающих высокую вероятность и конкурентные логарифмические показатели при разделении выборов 70/30.
Прирост точности по сравнению с богатым VW был незначительным, но потери в логарифмическом масштабе были существенными. Поскольку Kaggle оценивает вероятностные распределения, это было основанием для улучшения.
Логистическая регрессия в стиле NB-SVM
Модель в стиле NB-SVM выделена в отдельный раздел, поскольку это простой, но эффективный классический метод классификации текста.
И состоит в вычислении логарифмических соотношений определений для каждого из них: реальные примеры встречаются в одном классе, чем в других. Затем каждый признак умножается на это отношение перед построением линейного классификатора.
Несмотря на название, моя реализация не является единственным SVM. Она использует логистическую регрессию, изученную на разреженных признаках, взвешенных методом наивного Байеса. Преимущество заключается в том, что признаки, тесно связанные с этим автором, усиливаются при обучении линейных моделей.
4. Объединение с прогнозами, выходными за пределы выбораки.
После комплекта TF-IDF у меня осталось несколько продуктов базовых моделей. Усреднение по всем моделям дает каждой модели равный вес, но не основано предположение, что данная модель надежна для каждого класса. Метод стекинга позволяет моделям второго уровня научиться комбинировать их.
Основной риск утечки информации связан с обучением метаобучающей модели на основе прогнозов базовых моделей, которые уже рассматривались в тех же примерах. Чтобы избежать этого, я использовал прогнозы, выбирая рамки выбора:
В обучающих примерах базовая модель показывает только те примеры в той части набора данных, на которой она не обучалась.
Для контрольных или тестовых примеров прогнозы усредняются по версии каждой модели местоположения, прошедшие обучение с использованием метода фолдов.
Инструмент построения метод стекирования построения матрицу с одним блоком столбцов вероятностей для каждого формирования модели. В наличии пять базовых моделей и три автора метаобучающаяся система получает 15 вероятностных признаков на каждый пример.
Я построил метаобучающую модель логистической регрессии, используя перекрестную проверку на основе объединенных вероятностных признаков. 0.3, 1, 3, 10, 30))): skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=17) для C в C_grid: oof_meta = np.zeros((oof_stack.shape[0], len(CLASSES))) для tr_idx, va_idx в skf.split(oof_stack, y): мета = ЛогистическаяРегрессия(C=C, max_iter=3000) Meta.fit(oof_stack[tr_idx], y[tr_idx]) oof_meta[va_idx] = align_proba(meta, oof_stack[va_idx]) print(C, log_loss(y, oof_meta, labels=CLASSES))
При разделении выборки 70/30 методами настройки статических моделей были:
Наилучшие гиперпараметры координатных моделей, используемые в совокупности моделей при выборе 70/30. Эти настроенные базовые модели позволяют получить вероятностные признаки, используемые метаобучающим алгоритмом логистической регрессии.
Модель, построенная методом стекирования, получены следующие результаты:
Итоговые результаты работы настроенного ансамбля моделей. Ансамбль оценки качества вероятностного моделирования, достигнув наименьшей логарифмической потери среди классических конвейеров обработки данных.
Это был самый убедительный результат в проекте. Наибольшее улучшение произошло не в точности, а в потерях в логарифмической функции. Это означает, что любая защита оценивает вероятность, а именно это и поощряет метрику Kaggle.
5. Окончательная полная корректировка данных и отправка на Kaggle.
Для итоговой версии я переобучил представление TF-IDF на полных размеченных обучающихся данных, перестроил признаки стекирования, перенастроил базовые модели, обучил окончательный метаобучающий алгоритм и сгенерировал прогнозы для тестового.
Наилучшие гиперпараметры модели на полных данных для окончательной версии, полученной методом стекирования. Эти настройки были выбраны после повторного обучения конвейера на основе полного размеченного обучающего набора data.
Наилучшей итоговой настройкой метаобучающего алгоритма стало значение C=30 .
В коде также явно соотнесен мой внутренний порядок классов [1, 2, 3] = [EAP, MWS, HPL] с требуемым порядком столбцов в ответах Kaggle: EAP , HPL , MWS .
Оценка OOF уровня 2 для метаобучающего алгоритма на основе полных данных формируется:
Оценка уровня 2 полных данных окончательно для метаобучающей модели. Это полезно при проверке корректности, но ее нельзя напрямую сравнивать с более ранними результатами, полученными с использованием контрольной выборки 70/30.
Это число полезно для проверки правильности данных, но его не следует напрямую сравнивать с конкретными строками с контрольной последовательностью 70/30, поскольку оно получено в результате другой оценки настройки. Оно измеряет метаобучающую модель, используя признаки, полученные методом стеклирования вне фолдов, по всем обучающим данным, а не по всей вложенной поперечной стороне всего конвейера. class=»wp-block-image»>Результаты итоговой настроения стековой модели в таблице лидеров Kaggle.Приватный балл был близок к оценке уровня OOF 2 на полных данных, что свидетельствует о достаточной надежности настроек валидации.
Результаты в таблице лидеров нашли сравнения по уровню OOF 2, полученной на основе полных данных, что обнадеживает. Тем не менее, я бы рассматривал это как подтверждение правильности результатов, а не как доказательство полной непредвзятости системы. Я использовал прогнозы контрольной группы из объединенной модели для анализа матрицы ошибок, полноты по каждому автору и ошибок с высокой степенью достоверности.
AUTHORS = {1: "EAP", 2: "MWS", 3: "HPL"} cm = путаница_матрица(y_valid, valid_predictions, labels=CLASSES) cm_df = pd.DataFrame( cm, index=[f"true_{AUTHORS[c]}" для c в CLASSES], columns=[f"pred_{AUTHORS[c]}" для c in CLASSES] ) display(cm_df)
Матрица ошибок действует следующим образом:
Матрица ошибки для настроенной многослойной модели при контрольном выборе 70/30. Большинство прогнозов, основанных на диагональности, в то время как наибольшие диагональные направления из-за путаницы между MWS и EAP.
Показатели запоминаемости у каждого автора были относительно сбалансированными:
Показатель полноты для каждого автора в настроенной многоуровневой модели при разделении выборки на 70/30. Показатель полноты достаточной сбалансированности среди всех трех критериев, что говорит о том, что модель не сильно зависит от одного базового class.
Наиболее распространенными ошибками являются следующие:
Наиболее распространенные пары ошибок классификации для настроенной многоуровневой модели. Наибольшие ошибочные тенденции между MWS и EAP, за последние годы HPL и EAP, показывают, что в основном различия со стилистически совпадающими авторами.
Главное, что модель не свелась к прогнозированию наибольшего класса. Показатели полноты были близкими у всех трех авторов, и ошибки были двунаправленными. MWS и EAP часто ставили друг друга, в то время как HPL и EAP также частично совмещали некоторые в последовательности или стилистически нейтральных предложений.
Я также проверил, в чем была высокая степень достоверности. Например, вот такое предложение:
«Я обошел подвал от одного конца до другого».
Истинным автором был ЭАП, но модель присвоила шансы GPL выше 0,97. Это полезное напоминание о том, что авторские предложения могут оказаться недостаточными. Некоторые предложения просто содержат недостаточно отличительных стилистических признаков, чтобы разреженная линейная модель могла достоверно различать трех похожих гических авторов. несколько базовых способов представления информации на той же контрольной выборке.
Для метода «мешка слов» я использовал подсчет слов с помощью униграмм и биграмм:
В случае с BM25 я рассматривал поиск как классификатор ближайшего соседа. Это не является следствием использования BM25, но это было полезно в качестве точек сравнения. np.argpartition(-scores, kth=K — 1, axis=1)[:, :K]
Для Word2Vec и FastText я обучал векторные представления об обучающем выборе, а затем каждое предложение проявлялось как средневзвешенное значение векторных представленных в IDF его слов. np.zeros((len(tokenized_docs), model.vector_size), dtype=np.float32) для i, токены в enumerate(tokenized_docs): doc_vecs, doc_weights = [], [] для токена в токенах: попробуйте: doc_vecs.append(model.wv[token]) doc_weights.append(idf_weight.get(token, 1.0)) за исключением KeyError: продолжить, если doc_vecs: векторы[i] = np.average(doc_vecs, axis=0, Weights=doc_weights) возвращают векторы
Результаты были приняты:
Обзор, представленный при выборе точек расположения 70/30. Разреженные признаки, основанные на подсчете, показывают лучшие результаты, чем поиск с помощью BM25 и простые усредненные векторные представления Word2Vec/FastText в этой задаче определения авторства сохраняются. тексты.
В схеме данных разреженные признаки, основанные на подсчете слов, оказываются явно более сильными, чем простые усредненные векторные представления. Это не означает, что Word2Vec или FastText в целом слабы. Это означает, что для этой задачи определения авторства требовалось усреднение векторных представленных слов, размыло многие стилистические детали, которые сохранялись при использовании разреженных символов слов, символов и знаков препинания. в строках используется такое же стратифицированное разделение 70/30, поэтому они соединяются напрямую.
Сводка результатов основной модели по всем параметрам валидации.Данные в контрольной группе напрямую блокируются, уровень OOF уровня 2 для полных данных включен в качестве отдельной проверки правильности для окончательной объединенной модели. class=»wp-block-image»>Результат в таблице лидеров Kaggle для финансовой настроенной стековой модели. Итоговая версия показала логарифмическую ошибку в закрытом режиме 0,30414 и в предложенном режиме 0,33621.
Оценка OOF уровня 2 не может быть напрямую отображена с контрольными строками, поскольку в ней используется другая схема оценки.
Что действительно помогло
Наибольшую пользу удалось добиться за счет более качественного представления данных и более четких проверок, а не за счет усложнения ради самой сложности. и разреженные n-граммовые символы сохраняют детали, которые объединяют плотные фигуры, как правило, поглаживают.
Использование знаков препинания и символов n-грамм обеспечивает эффективное моделирование авторства. Добавление функций, проверяющих стиль, подтверждение точности проверок моделей VW с от 0,8332 до 0,8553.
TF-IDF оценка качества вероятностных оценок. Оптимизированный ансамбль TF-IDF не привел к существенному повышению точности, но дал хорошие результаты в логарифмической функции потерь, что и является целью обычных. логарифмическая функция потерь при отложенной выборке с 0,3843 до 0,3504. Это говорит о том, что метаобучающая модель нашла лучший способ объединения оценок, чем простое усреднение.Я разделил результаты на три типа: контрольный образец 70/30, уровни оценки OOF на основе полных данных второго уровня и результаты из таблиц лидеров Kaggle. Они обеспечивают решение разных вопросов, поэтому их движение создавало впечатление большей достоверности результатов, чем они есть на самом деле. class=»wp-block-paragraph»> Первоначальное стекирование конвейера оценивалось с использованием одной контрольной пробы плюс оценка OOF уровня 2 на основе полных данных. Полностью встроенная схема перекрестной проверки выполнена с помощью более внимательной оценки всего процесса моделирования и настройки.
Во-вторых, в качестве основного показателя вероятностной оценки качества я использовал логические функции потерь, но не учитывал явные диагностические данные результатов, такие как диаграммы надежности или ожидаемые ошибки. поскольку конечная цель — качество вероятностной оценки, анализ последовательностей включал следующий шаг. Следующим очевидным эталоном был тонко настроенный трансформер, особенно для проверки того, что постепенно расширялось контекстное представление по сравнению с разреженными классическими эффектами на протяжении литературных предложений.
В-четвертых, поиск гиперпараметров был намеренно ограничен. Более широкий поиск по протоколам TF-IDF, настройкам VW, значениям сглаживания, силам регулярного регулирования и стандартам проектирования стекирования может улучшить конечный результат.
Наконец, набор данных невелик и специфичен для данной предметной области. Эти результаты подтверждают выводы об атрибуции авторства в последующих текстах в данном пятом, неуниверсальном рейтинговом методе обработки естественного языка. Базовая модель Vowpal Wabbit, основанная только на словах, уже была достаточно независимой, но добавлены признаки, различительный стиль, n-граммы слов и символов TF-IDF, настройки с упором на ограничения и многоуровневая генерализация еще большей модели ограничения.
Наиболее распространенные данные обработки классического конвейера показали <60>точность 0,8687 и ~60>потери в логарифмической шкале 0,3504 при разделении выборки на 70/30, объединенная объединенная модель показала потери в логарифмическом измерении ~60>0,30414 для Наши выборы и 0,33621 для публичных выборок на Kaggle.
Главный вывод заключается не только в том, что использование метода стекирования гарантировано результата. Он состоит в том, что при рассмотрении авторства учитываются детали: пунктуация, субсловарная структура, служебные слова и высокие оценки вероятностей. Прежде чем приступить к более сложным контекстным моделям, хорошо проверенная базовая модель на основе разреженного текста все еще может быть главным конкурентом.
Источник данных и лицензия
Здесь используется набор данных Spooky Author Identification от Kaggle, представляющий собой набор данных для классификации текста, созданный на основе отрывков из образовавшихся, возникших в общественном достоянии, таких авторов, как статья Эдгар Аллан По, Г. П. Лавкрафт и Мэри Уолстонкрафт Шелли. Задача состоит в том, чтобы предсказать автору каждого предложения, используя три метки: EAP для Эдгара Аллана По, HPL для Г. П. Лавкрафта и MWS для Мэри Уолстонкрафт Шелли.
Набор данных размещен на Kaggle под лицензией CC BY 4.0. Эта лицензия разрешает распространение и адаптацию, в том числе в коммерческих целях, при наличии существенных указаний традиционных авторов. В статье данный набор данных используется для образовательного уровня машинного обучения, а ссылки на источники приведены в этом разделе.
Спасибо, что дочитали до конца! Надеюсь, этот проект оказался для вас таким же интересным и ключевым, как и для меня. Если у вас есть мысли, вопросы или идеи по расширению эксперимента, не стесняйтесь обращаться ко мне через LinkedIn или мой сайт.
Ссылки
• Полный блокнот + код • LinkedIn • Веб-сайт
Нахид Ахмадванд. Все материалы от Нахида Ахмадванда.