我对matplotlib中的箱线图有一些疑问:
问题A。我在下面用Q1、Q2和Q3突出显示的标记代表什么?我相信Q1是最大值,Q3是异常值,但是Q2是什么?
问题 B matplotlib 如何识别异常值?(即它怎么知道它们不是真值max
和min
值?)
我对matplotlib中的箱线图有一些疑问:
问题A。我在下面用Q1、Q2和Q3突出显示的标记代表什么?我相信Q1是最大值,Q3是异常值,但是Q2是什么?
问题 B matplotlib 如何识别异常值?(即它怎么知道它们不是真值max
和min
值?)
一张图片胜过千言万语。请注意,异常值(+
图中的标记)只是下面宽边距之外的点。[(Q1-1.5 IQR), (Q3+1.5 IQR)]
但是,该图片只是正态分布数据集的示例。重要的是要了解 matplotlib 不会首先估计正态分布,而是根据估计的分布参数计算四分位数,如上所示。
相反,中位数和四分位数是直接从数据中计算出来的。因此,您的箱线图可能看起来会有所不同,具体取决于数据的分布和样本的大小,例如不对称和或多或少的异常值。
方框代表第一个和第三个四分位数,红线代表中位数(第二个四分位数)。文档给出了 1.5 IQR的默认晶须:
boxplot(x, notch=False, sym='+', vert=True, whis=1.5,
positions=None, widths=None, patch_artist=False,
bootstrap=None, usermedians=None, conf_intervals=None)
和
whis : [ 默认 1.5 ]
将晶须的长度定义为内四分位范围的函数。它们扩展到 (whis*(75%-25%)) 数据范围内的最极端数据点。
如果您对不同的箱线图表示感到困惑,请尝试阅读wikipedia 中的描述。
这是一个图表,说明了来自stats.stackexchange answer的盒子的组件。请注意,如果您未whis
在 Pandas 中提供关键字,则 k=1.5。
Pandas 中的 boxplot 函数是matplotlib.pyplot.boxplot
. matplotlib 文档详细解释了这些框的组件:
问题一:
该框从数据的下四分位数延伸到上四分位数,中间有一条线。
即四分之一的输入数据值位于框下方,四分之一的数据位于框的每个部分,其余四分之一位于框上方。
问题乙:
whis:浮点数、序列或字符串(默认 = 1.5)
作为浮点数,确定胡须的范围超出第一和第三四分位数。换句话说,如果 IQR 是四分位距 (Q3-Q1),则上须线将延伸到小于 Q3 + whis*IQR 的最后一个数据。类似地,下须线将延伸到大于 Q1 - whis*IQR 的第一个数据。除了胡须,数据被认为是异常值,并被绘制为单独的点。
Matplotlib(和 Pandas)还为您提供了很多选项来更改胡须的默认定义:
将此设置为不合理的高值以强制胡须显示最小值和最大值。或者,将其设置为百分位数的升序(例如,[5, 95])以将须线设置在数据的特定百分位数。最后,whis 可以是字符串“范围”,以强制胡须达到数据的最小值和最大值。
下图显示了箱线图的不同部分。
分位数 1/Q1:第 25 个百分位数
四分位距 (IQR):第 25 个百分位到第 75 个百分位。
中位数(分位数 2/Q2):第 50 个百分位数。
分位数 3/Q3:第 75 个百分位数。
我应该注意到蓝色部分是箱线图的胡须。
下图比较了正态分布的箱线图与概率密度函数。它应该有助于解释“最小值”、“最大值”和异常值。
“最低”:(Q1-1.5 IQR)
“最大值”:(Q3+1.5 IQR)
正如 zelusp 所说,对于正态分布,99.3% 的数据包含在 2.698σ(标准差)内。下图中的绿色圆圈(异常值)是剩余 0.7% 的数据。以下是这些数字是如何产生的推导。
除了 seth 答案(因为文档对此不是很精确): Q1(胡须)置于最大值低于 75% + 1.5 IQR
(最小值为 25% - 1.5 IQR)
这是计算胡须位置的代码:
# get high extreme
iq = q3 - q1
hi_val = q3 + whis * iq
wisk_hi = np.compress(d <= hi_val, d)
if len(wisk_hi) == 0 or np.max(wisk_hi) < q3:
wisk_hi = q3
else:
wisk_hi = max(wisk_hi)
# get low extreme
lo_val = q1 - whis * iq
wisk_lo = np.compress(d >= lo_val, d)
if len(wisk_lo) == 0 or np.min(wisk_lo) > q1:
wisk_lo = q1
else:
wisk_lo = min(wisk_lo)