基于基站定位数据的商圈分析
目录
由于本书中很多没有给出最原始的数据。多是处理过程中的数据,失去了很多做数据特征工程的训练。
以后会更加注重kaggle比赛上的数据特征分析。
实验介绍
实验背景
随着个人手机和网络的普及,手机已经基本成为所有人必须持有的工具。根据手机信号再地理空间的覆盖情况结合时间序列的手机定位数据可以完整的还原人群的现实活动轨迹从而得到人口空间分布于活动联系的特征信息。
商圈是现代市场中的重要企业活动空间,商圈划分的目的之一是为了研究潜在的顾客分布,以制定适宜的商业对策。本次数据,是由通信运营商提供的,特定接口解析得到的用户定位数据。
实验目标
- 对用户的历史定位数据,采用数据挖掘技术,对基站进行分群
- 对不同的商圈分群进行特征分析,比较不同商圈类别的价值,选择合适区域进行针对性的营销活动
实验分析方法与过程
通过数据是由通信运营商提供,可以推测手机用户在使用短信业务、通话业务和上网业务等信息时产生的定位数据。由于数据中是由不同基站作为位置的辨别,可以将每个基站当做一个”商圈“,再通过归纳基站范围的人口特征,运用聚类算法,识别不同类别的基站范围,即可等同识别不同类别的商圈。衡量区域人口特征,可以从人流量和人均停留时间的角度进行分析。
分析流程
1)从移动通信运营商提供的特定接口上解析、处理、并滤除用户属性后得到用户定位数据。
2)以单个用户为例,进行数据探索分析,研究在不同基站的停留时间,并进一步地进行预处理,包括数据规约和数据变换。
3)利用步骤2)形成的已完成数据预处理的建模数据,基于基站覆盖范围区域的人流特征进行商圈聚类,对各个商圈分群进行特征分析,选择合适的区域进行运营商的促销活动。
数据抽取分析
数据抽取
从移动通信运营商提供的特定接口上解析、处理和过滤后,获得位置数据。时间设定为,2014-1-1为开始时间,2014-6-30为结束时间作为分析的观测窗口,抽取窗口内某市某区域的定位数据形成建模数据。
数据分析
为了便于观察数据,先提取用户的ID即EMASI号为”55555“的用户再2014年1月1号的定位数据。
观察数据,可以发现,两条数据可能是同一基站的不同时间。
从表中可以看到,用户在2014年1月1日00:31:48处于36908基站的范围,下一个记录是用户在2014年1月1日00:53:46处于36908基站的范围,这表明了用户从00:31:48到00:53:46都是处于36908基站,共停留了21分58秒,并且在00:53:46进入了36902基站的范围。判断用户在每个基站的停留时间需要依靠当前记录与下一条记录的对比,发生变化则意味着用户所在基站发生改变,可以记录在上一个基站停留的时间。
数据预处理
数据规约
原始数据的属性较多,由我们的挖掘目标,网络类型、LOC编号和信令类型这三个属性没有作用,剔除。衡量用户停留时间,没有必要精确到毫秒,故一同删除。在计算用户的停留时间,只计算两条记录的时间差,为了减少数据维度,把年月日合并为日期,时分秒合并为时间,得到数据。
数据变换
挖掘的目标是寻找高价值的商圈,需要根据用户的定位数据,提取出基站范围内区域的人流特征,如人均停留时间和人流等。高价值商圈,在人流特征上有人流量大和人均停留时间长的特点。写字楼的上班族在白天所处基站范围固定,时间也较长,人流量也大。居住区,也有基站范围固定,时间长,人流量大的特点。所以,单纯的停留时间无法判断商圈类别。现代社会工作,以一周为一个工作小周期,分为工作日和周末。一天中,分为上班时间和下班时间。
综上所述,设计人流特征的四个指标,工作日上班时间人均停留时间、凌晨人均停留时间、周末人均停留时间和日均人流量。工作日上班时间人均停留时间,意思是所有用户在上班时间9:0018:00处在该基站范围内的平均时间凌晨人均停留时间,意思是所有用户在凌晨时间00:0007:00处在该基站范围的平均时间周末人均停留时间,如上类推。日均人流量,指的是平均每天曾经在该基站范围内的人数。
这四个指标的计算,直接从原始数据计算比较复杂,需要先处理成中间数据,再从中计算得出四个指标。对于基站1,有以下公式,再带入所有基站,得出结果。
由于各个属性之间的差异较大。为了消除数量级数据带来的影响,在聚类之前,需要进行离差标准化处理,离差标准化处理的代码如下,得到建模的样本数据。
#-*- coding: utf-8 -*-
#数据标准化到[0,1]
import pandas as pd
#参数初始化
filename = '../data/business_circle.xls' #原始数据文件
standardizedfile = '../tmp/standardized.xls' #标准化后数据保存路径
#########使用index_col来建立索引列,不包含在data中
data = pd.read_excel(filename, index_col = u'基站编号') #读取数据
data = (data - data.min())/(data.max() - data.min()) #离差标准化
data = data.reset_index()
data.to_excel(standardizedfile, index = False) #保存结果
标准化后数据:
模型构建——层次聚类算法
层次聚类
层次聚类方法对给定的数据集进行层次的分解,直到某种条件满足为止。
在已经得到距离值之后,元素间可以被联系起来。通过分离和融合可以构建一个结构。传统上,表示的方法是树形数据结构,层次聚类算法,要么是自底向上聚集型的,即从叶子节点开始,最终汇聚到根节点;要么是自顶向下分裂型的,即从根节点开始,递归的向下分裂。
1.凝聚层次聚类:AGNES算法(自底向上)
首先将每个对象作为一个簇,然后合并这些原子簇为越来越大的簇,直到某个终结条件被满足
2.分裂层次聚类:DIANA算法(自顶向下)
首先将所有对象置于一个簇中,然后逐渐细分为越来越小的簇,直到达到了某个终结条件。
数据进行预处理以后,已经形成了建模数据。这次聚类,采用层次聚类算法,对建模数据进行基于基站数据的商圈聚类,画出谱系聚类图,代码如下。
#-*- coding: utf-8 -*-
#谱系聚类图
import pandas as pd
#参数初始化
standardizedfile = '../data/standardized.xls' #标准化后的数据文件
data = pd.read_excel(standardizedfile, index_col = u'基站编号') #读取数据
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (15.0, 4.0)
plt.rcParams['figure.dpi'] = 100
from scipy.cluster.hierarchy import linkage,dendrogram
#这里使用scipy的层次聚类函数
Z = linkage(data, method = 'ward', metric = 'euclidean') #谱系聚类图
P = dendrogram(Z, 0) #画谱系聚类图
plt.savefig(u'cluster.png')
plt.show()
根据代码,得到谱系聚类图,如图。
从图中可以看出,可以把聚类类别数取3类,再使用层次聚类算法进行训练模型,代码如下。
#-*- coding: utf-8 -*-
#层次聚类算法
import pandas as pd
#参数初始化
standardizedfile = '../data/standardized.xls' #标准化后的数据文件
k = 3 #聚类数
data = pd.read_excel(standardizedfile, index_col = u'基站编号') #读取数据
from sklearn.cluster import AgglomerativeClustering #导入sklearn的层次聚类函数
model = AgglomerativeClustering(n_clusters = k, linkage = 'ward')#凝聚层次聚类
model.fit(data) #训练模型
#详细输出原始数据及其类别
r = pd.concat([data, pd.Series(model.labels_, index = data.index)], axis = 1) #详细输出每个样本对应的类别
r.columns = list(data.columns) + [u'聚类类别'] #重命名表头
r.to_excel('../tmp/r.xls')
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
style = ['ro-', 'go-', 'bo-']
xlabels = [u'工作日人均停留时间', u'凌晨人均停留时间', u'周末人均停留时间', u'日均人流量']
pic_output = '../tmp/type_' #聚类图文件名前缀
for i in range(k): #逐一作图,作出不同样式
plt.figure()
tmp = r[r[u'聚类类别'] == i].iloc[:,:4] #提取每一类
for j in range(len(tmp)):
plt.plot(range(1, 5), tmp.iloc[j], style[i])
plt.xticks(range(1, 5), xlabels, rotation = 20) #坐标标签
plt.title(u'商圈类别%s' %(i+1)) #我们计数习惯从1开始
plt.subplots_adjust(bottom=0.15) #调整底部
plt.savefig(u'%s%s.png' %(pic_output, i+1)) #保存图片
本节我们使用了scipy和sklearn两种python库来实现层次聚类算法。根据scipy库的linkage聚类结果,将聚类类别个数定为3。再使用sklearn库的层次聚类模型将数据分为3类,进行类别分析。
模型分析
针对聚类结果,按不同类别画出了3个特征的折线图:
- 商圈类别1,工作日人均停留时间、凌晨人均停留时间都很低,周末人均停留时间中等,日均人流量极高,这符合商业区的特点。
- 商圈类别2,工作日人均停留时间中等,凌晨和周末人均停留时间很长,日均人流量较低,这和居住区的特征符合
- 商圈类别3,这部分工作日人均停留时间很长,凌晨和周末停留较少,日均人流量中等,这和办公商圈非常符合。