Введение в использование Keras с Neo4j

Мы демонстрируем подключение графической базы данных Neo4j к Keras. Мы строим нейронную сеть, достигающую 100% точности теста на простой задаче прогнозирования обзора.

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

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

Машинное обучение (ML) - мощная технология, которая быстро внедряется технологическими командами по всему миру. Он способен решать проблемы, которые очень сложно решить с помощью написанного вручную кода; например, с помощью написанного от руки кода можно было обыграть гроссмейстера по шахматам в 1997 году, но потребовалось появление машинного обучения, чтобы компьютер победил профессионала в го в 2015 году.

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

Ресурсов о том, как создавать системы машинного обучения на основе графов, не так много. Вместе с Эндрю Джефферсоном я исследовал разные подходы. В ближайшие месяцы мы поделимся тем, что нашли.

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

Краткое введение в графические базы данных и Neo4j

Мы собираемся изучать обзоры продуктов. В нашем мире есть люди, которые пишут отзывы о продуктах. Вот как это выглядит на графике:

В базе данных графов мы можем запрашивать информацию на основе шаблонов. База данных Neo4j, которую мы здесь будем использовать, использует язык запросов под названием Cypher. Приведенный выше график был создан с помощью простого запроса:

MATCH g=(:PERSON) -[:WROTE]-> (:REVIEW) -[:OF]-> (:PRODUCT) 
RETURN g LIMIT 1

При этом выполняется поиск узла с меткой PERSON с отношением метки WROTE к узлу с меткой REVIEW с отношением метки OF к узлу с ярлыком PRODUCT. Квалификатор «LIMIT 1» требует от базы данных вернуть только один экземпляр, соответствующий этому шаблону.

Neo4j реализует модель графа свойств, в которой узлы и отношения могут иметь свойства. Это действительно гибкая модель, позволяющая нам удобно размещать данные там, где мы хотим.

В нашем примере диаграммы отзывы имеют свойство оценки от 0 до 1:

review = {
  "score": 1,
  "id": "7409a120-c85e-4297-90a7-7a2e04cc5a43",
}

Задача, которую мы решим

Мы создали очень простую диаграмму обзора продукта. Это синтетический набор данных, созданный на основе вероятностной модели, которую мы разработали с целью изучения графового машинного обучения.

Задача состоит в том, чтобы предсказать, какую оценку по отзывам получит продукт.

На нашем графике есть следующие узлы со свойствами:

  • Человек с вектором style_preference шириной 6, который быстро кодирует, какой стиль продукта ему нравится.
  • Товар с вектором style шириной 6, который быстро кодирует стиль этого товара.
  • Обзор между человеком и продуктом с score числом с плавающей запятой.

Примечание по style и style_preference : эти векторы предоставляются в виде горячих кодировок, чтобы упростить модель машинного обучения. В более реалистичной базе данных графов они могут быть закодированы как отношения.

Как рассчитываются оценки по отзывам

Отзыв score рассчитывается как скалярное произведение между личным style_preference и товарным style.

Например, Джейн с style_preference [0,1,0,0,0,0] рассматривает продукт Nintendo Switch с style [0,1,0,0,0,0], а ее обзор score равен 1.0. Когда она рецензирует PS4 с style [1,0,0,0,0,0], ее рецензия score составляет 0,0.

Создание собственной системы графического машинного обучения

Базовая настройка

Вы можете скачать код этой статьи с нашего общедоступного github:

git clone https://github.com/Octavian-ai/article-0.git

Мы написали эту систему на Python. Python - популярный выбор среди специалистов по обработке данных и исследователей искусственного интеллекта, поскольку он имеет множество полезных библиотек для анализа данных, включая Tensorflow, SciPy и Numpy. Мы собираемся использовать Keras для машинного обучения, потому что он позволяет очень легко писать и обучать нашу простую сеть.

Давайте установим наши зависимости с помощью pipenv:

$ cd article-0/
$ pip install pipenv
$ pipenv install
$ pipenv shell
(article-0) $

Мы разместили для вас базу данных Neo4j с уже загруженным набором данных. Когда вы запустите ./train.py, он по умолчанию будет использовать нашу размещенную базу данных.

Если вы хотите разместить данные локально, установите Neo4j и используйте наш репозиторий для генерации данных для генерации набора данных article-0, затем обновите settings.json, чтобы он указывал на вашу базу данных.

Вы можете проверить данные самостоятельно. Откройте браузер Neo4j с этим именем пользователя и паролем, затем попробуйте выполнить запрос MATCH g = (person) -[:WROTE]-> (review) -[:OF]-> (product) RETURN g LIMIT 100:

Машинное обучение

Следующим шагом является выполнение машинного обучения данных в нашей базе данных графов.

Мы собираемся использовать для этого Keras (часть проекта Tensorflow). Keras - это оболочка высокого уровня для фреймворков глубокого обучения, таких как Tensorflow. Keras позволяет создавать и обучать модель всего несколькими строками кода, поскольку библиотека берет на себя большую часть повторяющегося шаблона.

Общая схема нашей обучающей системы состоит в том, чтобы передавать каждый (:PERSON)-->(:REVIEW)-->(:PRODUCT) путь в виде конкатенированного [product.style, person.style_preference] вектора и просить систему предсказать review.score

Мы собираемся построить модель с двумя скрытыми слоями - входные данные проходят через два полностью связанных слоя, а затем проходят через выходной слой с одним узлом. Для всестороннего введения в нейронные сети с прямой связью см. Некоторые из отличных руководств в Интернете.

Импорт данных в Керас

Давайте начнем составлять код для запроса к базе данных, чтобы мы могли передать данные в Keras.

Keras предоставляет Sequence класс для ввода данных в структуру. Мы создадим наш собственный подкласс, который сможет потреблять данные из базы данных Neo4j.

Вот шифровальный запрос, который мы будем использовать для получения входных данных для обучающей системы:

MATCH p=
    (person:PERSON)
    -[:WROTE]->
    (review:REVIEW {dataset_name:{dataset_name}, test:{test}})
    -[:OF]->
    (product:PRODUCT)
RETURN person.style_preference + product.style as x, review.score as y

Как описано ранее, мы сопоставляем все (:PERSON)-->(:REVIEW)-->(:PRODUCT) пути. Затем мы объединяем product.style + person.style_preference, чтобы сформировать вектор, значение x (вход модели) и использовать review.score в качестве значения y (цель прогнозирования).

У нас есть два параметра запроса: dataset_name (для этого эксперимента это 'article_0', чтобы вы могли проводить несколько экспериментов вместе в одной базе данных) и test (набор данных содержит отдельные данные для обучения модели и тестирования модели, мы подробнее об этом позже)

Благодаря нашему зашифрованному запросу мы упростили задачу до прогнозирования на основе строк, известного формата в мире машинного обучения. Цель нашей системы машинного обучения - предсказать значения y по значениям x.

В graph-sequence.py мы выполняем некоторую стандартную настройку драйвера Neo4j, затем запрашиваем и упаковываем данные для Keras. Данные разбиваются на партии, как того требует Керас:

data = session.run(self.query, **self.query_params).data()
data = [ (np.array(i["x"]), i["y"]) for i in data]
# Split the data up into "batches"
data = more_itertools.chunked(data, self.batch_size)
# Format our batches in the way Keras expects them
self.data = [ (np.array([j[0] for j in i]), np.array([j[1] for j in i])) for i in data]

Создание модели машинного обучения

Теперь, когда у нас есть данные, последний шаг - построение модели Keras, а затем ее обучение на наших данных.

Keras предоставляет очень быстрый и простой API для построения моделей. Вот модель, которую мы будем использовать:

model = Sequential([
    Dense(6, input_shape=(12,), activation='tanh'),
    Dense(6, activation='tanh'),
    Dense(1, activation='tanh'),
])
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])

Модель имеет два плотных слоя шириной 6 с активационными слоями tanh. Это дает возможность отдельно комбинировать соответствующие элементы из векторов style_preference и style.

Затем наносится выходной слой шириной один, также с активацией tanh. В этот момент сеть сгенерировала единственное значение, прогноз для обзора score.

Построив нашу модель, мы компилируем ее, используя популярный оптимизатор Адама и среднеквадратичную ошибку в качестве функции потерь.

Как вкратце упоминалось ранее, мы разделили наши данные на отдельные данные для обучения и данные для тестирования. Обучающие данные используются для обучения нейронной сети, а тестовые данные используются для оценки производительности обученной сети.

Мы разделяем данные таким образом, потому что нейронные сети очень хорошо запоминают ответы на свои обучающие данные, не обучаясь предсказывать новые данные. Отдельный набор тестов позволяет нам определить, действительно ли сеть научилась предсказывать невидимые данные.

Мы используем данные обучения для обучения сети:

seq_train = GraphSequence(args)
model.fit_generator(seq_train, epochs=10)

Затем, наконец, мы оцениваем его прогностические возможности, используя тестовые данные:

seq_test = GraphSequence(args, test=True)
result = model.evaluate_generator(seq_test)
print(f"Accuracy: {round(result[1]*100)}%")
# Accuracy: 100.0%

Сеть достигает 100% точности на тестовом наборе. Обучение на Macbook Pro 2015 года занимает 12 секунд без ускорения графического процессора (это очень простая модель!). Это означает, что для каждого элемента данных в наборе тестов он правильно предсказывает оценку обзора. Наша задача выполнена!

Поскольку эта сеть может предсказать продукты, которые человек, скорее всего, оставит положительным отзывом, ее можно использовать для предложения покупок этому человеку.

Вы можете увидеть полный код здесь.

Резюме

Мы продемонстрировали подключение графической базы данных Neo4j к Keras и запроса Cypher, который форматирует данные для обучения нейронной сети.

Мы построили нейронную сеть, обеспечивающую 100% точность тестирования на простой задаче прогнозирования отзывов.

Следующие шаги

Если вам интересно, попробуйте добавить новые функции в узлы Человек и Продукт, которые влияют на оценку отзыва. Кроме того, попробуйте внести некоторый шум в расчет оценки по обзору и посмотрите, как это повлияет на точность теста. Нейронная сеть должна быть устойчивой к умеренному шуму и должна хорошо справляться с новыми функциями - если она не справляется, попробуйте сделать скрытые слои немного шире, чтобы она могла выполнять больше вычислений.

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

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