對于圖論而言,大家或多或少有些了解,數學專業或計算機相關專業的讀者可能對其更加清楚。圖論中的圖像是由若幹給定的點及連接配接兩點的線所構成的圖形,這樣的圖像通常用來描述某些事物之間的某種特定關系,用點代表事物,用兩點之間的連接配接線表示二者具有的某種關系,在網際網路與通信行業中應用廣泛。圖論分析(Graph analysis)并不是資料科學領域中的新分支,也不是資料科學家目前應用的常用首選方法。然而,圖論可以做一些瘋狂的事情,一些經典用例包括欺詐檢測、推薦或社交網絡分析等,下圖是 NLP中的非經典用例——處理主題提取。

欺詐檢測用例
假設現在你有一個客戶資料庫,并想知道它們是如何互相連接配接的。特别是,你知道有些客戶涉及複雜的欺詐結構,但是在個人層面上可視化資料并不會帶來欺詐證據,欺詐者看起來像其他普通客戶一樣。
隻需檢視原始資料,處理使用者之間的連接配接就可以顯示更多資訊。具體而言,對于通常的基于機器學習的評分模型而言,這些特征不會被視為風險,但這些不會被認為存在風險的特征可能成為基于圖表分析評分模型中的風險特征。
示例:三個具有相同電話号碼的人,連接配接到具有相同電子郵件位址的其他人,這是不正常的,且可能存在風險。電話号碼本身沒有什麼價值,并不會提供任何資訊(是以,即使最好的深度學習模型也不能從中擷取任何價值資訊),但個人通過相同的電話号碼或電子郵件位址連接配接這一問題,可能是一種風險。
下面在Python中進行一些處理:
設定資料、清理和建立圖表
(構造的仿真資料)
首先從一個pandas DataFrame開始(它基本上是Python中的Excel表)
import pandas as pd
df = pd.DataFrame({'ID':[1,2,3,4,5,6],
'First Name':['Felix', 'Jean', 'James', 'Daphne', 'James', 'Peter'],
'Family Name': ['Revert', 'Durand', 'Wright', 'Hull', 'Conrad', 'Donovan'],
'Phone number': ['+33 6 12 34 56 78', '+33 7 00 00 00 00', '+33 6 12 34 56 78', '+33 6 99 99 99 99', '+852 0123 4567', '+852 0123 4567'],
'Email': ['[email protected]', '[email protected]', '[email protected]', pd.np.nan, '[email protected]', pd.np.nan]})
從代碼中看到,先加載資料,以df表示。下面對其做一些準備,需要連接配接具有相同電話号碼和相同電子郵件的個人(由其ID表示)。首先從電話号碼開始:
column_edge = 'Phone number'
column_ID = 'ID'
data_to_merge = df[[column_ID, column_edge]].dropna(subset=[column_edge]).drop_duplicates() # select columns, remove NaN
# To create connections between people who have the same number,
# join data with itself on the 'ID' column.
data_to_merge = data_to_merge.merge(
data_to_merge[[column_ID, column_edge]].rename(columns={column_ID:column_ID+"_2"}),
on=column_edge
)
處理的資料看起來像這樣:
從圖中看到,裡面有一些聯系,但存在兩個問題:
- 個人與自己聯系在一起
- 從資料中看到,當X與Y連接配接時,Y也與X連接配接,有兩行資料用于同一連接配接。下面讓我們清理一下:
# By joining the data with itself, people will have a connection with themselves.
# Remove self connections, to keep only connected people who are different.
d = data_to_merge[~(data_to_merge[column_ID]==data_to_merge[column_ID+"_2"])] \
.dropna()[[column_ID, column_ID+"_2", column_edge]]
# To avoid counting twice the connections (person 1 connected to person 2 and person 2 connected to person 1)
# we force the first ID to be "lower" then ID_2
d.drop(d.loc[d[column_ID+"_2"]<d[column_ID]].index.tolist(), inplace=True)
下面,資料看起來像這樣:
從圖中看到,1和3連接配接,5和6也連接配接。我們對電子郵件位址也進行同樣的處理。下面建構一個圖表,将在這裡隻分享代碼的一部分,因為添加全部代碼比較棘手,項目代碼位址在文末給出。
import networkx as nx
G = nx.from_pandas_edgelist(df=d, source=column_ID, target=column_ID+'_2', edge_attr=column_edge)
G.add_nodes_from(nodes_for_adding=df.ID.tolist())
下面進行資料可視化
使用networkx進行圖形可視化
簡單的nx.draw(G)代碼就能獲得以下内容:
從圖中看到,這是一個相當有趣的形式!但是我們看不出圖中的每個點代表的是誰,誰和誰之間有什麼連接配接。下面将其具體化:
從圖中可以看到, 4個人通過2個不同的電話号碼和1個電子郵件位址連接配接在一起,後續還應該進行更多的調查!
真正實作工業化的下一步
讓我們回顧一下我們前面做過的事情:
- 根據使用者資料庫建立圖表
-
自定義可視化,幫助我們發現潛在奇怪的模式
如果你是業務驅動的,并希望一些專家使用你已經完成的工作,那麼你的下一個重點應該是:
- 将查找多個人連接配接在一起的這一過程自動化,或風險模式檢測
-
通過圖形可視化和原始資料自動建立可視化和建立自定義儀表闆的過程
本文不會在這裡詳細介紹上述内容,但是會告訴你如何繼續進行上述兩個步驟:
1.風險模式檢測
這裡有兩種方法:
- 從你認為有風險的人(或你被發現為欺詐者的人)那裡開始,檢查他們與其他人的關系。這與機器學習相關,這是一種“有監督”方法。更進一步,你還可以從機器學習評分(例如,使用XGBoost)開始,尋找他們之間存在的緊密聯系。
-
從奇怪的模式(太多的連接配接、密集的網絡...),這是“無監督”的方法。
在我們舉的例子中,我們沒有已知的欺詐者,是以我們将采用上述的第二種方法。
Networkx已經實作了完全正确的算法:degree( )、centrality( )、pagerank( )、connected_components( )......這些算法可以讓你以數學的形式定義風險。
2.為業務建立可視化和自動化分析
對于大多數資料科學家來說,這内容聽起來是老派,但快速做到這一點的方法就是使用Excel。
Xlsxwriter軟體包可幫助你粘貼風險人物圖表中的資料,并将我們建立的圖表圖像直接粘貼到Excel檔案中。通過這種操作之後你将獲得每個風險網絡的儀表闆,如下所示:
對于每個具有潛在風險的網絡,你都可以自動地建立儀表闆,讓專家完成他們的工作。同樣你也可以在資訊中心中添加一些名額:涉及的人數、不同電話号碼的數量及電子郵件位址等。
全文源碼在此,希望這篇文章對你有所幫助。
數十款阿裡雲産品限時折扣中,趕緊點選領劵開始雲上實踐吧!
作者資訊
Félix Revert,資料科學家
LinkedIn:
https://www.linkedin.com/in/f%C3%A9lix-revert-00998852/本文由阿裡雲雲栖社群組織翻譯。
文章原标題《Getting started with graph analysis in Python with pandas and networkx》,譯者:海棠,審校:Uncle_LLD。
文章為簡譯,更為詳細的内容,
請檢視原文。