Highcharts 与数据科学可视化|高斯核密度估计(KDE)

📅 发布时间:2026/7/16 12:35:53
Highcharts 与数据科学可视化|高斯核密度估计(KDE) 为了更清晰地探索那些不符合常规概率分布如正态分布、二项分布等的原始数据核密度估计Kernel Density Estimation简称 KDE是一种更加优雅且实用的统计方法。它通过“平滑”数据点帮助我们洞察数据的真实结构。本教程将带你一步步使用原生 JavaScript 进行 KDE 计算并利用功能强大的Highcharts图表库将结果转化为动态交互式图表。核密度估计Kernel Density Estimation简称 KDE是无参数统计方法用于拟合随机变量的分布轮廓。 日常数据分析中很多数据集不服从正态分布、二项分布等标准概率模型直方图分段展示又容易丢失细节、受区间宽度影响极大而 KDE 通过平滑拟合能直观还原数据真实分布形态常用于指标分布分析、样本特征探索、异常值识别等场景。核心原理高斯核 KDE本次示例调用 Highcharts 渲染分层图表散点原始样本、实线KDE 密度、虚线单条高斯核。选用高斯核正态核优势是曲线平滑、收敛稳定也是工业数据分析最通用的核函数。 逻辑拆解对每一个原始观测样本点单独生成一条高斯核曲线将所有样本对应的核曲线叠加求和再做均值归一化最终得到整体密度曲线可视化分层展示原始离散样本点、单条独立高斯核曲线、汇总后的 KDE 密度曲线三层数据直观对比交互可读性更强。高斯核基础公式K(xi​,x)2π​1​exp(−2(xi​−x)2​)x原始观测数据点xi​横轴连续采样区间用于绘制完整平滑曲线除高斯核外还支持均匀核、Epanechnikov 核等高斯核视觉平滑度最优适合业务看板展示。代码实现核心步骤要在前端渲染出这个图表我们的 JavaScript 代码主要分为以下四个步骤构建高斯核函数计算整体密度估计点KDE 曲线计算单个数据的核曲线点可选用于视觉拆解使用 Highcharts 渲染图表第一步创建高斯核函数首先我们用 JavaScript 代码来实现高斯核公式。/** * 高斯核密度函数 * param {number} xi - 当前采样的横坐标绘图范围内的点 * param {number} x - 实际的观测数据点 */ function GaussKDE(xi, x) { return (1 / Math.sqrt(2 * Math.PI)) * Math.exp(Math.pow(xi - x, 2) / -2); } 注意x代表我们拥有的观测数据集xi代表为了画出平滑曲线而设定的X轴连续范围。例如若观测数据分布在 93 到 102 之间我们可以将xi的范围设为 88 到 107以确保曲线两端能自然收拢回零。第二步生成密度估计点KDE 曲线接着我们遍历采样范围xiData计算每个采样点上所有观测数据核函数的总和。JavaScriptlet data []; // 存放最终的 KDE 曲线数据 [[xi, y], ...] let kernel []; // 缓存中间结果用于后续绘制单个核 // N 为观测数据集的长度 const N dataSource.length; for (let i 0; i xiData.length; i) { let temp 0; kernel.push([]); // 累加每个观测点在该采样点上的高斯值 for (let j 0; j N; j) { let kdeValue GaussKDE(xiData[i], dataSource[j]); temp kdeValue; kernel[i].push(kdeValue); // 暂存供第三步使用 } // 乘以 1/N 得到平均密度并推入结果集 data.push([xiData[i], (1 / N) * temp]); }第三步处理单个核数据点Kernels如果你希望像演示动画一样展示出每一个数据点是如何撑起独立核函数的橙色曲线可以通过下面的循环将步骤二中暂存的数据结构进行转置JavaScriptlet kernelChart []; for (let i 0; i dataSource.length; i) { kernelChart.push([]); for (let j 0; j xiData.length; j) { // 结合 X 轴坐标并计算单个核的缩放值 kernelChart[i].push([xiData[j], (1 / N) * kernel[j][i]]); } } 提示如果你的项目只需要显示最终的蓝色 KDE 曲线这一步可以完全跳过从而减少内存占用和计算量。第四步使用 Highcharts 绘制图表最后我们通过 Highcharts 将三种不同类型的数据融合在同一张图表里观测数据使用scatter散点图置于底部KDE 和 单个核使用spline平滑曲线图。JavaScriptHighcharts.chart(container, { chart: { type: spline, animation: true }, title: { text: 高斯核密度估计图 (Gaussian KDE) }, yAxis: { title: { text: 密度 (Density) } }, tooltip: { valueDecimals: 3 }, plotOptions: { series: { marker: { enabled: false }, dashStyle: shortdot, color: #ff8d1e, // 默认单个核的橙色 animation: { duration: 2000 } } }, series: [ { type: scatter, name: 原始观测数据, marker: { enabled: true, radius: 5, fillColor: #ff1e1f // 红色散点 }, data: dataPoint, // 你的原始数据点如 [[93, 0], [95, 0]...] zIndex: 9 // 保证散点在最上层显示 }, { name: KDE 整体估计, dashStyle: solid, lineWidth: 3, color: #1E90FF, // 蓝色主曲线 data: data, // 步骤二计算出的数据 zIndex: 10 }, // 动态展开单个核系列 { name: 核函数 (数据点: ${dataSource[0]}), data: kernelChart[0] }, // ... 可以使用 map 循环将 kernelChart 中的其余核加入 series ] }); 总结与延伸通过核密度估计KDE图表我们能够非常直观地看到数据在图表的开头和结尾处高度集中而在中间部分相对稀疏。相比于冷冰冰的表格或生硬的直方图KDE 提供了一种兼具美感与科学性的数据洞察方式。进一步思考在实际工程中除了核函数的选择带宽Bandwidth的设定也是影响平滑度的关键参数。带宽过小会导致曲线过于敏感过拟合带宽过大会导致曲线过于平滑欠拟合。有兴趣的朋友可以在高斯核公式中加入带宽参数h进行调整$\frac{1}{h}K(\frac{xi-x}{h})$。