[Python, Data Mining, Хакатоны, Машинное обучение, Natural Language Processing] Sibur Challenge 2020 или «как мы фичи придумывали»

Автор Сообщение
news_bot ®

Стаж: 6 лет 4 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
21-Дек-2020 16:31

Всем привет! В этом году компания Sibur Digital вновь проводила крупный (по сравнению с другими российскими) чемпионат по анализу данных. Мы с другом в нём участвовали и хотели бы поделиться с читателями Хабра своим решением и опытом, полученным от участия. Конечно вряд ли мы америку откроем этой статьей, но какой-нибудь новичок в соревнованиях по АД точно сможет почерпнуть для себя что-то полезное.Кто мы такие? Мы студенты которые очень сильно увлеклись темой DS и ML. Впервые мы узнали об этой сфере на конференции AI Journey, проходившей в нашем вузе. С того момента прошли не один, и не два, и не три курса (от Омского Государственного Технического университета до Andrew NG) и теперь постоянно участвуем в хакатонах и соревнованиях(в некоторых даже заняли призовые места), параллельно ищем стажировку.О задачеМы взялись за вторую задачу соревнования - "сопоставление названий". Суть следующая : Сибур работает с огромным количеством новых компаний, и для оптимизации рабочего процесса им было бы полезно понимать, что они работают с уже ранее знакомым холдингом. К примеру "Сибур Нефтехим" и "СИБУР ИТ" из одного холдинга, и при работе с одной из этих компаний было бы полезно использовать накопленную ранее информацию о холдинге СИБУР.Перефразируем задачу на язык DS. Даны два названия, по ним мы должны определить - принадлежат ли компании одному холдингу или нет.name_1name_2is_duplicateJapan Synthetic Rubber CoJsr Bst Elastomer1JSR CorporationBST ELASTOMERS CO.0Примерно так выглядел датасет.Предобработка данныхВ первую очередь мы привели данные к латинице с помощью волшебного модуля unidecode. Далее привели к нижнему регистру, убрали всякий мусор в виде ненужных знаков препинания, двойных пробелов и т.д.
from unidecode import unidecode
import re
def preprocess(text: str):
    text = unidecode(text)
    text = text.lower()
    text = re.sub(r'[\.,]+', '', text)
    text = re.sub(r"\(.*\)", ' ', text)
    text = re.sub(r"[^\w\s]", ' ', text)
    text = re.sub(r'\b\w\b', ' ', text)
    text = ' '.join(text.split())
    return text
После взялись за удаление ненужных слов. Первыми в список мусора полетели названия стран в названиях, для этого взяли модуль pycountry(который любезно подсказали организаторы в бейзлайн решении) и немного дополнили этот список стран их сокращениями, аббревиатурами которые сами нашли в выборке. Со стоп словами было посложнее. Конечно мы сразу удалили некоторое количество самых частотных слов, но понижая порог количества вхождений для удаления, мы заметили, что большинство названий в выборке просто остается пустым. При этом в "уцелевших названиях" остаются такие слова как "shanghai", и, очевидно они никак не подчеркивают уникальность компании, а лишь увеличивают путаницу среди шанхайских компаний. В результате пришлось из наиболее частотных слов самим выбирать бессмысленные и удалять их.Поиск фичейВзявшись за соревнование мы сразу решили, что не будем заострять свое внимание на сложных ансамблях моделей и огромных нейронных сетях, а постараемся подойти креативнее и больше работать с данными - искать закономерности и на их основе придумывать фичи (как минимум, второй подход казался нам поинтереснее). В целом, можно обобщить : мы пытались использовать придуманные фичи для оценивания "похожести" строк, и уже на них обучать модель.Первый прорыв нам дал признак "сколько букв сначала совпадает в двух словах подряд". Обучив логистическую регрессию в начале соревнования только на одном этом признаке мы получили результат чуть более 0.3 и перепрыгнули большинство в начале соревнования. В дальнейшем мы использовали не просто число совпадающих букв, а число совпадающих букв делим на суммарное количество букв обоих названий.Вторым полезным признаком оказался коэффициент Жаккара взятый по словам из двух названий. Т.е мы разделили число пересекающихся слов в названиях на количество уникальных слов в двух названиях.И в конце мы добавили бинарный признак, который непонятно почему пришел нам в голову последним, хотя на первый взгляд он самый очевидный. Содержит ли одно название все слова другого.Остальные признаки, которые не оказались столь удачными, приведены в списке ниже:
  • количество совпадающих первых гласных, согласных
  • количество совпадающих первых буквы сокращения (аббревиатуры)
  • стандартные метрики: левенштейн, яро винклер, фузи вузи
  • tfidf - при подсчёте жаккара (или косинусного расстояния с нграммами)
  • сортировать уникальные слова в имени и считать наши метрики
  • процент пересекающихся ngram
  • количество совпадающих первых букв каждого слова (брать максимум)
  • количество букв первого, количество букв второго
  • количество слов первого, количество второго
Модель и блендинг решений Как упоминалось выше, мы не собирались строить свое решение целиком и полностью на сильной модели, поэтому в качестве классификатора использовали XGBoost, который показал себя получше других простых моделей. И мы получили результат ~ 0.59 на лидерборде. Далее мы понимали, что было бы неплохо обменяться с кем-то идеями и объединить решения. Мы познакомились с двумя другими участниками(Алехандро, Дмитрий, привет!), и заблендили наши решения, получив скор 0.69 на лидерборде. Так получилось, что все три наших решения имели разные подходы к задаче, поэтому их объединение и улучшило результат.Выводы В любой истории главное - выводы, поэтому, уверен, это будет самая интересная часть.Начать стоит с того, что помогло нам достичь результата. В первую очередь это то, что мы не пошли простым путем fit_predict, а постарались посмотреть на задачу с разных сторон. Перепробовали огромное количество различных методов(начиная от метрики Левенштейна и подсчитывания косинусного расстояния и заканчивая сиамскими нейросетями). Провели анализ ошибок модели, который помог выстроить правильную предобработку и обновить словарь стоп-слов.Что можно было доработать?Можно было учитывать семантику слов или выдавать словам веса: если слово в двух названиях совпало и оно полезно (относится к названию компании) - имеет вес, мы автоматически считаем что оно настолько же вредно в "разнице" слов; использование как можно больше внешних данных с названием компаний и т. д. Также не забывать анализировать наблюдения, на которых ошибается модель (False Positive, False Negative), и на основе этого конструировать новые признаки.P.S.Весь код лежит здесь Если хотите связаться с нами : matnik2001@gmail.com , domonion@list.ru
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_python, #_data_mining, #_hakatony (Хакатоны), #_mashinnoe_obuchenie (Машинное обучение), #_natural_language_processing, #_analiz_dannyh (анализ данных), #_mashinnoe_obuchenie (машинное обучение), #_hakaton (хакатон), #_nlp, #_obrabotka_estestvennogo_jazyka (обработка естественного языка), #_python, #_features, #_feature_selection, #_fichi (фичи), #_feature_extraction, #_python, #_data_mining, #_hakatony (
Хакатоны
)
, #_mashinnoe_obuchenie (
Машинное обучение
)
, #_natural_language_processing
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 11-Июн 06:03
Часовой пояс: UTC + 5