Русский
Русский
English
Статистика
Реклама

Анализ социальных сетей

Изучаем YELP с помощью Neo4j, python

12.05.2021 16:20:09 | Автор: admin

YELP зарубежная сеть, которая помогает людям находить местные предприятия и услуги, основываясь на отзывах, предпочтениях и рекомендациях. В текущей статей будет проведен определенный ее анализ с использованием платформы Neo4j, относящаяся к графовым СУБД, а также язык python.
Что посмотрим:
как работать с Neo4j и объемными датасетами на примере YELP;
чем может быть полезен YELP dataset;
частично: какие особенности в новых версиях Neo4j и почему книга Графовые алгоритмы 2019 года от O'REILLY уже устарела.


Что такое YELP и yelp dataset.


Сеть YELP на текущий момент охватывает 30 стран, РФ пока не входит в их число. Русский язык сетью не поддерживается. Сама сеть содержит достаточно объемное количество сведений о различного рода предприятиях, а также отзывах о них. Также yelp можно смело назвать социальной сетью, так как в ней имеются данные о пользователях, оставлявших отзывы. Никаких персональных данных там нет, только имена. Тем не менее пользователи образуют сообщества, группы или же могут быть в дальнейшем в эти группы и сообщества объединены по различным признакам. Например по количеству звезд (stars), которые поставили той точке (ресторану, заправке и т.п.), которую посетили.
Сама себя YELP описывает следующим образом:
-8,635,403 отзывов
-160,585 предприятий
-200,000 картинок
-8 мегаполисов
1,162,119 рекомендаций от 2,189,457 пользователей
Более 1.2 миллиона бизнес-атрибутики: часы работы, парковка, доступность и т.п.

С 2013 года Yelp регулярно проводит конкурс Yelp Dataset, призывая всех желающих
исследовать и изучать открытый набор данных Yelp.
Сам датасет доступен по ссылке
Датасет достаточно объемный и после распаковки представляет из себя 5 файлов формата json:


Все бы ничего, да вот только YELP выкладывает сырые (raw), необработанные данные и, чтобы начать с ними работать, потребуется предобработка.

Установка и быстрая настройка Neo4j.


Для анализа будет использоваться Neo4j, используем возможности графовой СУБД и их незамысловатый язык cypher для работы с датасетом.
О Neo4j как графовой СУБД неоднократно писали на Habrе (здесь и здесь статьи для начинающих), поэтому повторно представлять ее нет смысла.
Для того, чтобы начать работу с платформой, необходимо скачать desktop версию (около 500Mb) либо поработать в online песочнице. На момент написания статьи доступна Neo4j Enterprise 4.2.6 for Developers, а также иные, более ранние версии для установки.
Далее будет использоваться вариант работа в desktop версии в среде Windows (версии 4.2.5, 4.2.1).
Не смотря на то, что самая свежая версия 4.2.6, лучше ее пока не устанавливать, так как для нее еще не актуализированы все плагины, использующиеся в neo4j. Достаточно будет предыдущей версии 4.2.5.
После установки скачанного пакета, необходимо будет:
создать новую локальную БД, указав пользователя neo4j и пароль 123 (почему именно их, объясню ниже),
картинка


установить плагины, которые понадобятся APOC, Graph Data Science Library.
картинка


проверить, запускается ли БД и открывается ли браузер при нажатии на кнопку старт.
картинка




*- включить offline режим, чтобы БД истово не пыталась предлагать новые версии.
картинка



Загружаем данные в Neo4j.


Если с установкой Neo4j все прошло гладко, можно двигаться дальше и тут есть два пути.

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

и итоговой схемой:


Чтобы пройти первый путь, лучше ознакомиться сперва со статьей на medium.
*Большое человеческое спасибо за это TRAN Ngoc Thach.
И воспользоваться готовым jupyter notebookом (адаптирован мною под windows) ссылка.
Процесс импорта не из простых и занимает достаточно продолжительное время

Проблем с памятью при этом не возникает даже при наличии всего лишь 8Гб Ram, так как используется пакетный импорт.
Однако потребуется создать swap файл размером на 10Гб, так как при проверке импортированных данных jupyter крашится, об этом моменте есть упоминание в вышеуказанной тетрадке jupyter.

Второй путь самый быстрый и был обнаружен случайно. Он подразумевает копирование уже готовой БД neo4j в существующую БД neo4j напрямую. Из минусов (пока обнаруженных) нельзя произвести backup БД средствами Neo4j (neo4j-admin dump --database=neo4j --to=D:\neo4j\neo4j.dump). Однако, это может быть связано с различиями в версиях в версии 4.2.1 была скопирована БД от версии 4.2.5.
Как реализуется этот метод:
открыть вкладку Manage БД, куда будет произведен импорт
картинка




перейти в папку с БД и скопировать туда папку data, перезаписав возможные совпадения.
картинка


При этом сама БД, куда произведено копирование не должна быть запущена.
перезапустить Neo4j.
И вот здесь пригодятся логин-пароль, которые ранее были использованы (neo4j,123) для избежания конфликтов.
После старта скопированной БД будет доступна БД c yelp-датасетом:


Смотрим YELP.


Изучать YELP можно как из Neo4j браузера, так и отправляя запросы в БД из того же jupyter notebook.
Благодаря тому, что БД графовая, в браузере будет сопровождать приятная наглядная картинка, на которой эти графы и будут отображаться.
Приступая к ознакомлению с YELP необходимо оговориться, что в БД будут только 3 страны US,KG и CA:

Посмотреть схему БД можно написав запрос на языке cypher в браузере neo4j:
CALL db.schema.visualization()

И вот здесь, если мы пошли по пути импорта БД путем прямого копирования (второй путь) нас ждет совсем иная картинка:

На работоспособность БД это не влияет.
Однако будем ориентироваться на оригинальную схему


Как читать эту схему? Выглядит все следующим образом. Вершина User имеет связь сама с собой типа FRIENDS, а также связь WROTE с вершиной Review. Rewiew в свою очередь имеет связь REVIEWS с Business и так далее. Посмотреть на это можно наглядно после нажатия на одной из вершин (node labels), например на User:

БД выберет любых 25 пользователей и покажет их:

Если нажать на соответствующий значок прямо на пользователе, то будут показаны все идущие от него прямые связи, а так как связи у User двух типов FRIENDS и REVIEW, то все они появятся:

Это удобно и неудобно одновременно. С одной стороны о пользователе можно посмотреть всю информацию одним кликом, но в то же время этим кликом нельзя убрать лишнее.
Но здесь нет ничего страшного, можно по id найти этого пользователя и только всех его друзей:
MATCH p=(:User {user_id:"u-CFWELen3aWMSiLAa_9VANw"}) -[r:FRIENDS]->() RETURN p LIMIT 25


Точно так же можно посмотреть какие отзывы написал данный человек:

YELP хранит отзывы аж от 2010 года! Сомнительная полезность, но тем не менее.
Чтобы почитать эти отзывы необходимо переключиться в вид текста, нажав на А

Посмотрим на место, о котором писала Sandy 10 лет назад и найдем его на yelp.com
Такое место действительно существует www.yelp.com/biz/cafe-sushi-cambridge,
а вот и сама Sandy co своим отзывом www.yelp.com/biz/cafe-sushi-cambridge?q=I%20was%20really%20excited
картинка



Запросы на python из jupyter notebook.


Здесь будут частично использованы сведения из упомянутой свободно распространяемой книги Графовые алгоритмы 2019 года от O'REILLY. Частично, потому как синтаксис из книги во многих местах устарел.
База, с которой мы будем работать должна быть запущена, при этом сам neo4j браузер запускать нет необходимости.
Импорт библиотек:
from neo4j import GraphDatabaseimport pandas as pdfrom tabulate import tabulateimport matplotlibmatplotlib.use('TkAgg')import matplotlib.pyplot as plt

Подключение к БД:
driver = GraphDatabase.driver("bolt://localhost", auth=("neo4j", "123"))

Подсчитаем количество вершин для каждой метки в БД:
result = {"label": [], "count": []}with driver.session() as session:    labels = [row["label"] for row in session.run("CALL db.labels()")]    for label in labels:        query = f"MATCH (:`{label}`) RETURN count(*) as count"        count = session.run(query).single()["count"]        result["label"].append(label)        result["count"].append(count)df = pd.DataFrame(data=result)print(tabulate(df.sort_values("count"), headers='keys',tablefmt='psql', showindex=False))

На выходе:
+----------+---------+
| label | count |
|----------+---------|
| Country | 3 |
| Area | 15 |
| City | 355 |
| Category | 1330 |
| Business | 160585 |
| User | 2189457 |
| Review | 8635403 |
+----------+---------+
Похоже на правду, в нашей базе 3 страны, как мы увидели ранее через neo4j браузер.
А этот код подсчитает количество связей (ребер):
result = {"relType": [], "count": []}with driver.session() as session:    rel_types = [row["relationshipType"] for row in session.run    ("CALL db.relationshipTypes()")]    for rel_type in rel_types:        query = f"MATCH ()-[:`{rel_type}`]->() RETURN count(*) as count"        count = session.run(query).single()["count"]        result["relType"].append(rel_type)        result["count"].append(count)df = pd.DataFrame(data=result)print(tabulate(df.sort_values("count"), headers='keys',tablefmt='psql', showindex=False))

Выход:
+-------------+---------+
| relType | count |
|-------------+---------|
| IN_COUNTRY | 15 |
| IN_AREA | 355 |
| IN_CITY | 160585 |
| IN_CATEGORY | 708884 |
| REVIEWS | 8635403 |
| WROTE | 8635403 |
| FRIENDS | 8985774 |
+-------------+---------+
Думаю, принцип понятен. В завершение напишем запрос и визуализируем его.
Top 10 отелей Ванкувера с наибольшим количеством отзывов
# Find the 10 hotels with the most reviewsquery = """MATCH (review:Review)-[:REVIEWS]->(business:Business),      (business)-[:IN_CATEGORY]->(category:Category {category_id: $category}),      (business)-[:IN_CITY]->(:City {name: $city})RETURN business.name AS business, collect(review.stars) AS allReviewsORDER BY size(allReviews) DESCLIMIT 10"""#MATCH (review:Review)-[:REVIEWS]->(business:Business),#(business)-[:IN_CATEGORY]->(category:Category {category_id: "Hotels"}),#(business)-[:IN_CITY]->(:City {name: "Vancouver"})#RETURN business.name AS business, collect(review.stars) AS allReviews#ORDER BY size(allReviews) DESC#LIMIT 10fig = plt.figure()fig.set_size_inches(10.5, 14.5)fig.subplots_adjust(hspace=0.4, wspace=0.4)with driver.session() as session:    params = { "city": "Vancouver", "category": "Hotels"}    result = session.run(query, params)    for index, row in enumerate(result):                business = row["business"]        stars = pd.Series(row["allReviews"])        #print(dir(stars))        total = stars.count()        #s = pd.concat([pd.Series(x['A']) for x in data]).astype(float)        s = pd.concat([pd.Series(row['allReviews'])]).astype(float)        average_stars = s.mean().round(2)        # Calculate the star distribution        stars_histogram = stars.value_counts().sort_index()        stars_histogram /= float(stars_histogram.sum())        # Plot a bar chart showing the distribution of star ratings        ax = fig.add_subplot(5, 2, index+1)        stars_histogram.plot(kind="bar", legend=None, color="darkblue",                             title=f"{business}\nAve:{average_stars}, Total: {total}")                                    #print(business)        #print(stars)plt.tight_layout()plt.show()


Результат должен получиться следующий

Ось X представляет рейтинг отеля в звездах, а ось Y общий процент каждого рейтинга.

Чем может быть полезен YELP dataset

.
Из плюсов можно выделить следующие:
достаточно богатое информационное поле по содержательной составляющей. В частности можно просто насобирать отзывы со звездами 1.0 или 5.0 и заспамить какой-либо бизнес. Гм. Немного не в ту сторону, но вектор понятен;
датасет объемен, что создает дополнительные приятные трудности в плане тестирования производительности различных платформ по анализу данных;
представленные данные имеют определенную ретроспективу и в принципе возможно понять, как менялось предприятие, исходя из отзывов о нем;
данные можно использовать как ориентиры по предприятиям, учитывая, что имеются адреса;
пользователи в датасете зачастую образуют интересные взаимосвязанные структуры, которые можно брать как есть, не формируя пользователей в искусственную соц. сеть и не собирая данную сеть из иных существующих соц. сетей.
Из минусов:
всего лишь три страны представлены из 30-ти и есть подозрение, что и то не полностью,
отзывы хранятся по 10 лет, что может искажать и зачастую портить характеристику существующего бизнеса,
о пользователях мало данных, они обезличены, поэтому, рекомендательные системы на базе датасета будут явно хромать,
в связях FRIENDS используются направленные графы, то есть Аня дружит -> Петей. Получается, что Петя не дружит с Аней. Это решается программно, но все равно это неудобно.
датасет выкладывается сырой и требуется значительные усилия для его предобработки.

Несколько слов об особенностях новых версий Neo4j


Neo4j динамично обновляется и новая версия интерфейса, используемого в 4.2.6 не совсем удобна, на мой взгляд. В частности не хватает наглядности в части сведений о количестве нод и связей в БД, что было в предыдущих версиях. Кроме того, интерфейс перемещения по вкладкам при работе с БД был изменен и к нему тоже необходимо привыкнуть.
Главная неприятность в обновлениях интеграция графовых алгоритмов в плагин Graph Data Science Library. Ранее они именовались neo4j-graph-algorithms
После интеграции многие алгоритмы значительно изменили синтаксис. По этой причине, изучение книги Графовые алгоритмы 2019 года от O'REILLY может быть затруднено.

Обработанная БД yelp для neo4j для прямого копирования и последующего анализа будет выложена позднее.
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru