核密度估计(KDE)原理及实现 |
您所在的位置:网站首页 › 频率组距总数 › 核密度估计(KDE)原理及实现 |
https://blog.csdn.net/qq_40996400/article/details/103772706 此处仅为备档收藏,建议查看原文,链接见上 参数估计指样本数据来自一个具有明确概率密度函数的总体,而在非参数估计中,样本数据的概率分布未知,这时,为了对样本数据进行建模,需要估计样本数据的概率密度函数,核密度估计即是其中一种方式。 引言统计学中,核密度估计,即Kernel Density Estimation,用以基于有限的样本推断总体数据的分布,因此,核密度估计的结果即为样本的概率密度函数估计,根据该估计的概率密度函数,我们就可以得到数据分布的一些性质,如数据的聚集区域。 从直方图开始直方图由 Karl Pearson 提出,用以表示样本数据的分布,帮助分析样本数据的众数、中位数等性质,横轴表示变量的取值区间,纵轴表示在该区间内数据出现的频次与区间的长度的比例。 美国人口普查局(The U.S. Census Bureau)调查了 12.4 亿人的上班通勤时间,数据如下: 起点 组距 频次 频次/组距 频次/组距/总数0 5 4180 836 0.00675 5 13687 2737 0.022110 5 18618 3723 0.0315 5 19634 3926 0.031620 5 17981 3596 0.02925 5 7190 1438 0.011630 5 16369 3273 0.026435 5 3212 642 0.005240 5 4122 824 0.006645 15 9200 613 0.004960 30 6461 215 0.001790 60 3435 57 0.0005使用直方图进行数据可视化如下:
该直方图使用单位间隔的人数(频次/组距)表示为每个矩形的高度,因此每个矩形的面积表示该区间内的人数,矩形的总面积即为 12.4 亿。 而当直方图使用(频次/组距/总数)表示为每个矩形的高度时,数据可视化如下:
此时,矩形的面积表示该区间所占的频率,矩形的总面积为 1,该直方图也即频率直方图。 频率直方图有以下特点: 矩形面积为该区间的频率;矩形的高度为该区间的平均频率密度。概率密度函数极限思维:我们使用微分思想,将频率直方图的组距一步步减小,随着组距的减小,矩形宽度越来越小,因此,在极限情况下频率直方图就会变成一条曲线,而这条曲线即为概率密度曲线。 对于概率密度曲线,我们知道:随机变量的取值落在某区域内的概率值为概率密度函数在这个区域的积分(见概率密度函数),即:P ( a < x ≤ b ) = ∫ a b f ( x ) d x P(a< x \leq b) = \int\limits_a^b f(x)dxP(a { SDx += Math.pow(pt.lon - avePt.lon, 2); SDy += Math.pow(pt.lat - avePt.lat, 2); }); return Math.sqrt(SDx / pts.length + SDy / pts.length);}123456789101112131415Dm(到平均中心距离的中值): /** * Dm * @param {Point[]}} pts 所有POI点 * @param {Point} avePt 平均中心 * @returns */function Dm(pts, avePt) { let distance = []; pts.forEach((pt) => { distance.push(Dist(pt, avePt)); }); distance.sort(); return distance[distance.length / 2];}1234567891011121314核密度估计: /** * 核密度估计 * @param {Point[]} pts 所有POI点 * @param {Rect} rect POI点边界 * @param {Number} width 栅格图像宽度 * @param {Number} height 栅格图像高度 */function kde(pts, rect, width, height) { const estimate = new Array(height) .fill(0) .map(() => new Array(width).fill(0)); let min = Infinity, max = -Infinity; const avePt = ave(pts); const bandWidth = h(pts, avePt); rect.top += bandWidth; rect.bottom -= bandWidth; rect.left -= bandWidth; rect.right += bandWidth; const itemW = (rect.right - rect.left) / width; const itemH = (rect.top - rect.bottom) / height; for (let x = 0; x < width; x++) { const itemX = rect.left + itemW * x; for (let y = 0; y < height; y++) { const itemY = rect.bottom + itemH * y; let fEstimate = 0; for (let m = 0; m < pts.length; m++) { const distance = Dist(pts[m], new Point(itemX, itemY)); if (distance < Math.pow(bandWidth, 2)) { fEstimate += kernel(distance / bandWidth); } } fEstimate = fEstimate / (pts.length * Math.pow(bandWidth, 2)); min = Math.min(min, fEstimate); max = Math.max(max, fEstimate); estimate[height - y - 1][x] = fEstimate; } } return { estimate, min, max };}12345678910111213141516171819202122232425262728293031323334353637383940然后使用 html5 canvas 进行可视化: /** * 绘制核密度估计结果栅格图 * @param {CanvasRenderingContext2D} ctx canvas上下文 * @param {*} param0 核密度估测值,最大值,最小值 */function draw(ctx, { estimate, min, max }) { const height = estimate.length, width = estimate[0].length; for (let x = 0; x < width; x++) { for (let y = 0; y < height; y++) { const val = (estimate[y][x] - min) / (max - min); if (val > 0 && val < 0.4) { ctx.fillStyle = "rgb(228, 249, 245)"; ctx.fillRect(x, y, 1, 1); } else if (val >= 0.4 && val < 0.7) { ctx.fillStyle = "rgb(48, 227, 202)"; ctx.fillRect(x, y, 1, 1); } else if (val >= 0.7 && val < 0.9) { ctx.fillStyle = "rgb(17, 153, 158)"; ctx.fillRect(x, y, 1, 1); } else if (val >= 0.9 && val |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |