在資料科學領域,圖形資料模型提供了一種強大的方式來表示和分析資料之間的關係。本文將引導讀者逐步將傳統表格資料轉換為圖形結構,並使用 Python 的 igraph 函式庫進行圖形分析。文章首先介紹如何探索鄰近節點的屬性,包含如何取得鄰近節點的特定屬性,例如 page_type,以及如何分析這些屬性的分佈。接著,文章示範如何結合節點 ID 和屬性來尋找特定的鄰近節點,例如找出與特定電視節目分享相同喜好的政治人物。文章後半部分以 Steam 遊戲資料為例,詳細說明如何從關聯式資料函式庫(MySQL)轉換至圖形資料函式庫,並設計合理的圖形結構。最後,文章探討如何根據使用者購買和遊玩遊戲的資料,建立一個遊戲推薦系統,並使用 Python 與 MySQL 互動,執行資料函式庫查詢並提取相關資料。
從表格資料轉換到圖形結構:深入探索圖形資料模型
在前面的章節中,我們探討了圖形資料模型的基本概念,包括節點、屬性和邊的建立。本章節將進一步探討如何從傳統的表格資料轉換到圖形結構,並介紹如何使用Python中的igraph函式庫來建立和分析圖形。
探索鄰近節點的屬性
在建立好圖形後,我們可以開始探索節點之間的關係。假設我們想要了解與「Today Show」這個電視節目分享相同喜好的鄰近節點的屬性。我們可以使用以下程式碼來取得這些鄰近節點的page_type屬性:
neighbor_nodes = g.neighbors("Today Show")
neighbor_page_types = g.vs[neighbor_nodes]['page_type']
print(neighbor_page_types)
內容解密:
g.neighbors("Today Show"):取得與「Today Show」節點直接相連的鄰近節點ID。g.vs[neighbor_nodes]['page_type']:根據鄰近節點ID,查詢這些節點的page_type屬性。print(neighbor_page_types):輸出鄰近節點的page_type屬性列表。
分析鄰近節點的屬性分佈
為了了解這些鄰近節點的屬性分佈,我們可以使用Python中的Counter類別來統計不同page_type的出現頻率:
from collections import Counter
page_type_dict = Counter(neighbor_page_types)
print(page_type_dict)
內容解密:
Counter(neighbor_page_types):統計neighbor_page_types列表中每個元素的出現次數。print(page_type_dict):輸出統計結果,以字典形式呈現。
尋找特定的鄰近節點
假設我們想要找出哪個政治人物與「Today Show」分享相同的喜好。我們可以結合節點ID和page_type屬性來達成這個目標:
ids_and_page_types = zip(neighbor_nodes, neighbor_page_types)
politician_id = [id_tuple for id_tuple in list(ids_and_page_types) if id_tuple[1] == 'politician']
print(politician_id)
內容解密:
zip(neighbor_nodes, neighbor_page_types):將鄰近節點ID和對應的page_type屬性組合成一個可迭代的物件。list(ids_and_page_types):將可迭代物件轉換成列表,以便進行列表推導。[id_tuple for id_tuple in list(ids_and_page_types) if id_tuple[1] == 'politician']:篩選出page_type為’politician’的節點ID。
下一步:圖形資料函式庫轉換與推薦系統建立
在下一章節中,我們將進一步探討如何將傳統的關聯式資料函式庫轉換為圖形資料函式庫,並建立一個推薦系統,以預測使用者可能感興趣的遊戲。這將涉及MySQL資料函式庫的設定、圖形資料的查詢以及路徑分析等主題。敬請期待!
本章重點回顧
如何從表格資料建立圖形結構
使用igraph函式庫建立和分析圖形
探索鄰近節點的屬性和分析屬性分佈
尋找特定的鄰近節點
圖形資料函式庫轉換與設定
建立根據圖形的推薦系統
使用Jaccard相似度和路徑遍歷進行分析
從關聯式資料函式庫轉換至圖資料函式庫的資料模型轉換
在現實世界中,大量的資料以關聯式資料表的形式儲存,並使用SQL或類別似SQL的儲存系統和查詢語言進行存取。本章將以Steam線上遊戲發行服務的資料為例,展示如何使用關聯式資料函式庫處理圖形相關的問題。
技術需求
本章的程式碼練習需要使用Jupyter Notebooks,並安裝以下Python套件:
- igraph==0.9.8
- mysql==0.0.3
- mysql-connector-python==8.0.31
安裝MySQL
為了示範如何處理關聯式資料函式庫,我們將安裝MySQL。我們將使用MySQL 5.7.39版本。下載並安裝MySQL時,請選擇預設選項。
設定MySQL資料函式庫
- 開啟命令提示字元,導航至MySQL安裝資料夾的bin目錄。
- 使用以下命令存取MySQL shell:
mysql -u root -p - 在MySQL shell中,建立一個名為
steam_data的資料函式庫:CREATE DATABASE steam_data; - 將
steam_play.csv和steam_purchase.csv檔案複製到MySQL可以存取的位置,例如C:\ProgramData\MySQL\MySQL Server 5.7\Uploads。 - 在MySQL shell中,建立兩個表格:
steam_play和steam_purchase,並使用LOAD DATA INFILE命令將CSV檔案中的資料匯入表格中。
建立表格與匯入資料
USE steam_data;
CREATE TABLE steam_play (
id VARCHAR(100),
game_name VARCHAR(255),
type VARCHAR(10),
hours FLOAT(10, 1),
misc_column INT
);
CREATE TABLE steam_purchase (
id VARCHAR(100),
game_name VARCHAR(255),
type VARCHAR(10),
game_purchased_flag FLOAT(2, 1),
misc_column INT
);
LOAD DATA INFILE 'C:/ProgramData/MySQL/MySQL Server 5.7/Uploads/steam_play.csv'
INTO TABLE steam_play
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '\"'
LINES TERMINATED BY '\r\n';
LOAD DATA INFILE 'C:/ProgramData/MySQL/MySQL Server 5.7/Uploads/steam_purchase.csv'
INTO TABLE steam_purchase
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '\"'
LINES TERMINATED BY '\r\n';
連線MySQL與Python
要將關聯式資料函式庫轉換為圖形,首先需要檢查資料並設計合理的圖形結構。我們將使用mysql-connector-python驅動程式從Python存取MySQL中的資料。
import mysql.connector
PASSWORD = '<Your MySQL password upon creating MySQL instance>'
connection = mysql.connector.connect(
host='localhost',
user='root',
password=PASSWORD,
database='steam_data'
)
內容解密:
此段程式碼首先匯入了mysql.connector模組,接著定義了連線MySQL所需的密碼。然後,使用mysql.connector.connect()方法建立了一個到本地MySQL資料函式庫的連線,指定了主機名稱、使用者名稱、密碼和要使用的資料函式庫名稱。
從關聯式資料函式庫查詢資料
連線到MySQL後,我們可以開始查詢資料並設計圖形結構。接下來的步驟將涉及檢查資料集的前幾行,以瞭解資料的結構和內容。
cursor = connection.cursor()
query = "SELECT * FROM steam_play LIMIT 10"
cursor.execute(query)
results = cursor.fetchall()
for row in results:
print(row)
內容解密:
這段程式碼首先建立了一個遊標物件,用於執行SQL查詢。然後,定義了一個查詢陳述式,用於從steam_play表格中選取前10行資料。執行查詢後,結果被擷取並逐行列印出來。
資料函式庫查詢與遊戲推薦系統的基礎
在建立遊戲推薦系統的過程中,首先需要從資料函式庫中提取相關資料。本章節將介紹如何使用Python與MySQL資料函式庫互動,並探討如何將關係型資料轉換為圖資料函式庫中的資料,以支援路徑基礎的分析。
連線MySQL資料函式庫
要與MySQL資料函式庫互動,需要先建立連線。以下是一個基本的連線示例,使用了mysql-connector-python函式庫:
import mysql.connector
connection = mysql.connector.connect(
host="localhost",
user="root",
passwd=PASSWORD,
database="steam_data"
)
內容解密:
- 匯入必要的函式庫:使用
import mysql.connector匯入MySQL聯結器。 - 建立資料函式庫連線:透過
mysql.connector.connect()方法建立與MySQL資料函式庫的連線,引數包括主機名稱、使用者名稱、密碼和資料函式庫名稱。
執行SQL查詢
建立連線後,可以執行SQL查詢來檢索資料。以下是一個簡單的查詢示例:
sql = 'SELECT count(*) FROM steam_purchase;'
cursor = connection.cursor()
cursor.execute(sql)
result = cursor.fetchall()
print(result)
connection.close()
內容解密:
- 定義SQL查詢:將SQL查詢陳述式儲存在
sql變數中。 - 建立遊標:使用
connection.cursor()建立一個遊標物件,用於執行SQL查詢。 - 執行查詢:透過
cursor.execute(sql)執行SQL查詢。 - 檢索結果:使用
cursor.fetchall()取得查詢結果。 - 關閉連線:完成查詢後,使用
connection.close()關閉資料函式庫連線。
建立可重用的查詢方法
為了簡化重複的查詢操作,可以將查詢過程封裝成一個可重用的函式:
def query_mysql(query, password, host='localhost', user='root', database='steam_data'):
connection = mysql.connector.connect(
host=host,
user=user,
passwd=password,
database=database
)
cursor = connection.cursor()
cursor.execute(query)
result = cursor.fetchall()
connection.close()
return result
內容解密:
- 定義函式:建立一個名為
query_mysql的函式,接受查詢陳述式、密碼和其他可選的連線引數。 - 連線資料函式庫並執行查詢:在函式內部建立資料函式庫連線,執行查詢,並傳回結果。
檢視資料
使用前面定義的query_mysql函式,可以檢視steam_play和steam_purchase表格中的資料:
result = query_mysql('SELECT * FROM steam_play LIMIT 4;', password=PASSWORD)
for row in result:
print(row)
內容解密:
- 查詢資料:使用
query_mysql函式查詢steam_play表格的前幾行資料。 - 列印結果:遍歷查詢結果並列印每一行。
從關係型資料函式庫到圖資料函式庫
檢視完資料後,可以開始思考如何將這些關係型資料轉換為圖資料,以支援更複雜的路徑基礎查詢,例如遊戲推薦。
圖資料模型在遊戲推薦中的應用
圖資料模型特別適合用於處理路徑基礎的查詢,例如找出與某使用者有相似遊戲偏好的其他使用者,並根據此進行遊戲推薦。以下是一個簡單的圖模型,表示使用者與他們玩的遊戲之間的關係:
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title 圖資料模型在遊戲推薦中的應用
rectangle "圖資料模型在遊戲推薦中" as n1
rectangle "應用" as n2
n1 --> n2
@enduml此圖示表示使用者與遊戲之間的關係,可以用於找出相似使用者並進行遊戲推薦。
內容解密:
- 使用者與遊戲的關係:圖中的節點代表使用者或遊戲,邊代表使用者玩某遊戲的關係。
- 根據相似使用者的推薦:透過分析圖結構,可以找出玩相同遊戲的使用者,並根據此進行遊戲推薦。
從關聯式資料函式庫轉換至圖資料函式庫
在以下步驟中,我們將引導您如何查詢圖資料函式庫以取得所需的最佳資訊,進而根據我們先前所提供的資訊,為使用者推薦可能想要玩的遊戲:
- 首先,我們需要查詢 MySQL 資料函式庫,以找出特定使用者購買的所有遊戲。讓我們以
steam_purchase表格中最頂端的使用者(ID 為 151603712)為例。使用我們的查詢方法,我們可以查詢steam_purchase表格以取得此資訊:
result = query_mysql('SELECT game_name from steam_purchase WHERE id = "151603712";', password=PASSWORD)
print(result[:10])
print(len(result))
- 從
print()陳述式中,我們可以看到該使用者購買了 40 款不同的遊戲。請注意,MySQL 回傳的資料是一個由 Tuple 組成的 List,其中每個 Tuple 都有一個空元素。我們需要存取每個 Tuple 的第一個元素,並將每個遊戲名稱用引號括起來,以便找出與這些遊戲相關的使用者。同時,我們需要將此初始查詢的結果加入新的 SQL 查詢字串中,因此讓我們來準備這個字串:
games = ['"' + game[0] + '"' for game in result]
games_string = ','.join(games)
print(games_string)
內容解密:
- 首先,我們使用 List Comprehension 將
result中的遊戲名稱提取出來,並在每個遊戲名稱前後加上引號。 - 然後,使用
','.join(games)將這些遊戲名稱組合成一個以逗號分隔的字串。
- 現在,我們可以使用這些結果再次查詢表格,以找出也購買了這些遊戲的其他使用者(非原始使用者):
query_2 = f'SELECT id from steam_purchase WHERE game_name IN ({games_string}) AND id != "151603712";'
result_2 = query_mysql(query_2, password=PASSWORD)
users = [user[0] for user in result_2]
print(users[:10])
print(len(users))
內容解密:
- 我們構建了一個新的 SQL 查詢,使用
games_string來找出購買了相同遊戲的其他使用者的 ID。 - 然後,將查詢結果中的使用者 ID 提取出來,存入
users列表中。
- 我們的查詢結果中有 16223 個使用者,但其中包含重複項,因此讓我們使用
set()運算來移除重複項:
users = list(set(users))
print(users[:10])
print(len(users))
內容解密:
- 使用
set()將users列表轉換為集合,以移除重複的使用者 ID。 - 然後,將集合轉換回列表,以便於後續操作。
- 現在,我們需要根據已識別的使用者的購買記錄,為原始使用者推薦新的遊戲。讓我們設定一個新的 SQL 查詢引數,類別似於前一個查詢:
users = ['"' + user + '"' for user in users]
users_string = ','.join(users)
query_3 = f'SELECT game_name from steam_purchase WHERE id IN ({users_string}) AND game_name NOT IN ({games_string});'
result_3 = query_mysql(query_3, password=PASSWORD)
recommended_games = [game[0] for game in result_3]
print(recommended_games[:10])
內容解密:
- 首先,將
users列表中的每個使用者 ID 用引號括起來,並組合成一個以逗號分隔的字串users_string。 - 然後,構建一個新的 SQL 查詢,使用
users_string和games_string來找出推薦遊戲。 - 最後,將查詢結果中的遊戲名稱提取出來,存入
recommended_games列表中。
- 現在,我們只需要找出傳回的遊戲中最受歡迎的遊戲,即可向原始使用者提出推薦。我們可以使用 Python 的
collections函式庫中的內建Counter()方法來實作這一點:
from collections import Counter
game_frequency = Counter(recommended_games)
print(game_frequency)
內容解密:
- 使用
Counter()方法統計recommended_games列表中每個遊戲的出現頻率。 - 結果是一個字典,顯示每個遊戲的頻率,從而幫助我們找出最受歡迎的遊戲。
從關聯式資料函式庫到圖資料函式庫的轉換
由於我們的關聯式資料函式庫在回答類別似圖的查詢時表現不佳,因此我們可能希望將表格資料轉換為圖格式。首先,我們將根據可用的資訊,為我們的資料設計一個合理的圖模式,然後編寫一個管道,將資料從 MySQL 遷移到 Python igraph 網路中。
圖模式設計
在我們的表格中,有兩種實體:使用者和遊戲,它們具有不同的屬性。因此,將使用者和遊戲視為不同的節點型別是合理的。
對於使用者,我們只有唯一的 ID。為了將資料加入 igraph 圖中,我們需要為每個不同的節點新增一個遞增的整數 igraph 節點 ID。
對於遊戲,我們有遊戲的名稱字串。同樣地,我們需要為不同的遊戲節點新增 igraph ID。
圖模式的關係表示
對於我們的目標,我們感興趣的是使用者和遊戲之間的互動。我們有關於使用者購買的遊戲以及使用者玩遊戲的時長的資訊。因此,將這些不同的互動視為不同的邊型別是合理的。
圖資料的擷取考量
現在我們已經決定了圖的模式,接下來可以開始將資料從 MySQL 關聯式資料函式庫遷移到 igraph 圖中。後續步驟將詳細介紹如何實作這一點:
- 首先,我們需要從 MySQL 資料函式庫中提取資料並將其遷移到 Python 中。我們可以使用本章前面編寫的
query_mysql()方法來實作這一點。現在我們對資料有了更多的瞭解,並且已經設計了圖模式,因此可以只提取建立圖所需的欄位:
play_query = 'SELECT id, game_name, hours FROM steam_play'
play_data = query_mysql(play_query, password=PASSWORD)
內容解密:
- 使用
query_mysql()方法執行 SQL 查詢,從steam_play表格中提取所需的欄位:id、game_name和hours。 - 將查詢結果存入
play_data中,以便於後續處理。