做数据挖掘实战时我最怕的不是模型不收敛而是连数据的“脾气”都没摸清就直接丢进算法。描述统计就是摸清数据脾气的第一步而在这套【数据挖掘数学基础】系列里01描述统计的“中”篇重点不在均值、中位数这些中心趋势而在离中趋势与分布形态方差、标准差、四分位数、偏度、峰度以及它们如何过渡到数据预处理。这篇文章适合正在打数据挖掘数学基础、想搞清楚特征分布怎么影响建模结果的同学我会把公式讲透也会补上一些我实际项目中踩过的坑。1. 为什么本阶段不继续讲均值而要讲“离中趋势”1.1 从“均值相同”到“分布完全不同”一个绕不开的案例先看一个我做入门培训时经常抛出去的例子。假设两个产品团队都告诉你他们用户的平均单次在线时长是52分钟听起来都是不错的数字对吧但如果把原始数据摊开A团队是45、50、52、55、58分钟B团队是1、98、2、102、57分钟两个团队的平均值确实都是52分钟但业务含义完全不一样。A团队是典型的高粘性应用用户行为很稳定大部分人都集中在50分钟上下平均值能代表主流。B团队则像一锅沸水大量用户只进来几秒就流失少数用户又长时间停留平均值52分钟在这种场景下几乎没有代表性甚至会产生误导。如果你只拿平均值去做下一步分析结果很可能是错误结论。两个数据集中心位置一致但整个数据的“紧凑程度”截然不同这种差异在描述统计里就叫离中趋势也叫离散程度。数据挖掘里讲数据分布本质上讲的就是四件事中心在哪里、离散有多大、形状是否对称、尾巴有多重。上一部分我们解决了中心问题这一部分就要把后面三件事一口气补上。原因也很简单后续做特征工程、异常检测、标准化甚至选择模型时都需要先知道数据在均值附近的波动幅度以及分布长相。比如你想对用户时长做异常检测不知道该变量的标准差就根本没法判断一条记录到底偏得像不像离群点。1.2 离中趋势的三个层次极差、四分位距、方差与标准差描述离散程度的常用指标大致可以分成三套极差、四分位距、方差与标准差。它们不是彼此的替代品而是从不同角度回答“数据多散”这个问题。极差计算最简单最大值减最小值一眼能看出整体跨度但它完全由两个边界值决定只要出现一个极端值极差立刻失真。上面B团队的极差是101分钟而A团队只有13分钟极差能够在几秒内告诉你两个团队的数据覆盖范围差异同时也告诉你它极不稳定。四分位距取的是分位数的差用Q3-Q1来描述中间50%数据的分散程度。它的核心优势是稳健即使数据里混进几个极大或极小值只要这些值没有挤进首尾四分之一区域IQR就几乎不动。之前在数据集中出现过几次极端异常我都是先看IQR而不是先看标准差因为这个指标能更沉着地反映数据主体的波动情况。方差和标准差则是数据挖掘中使用频率最高的离散度量。它们的思路是把每个样本与平均值的偏差全部加起来再折算成一个平均水平。方差表示平方偏差的平均值标准差再开根号让单位回到原数据的量纲。在统计推断、假设检验、方差分析这一系列后续操作里方差几乎都是核心在工程层面标准差则因为单位直观更适合直接写进业务规则里。指标计算公式回答什么问题对异常值的敏感度极差max - min数据整体跨度多大非常敏感四分位距Q3 - Q1中间一半数据有多分散稳健方差Σ(xᵢ-μ)² / N平方平均偏差多大较敏感标准差√方差平均偏差大概多大较敏感所以实践中正确的用法是做粗筛用极差画分布图优先看箱线图和IQR做统计计算和标准化时用标准差。不要在任何场景下都抱着同一个指标不放先想清楚这个环节要回答什么问题。2. 方差与标准差数据挖掘中最常用的离散指标2.1 为什么是“平方”而不是取绝对值很多初学者都会问同一个问题要衡量每个点偏离均值多远直接算|xi-μ|然后取平均不是更直观吗为什么非要平方这个问题问得非常好我当初也纠结了一圈。绝对值算出来的指标叫平均绝对偏差它的确很直观每个点离均值多远平均下来就是多远。但它有两个硬伤。第一绝对值函数在零点处不可导做各种最优化推导时非常难受经典统计理论中的最小二乘、正态分布、最大似然估计都建立在平方结构之上。第二平方会对较大偏差施加更重的惩罚一个偏差从1变成4绝对值贡献从1变成4平方贡献则从1变成16。数据挖掘中极端值通常意味着风险或异常让它们对离散度有更大的话语权反而是我们想要的性质。当然平方的代价是单位被改变了。原始数据单位是秒方差单位就变成秒平方这个数值读起来很抽象。所以实际工程中我几乎总是用标准差它开一次根号单位回到秒可以直接跟均值放在一起讨论。补充一个高频考点样本方差的分母是n-1而不是n。公式写出来是总体方差σ²Σ(xᵢ-μ)²/N样本方差s²Σ(xᵢ-x̄)²/(n-1)。为什么除以n-1因为样本均值x̄本身就是从这批样本估计出来的它已经消耗了一个自由度。可以这样理解当你知道样本均值之后n个偏差值里其实只有n-1个能自由变化最后一个会被均值条件锁死。这个校正让样本方差在多个维度上都能更准确地估计总体方差避免系统性低估。做数据分析时绝大多数场景面对的都是样本而非普查式全量数据所以默认应该使用n-1分母。2.2 手算一遍彻底记住方差和标准差与其死背公式不如拿一组小数据亲手算一次。我现在取5个用户的登录次数4、8、6、5、12。第一步计算均值(486512) / 5 7。 第二步算每个值偏离均值的偏差-3、1、-1、-2、5。 第三步平方后求和9 1 1 4 25 40。 第四步如果把这5条数据看成整个总体方差是40/5 8标准差约2.83如果看成从总体里抽出的一个样本方差是40/4 10标准差约3.16。同一个数据因为分母选择不同结果会有明显区别。当样本量很小时这个区别不能忽略当样本量上千上万时n-1和n的差异几乎可以忽略这也是为什么很多工具在数据量大时不会让你察觉到这种差异。但严谨的项目仍应明确标注用的是总体标准差还是样本标准差否则后续推导置信区间、设置异常阈值时边界就容易偏。如果你用Python里的pandas做同样计算直接调用s.std()得到的是样本标准差默认ddof1如果调用s.std(ddof0)才是总体标准差。这一点最好形成肌肉记忆。2.3 标准差在业务和数据挖掘里的实际意义标准差不只是公式里的一个符号它在业务分析里有一个非常实用的解释标准差衡量的是数据围绕均值的典型波动幅度。在一个近似正态分布的变量上可以借用3σ经验规则做快速判断大约68%的数据落在均值±1个标准差内约95%落在±2个标准差内约99.7%落在±3个标准差内。于是很多异常检测系统会把“超过均值3倍标准差”当作一个筛选条件。这个规则本身没有错但它隐含的前提是分布接近对称、没有重尾。数据挖掘里碰到的时长、金额、点击量这类变量往往是强右偏的直接套3σ会把大量正常用户标记成异常。我见过不少团队在日志告警上栽过这个跟头所以用标准差设阈值前一定要先看分布形状。标准差还能直接变成特征。比如用户每笔订单金额的标准差就能作为一个“消费波动”特征输入模型它比单纯用平均值更能刻画用户行为。一个均值相同但标准差很大的用户可能今天买几千块明天只买几块钱这种不稳定性和风险偏好是有预测价值的。特征工程本质上就是在描述统计里找出那些能切开业务差异的指标。如果需要比较两个不同均值水平的变量谁更“波动”建议再向前一步计算离散系数CV标准差/均值。比如某商品价格均值为100元标准差20元CV0.2另一个用户活跃天数均值5天标准差2天CV0.4。后者相对波动更大。直接比较标准差20和2是没有意义的因为量纲和均值水平都不同这也是新手最容易忽略的细节。2.4 一批代码快速输出关键描述统计指标在实际项目中我很少手算一部是交给代码。下面这段代码可以快速把本节提到的指标都打出来适合放在探索性数据分析的起始位置。import numpy as np import pandas as pd data np.array([5, 7, 8, 12, 15, 16, 19, 22, 30, 300]) s pd.Series(data) print(均值, s.mean()) print(标准差样本, round(s.std(ddof1), 3)) print(方差样本, round(s.var(ddof1), 3)) print(分位数, s.quantile([0.25, 0.5, 0.75]).round(3).tolist()) print(偏度, round(s.skew(), 3)) print(峰度, round(s.kurt(), 3))跑完这五行均值、标准差、分位数、偏度、峰度一次性拿到。你会看到300这个极端值把均值抬得很高但分位数几乎不受影响。这就是为什么我强调在发现异常值之前不要让单一指标替你下结论。3. 四分位数与箱线图抗异常值的主力工具3.1 用一组实际数据把四分位数算清楚四分位数是描述统计里被误解最多、也最容易被工具实现差异坑到的知识点。先把概念讲清楚Q1是第一四分位数也叫下四分位数代表从小到大排列后处于25%位置的值Q2就是中位数50%位置Q3是第三四分位数75%位置。举个例子某用户行为日志里提取9个每日登录次数排序后是5、7、8、12、15、16、19、22、30。Q2显然是中位数15。计算Q1和Q3时核心问题是数据总个数是奇数前后两半怎么切。常见的做法是这样以中位数15为界把序列分成前一半5、7、8、12和后一半16、19、22、30。前一半的中间位置在7和8之间取平均是7.5后一半的中间位置在19和22之间取平均是20.5。于是Q17.5Q320.5IQR13。但如果你换用numpy的线性插值法得到的Q1和我上面写的7.5可能略有差别。这里要特别提醒不同工具对四分位数的算法并不完全一致numpy、pandas、Excel、SPSS都可能有各自的插值规则。拿到同一份数据不同工具算出不同IQR是正常现象。关键是别因此怀疑自己的数据出问题。数据量越小、数据越离散时算法差异对结果的影响越明显所以我在做项目时会在流程里固定用同一套计算方式避免中途更换工具导致异常值筛选结果跳动。3.2 箱线图到底在告诉我们什么基于四分位数可以画出数据挖掘中最实用的一张图箱线图。它由三要素构成盒子的左右边界分别是Q1和Q3盒中竖线是Q2盒外侧的两条须线延伸到“正常范围”的边界。判断异常值最常用的标准是1.5倍IQR下边界是Q1-1.5×IQR上边界是Q31.5×IQR凡是在边界之外的点都标记为离群点。拿刚才的序列加上一个极端值再看5、7、8、12、15、16、19、22、30、300。此时Q1(812)/210Q3(1922)/220.5IQR10.5。上边界20.51.5×10.5≈36.25300这个值远在上边界之外箱线图会直接把它单拎出来展示。这种视觉表达非常高效一张图就能看出数据主体分布在哪、异常点在哪、是否对称。为什么选1.5倍IQR而不是别的数这是经验法则在接近正态分布的数据中这个边界大约对应±2.7个标准差的位置能够覆盖绝大部分正常值。它不是必须墨守的硬规则遇到业务特性完全不同的问题时可以按需调整阈值。更重要的是箱线图只能提示“这个值离主体很远”具体要不要剔除还要结合业务来源判断。一个300次登录的用户可能是机器人也可能是重度用户属性完全不同应该先回到原始日志里去核验。3.3 分位数在数据挖掘里的三个实战用法除了画图分位数在数据挖掘流程里有三个角色特别有价值。第一用分位数做离散化。连续特征可以直接按四分位数或更多分位点切成等级。比如把用户活跃天数按0.25、0.5、0.75三个分位点切成低、中、较高、高四档生成有序类别特征这种做法在风控画像里非常常见。它比直接丢原始连续值更稳定也能避免极端值干扰。第二用分位数做鲁棒缩放。常规Z-score标准化容易受异常值影响而鲁棒缩放器用“减去中位数再除以IQR”的方式来缩放特征。它的好处是既消除量纲差异又不至于因为几个极端值把整个特征范围压扁。如果数据里明显有异常点这个方法往往比普通标准化更稳妥。第三用高百分位做异常检测。业务上经常用99分位、95分位当作告警线。比如交易金额超过P99就触发风控复核。实际操作中分位数比“均值加标准差”更直观因为它的含义是“比99%的历史记录都高”而均值加标准差在偏态分布里很难向业务解释清。4. 分布形状偏度与峰度建模前的最后两道诊断4.1 偏度分布不对称怎么办偏度是刻画分布对称性的指标。它的公式常写作Skew (1/n Σ(xᵢ-μ)³) / σ³分子对偏差取三次方分母用标准差立方做无量纲化。计算结果的符号很有讲究。Skew大于0说明分布右偏/正偏右侧有一条较长尾巴均值通常大于中位数Skew小于0说明左偏/负偏左侧尾巴更长均值通常小于中位数Skew接近0分布近似对称。现实数据里用户访问时长、订单金额、搜索频次这类非负变量基本都是右偏少数大额用户把长尾巴拖到右端。左偏相对少见常见于考试分数这类有明确上限的指标。判断偏度严重程度时我一般用这样的经验参考绝对值小于0.5可视为近似对称0.5到1属于中等偏斜超过1属于强偏斜。样本量较小时偏度估计本身的波动也不小不要只凭一个0.7的数值就急着做转换可以结合直方图一起看。偏度为什么和数据挖掘强相关因为很多模型和预处理方法都隐含了对称分布的假设。距离类算法对特征尺度敏感如果某个特征严重右偏个别极端值会把整个样本的距离关系带偏均值填充缺失值在强偏态下也容易给数据加入偏移。看到偏度很高就要提前安排对数变换、开方变换或更专业的Box-Cox变换。4.2 峰度判断重尾和极端值风险峰度衡量的是分布的“尾部厚度”和“中心尖峭程度”。常见公式是Kurt (1/n Σ(xᵢ-μ)⁴) / σ⁴ - 3标准正态分布的峰度恰好为3扣除3以后超额峰度为0。因此正峰度说明数据比正态分布有更胖的尾巴极端值出现的概率更高负峰度说明尾部偏薄分布更平展。关于峰度有一个常见误解很多人以为正峰度只表示分布峰值更高更尖其实它更关键的含义是重尾。比如用户群里如果混入极少量超高消费用户峰度往往明显为正。在金融和风控场景高峰度本身就是风险提示它说明极端事件发生的概率高于正态分布给出的估计。数据挖掘里峰度高意味着方差、标准差、均值这些指标对极端值极度敏感任何基于均值和方差的规则都可能被少数样本牵着走。我在实际项目里通常把偏度和峰度看成一对搭档偏度告诉我们尾巴在左还是右峰度告诉我们尾巴有多厚重。两者一起看比只看直方图更能快速定位分布形态问题。当某个特征的偏度和峰度都显著偏离正常范围时建模前就应该重点处理它。4.3 偏度和峰度如何影响算法选型与特征变换拿到一批连续特征我会先列一个描述统计表把均值、标准差、偏度、峰度摊开。接下来根据形态决定下一步动作。线性回归、逻辑回归、线性SVM这类模型对特征分布比较敏感尤其当特征尺度差异大或强偏斜时训练过程容易被极端样本主导。遇到这种情况我会先对强右偏特征做log1p变换把长尾压缩如果数据仍不对称再考虑Box-Cox变换。对左偏特征可以考虑平方、立方等幂变换。树模型不依赖特征距离计算对偏度相对不敏感但偏态分布也会让基于方差的特征重要性计算产生偏差所以该处理的还是应该处理。聚类、K近邻、PCA这类基于距离的算法更依赖特征的尺度和分布形态。它们的共同点是默认所有特征都在同一尺度下参与计算一旦某个偏态特征携带极端值欧氏距离就会被它主导。处理顺序先解决偏态再做标准化最后才能进入模型。偏度和峰度数值本身可以直接作为特征被模型使用尤其是在异常检测问题中很有价值。比如在时间窗口内计算用户交易金额分布的偏度偏度突然变大往往意味着一笔不正常的超大交易挤了进来。描述统计的指标不只是预处理的工具它们本身就是数据挖掘的特征来源。5. 从描述统计到数据预处理标准化的那座桥5.1 Z-score标准化与Min-Max归一化到底怎么选标准化这一步几乎是所有数据挖掘流程的标配而它的数学依据恰恰来自描述统计。最常用的两种方法对离散度量的依赖完全不同。Z-score标准化公式z (x-μ)/σ。它把原始数据转换成均值为0、标准差为1的分布。它适合分布近似对称的场景因为它本质上是把“距离均值多少个标准差”变成数值标准差越大越远处的值被压缩得越厉害。Z-score不改变原始数据的分布形态只改变尺度。如果原始数据强偏标准化后仍然偏。Min-Max归一化公式x (x-min)/(max-min)。它把数据压到0到1区间但最大和最小值对结果影响很大一旦样本外出现新极端值区间就会重新变动。所以它更适合取值范围相对稳定、或者业务上已经有明确边界的变量。在梯度下降类模型中把特征全部归一化到相同区间可以加速收敛但这也意味着对异常值敏感使用前要先确保异常值已经处理过。我的默认选择是没有特殊理由就用Z-score。它既保留了数据的相对结构又让描述统计的均值和标准差直接参与运算后续解释起来也方便。如果异常值比较多就走鲁棒路线用中位数替代均值用IQR替代标准差。如果后续要喂给神经网络或距离模型才会考虑Min-Max。5.2 一个完整小案例从描述统计直接推导预处理方案为了让这一整套逻辑落地我讲一个模拟项目里的实际流程。某业务要给用户做活跃度聚类原始特征之一是用户最近30天的总访问时长。第一次取数后我按照标准流程先跑描述统计。结果是这样均值187分钟中位数只有25分钟Q3是60分钟最大值6420分钟标准差接近120分钟偏度算出6.7。看到这组数字几乎不用画图问题就已经暴露了均值比中位数高出一个数量级严重右偏标准差比Q3还大说明极端值对离散度的影响极其严重直接拿去聚类结果大概率是一两个离群点把整个簇拽走。接下来处理。第一步先对访问时长做log1p变换。为什么要log1p而不是log因为数据里可能包含0分钟的用户log(0)没有定义加1后再取对数可以保住零值样本。变换后再看偏度从6.7降到0.5左右IQR和标准差的数量级差距也变小分布接近对称。第二步再用Z-score标准化把变换后的特征和另一个量纲不同的特征统一到同一尺度。这个案例看起来平淡却是数据挖掘里最常见的真实操作。很多人调了半天聚类参数没效果最后定位原因就是没有先跑描述统计。描述统计说的不只是一堆数字它直接告诉你这一列数据该不该变换、该用什么方式变换、变换做完应该长成什么样这些判断比盲目调参重要得多。5.3 用一段代码落实标准化与形态检查如果你想把上面的流程做成一个可复用模板下面这段代码可以当作起点。它分三步走第一步检查特征形态第二步做分布变换第三步标准化。import pandas as pd import numpy as np from sklearn.preprocessing import StandardScaler df pd.DataFrame({ active_duration: [3, 5, 12, 80, 150, 30, 0, 400, 200, 90], login_days: [1, 2, 4, 6, 7, 3, 1, 8, 6, 5] }) # 第一步形态检查 desc df.agg([mean, std, skew, kurt]).T print(desc) # 第二步对右偏特征做对数变换 df[active_duration_log] np.log1p(df[active_duration]) # 第三步标准化 scaler StandardScaler() scaled scaler.fit_transform(df[[active_duration_log, login_days]]) print(scaled.mean(axis0).round(6)) print(scaled.std(axis0).round(6))最后两行输出的均值应该接近0标准差接近1这就是标准化的验收标准。如果这两条线不过后续一切距离计算和模型训练都要重新审视。6. 常见问题与实操心得这些坑我替你先踩过6.1 样本方差和总体方差混着用这是最普遍的问题。很多人算一个特征的标准差写完代码不检查工具默认值就交给下游。pandas里Series.std默认是样本标准差ddof1numpy里np.std默认却是总体标准差ddof0Excel里STDEV.S和STDEV.P也分两套。同一个特征不同函数算出不同标准差是非常正常的事。记住一条原则只要你不是在计算“全量数据本身”的统计量而是在用样本推断总体就统一用样本版本并在文档里标明。6.2 只盯均值和方差差点漏掉异常值我在初期做特征分析时也习惯列均值、标准差然后就开始下一步结果某次建模效果特别差回查才发现数据里有大量异常值均值被拉高标准差被拉大后续的标准化、归一化全部受到牵连。后来我把探索性数据分析的固定动作改成三步先看箱线图找离群点再算偏度和峰度判断形态最后才看均值和标准差。顺序变一下问题暴露的速度完全不一样。6.3 分位数算法差异引发的“对不上账”同一个数据集用自己写的函数算是Q320.5用另一个平台算却是19.8看起来像出了bug。其实四分位数算法有好几种位置方法、线性插值方法、样本无偏估计方法都会造成差异。我的习惯是项目一开始就确定好标准实现比如固定用pandas的quantile默认方法并且不随意切换。涉及给业务方的报告时也把算法说明写清楚免得后续对接时扯皮。6.4 用标准差去比较量纲完全不同的特征比较年龄的标准差12和消费金额的标准差120直接读数没有任何意义因为量纲和均值水平完全不同。数据挖掘里需要比较多个特征时先标准化或者使用离散系数CV标准差/均值。CV是无量纲的相对指标适合衡量不同业务指标的相对稳定性。6.5 不要盲目相信“变换能解决一切分布问题”看到偏度大就做log看到峰度高就做分位数变换这确实容易上手但不能解决所有问题。如果数据分布是多峰的比如用户群体本来就分注册用户和核心用户两层单纯做对数变换无法抹平业务分层更好的办法是先把分层变量拆出来。如果数据包含大量零值log1p只能缓解不能根治这种情况可能需要考虑零膨胀模型或单独构造二值特征。描述统计负责诊断要不要做变换、怎么做变换还得结合业务逻辑。最后说一点个人感受。我这些年做项目最大的收获反倒不是用了什么复杂的算法而是养成了一个看数据先做描述统计的习惯。每次建模前把所有连续特征集中过一遍看一眼分布形态、离散程度和异常点数量就能提前躲掉大半数据问题。这套“01描述统计中”的内容说到底是把数据挖掘工程师的体检报告做扎实。按照这个流程走后续的特征工程和模型调参会轻松非常多。
阅读完成 · 觉得有帮助?