相关文章推荐
坐怀不乱的铅笔  ·  Nature子刊 | ...·  1 年前    · 
有爱心的香烟  ·  OPC UA ...·  1 年前    · 
首发于 交通科研
共享单车模式分析和社区发现(Networkx+Gephi)—以上海为例

共享单车模式分析和社区发现(Networkx+Gephi)—以上海为例

小伙伴们!之前的推送简单介绍了Networkx的功能,本次推送继续使用Networkx进行数据的分析,主题是共享单车模式分析和社区发现,思路主要来自以下两篇论文(论文见文末百度云链接~):





下图是论文1中的配图,本次推送一部分的内容就是复现这个图!另一部分内容是复现论文2中的社区发现。图的复现用到的软件主要是Gephi,社区发现算法用到的是Networkx。



本次推送用到的数据是 上海市共享单车数据 (公众号内资料下载的资料一期),用到的字段主要有:orderid、start_location_x、start_location_y、end_location_x、end_location_y。


1 获取Networkx需要的结构

先把共享单车数据处理成(源节点,目标节点,权重)的格式,其他格式也可以构造复杂网络,这里是为了对应共享单车的数据结构(O——>D)。

import networkx as nx
import pylab
import numpy as np
import pandas as pd
import seaborn as sn
from datetime import datetime
import calendar
import matplotlib.pyplot as plt
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all" 
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
SH = pd.read_csv("F:\\20201004bike\\mobike_shanghai_sample_updated.csv")#读取共享单车数据
SH1 = SH[['orderid','start_location_x','start_location_y','end_location_x','end_location_y']]#tiqu 关键字段
#下边需要根据订单起点和终点经纬度确定起点和终点的唯一编码,这里是使用geopandas将订单OD点转为了点图层,然后提取O点和D点,以及计算OD之间的距离做为边的权重。
import pandas as pd
import geopandas as gpd
import os
from shapely.geometry import Point
OD = SH1
col_name = ["start_location_x","start_location_y"]
data = OD
data["geometry"] = data.apply(lambda x: Point(x[col_name]),axis=1)
shape_data = gpd.GeoDataFrame(data)
shape_data.head()
shape_data.crs = {'init' :'epsg:4326'} #指定坐标系





def extract(x):#x是geometry列
p1 = list(x.coords)[0]#coord
return p1
shape_data['coord'] = shape_data['geometry'].map(extract)



同样可以获得D点的坐标coord2,现在可以把coord和coord2分别当作源节点和目标节点传入networkx里了,为了简便,这里将坐标转换成了编号。



SOD =shape_data
G = nx.from_pandas_edgelist(SOD, 'ID', 'ID2', 'D', create_using=nx.DiGraph())#构造Grahp
pos = nx.spring_layout(G)# 
pylab.figure(1)
nx.draw(G, pos, with_labels=False, node_size=100, node_color="skyblue", node_shape="o", alpha=0.5,width=0.5)


Networkx输出的图是这样的:



Networkx可视化的能力相较于Gephi还是逊色了一点,下面用Gephi做可视化和一些指标分析。Networkx可以直接导出Gephi文件的格式。

nx.write_gexf(G,'1009-Networkx.gexf')

2. Gephi可视化

首先是Gephi的安装,链接 gephi.org/ ,下载后安装即可,如果能够正常打开 Gephi,跳过下面提示。 提示:如果安装完后出现“cannot find java 1.6 or higer”,解决方法如下,点击链接 itmop.com/soft/downinfo ,下载安装,安装jdk之后便可正常打开 Gephi。

  • 导入数据 :本次推送选择的是导入边表格,为了避免编码错误,参考 blog.csdn.net/SunCherry 进行csv设置,尝试将csv格式文件利用记事本另存的方式,将编码改为ANSI格式。Gephi输入表格时,将编码改为GB2312,结果,可以正常显示



其中,我的csv文件格式部分截图如下:



  • 可视化设置

导入边表格以后可以在概览界面看到初始网络效果:一般是分不开的正方形图:



在左下角有布局选项,选择一个算法,点运行展开(lay out) 我这里选用的是ForceAtlas 。展开后的结果如下所示,其它布局的介绍请看这里 blog.csdn.net/qq_353188




这个布局明显跟论文一的不一致,经过尝试后发现是“Fruchterman Reingold”(力引导布局)



设置好布局后运行,得到的结果还是不能对节点进行区分,需要设置节点的颜色和大小,同样的边也可以进行设置。





设置好后就可以得到论文一配图的高仿版






  • 指标计算

Gephi界面里有很多复杂网络的计算指标:平均度,平均加权度,网络直径等等。








  • 社区发现

点击模块化后可以实现社区发现,将节点设置中的“度”改为“模块”就可以看到不同社区的分布,不同的颜色代表不同的社区。



至此,复现论文一配图的任务完成了,Gephi还有很多强大的功能,等待大家去探索。

  • Louvain算法

社区发现算法有很多,例如LPA,HANP,SLPA以及Louvain,不同的算法划分社区的效果不尽相同。Louvain算法是基于模块度的社区发现算法,该算法在效率和效果上都表现较好,并且能够发现层次性的社区结构,其优化目标是最大化整个社区网络的模块度。






算法流程:

1、初始时将每个顶点当作一个社区,社区个数与顶点个数相同。

2、依次将每个顶点与之相邻顶点合并在一起,计算它们的模块度增益是否大于0,如果大于0,就将该结点放入该相邻结点所在社区。

3、迭代第二步,直至算法稳定,即所有顶点所属社区不再变化。

4、将各个社区所有节点压缩成为一个结点,社区内点的权重转化为新结点环的权重,社区间权重转化为新结点边的权重。

5、重复步骤1-3,直至算法稳定。


Networkx实现:安装“python-louvain”

pip install python-louvain

from community import community_louvain
G2 = nx.from_pandas_edgelist(SOD, 'ID', 'ID2', 'D')
partition =community_louvain.best_partition(G2)
size = float(len(set(partition.values())))
pos = nx.spring_layout(G)
count = 0.
for com in set(partition.values()) :
    count = count + 1.
    list_nodes = [nodes for nodes in partition.keys()
                                if partition[nodes] == com]