核密度分析

一.算法介绍

核密度估计(Kernel Density Estimation)是一种用于估计数据分布的非参数统计方法。它可以用于多种目的和应用,包括:

  • 数据可视化:核密度估计可以用来绘制平滑的密度曲线或热力图,从而直观地表示数据的分布情况。它可以帮助我们观察数据集中的高密度区域、低密度区域以及变化趋势。
  • 异常检测:通过核密度估计,我们可以识别数据中的异常点或离群值。异常点通常表现为低密度区域或与其他数据点明显不同的区域。
  • 概率密度计算:核密度估计可以用于计算给定数值的概率密度。通过将新数据点带入核密度估计函数,可以估计出该点在数据分布中的密度。
  • 模式识别:核密度估计可以用于识别数据中的模式或聚类。通过观察密度最高的区域,可以推断数据的聚类情况或潜在的模式。
  • 预测建模:核密度估计可以用于构建概率模型,进而进行预测。例如,在分类问题中,可以使用核密度估计来估计每个类别的概率密度,然后根据新的数据点所属的密度来进行分类预测。

根据具体的应用需求,我们可以灵活地使用核密度估计来分析和理解数据集的特征和结构,可能的用途包括针对社区规划分析房屋密度或犯罪行为,或探索道路或公共设施管线如何影响野生动物栖息地。
每个点位可以设置 weight 字段赋予某些要素比其他要素更大的权重,该字段还允许使用一个点表示多个观察对象。例如,一个地址可以表示一栋六单元的公寓,或者在确定总体犯罪率时可赋予某些罪行比其他罪行更大的权重。

二.算法计算原理

本算法以四次核函数为基础,四次核函数的特点是具有平滑的曲线形状,具有较宽的窗口,对数据点的贡献在距离较远时会迅速减小。由于其平滑性和较大的支持范围,四次核函数在核密度估计中被广泛使用。

在这里插入图片描述

在核密度估计中,通过将核函数应用于每个数据点,并对所有数据点的贡献进行求和,可以计算出在每个位置上的密度估计值。四次核函数的结果可视为在核密度估计中每个位置的密度贡献权重。较大的结果表示该位置的密度较高,而较小或接近零的结果表示该位置的密度较低。
本算法中主要利用核密度公式计算空间范围内的核密度值,根据核密度值生成 png 或 jpg 格式的热力图,或者将整个空间切割成网格,用网格中心点参与核密度计算生成 geojson 文件,以供进一步空间探索分析。

    /***  计算单个核密度* @param radius 半径* @param dist 两点的距离* @param weight 权重* @return*/public static double computeKernel(double radius, double dist, double weight){return  (3 / Math.PI) * weight * Math.pow((1 - Math.pow(dist / radius,2)), 2);}

创新性说明:

  • 1.算法会自适应数据中的空间点位范围,此范围可根据参数bufferSize 设置缓冲区扩展,以获取数据范围外的点参与计算。
  • 2.根据空间范围每隔特定步长创建虚拟点位或划分网格,灵活性较高,步长越小则结果在地图分布上的精度越高,步长参数step(米) 可选,如果没有设置, 则默认在空间范围内自适应创建一百万左右虚拟点或网格。
  • 3.采用多线程的方式进行核密度计算,速度更快。
  • 4.可将结果值进行归一化处理,核密度计算出来的结果值主要用于观察数据分布,但是各个结果值之间相差范围较大,不易观察数据分布,归一化后能更清晰观察不同区域间的分布情况。
  • 5.可根据核密度值的大小根据不同需求生成热力图或 geojson 文件。可在geojson文件上做进一步探索。

三.算法程序

1. 核心流程代码

从csv中获取源数据点信息, 获取坐标范围,如果需要缓冲区, 则设置缓冲区, 获取步长长度(默认一百万个像素点或网格),然后根据核密度信息创建图片或geojson

        // 输入文件路径String inputPath ="D:\\测试数据.csv";// 输出文件路径String outPath ="D:\\测试数据.geojson";// String outPath ="D:\\测试数据.jpg";// 经度字段String lonKey = "lon";// 纬度字段String latKey = "lat";// 权重字段String weightKey = "";// 影响半径double radius = 300.0;// 缓冲区double bufferSize = 0.1;// 生成的网格长度(单位: 米)int step = 0;int type;if (outPath.endsWith("png") || outPath.endsWith("jpg")){type = 0;}else if (outPath.endsWith("geojson")){type = 1;}else {throw new RuntimeException("输出文件格式只能是 png、jpg 或者 geojson");}// 从csv中获取源数据点信息List<EntryPoint> entryPoints = EntryPoint.formatToEntryPoints(inputPath, lonKey, latKey, weightKey, radius);// 获取坐标范围double[] coordsScope = KernelUtils.getCoordsScope(entryPoints);// 如果需要缓冲区, 则设置缓冲区if (bufferSize != 0){coordsScope = KernelUtils.getBufferScope(coordsScope[0], coordsScope[1], coordsScope[2], coordsScope[3], bufferSize);}// 获取默认的步长长度, 默认一百万个像素点或网格if (step ==0){step = KernelUtils.getDefaultSize(coordsScope);}// 根据核密度信息创建图片或geojsonkernel(coordsScope, entryPoints, step, radius, type, outPath);
    /*** 核密度方法* @param coordsScope 坐标范围* @param entryPoints  从csv中获取源数据点信息* @param step 步长长度* @param radius 影响半径* @param type 输出文件类型*/public static void kernel(double[] coordsScope, List<EntryPoint> entryPoints, int step, double radius, int type, String path){// 获取网格坐标系的lon, lat的列表List<Double[]> coords = KernelUtils.getKennelPointCoords(coordsScope[0], coordsScope[1],coordsScope[2],coordsScope[3], step);Progress.progress( progress++);int width =  coords.get(0).length;int high = coords.get(1).length;if (type == 1){// 生产 geojson 网格结果generatorGridGeojson(coords, entryPoints, width-1, high-1, radius, path, step);}else {// 生产热力图图片generatorThermalMap(coords, entryPoints, width, high, radius, path, step);}}

2.创建面的 geojson 文件

    /***  根据核密度信息创建面的 geojson 文件* @param coords 虚拟数据点经纬度列表* @param entryPoints 数据点* @param width 横向点位数量* @param high 纵向点位数量* @param radius 影响半径*/public static void generatorGridGeojson(List<Double[]> coords, List<EntryPoint> entryPoints,int width, int high, double radius, String path, int step){// 获取所有中心点位的数据List<PixelPoint> pixelPoints = KernelUtils.getGridCenters(coords);// 进行核密度计算, 并记录受到影响的网格信息KernelResult kernelResult = kernelCompute(entryPoints, pixelPoints, width, high, radius);Double[][] matrix = kernelResult.getMatrix();Double max = kernelResult.getMax();Double min = kernelResult.getMin();// 生产面的 geojson 文件writeToFile(KernelUtils.jointGridGeojson(matrix, max, min, coords), path);System.out.println(String.format("计算完成, 生成 geojson 文件, 参与计算网格  %d 个, 受影响网格 %d 个, 相邻网格间距 %s 米",pixelPoints.size(), KernelUtils.effectiveGrid, step));}

3.热力图图片

    /*** 根据核密度信息创建热力图图片* @param coords 虚拟数据点经纬度列表* @param entryPoints 数据点* @param width 横向点位数量* @param high 纵向点位数量* @param radius 影响半径*/public static void generatorThermalMap(List<Double[]> coords, List<EntryPoint> entryPoints,int width, int high, double radius, String path, int step){// 获得所有点位List<PixelPoint> pixelPoints = KernelUtils.spliceKennelPoints(coords);// 进行核密度计算, 并记录受到影响的网格信息KernelResult kernelResult = kernelCompute(entryPoints, pixelPoints, width, high, radius);Double[][] matrix = kernelResult.getMatrix();Double max = kernelResult.getMax();Double min = kernelResult.getMin();// 生产热力图ImageGenerator.generatorImage(matrix, max, min, path);System.out.println(String.format("计算完成, 生成图片 像素: %d x  %d, 相邻像素点实际代表距离 %s 米", width, high, step));}

4.计算所有点位的核密度

    /*** 计算所有点位的核密度* @param entryPoints 数据点信息* @param pixelPoints 创建的虚拟像素点* @param radius 影响半径* @return*/public static KernelResult kernelCompute(List<EntryPoint> entryPoints, List<PixelPoint> pixelPoints, int width, int high, double radius){List<Double> values = new ArrayList<>();double affectLat = KernelUtils.getLatDist(radius);// 记录受到影响的网格Double[][] matrix = new Double[high][width];// 建立线程池ThreadPoolExecutor threadPool = new ThreadPoolExecutor(30, 30, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(Integer.MAX_VALUE));// 线程等待计数器CountDownLatch countDownLatch = new CountDownLatch(pixelPoints.size());// 创建锁, 使计算数据具有线程间可见性Lock lock = new ReentrantLock();int stepPosition = pixelPoints.size() / 75;for (int i = 0; i < pixelPoints.size(); i++){PixelPoint pixelPoint = pixelPoints.get(i);Double kennelLon = pixelPoint.getLon();Double kennelLat = pixelPoint.getLat();threadPool.execute(() -> {// 开始计算每个网格受到其他所有点所影响的核密度double kernel = 0.0;for (int j = 0; j < entryPoints.size(); j++){EntryPoint entryPoint = entryPoints.get(j);double lon = entryPoint.getLon();double lat = entryPoint.getLat();if (Math.abs(lon - kennelLon) > entryPoint.getAffectLon() || Math.abs(lat - kennelLat) > affectLat){continue;}// 获取权重, 默认为 1.0double weight = 1.0;if (entryPoint.getWeight() != null){weight = entryPoint.getWeight();}// 计算网格中心点与源数据点的距离double distance = KernelUtils.getDistance(lon, lat, kennelLon, kennelLat);// 影响半径大于距离的点直接去掉if (distance <= radius){// 计算每个网格所受影响的核密度kernel += computeKernel(radius, distance, weight);}}lock.lock();// 为中心点实体类赋予核密度的值Double value = 1 / Math.pow(radius, 2) * kernel;matrix[pixelPoint.getI()][pixelPoint.getJ()] = value;values.add(value);lock.unlock();countDownLatch.countDown();if (countDownLatch.getCount() % stepPosition == 0 && progress < 80){Progress.progress(progress++);}});}// 等待所有任务执行完毕try {countDownLatch.await();} catch (InterruptedException e) {throw new RuntimeException(e);}// 关闭线程池threadPool.shutdown();return  new KernelResult(matrix, Collections.max(values), Collections.min(values));}

5.可执行 jar 包

该程序可打为可执行jar包, 文件夹中的: kernel.jar
运行环境: jdk 1.8

执行示例:

java -jar kernel.jar 杭州市超市营业额.csv 杭州市超市营业额热力.jpg 经度 纬度 利润 2000.0 0.1 0
java -jar kernel.jar 杭州市超市营业额.csv 杭州市超市营业额分布.geojson 经度 纬度 利润 2000.0 0.1 0
java -jar kernel.jar 测试数据.csv 测试数据.jpg lon lat "" 300.0 0.1 0
java -jar kernel.jar 测试数据.csv 测试数据.geojson lon lat "" 300.0 0.1 0
参数参数位置参数说明
inputPath1输入的csv文件路径
outPath2输出的文件路径,程序根据文件后缀选择生产的文件类型,只允许 jpg、png、geojson 三种文件。
lonKey3输入文件中的经度字段名
latKey4输入文件中的纬度字段名
weightKey5输入文件中的权重字段名,没有则输入””
radius6影响半径,单位米,影响半径越长,周围空间受该数据的影响越广,需根据不同的输入数据情况调整
bufferSize7空间缓冲区,可扩大数据空间范围,一般0.1即可,即扩大 10% 的区域
step8空间划分步长,步长越小则参与计算的空间点数据越多,计算量越大,结果数据越精确, 需根据不同的输入数据情况调整,当值为0时,程序则适配生成一百万个点或网格参与计算,注:尽量不要在城市级别范围设置过低步长

四.执行结果展示

热力图示例:
在这里插入图片描述

平台分析示例:

在这里插入图片描述

杭州市超市营业额区域性分析-热力图:

在这里插入图片描述

杭州市超市营业额区域性分析-平台分析:
在这里插入图片描述

五、应用场景

  1. 金融风险评估:核密度算法可以用于评估某种投资方式的风险程度。将历史数据输入核密度估计器中,可以得出该投资方式在不同风险水平下的收益概率密度分布。这有助于金融机构更好地了解风险和收益之间的平衡。

  2. 生态学:核密度算法可用于研究动植物的栖息地和迁徙模式。将动植物的观察数据输入核密度估计器中,可以得出它们在不同地点出现的概率密度分布,帮助科学家更好地了解动植物的栖息地范围和活动规律。

  3. 交通流量预测:核密度算法可以用于预测道路上的交通流量。将历史交通流量数据输入核密度估计器中,可以得出在不同时间段内和不同位置上的交通流量概率密度分布。这有助于交通管理人员更好地规划道路、优化路线和管理交通拥堵。

  4. 模式识别:核密度算法可以使用于人脸识别、图像处理等领域。将输入数据的特征值输入核密度估计器中,可以得出不同特征值下相应数据的概率密度分布。这可用于识别图像中不同物体的特征值,例如人脸的轮廓和眼睛的位置,从而实现自动化识别。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/697014.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

win系统下安装php8.3版本并配置环境变量的详细教程

本篇文章主要讲解在win系统下安装和配置php8.3版本&#xff0c;并配置环境变量的详细教程。 日期&#xff1a;2024年2月22日 作者&#xff1a;任聪聪 一、下载php8.3版本包 php8.3版本官方下载地址&#xff1a;https://windows.php.net/download#php-8.3 步骤一、打开下载地址…

【Unity】Unity与安卓交互

问题描述 Unity和安卓手机进行交互&#xff0c;是我们开发游戏中最常见的场景。本教程将从一个简单的例子来演示一下。 本教程需要用到Android Studio2021.1.1 1.Android Studio新建一个工程 2.选择Empty Activity 然后点击Next 3.点击Finish完成创建 4.选择File-New-New Mo…

【python 3.9.18】windowns安装版

因为这个版本官方未提供&#xff0c;所以需要自己编译出来&#xff0c;其他没有的版本可以依据下面的进行生成一个exe也可行。 成品&#xff1a; https://gitee.com/greatLong/python-3.9.18/tree/master/python-3.9.18/PCbuild/amd64 1、环境准备 需要使用到 这里面还需要选…

【MATLAB GUI】 5. 图像处理菜单(菜单编辑器)

看B站up主freexyn的freexyn编程实例视频教程系列36Matlab GUI的学习笔记 任务要求设计一个图像处理菜单&#xff0c;实现图像的打开导入、灰度处理、存储等功能 修改过文件名&#xff0c;所以运行的时候会有一点点报错&#xff0c;但是不影响运行 打开工具栏下边的菜单编辑器…

创建一个基于Node.js的实时聊天应用

在当今数字化社会&#xff0c;实时通讯已成为人们生活中不可或缺的一部分。无论是在社交媒体平台上与朋友交流&#xff0c;还是在工作场合中与同事协作&#xff0c;实时聊天应用都扮演着重要角色。与此同时&#xff0c;Node.js作为一种流行的后端技术&#xff0c;为开发者提供了…

CrossOver虚拟机软件2024有哪些功能?最新版本支持哪些游戏?

CrossOver由codewaver公司开发的类虚拟机软件&#xff0c;目的是使linux和Mac OS X操作系统和window系统兼容。CrossOver不像Parallels或VMware的模拟器&#xff0c;而是实实在在Mac OS X系统上运行的一个软件。CrossOvers能够直接在Mac上运行Windows软件与游戏&#xff0c;而不…

LangChain支持哔哩哔哩视频总结

是基于LangChain框架下的开发&#xff0c;所以最开始请先 pip install Langchain pip install bilibili-api-python 技术要点&#xff1a; 使用Langchain框架自带的Document loaders 修改BiliBiliLoader的源码&#xff0c;自带的并不支持当前b站的视频加载 源码文件修改&a…

【高德地图】Android高德地图绘制标记点Marker

&#x1f4d6;第4章 Android高德地图绘制标记点Marker ✅绘制默认 Marker✅绘制多个Marker✅绘制自定义 Marker✅Marker点击事件✅Marker动画效果✅Marker拖拽事件✅绘制默认 Infowindow&#x1f6a9;隐藏InfoWindow 弹框 ✅绘制自定义 InfoWindow&#x1f6a9;实现 InfoWindow…

ArcgisForJS如何实现添加含图片样式的点要素?

文章目录 0.引言1.加载底图2.获取点要素的坐标3.添加含图片样式的几何要素4.完整实现 0.引言 ArcGIS API for JavaScript 是一个用于在Web和移动应用程序中创建交互式地图和地理空间分析应用的库。本文在ArcGIS For JavaScript中使用Graphic对象来创建包含图片样式的点要素。 …

MIT-6.824-Lab2,Raft部分笔记|Use Go

文章目录 前记Paper6&#xff1a;RaftLEC5、6&#xff1a;RaftLAB22AtaskHintlockingstructureguide设计与编码 2BtaskHint设计与编码 2CtaskHint question后记 LEC5&#xff1a;GO, Threads, and Raftgo threads技巧raft实验易错点debug技巧 前记 趁着研一考完期末有点点空余…

软考29-上午题-【数据结构】-排序

一、排序的基本概念 1-1、稳定性 稳定性指的是相同的数据所在的位置经过排序后是否发生变化。若是排序后&#xff0c;次序不变&#xff0c;则是稳定的。 1-2、归位 每一趟排序能确定一个元素的最终位置。 1-3、内部排序 排序记录全部存放在内存中进行排序的过程。 1-4、外部…

微信小程序 --- wx.request网络请求封装

网络请求封装 网络请求模块难度较大&#xff0c;如果学习起来感觉吃力&#xff0c;可以直接学习 [请求封装-使用 npm 包发送请求] 以后的模块 01. 为什么要封装 wx.request 小程序大多数 API 都是异步 API&#xff0c;如 wx.request()&#xff0c;wx.login() 等。这类 API 接口…

【精选】Java面向对象进阶——内部类

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …

【操作系统】磁盘文件管理系统

实验六 磁盘文件管理的模拟实现 实验目的 文件系统是操作系统中用来存储和管理信息的机构&#xff0c;具有按名存取的功能&#xff0c;不仅能方便用户对信息的使用&#xff0c;也有效提高了信息的安全性。本实验模拟文件系统的目录结构&#xff0c;并在此基础上实现文件的各种…

FISCO BCOS(十七)利用脚本进行区块链系统监控

要利用脚本进行区块链系统监控&#xff0c;你可以使用各种编程语言编写脚本&#xff0c;如Python、Shell等 利用脚本进行区块链系统监控可以提高系统的稳定性、可靠性&#xff0c;并帮助及时发现和解决潜在问题&#xff0c;从而确保区块链网络的正常运行。本文可以利用脚本来解…

Vue3 使用动态组件 component

component 标签&#xff1a;用于动态渲染标签或组件。 语法格式&#xff1a; <component is"标签或组件名">标签内容</component> 动态渲染标签&#xff1a; <template><h3>我是父组件</h3><component is"h1">动态…

SpringCloud(15)之SpringCloud Gateway

一、Spring Cloud Gateway介绍 Spring Cloud Gateway 是Spring Cloud团队的一个全新项目&#xff0c;基于Spring 5.0、SpringBoot2.0、 Project Reactor 等技术开发的网关。旨在为微服务架构提供一种简单有效统一的API路由管理方式。 Spring Cloud Gateway 作为SpringCloud生态…

【Unity】MySql +Navicat 安装教程

问题描述 在使用Unity开发的时候&#xff0c;有的时候我们是需要使用Mysql数据库的&#xff0c;本教程使用的MySql 和Navicat均为免安装版 ❶mysql安装 1.下载mysql解压至任意目录&#xff0c;此处以“C:\mysql-5.6.39-winx64”为例. mysql百度云连接&#xff1a; 链接&…

Java的递归【详解】

1.认识递归基础知识 什么是方法递归&#xff1f; 递归是一种算法&#xff0c;在程序设计语言中广泛应用。 从形式上说&#xff1a;方法调用自身的形式称为方法递归&#xff08; recursion&#xff09;。 递归的形式&#xff1a; 直接递归&#xff1a;方法自己调用自己。 间接递…

【监控】Spring Boot+Prometheus+Grafana实现可视化监控

目录 1.概述 2.spring actuator 3.Prometheus 3.1.介绍 3.2.使用 1.client端的配置 2.server端的配置 4.grafana 5.留个尾巴 1.概述 本文是博主JAVA监控技术系列的第四篇&#xff0c;前面已经聊过了JMX、Spring actuator等技术&#xff0c;本文我们就将依托于Spring …