从零开始搭建django前后端分离项目 系列六(实战之聚类分析)
项目需求
本项目从impala获取到的数据为用户地理位置数据,每小时的数据量大概在8000万条,数据格式如下:

公司要求对这些用户按照聚集程度进行划分,将300米范围内用户数大于200的用户划分为一个簇,并计算这个簇的中心点和簇的边界点。
附模拟的数据:https://files.cnblogs.com/files/dotafeiying/test.zip
实现原理
下面我们来一步一步实现上述需求:
1、将用户按照聚集程度进行划分
我们可以选择基于密度的聚类算法DBscan算法,DBSCAN算法的重点是选取的聚合半径参数eps和聚合所需指定的数目min_samples,正好对应这里的300米和200个用户。但是需要注意的是,dbscan算法的默认距离度量为欧几里得距离,而我们需要的是球面距离,所以需要定制我们自己的距离算法运用到dbscan算法中。解决方法是:将dbscan设置为 metric='precomputed' ,这时fit传入的X参数必须为相似度矩阵,然后fit函数会直接用你这个矩阵来进行计算。这意味着我们可以用我们自定义的距离事先计算好各个向量的相似度,然后调用这个函数来获得结果。
2、识别簇的边界点
这里我使用凸包算法来计算簇的边界点,那么问题就变成:如何求一个平面内所有点的最小凸边形。在scipy.spatial 和opencv 分别有计算凸包的函数,不清楚的可以自行百度。
3、计算簇的中心点
由于dbscan算法中并没有提到获取簇中心点的方法,那么我们就需要自己设计来计算簇的中心点。现在簇的所有点已知,我们可以利用k-means算法来计算簇的中心点,只需要设置K=1(即质心为1)。
实现代码
# -*- coding:utf-8 -*-
from math import radians, cos, sin, asin, sqrt,degrees
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN, KMeans
from scipy.spatial import ConvexHull
from sklearn.cluster import MeanShift, estimate_bandwidth
from scipy.spatial.distance import pdist, squareform
from sklearn import metrics pd.set_option('display.width', 400)
pd.set_option('display.expand_frame_repr', False)
pd.set_option('display.max_columns', 70) def haversine(lonlat1, lonlat2):
lat1, lon1 = lonlat1
lat2, lon2 = lonlat2
lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2
c = 2 * asin(sqrt(a))
r = 6371 # Radius of earth in kilometers. Use 3956 for miles
return c * r if __name__=='__main__':
df=pd.read_csv('test.csv')
print(df.head())
X=df[['mr_longitude','mr_latitude']].values radius = 200
epsilon = radius / 100000
min_samples = 40 # model = DBSCAN(eps=epsilon, min_samples=min_samples)
# y_pred = model.fit_predict(X) # # 自定义度量距离
distance_matrix = squareform(pdist(X, (lambda u, v: haversine(u, v))))
db = DBSCAN(eps=300, min_samples=200, metric='precomputed')
y_pred = db.fit_predict(distance_matrix)
print(y_pred.tolist()) n_clusters_ = len(set(y_pred)) - (1 if -1 in y_pred else 0) # 获取分簇的数目
print('分簇的数目:',n_clusters_)
df['label'] = y_pred df_group = df[df['label'] != -1][['mr_longitude', 'mr_latitude', 'label']].groupby(['label'])
plt.figure(facecolor='w')
for label, group in df_group:
points = group[['mr_longitude', 'mr_latitude']].values
# 得到凸轮廓坐标的索引值,逆时针画
hull = ConvexHull(points).vertices.tolist()
hull.append(hull[0])
plt.plot(points[hull, 0], points[hull, 1], 'r--^', lw=2)
for i in range(len(hull) - 1):
plt.text(points[hull[i], 0], points[hull[i], 1], str(i), fontsize=10)
plt.scatter(X[:, 0], X[:, 1], c=y_pred,s=4)
plt.grid(True)
plt.show()
可视化

实际项目中的效果图

从零开始搭建django前后端分离项目 系列六(实战之聚类分析)的更多相关文章
- 从零开始搭建django前后端分离项目 系列一(技术选型)
前言 最近公司要求基于公司的hadoop平台做一个关于电信移动网络的数据分析平台,整个项目需求大体分为四大功能模块:数据挖掘分析.报表数据查询.GIS地理化展示.任务监控管理.由于页面功能较复杂,所以 ...
- 从零开始搭建django前后端分离项目 系列四(实战之实时进度)
本项目实现了任务执行的实时进度查询 实现方式 前端websocket + 后端websocket + 后端redis订阅/发布 实现原理 任务执行后,假设用变量num标记任务执行的进度,然后将num发 ...
- 从零开始搭建django前后端分离项目 系列三(实战之异步任务执行)
前面已经将项目环境搭建好了,下面进入实战环节.这里挑选项目中涉及到的几个重要的功能模块进行讲解. celery执行异步任务和任务管理 Celery 是一个专注于实时处理和任务调度的分布式任务队列.由于 ...
- 从零开始搭建django前后端分离项目 系列二(项目搭建)
在开始项目之前,假设你已了解以下知识:webpack配置.vue.js.django.这里不会教你webpack的基本配置.热更新是什么,也不会告诉你如何开始一个django项目,有需求的请百度,相关 ...
- 从零开始搭建django前后端分离项目 系列五(实战之excel流式导出)
项目中有一处功能需求是:需要在历史数据查询页面进行查询字段的选择,然后由后台数据库动态生成对应的excel表格并下载到本地. 如果文件较小,解决办法是先将要传送的内容全生成在内存中,然后再一次性传入R ...
- Django前后端分离项目部署
vue+drf的前后端分离部署笔记 前端部署过程 端口划分: vue+nginx的端口 是81 vue向后台发请求,首先发给的是代理服务器,这里模拟是nginx的 9000 drf后台运行在 9005 ...
- luffy项目搭建流程(Django前后端分离项目范本)
第一阶段: 1.版本控制器:Git 2.pip安装源换国内源 3.虚拟环境搭建 4.后台:Django项目创建 5.数据库配置 6.luffy前 ...
- nginx+vue+uwsgi+django的前后端分离项目部署
Vue+Django前后端分离项目部署,nginx默认端口80,数据提交监听端口9000,反向代理(uwsgi配置)端口9999 1.下载项目文件(统一在/opt/luffyproject目录) (1 ...
- List多个字段标识过滤 IIS发布.net core mvc web站点 ASP.NET Core 实战:构建带有版本控制的 API 接口 ASP.NET Core 实战:使用 ASP.NET Core Web API 和 Vue.js 搭建前后端分离项目 Using AutoFac
List多个字段标识过滤 class Program{ public static void Main(string[] args) { List<T> list = new List& ...
随机推荐
- Android为TV端助力 转载:内存泄露与内存溢出的区别
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory:比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出. ...
- Android为TV端助力 最详细的动画大全,包括如何在代码和在XML中使用
一.动画类型 Android的animation由四种类型组成:alpha.scale.translate.rotate XML配置文件中 alpha 渐变透明度动画效果 scale 渐变尺寸伸缩动画 ...
- vue 构建项目vue-cli
1.首先得有node和npm的环境,node的下载:http://nodejs.org/download/.安装node之后,npm也自动生成了,显示版本号就意味着安装成功 2.接下来就是安装vue- ...
- Android开发学习之RecyclerView
1.在app/build.gradle中添加RecyclerView依赖 implementation 'com.android.support:recyclerview-v7:28.0.0' 注意依 ...
- java StringBuffer读写文件
java StringBuffer读写文件 StringBuffer的优势 较String:String每更新一次就会new一个新的对象出来,更新次数上去之后,内存开销太大.而StringBuffer ...
- Oracle笔记----oracle数字类型number自增
创建序列 create sequence seq_student start increment maxvalue nominvalue nocycle nocache; 创建触发器 create o ...
- Mysql----修改MySQL5.7的root的密码
在开始服务的情况之下 进入mysql 更改密码:update mysql.user set authentication_string=password('新的密码') where user='r ...
- 用cmd命令行编译JAVA程序时出现“找不到或无法加载主类”
今天复习Java基础知识时,使用cmd命令窗口进行编译Java文件发现了如下问题: 网上有很多的解决方法,和问题出现的讨论,以下方法是解决我出现这个问题方式. 解决方式: 重点是圈住的部分. 下面是我 ...
- C++多线程同步技巧(二)--- 事件
简介 Windows在线程控制方面提供了多种信号处理机制,其中一种便是使用 CreateEvent() 函数创建事件,然后使用信号控制线程运行.其中将事件变为有信号可使用 SetEvent() 函数, ...
- phprpc的使用示例以及报错Fatal error: Cannot redeclare gzdecode() in D:\wamp\www\immoc\phprpc\compat.php 处理
今天看书,发现了PHPRPC这个好东东,故在此写下来以作笔记. PHPRPC 是一个轻型的.安全的.跨网际的.跨语言的.跨平台的.跨环境的.跨域的.支持复杂对象传输的.支持引用参数传递的.支持内容输出 ...