載入資料

在 scikit-network 中,圖形由其 鄰接矩陣 (或二部圖的雙鄰接矩陣) 以 SciPy 的 壓縮稀疏列 格式表示。

在本教學中,我們將介紹一些在該格式中建立實例的方法。

[1]:
from IPython.display import SVG

import numpy as np
from scipy import sparse
import pandas as pd

from sknetwork.data import from_edge_list, from_adjacency_list, from_graphml, from_csv
from sknetwork.visualization import visualize_graph, visualize_bigraph

從 NumPy 陣列

對於小型圖形,您可以將鄰接矩陣建立為密集的 NumPy 陣列,然後將它轉換成 CSR 格式的稀疏矩陣。

[2]:
adjacency = np.array([[0, 1, 1, 0], [1, 0, 1, 1], [1, 1, 0, 0], [0, 1, 0, 0]])
adjacency = sparse.csr_matrix(adjacency)

image = visualize_graph(adjacency)
SVG(image)
[2]:
../../_images/tutorials_data_load_data_4_0.svg

從邊緣清單

從邊緣清單建立圖形是另一個自然的方法。

[3]:
edge_list = [(0, 1), (1, 2), (2, 3), (3, 0), (0, 2)]
adjacency = from_edge_list(edge_list)

image = visualize_graph(adjacency)
SVG(image)
[3]:
../../_images/tutorials_data_load_data_6_0.svg

預設值下,圖形是不定向的,但您可以很容易地將它設為有向的。

[4]:
adjacency = from_edge_list(edge_list, directed=True)

image = visualize_graph(adjacency)
SVG(image)
[4]:
../../_images/tutorials_data_load_data_8_0.svg

您可能也想要在邊緣中加入權重。使用三元組代替成對資料即可!

[5]:
edge_list = [(0, 1, 1), (1, 2, 0.5), (2, 3, 1), (3, 0, 0.5), (0, 2, 2)]
adjacency = from_edge_list(edge_list)

image = visualize_graph(adjacency)
SVG(image)
[5]:
../../_images/tutorials_data_load_data_10_0.svg

您也可以建立二部圖。

[6]:
edge_list = [(0, 0), (1, 0), (1, 1), (2, 1)]
biadjacency = from_edge_list(edge_list, bipartite=True)

image = visualize_bigraph(biadjacency)
SVG(image)
[6]:
../../_images/tutorials_data_load_data_12_0.svg

如果節點沒有編號,您會得到一個類型為 Bunch 的物件,其中包含圖形屬性 (節點名稱)。

[7]:
edge_list = [("Alice", "Bob"), ("Bob", "Carey"), ("Alice", "David"), ("Carey", "David"), ("Bob", "David")]
graph = from_edge_list(edge_list)
[8]:
graph
[8]:
{'names': array(['Alice', 'Bob', 'Carey', 'David'], dtype='<U5'),
 'adjacency': <4x4 sparse matrix of type '<class 'numpy.int64'>'
        with 10 stored elements in Compressed Sparse Row format>}
[9]:
adjacency = graph.adjacency
names = graph.names
[10]:
image = visualize_graph(adjacency, names=names)
SVG(image)
[10]:
../../_images/tutorials_data_load_data_17_0.svg

預設值下,每個邊緣的權重是對應連結出現的次數

[11]:
edge_list_new = edge_list + [("Alice", "Bob"), ("Alice", "David"), ("Alice", "Bob")]
graph = from_edge_list(edge_list_new)
[12]:
adjacency = graph.adjacency
names = graph.names
[13]:
image = visualize_graph(adjacency, names=names)
SVG(image)
[13]:
../../_images/tutorials_data_load_data_21_0.svg

您可以將圖形設為無權重的。

[14]:
graph = from_edge_list(edge_list_new, weighted=False)
[15]:
adjacency = graph.adjacency
names = graph.names
[16]:
image = visualize_graph(adjacency, names=names)
SVG(image)
[16]:
../../_images/tutorials_data_load_data_25_0.svg

您同樣可以將圖形設為有向的

[17]:
graph = from_edge_list(edge_list, directed=True)
[18]:
graph
[18]:
{'names': array(['Alice', 'Bob', 'Carey', 'David'], dtype='<U5'),
 'adjacency': <4x4 sparse matrix of type '<class 'numpy.int64'>'
        with 5 stored elements in Compressed Sparse Row format>}
[19]:
adjacency = graph.adjacency
names = graph.names
[20]:
image = visualize_graph(adjacency, names=names)
SVG(image)
[20]:
../../_images/tutorials_data_load_data_30_0.svg

圖形也可以有明確的權重

[21]:
edge_list = [("Alice", "Bob", 3), ("Bob", "Carey", 2), ("Alice", "David", 1), ("Carey", "David", 2), ("Bob", "David", 3)]
graph = from_edge_list(edge_list)
[22]:
adjacency = graph.adjacency
names = graph.names
[23]:
image = visualize_graph(adjacency, names=names, display_edge_weight=True, display_node_weight=True)
SVG(image)
[23]:
../../_images/tutorials_data_load_data_34_0.svg

對於二部圖

[24]:
edge_list = [("Alice", "Football"), ("Bob", "Tennis"), ("David", "Football"), ("Carey", "Tennis"), ("Carey", "Football")]
graph = from_edge_list(edge_list, bipartite=True)
[25]:
biadjacency = graph.biadjacency
names = graph.names
names_col = graph.names_col
[26]:
image = visualize_bigraph(biadjacency, names_row=names, names_col=names_col)
SVG(image)
[26]:
../../_images/tutorials_data_load_data_38_0.svg

從鄰接清單

您也可以從鄰接清單載入圖形,格式為清單清單或清單辭典

[27]:
adjacency_list =[[0, 1, 2], [2, 3]]
adjacency = from_adjacency_list(adjacency_list, directed=True)
[28]:
image = visualize_graph(adjacency)
SVG(image)
[28]:
../../_images/tutorials_data_load_data_41_0.svg
[29]:
adjacency_dict = {"Alice": ["Bob", "David"], "Bob": ["Carey", "David"]}
graph = from_adjacency_list(adjacency_dict, directed=True)
[30]:
adjacency = graph.adjacency
names = graph.names
[31]:
image = visualize_graph(adjacency, names=names)
SVG(image)
[31]:
../../_images/tutorials_data_load_data_44_0.svg

從資料框

您的資料框可能包含邊緣清單。

[32]:
df = pd.read_csv('miserables.tsv', sep='\t', names=['character_1', 'character_2'])
[33]:
df.head()
[33]:
character_1 character_2
0 Myriel Napoleon
1 Myriel Mlle Baptistine
2 Myriel Mme Magloire
3 Myriel Countess de Lo
4 Myriel GEBORAND
[34]:
edge_list = list(df.itertuples(index=False))
[35]:
graph = from_edge_list(edge_list)
[36]:
graph
[36]:
{'names': array(['Anzelma', 'Babet', 'Bahorel', 'Bamatabois', 'Baroness',
        'Blacheville', 'Bossuet', 'Boulatruelle', 'Brevet', 'Brujon',
        'Champmathieu', 'Champtercier', 'Chenildieu', 'Child1', 'Child2',
        'Claquesous', 'Cochepaille', 'Combeferre', 'Cosette', 'Count',
        'Countess de Lo', 'Courfeyrac', 'Cravatte', 'Dahlia', 'Enjolras',
        'Eponine', 'Fameuil', 'Fantine', 'Fauchelevent', 'Favourite',
        'Feuilly', 'Gavroche', 'Geborand', 'Gervais', 'Gillenormand',
        'Grantaire', 'Gribier', 'Gueulemer', 'Isabeau', 'Javert', 'Joly',
        'Jondrette', 'Judge', 'Labarre', 'Listolier', 'Lt Gillenormand',
        'Mabeuf', 'Magnon', 'Marguerite', 'Marius', 'Mlle Baptistine',
        'Mlle Gillenormand', 'Mlle Vaubois', 'Mme Burgon', 'Mme Der',
        'Mme Hucheloup', 'Mme Magloire', 'Mme Pontmercy', 'Mme Thenardier',
        'Montparnasse', 'MotherInnocent', 'MotherPlutarch', 'Myriel',
        'Napoleon', 'Old man', 'Perpetue', 'Pontmercy', 'Prouvaire',
        'Scaufflaire', 'Simplice', 'Thenardier', 'Tholomyes', 'Toussaint',
        'Valjean', 'Woman1', 'Woman2', 'Zephine'], dtype='<U17'),
 'adjacency': <77x77 sparse matrix of type '<class 'numpy.int64'>'
        with 508 stored elements in Compressed Sparse Row format>}
[37]:
df = pd.read_csv('movie_actor.tsv', sep='\t', names=['movie', 'actor'])
[38]:
df.head()
[38]:
電影 演員
0 全面啟動 李奧納多·狄卡皮歐
1 全面啟動 瑪莉詠·柯蒂亞
2 全面啟動 約瑟夫·高登-李維
3 黑暗騎士:黎明昇起 瑪莉詠·柯蒂亞
4 黑暗騎士:黎明昇起 約瑟夫·高登-李維
[39]:
edge_list = list(df.itertuples(index=False))
[40]:
graph = from_edge_list(edge_list, bipartite=True)
[41]:
graph
[41]:
{'names_row': array(['007 Spectre', 'Aviator', 'Crazy Stupid Love', 'Drive',
        'Fantastic Beasts 2', 'Inception', 'Inglourious Basterds',
        'La La Land', 'Midnight In Paris', 'Murder on the Orient Express',
        'The Big Short', 'The Dark Knight Rises',
        'The Grand Budapest Hotel', 'The Great Gatsby', 'Vice'],
       dtype='<U28'),
 'names': array(['007 Spectre', 'Aviator', 'Crazy Stupid Love', 'Drive',
        'Fantastic Beasts 2', 'Inception', 'Inglourious Basterds',
        'La La Land', 'Midnight In Paris', 'Murder on the Orient Express',
        'The Big Short', 'The Dark Knight Rises',
        'The Grand Budapest Hotel', 'The Great Gatsby', 'Vice'],
       dtype='<U28'),
 'names_col': array(['Brad Pitt', 'Carey Mulligan', 'Christian Bale',
        'Christophe Waltz', 'Emma Stone', 'Johnny Depp',
        'Joseph Gordon Lewitt', 'Jude Law', 'Lea Seydoux',
        'Leonardo DiCaprio', 'Marion Cotillard', 'Owen Wilson',
        'Ralph Fiennes', 'Ryan Gosling', 'Steve Carell', 'Willem Dafoe'],
       dtype='<U28'),
 'biadjacency': <15x16 sparse matrix of type '<class 'numpy.int64'>'
        with 41 stored elements in Compressed Sparse Row format>}

對於類別資料,你可以使用 pandas 來取得樣本與特徵之間的二部圖。以下顯示一個取自 成年人收入 資料集的範例。

[42]:
df = pd.read_csv('adult-income.csv')
[43]:
df.head()
[43]:
年齡 工作類別 職業 關係 性別 收入
0 40-49 公務員 行政/文員 家庭以外 男性 <=5 萬美元
1 50-59 非家庭自營業者 執行/管理人員 丈夫 男性 <=5 萬美元
2 40-49 私人企業 操作員/清潔人員 家庭以外 男性 <=5 萬美元
3 50-59 私人企業 操作員/清潔人員 丈夫 男性 <=5 萬美元
4 30-39 私人企業 專業人員 妻子 女性 <=5 萬美元
[44]:
df_binary = pd.get_dummies(df, sparse=True)
[45]:
df_binary.head()
[45]:
年齡_20-29 年齡_30-39 年齡_40-49 年齡_50-59 年齡_60-69 年齡_70-79 年齡_80-89 年齡_90-99 工作類別_ ? 工作類別_聯邦政府 ... 關係_丈夫 關係_家庭以外 關係_其他親屬 關係_親生子女 關係_未婚 關係_妻子 性別_女性 性別_男性 收入_ <= 5 萬美元 收入_ > 5 萬美元
0 ...
1 ...
2 ...
3 ...
4 ...

5 行 × 42 欄

[46]:
biadjacency = df_binary.sparse.to_coo()
[47]:
biadjacency = sparse.csr_matrix(biadjacency)
[48]:
# biadjacency matrix of the bipartite graph
biadjacency
[48]:
<32561x42 sparse matrix of type '<class 'numpy.bool_'>'
        with 195366 stored elements in Compressed Sparse Row format>
[49]:
# names of columns
names_col = list(df_binary)
[50]:
len(names_col)
[50]:
42
[51]:
names_col[:8]
[51]:
['age_20-29',
 'age_30-39',
 'age_40-49',
 'age_50-59',
 'age_60-69',
 'age_70-79',
 'age_80-89',
 'age_90-99']

來自 CSV 檔

你可以直接從 CSV 或 TSV 檔載入圖形

[52]:
graph = from_csv('miserables.tsv')
[53]:
graph
[53]:
{'names': array(['Anzelma', 'Babet', 'Bahorel', 'Bamatabois', 'Baroness',
        'Blacheville', 'Bossuet', 'Boulatruelle', 'Brevet', 'Brujon',
        'Champmathieu', 'Champtercier', 'Chenildieu', 'Child1', 'Child2',
        'Claquesous', 'Cochepaille', 'Combeferre', 'Cosette', 'Count',
        'Countess de Lo', 'Courfeyrac', 'Cravatte', 'Dahlia', 'Enjolras',
        'Eponine', 'Fameuil', 'Fantine', 'Fauchelevent', 'Favourite',
        'Feuilly', 'Gavroche', 'Geborand', 'Gervais', 'Gillenormand',
        'Grantaire', 'Gribier', 'Gueulemer', 'Isabeau', 'Javert', 'Joly',
        'Jondrette', 'Judge', 'Labarre', 'Listolier', 'Lt Gillenormand',
        'Mabeuf', 'Magnon', 'Marguerite', 'Marius', 'Mlle Baptistine',
        'Mlle Gillenormand', 'Mlle Vaubois', 'Mme Burgon', 'Mme Der',
        'Mme Hucheloup', 'Mme Magloire', 'Mme Pontmercy', 'Mme Thenardier',
        'Montparnasse', 'MotherInnocent', 'MotherPlutarch', 'Myriel',
        'Napoleon', 'Old man', 'Perpetue', 'Pontmercy', 'Prouvaire',
        'Scaufflaire', 'Simplice', 'Thenardier', 'Tholomyes', 'Toussaint',
        'Valjean', 'Woman1', 'Woman2', 'Zephine'], dtype='<U17'),
 'adjacency': <77x77 sparse matrix of type '<class 'numpy.int64'>'
        with 508 stored elements in Compressed Sparse Row format>}
[54]:
graph = from_csv('movie_actor.tsv', bipartite=True)
[55]:
graph
[55]:
{'names_row': array(['007 Spectre', 'Aviator', 'Crazy Stupid Love', 'Drive',
        'Fantastic Beasts 2', 'Inception', 'Inglourious Basterds',
        'La La Land', 'Midnight In Paris', 'Murder on the Orient Express',
        'The Big Short', 'The Dark Knight Rises',
        'The Grand Budapest Hotel', 'The Great Gatsby', 'Vice'],
       dtype='<U28'),
 'names': array(['007 Spectre', 'Aviator', 'Crazy Stupid Love', 'Drive',
        'Fantastic Beasts 2', 'Inception', 'Inglourious Basterds',
        'La La Land', 'Midnight In Paris', 'Murder on the Orient Express',
        'The Big Short', 'The Dark Knight Rises',
        'The Grand Budapest Hotel', 'The Great Gatsby', 'Vice'],
       dtype='<U28'),
 'names_col': array(['Brad Pitt', 'Carey Mulligan', 'Christian Bale',
        'Christophe Waltz', 'Emma Stone', 'Johnny Depp',
        'Joseph Gordon Lewitt', 'Jude Law', 'Lea Seydoux',
        'Leonardo DiCaprio', 'Marion Cotillard', 'Owen Wilson',
        'Ralph Fiennes', 'Ryan Gosling', 'Steve Carell', 'Willem Dafoe'],
       dtype='<U28'),
 'biadjacency': <15x16 sparse matrix of type '<class 'numpy.int64'>'
        with 41 stored elements in Compressed Sparse Row format>}

圖形也可以鄰接清單的形式提供(檢查 from_csv 函數)。

來自 GraphML 檔

你也可以載入以 GraphML 格式儲存的圖形。

[56]:
graph = from_graphml('miserables.graphml')
adjacency = graph.adjacency
names = graph.names
[57]:
# Directed graph
graph = from_graphml('painters.graphml')
adjacency = graph.adjacency
names = graph.names

來自 NetworkX

NetworkX 具有 匯入匯出 功能,可用於 CSR 格式。

其他選項

  • 你想要測試我們的範例圖形

  • 你想要從模型產生圖形

  • 你想要從現有儲存庫載入圖形(請參閱 NetSetKONECT

查看 資料 區段的其他教學課程!