摘要: 本文是一篇pandas/networkx图分析入门,对所举的欺诈检测用例进行了简单的图论分析,便于可视化及操作。
对于图论而言,大家或多或少有些了解,数学专业或计算机相关专业的读者可能对其更加清楚。图论中的图像是由若干给定的点及连接两点的线所构成的图形,这样的图像通常用来描述某些事物之间的某种特定关系,用点代表事物,用两点之间的连接线表示二者具有的某种关系,在互联网与通信行业中应用广泛。图论分析(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': ['felix.revert@gmail.com', 'jean.durand@gmail.com', 'j.custom@gmail.com',
pd.np.nan, 'j.custom@gmail.com', 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"]
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?