TL; DR
Мы предложили новую поисковую систему для статей, опубликованных в последние годы по ICCV и CVPR. И это работает очень хорошо! Полный код доступен на нашем Github.
Введение
С развитием искусственного интеллекта каждый год публикуются тысячи статей. Как управлять всеми этими бумагами становится проблемой. Кроме того, чтобы лучше использовать эти ценные результаты исследований, как мы можем создать поисковую систему, которая поможет нам быстро и точно найти связанную работу?
Одним из больших успехов является хорошо известный ArXiv, который является бесплатной службой распространения и архивом с открытым доступом для 1 968 218 научных статей в области физики, информатики, статистики, электротехники и так далее. Несомненно, это здорово, что люди могут найти большинство документов, которые они хотят, с помощью такой поисковой системы, но ее можно улучшить во многих аспектах.
Во-первых, ArXiv чувствителен к опечаткам. Даже если вы наберете заглавную букву или забудете использовать ее, вы можете не получить желаемого результата.
Во-вторых, алгоритм поиска в ArXiv недостаточно умен, чтобы понять ваш запрос. Например, если вы только начали свое путешествие в области компьютерного зрения и хотите узнать больше о знаменитой «ResNet», вы не сможете найти статью, если будете искать «Остаточные сети». Вместо этого статья называется «Глубокое остаточное обучение для распознавания изображений».
В-третьих, во время обзора статьи исследователям необходимо искать конкретную тему или метод. Для опытных исследователей это может не быть проблемой, но новичкам нужна более дружелюбная платформа.
Основываясь на вышеуказанных причинах, мы стремимся разработать поисковую систему для поиска научных работ.
- Он должен быть удобен для пользователей, которые не очень разбираются в компьютерном зрении, например, для студентов.
- Пользователи могут искать конкретную тему или метод, например «Трансформатор», «Берт», «MLP-Mixer», и получать соответствующие документы, в которых используются эти методы.
- Он устойчив к небольшим проблемам с опечатками. Например, если пользователь вводит «RexNet», поисковая система все равно найдет документы, связанные с «ResNet».
Мы создали поисковую систему с помощью модели обучения ранжированию, обученной lightGBM (также LGBM), которая представляет собой мощную модель машинного обучения, часто используемую для классификации и ранжирования. Наша модель принимает несколько функций в качестве входных данных и выводит список статей с высокими показателями релевантности.
Данные
Прежде чем перейти к этапу построения модели, мы должны получить хорошо размеченный набор данных для этой конкретной задачи.
В качестве наших данных мы выбираем статьи, опубликованные на конференции по компьютерному зрению и распознаванию образов (CVPR) и Международной конференции по компьютерному зрению (ICCV). CVPR — это ежегодная конференция по компьютерному зрению и распознаванию образов, которая считается одной из самых важных конференций в своей области. ICCV — еще одна ведущая конференция в области компьютерного зрения, которая проводится каждые два года. Мы выбрали CVPR и ICCV в качестве нашей области, потому что по ним опубликовано много выдающихся статей.
Selenium — удобный автономный краулер на Python. С помощью Selenium мы получили около 15 000 статей, опубликованных в CVPR и ICCV с 2015 по 2021 год. Каждую статью можно рассматривать как документ, который состоит из названия, авторов, аннотации, версии LaTex, года публикации, находится ли она на семинаре и есть дополнительный материал. И мы используем регулярные выражения для извлечения подразделов из латекса. Полученные данные сохраняются в pandas DataFrame.
Следующим шагом является выбор нескольких запросов и аннотирование релевантности между запросами и некоторыми документами-кандидатами. Кандидаты сначала извлекаются классическими методами, такими как BM25. Мы оценили релевантность от 5 (очень высокая релевантность) до 1 (очень низкая релевантность) и разделили набор данных на обучающие данные (40 запросов), проверочные данные (10 запросов) и тестовые данные (10 запросов).
Методы
Сначала мы используем PyTerrier для индексации документов и получения 50 статей с максимальной релевантностью. А затем для переранжирования этих работ будет применена модель обучение ранжированию.
Word2Vec
Gensim — полезная библиотека, когда дело доходит до преобразования каждого слова в семантический вектор, который называется вектором встраивания. После преобразования слов во вложения слова со схожими значениями имеют аналогичные вложения.
Чтобы поместить все текстовые данные в модель Word2vec, мы должны разобрать тексты на списки строк. NLTK может помочь превратить кучу длинных текстов в короткие списки токенов.
from nltk.tokenize import RegexpTokenizer from nltk.corpus import stopwords from nltk.stem import PorterStemmer tokenizer = RegexpTokenizer(r'\w+') ps = PorterStemmer() stops = set(stopwords.words('english')) data['abstract_tokens'] = data['abstract'].apply(lambda s: [ps.stem(t) for t in tokenizer.tokenize(s) if t not in stops])
После применения функций предварительной обработки ко всем нашим текстовым полям мы можем объединить все поля, чтобы получить обучающий корпус, с помощью которого модель Word2vec может изучать отношения между словами. Здесь мы выбираем размер встраивания равным 256.
corpus = list(data['abstract_token']) + list(data['subsections_token']) + list(data['title_token']) model = Word2Vec(sentences=corpus, vector_size=256, window=5, min_count=1, workers=4, epochs=10)
Затем эту модель можно использовать для создания вложений для всех слов в словаре. Но чтобы получить вложение для реферата, нам нужно просуммировать все вложения слов в этом реферате. Для запросов то же самое. Вложения документов рассчитываются заранее, в то время как встраивания для запросов генерируются на лету.
Подготовка функций
Для каждой пары запроса и документа мы объединяем метаданные с парами и начинаем извлекать функции, которые могут измерять отношения между запросом и документами или некоторые характеристики документов.
Для этой задачи мы определили четыре типа признаков:
- Функция первого типа измеряет сходство между встраиванием запроса и наложением documentem. Мы включили три типа «расстояний»: внутренний продукт, косинусное сходство и евклидово расстояние.
def _cal_embedding_dists(self, doc_data): series = [] distances = { 'dot': lambda x, y : x.dot(y), 'cos': lambda x, y : x.dot(y) / (np.linalg.norm(x) * np.linalg.norm(y) + 1e-9), 'euclidean': lambda x, y : np.linalg.norm(x - y) } for _, row in doc_data.iterrows(): cur_dists = [] query_embedding = self.query_embeddings_dict[row['qid']] for field in ['title', 'abstract', 'subsections']: dists = [dist_func(query_embedding, row[field + '_embedding']) for dist_func in distances.values()] cur_dists.extend(dists) series.append(np.array(cur_dists)) return pd.Series(series)
- Второй тип функции — это релевантность PyTerrier. Мы приняли методы tf-idf, BM25, CoordinatMatch для оценки текстов.
- Элементы третьего типа отображают некоторые основные атрибуты документов, такие как год, конференция, исходят ли они из семинара и содержат ли они дополнительные материалы.
import pyterrier as pt def _get_doc_property(self): # publish time, conference, is_workshop, has_supp ... pipeline = ( (pt.apply.doc_score(lambda row: int(row["year"]))) ** (pt.apply.doc_score(lambda row: int(row["conference"]=="CVPR"))) #CVPR:1,ICCV:0 ** (pt.apply.doc_score(lambda row: int(row["workshop"]!=''))) ** (pt.apply.doc_score(lambda row: int(row["supp_link"]!=''))) ** (pt.apply.doc_score(lambda row: row['score'])) ) res = pipeline.transform(self.data)['features'] return res
- Четвертый тип функции касается того, соответствует ли часть запроса именам авторов.
Научитесь ранжировать с LightGBM
Библиотека lightgbm — это хорошо написанная библиотека с открытым исходным кодом на Python, основанная на Scikit-Learn. Таким образом, мы можем легко использовать эту библиотеку для обучения нашей модели с помощью API-интерфейсов sklearn. Также в этом классе реализована версия для ранжирования по списку, которая больше всего подходит для нашей задачи обучения ранжированию. Для обучения мы напрямую используем аннотированную релевантность от 1 до 5 в качестве целевой метки и подбираем модель, используя извлеченные функции и соответствующие метки.
self.model = lgb.LGBMRanker( task="train", silent=True, min_child_samples=1, num_leaves=24, max_depth=5, objective="lambdarank", metric="ndcg", learning_rate= 0.064, importance_type="gain", num_iterations=150, subsample=0.8 ) self.model.fit( train_feats, train_labels, group=train_features.groupby('qid')['qid'].count().to_numpy(), eval_set=[(val_feats,val_labels)], eval_group=[val_features.groupby('qid')['qid'].count().to_numpy()], eval_at=[5, 10, 20], eval_metric='ndcg' )
Результаты и обсуждения
Во-первых, давайте представим метрику, используемую в нашем проекте. nDCG — это тип взвешенной суммы оценок релевантности отсортированного списка извлеченных документов.
где relᵢ — это оценка релевантности i-го документа, а iDCG — максимально возможная оценка DCG, когда заказ становится идеальным заказом. Эта метрика придает большее значение правильному ранжированию топ-k результатов.
Затем давайте сравним нашу LGBM по списку с другими базовыми показателями, упомянутыми выше.
Из рисунка видно, что списочная модель LGBM работает лучше всего, в то время как точечная LGBM и логистическая регрессия не могут превышать BM25. Результат близок к ожидаемому.
LGBM — это повышающий алгоритм, но логистическая регрессия — это единственная модель. Поэтому разумно, что объединение различных моделей работает лучше, чем одна модель. Кроме того, LGBM может соответствовать нелинейным функциям, в то время как логистическая регрессия, как обобщенная линейная модель, не может хорошо соответствовать нелинейным функциям.
Причина, по которой списочная модель работает лучше, чем поточечная, заключается в том, что списочная модель может одновременно изучать как отношения между запросами и документами, так и отношения между различными документами по одному и тому же запросу. Суть переранжировки заключается в перестановке документов. Таким образом, ключом является не оценка, а порядок. Точечная модель фокусируется на прогнозировании оценки для каждой выборки, но игнорирует взаимосвязь между различными выборками.
Чтобы лучше понять, как работает наша модель, мы задаемся вопросом, какие функции играют важную роль в нашей модели, и инструмент для выяснения этого — важность функций. Обычные методы включают линейную регрессию и древовидные методы. Учитывая, что наша модель LightGBM основана на деревьях решений, мы можем легко определить важность каждой функции.
def plot_importance(model, feat_names): values = model.booster_.feature_importance() fi = sorted(zip(values, feat_names), reverse=True) values, features = zip(*fi) plt.bar(values[:-1], features[:-1]) plt.xticks(rotation=90) plt.show()
Число показывает, сколько раз эта функция использовалась для разделения узла в деревьях решений LGBM. Чем больше раз он используется, тем более важной становится функция.
На рисунке «оценка» — это взвешенная сумма оценок BM25 для различных частей документа. Суффикс «s» обозначает субтитры, «a» — «аннотация» и «t» — заголовок. Мы можем получить, что наиболее важными функциями являются оценки BM25 и внутренние продукты вложений, что согласуется с нашими ожиданиями.
Что дальше
Есть некоторые возможные улучшения в нашей будущей работе.
- Более мощные модели. Алгоритм на основе дерева делит данные на ячейки, которые могут терять точность при работе со смежными переменными. Большие языковые модели, основанные на глубоких нейронных сетях, таких как BERT, вероятно, работают лучше.
- Дизайн запроса. Наши запросы могут быть субъективными. Мы не можем разрабатывать запросы, связанные с незнакомыми темами компьютерного зрения. Объективным способом является обращение к некоторым обзорным документам, которые делят компьютерное зрение на разные области. Затем мы можем разработать запросы, охватывающие все поля.
- Аннотация. Распределения оценок, помеченных двумя членами, различаются, что может быть потенциальной проблемой. Возможно, нам придется разработать строгое правило маркировки.
- Другие источники данных. Мы можем включить в нашу базу данных больше конференций по компьютерному зрению, таких как ECCV.
- Выборка. Отрицательная выборка — хороший способ увеличения данных. Кроме того, это хороший способ сбалансировать ярлыки, если низкорелевантные образцы представлены недостаточно.
- Внешняя презентация. Мы разместим нашу модель на веб-сайте, чтобы сделать вклад как для студентов, так и для исследователей.
Если вам интересно, посмотрите другие мои блоги на https://kungtalon.github.io/.