- Оригинальный адрес:Build an Article Recommendation Engine With AI/ML
- Оригинальный автор:Tyler Hawkins
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:jaredliw
- Корректор:greycodee,KimYangOfCat
Контент-платформы быстро выросли, рекомендуя релевантный контент пользователям. Чем более релевантный контент предлагает платформа, тем дольше пользователи остаются на сайте, что часто приводит к доходу от рекламы для компании.
Если вы когда-либо посещали новостной веб-сайт, электронное издательство или платформу для ведения блога, скорее всего, вы уже использовали систему рекомендаций. Каждая платформа рекомендует контент, который может вам понравиться, исходя из вашей истории чтения.
Чтобы назвать простое решение, платформа может реализовать механизм рекомендаций на основе тегов — скажем, вы прочитали статью «бизнес», и она также рекомендует пять связанных статей с тегом «бизнес». Однако лучший способ создать рекомендательный механизм — использоватьАлгоритмы поиска сходства и машинного обучения.
В этой статье мы создадим приложение Python Flask, которое используетPinecone(служба поиска по сходству), чтобы создать собственную систему рекомендаций по статьям.
Обзор демонстрационного приложения
Короткая анимация ниже демонстрирует, как работает наше приложение. Изначально на странице отображается десять статей. Пользователи могут выбрать любую комбинацию из этих десяти статей, чтобы представить свою историю чтения. Когда пользователь нажимает кнопку отправки, история чтения используется в качестве входных данных для запроса к базе данных статей, а затем пользователю отображаются десять связанных статей.
Как видите, возвращенные связанные статьи очень точны! В этом примере есть 1024 возможных комбинации истории чтения, которые можно использовать в качестве входных данных, и каждая комбинация дает значимые результаты.
Итак, как мы это делаем?
При создании приложения мы сначала нашли приложение от Kaggle.Набор данных новостных статей. Набор данных содержит 143 000 новостных статей от 15 крупных издателей, но мы используем только первые 20 000. (Полный набор данных содержит более 2 миллионов статей!)
После этого мы почистили набор данных, переименовав несколько столбцов и удалив ненужные. Затем мы загружаем статьи в модель встраивания, чтобы получитьвложение вектор— Это метаданные для алгоритмов машинного обучения для определения сходства между различными входными данными. мы используемСредняя модель встраивания слов. Затем мы вставляем эти векторы встраивания в управляемый Pineconeвекторный индекссередина.
После добавления вектора встраивания в индекс мы можем начать поиск релевантного контента. Когда пользователь отправляет свою историю чтения, запрос отправляется в конечную точку API, которая использует SDK Pinecone для запроса индекса вектора внедрения. Конечная точка возвращает десять похожих новостных статей и отображает их в пользовательском интерфейсе приложения. Вот и все! Разве это не просто?
Если вы хотите попробовать сами, вы можетеНайдите исходный код этого приложения на GitHub.. существуетREADME
содержит инструкции и инструкции о том, как запустить приложение на локальном устройстве.
Код
Мы видели внутреннюю работу приложения, но как мы на самом деле его создадим? Как уже упоминалось, это приложение Python Flask, использующее SDK Pinecone. HTML использует файлы шаблонов, а остальная часть внешнего интерфейса построена с использованием статического CSS и JavaScript. Для простоты весь внутренний код находится вapp.py
файл, я полностью скопировал файл ниже:
from dotenv import load_dotenv
from flask import Flask
from flask import render_template
from flask import request
from flask import url_for
import json
import os
import pandas as pd
import pinecone
import re
import requests
from sentence_transformers import SentenceTransformer
from statistics import mean
import swifter
app = Flask(__name__)
PINECONE_INDEX_NAME = "article-recommendation-service"
DATA_FILE = "articles.csv"
NROWS = 20000
def initialize_pinecone():
load_dotenv()
PINECONE_API_KEY = os.environ["PINECONE_API_KEY"]
pinecone.init(api_key=PINECONE_API_KEY)
def delete_existing_pinecone_index():
if PINECONE_INDEX_NAME in pinecone.list_indexes():
pinecone.delete_index(PINECONE_INDEX_NAME)
def create_pinecone_index():
pinecone.create_index(name=PINECONE_INDEX_NAME, metric="cosine", shards=1)
pinecone_index = pinecone.Index(name=PINECONE_INDEX_NAME)
return pinecone_index
def create_model():
model = SentenceTransformer('average_word_embeddings_komninos')
return model
def prepare_data(data):
# 重命名 id 列并删除不必要的列
data.rename(columns={"Unnamed: 0": "article_id"}, inplace = True)
data.drop(columns=['date'], inplace = True)
# 仅提取每篇文章的前几句话以加快向量的计算
data['content'] = data['content'].fillna('')
data['content'] = data.content.swifter.apply(lambda x: ' '.join(re.split(r'(?<=[.:;])\s', x)[:4]))
data['title_and_content'] = data['title'] + ' ' + data['content']
# 基于标题列和文章列,创建 embedding 向量
encoded_articles = model.encode(data['title_and_content'], show_progress_bar=True)
data['article_vector'] = pd.Series(encoded_articles.tolist())
return data
def upload_items(data):
items_to_upload = [(row.id, row.article_vector) for i, row in data.iterrows()]
pinecone_index.upsert(items=items_to_upload)
def process_file(filename):
data = pd.read_csv(filename, nrows=NROWS)
data = prepare_data(data)
upload_items(data)
pinecone_index.info()
return data
def map_titles(data):
return dict(zip(uploaded_data.id, uploaded_data.title))
def map_publications(data):
return dict(zip(uploaded_data.id, uploaded_data.publication))
def query_pinecone(reading_history_ids):
reading_history_ids_list = list(map(int, reading_history_ids.split(',')))
reading_history_articles = uploaded_data.loc[uploaded_data['id'].isin(reading_history_ids_list)]
article_vectors = reading_history_articles['article_vector']
reading_history_vector = [*map(mean, zip(*article_vectors))]
query_results = pinecone_index.query(queries=[reading_history_vector], top_k=10)
res = query_results[0]
results_list = []
for idx, _id in enumerate(res.ids):
results_list.append({
"id": _id,
"title": titles_mapped[int(_id)],
"publication": publications_mapped[int(_id)],
"score": res.scores[idx],
})
return json.dumps(results_list)
initialize_pinecone()
delete_existing_pinecone_index()
pinecone_index = create_pinecone_index()
model = create_model()
uploaded_data = process_file(filename=DATA_FILE)
titles_mapped = map_titles(uploaded_data)
publications_mapped = map_publications(uploaded_data)
@app.route("/")
def index():
return render_template("index.html")
@app.route("/api/search", methods=["POST", "GET"])
def search():
if request.method == "POST":
return query_pinecone(request.form.history)
if request.method == "GET":
return query_pinecone(request.args.get("history", ""))
return "Only GET and POST methods are allowed for this endpoint"
app.run()
Давайте рассмотримapp.py
важная часть файла, чтобы мы могли ее понять.
В строках с 1 по 14 мы представляем зависимости приложения. Наше приложение зависит от следующих пакетов:
-
dotenv
позаимствованно из.env
Чтение переменных окружения из файла -
flask
Для настройки веб-приложения -
json
для обработки JSON -
os
Также используется для получения переменных среды -
pandas
для обработки наборов данных -
pinecone
Для использования Pinecone SDK -
re
Для обработки регулярных выражений (RegEx) -
requests
Используется для отправки запросов API для загрузки наших наборов данных. -
statistics
Предоставляет некоторые удобные статистические функции -
sentence_transformers
для нашей модели встраивания -
swifter
для обработкиpandas
изDataFrame
В строке 16 мы предоставляем некоторый код шаблона, чтобы сообщить Flask имя нашего приложения.
В строках 18-20 мы определяем некоторые константы, которые будут использоваться в приложении, включая имя нашего индекса Pinecone, имя файла набора данных и количество строк для чтения из CSV-файла.
В строках с 22 по 25 нашinitialize_pinecone
метод из.env
Получите ключ API из файла и используйте его для инициализации Pinecone.
В строках 27-29 нашdelete_existing_pinecone_index
Метод ищет в экземпляре Pinecone индекс с тем же именем, что и индекс, который мы используем («служба рекомендаций статей»). Если существующий индекс найден, мы удаляем его.
В строках с 31 по 35 нашcreate_pinecone_index
Метод создает новый индекс с именем по нашему выбору («служба-рекомендации-статьи»), используя косинусное сходство в качестве метрики и сегмент данных, равный 1.
В строках с 37 по 40 нашcreate_model
использование методаsentence_transformers
библиотека для обработки средней модели встраивания слов. Позже мы будем использовать эту модель для кодирования нашего вектора встраивания.
В строках с 62 по 68 нашprocess_file
метод для чтения CSV-файла, а затем вызовитеprepare_data
иupload_items
метод. Оба метода описаны ниже.
В строках с 42 по 56 нашprepare_data
метод, переименовав первыйid
столбец и удалитьdate
столбцы для корректировки набора данных. Затем он берет первые четыре строки каждой статьи и объединяет их с заголовком статьи, чтобы создать новое поле в качестве данных для кодирования. Мы могли бы создать векторы встраивания на основе всего тела статьи, но для ускорения процесса кодирования достаточно четырех строк.
В строках с 58 по 60 нашupload_items
Метод создает вектор внедрения для каждой статьи, кодируя ее с помощью нашей модели, а затем вставляет вектор внедрения в индекс Pinecone.
В строках с 70 по 74 нашmap_titles
иmap_publications
Метод создает несколько словарей с названиями и издателями, чтобы потом было легче находить статьи по их ID.
Каждый из описанных выше методов вызывается в строках с 98 по 104 при запуске серверного приложения. Эта работа подготавливает нас к последнему шагу — запросу к индексу Pinecone на основе пользовательского ввода.
В строках со 106 по 116 мы определяем два маршрута для приложения: один для домашней страницы и один для конечной точки API. Предложения на главной страницеindex.html
Файлы шаблонов, а также ресурсы JavaSript и CSS, а также конечная точка API предоставляют функции поиска для запросов к индексу Pinecone.
Наконец, в строках с 76 по 96 нашquery_pinecone
Метод берет входные данные истории чтения пользователя, преобразует их в вектор внедрения, а затем запрашивает индекс Pinecone, чтобы найти похожие статьи. Получать/api/search
Этот метод будет вызываться при достижении конечной точки. Этот API вызывается всякий раз, когда пользователь отправляет новый поисковый запрос.
Для визуалов вот схема, показывающая, как работает приложение:
Пример сцены
Итак, соединив все это вместе, на что похож пользовательский опыт? Давайте рассмотрим три сценария: три группы пользователей, интересующихся спортом, технологиями и политикой.
Спортивные пользователи выбрали первые две статьи о двух известных теннисистках, Серене Уильямс и Энди Мюррее, в качестве своих историй чтения. После того, как они отправят свой выбор, приложение возвращает статьи об Уимблдоне, Открытом чемпионате США, Роджере Федерере и Рафаэле Надале. точный!
Пользователи, интересующиеся технологиями, выбрали статьи о Samsung и Apple. После того, как они отправят свой выбор, приложение отвечает на статьи о Samsung, Apple, Google, Intel и iPhone. Еще одна отличная рекомендация!
Пользователи, интересующиеся политикой, выбирают статью о фальсификациях на выборах. После того, как они отправят свой выбор, приложение возвращает статьи об удостоверении личности избирателя, выборах в США 2020 года, явке избирателей и незаконных заявлениях о выборах (и почему они не заблокировали его).
Попробовав три сценария! Наш механизм рекомендаций оказался очень полезным.
в заключении
Теперь мы создали простое приложение Python для решения реальной проблемы. Если контент-сайты могут рекомендовать релевантный контент пользователям, пользователи получат больше удовольствия от него и проведут на нем больше времени, что, в свою очередь, принесет компании больший доход. Беспроигрышная ситуация!
Поиск по сходству помогает предоставить пользователям более подходящие предложения. А Pinecone, служба поиска по сходству, позволяет вам легко давать рекомендации пользователям, чтобы вы могли сосредоточиться на том, что у вас получается лучше всего — на создании качественной платформы, наполненной контентом, который стоит прочитать.
Если вы обнаружите ошибки в переводе или в других областях, требующих доработки, добро пожаловать наПрограмма перевода самородковВы также можете получить соответствующие бонусные баллы за доработку перевода и PR. начало статьиПостоянная ссылка на эту статьюЭто ссылка MarkDown этой статьи на GitHub.
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.