2017-04-07 281 views
3

我不确定什么是最好的/最具统计性的完成我想要的东西的方法,但我基本上试图采用p值的分布并将其与通过排列我的原始数据而创建的更大的p值分布。我正在处理小的p值,所以我实际上比较了p值的log10。Python不同长度的两个分布的QQ和PP图

我一直在试图找出一个很好的通用方法来比较两个数组具有相似值但长度不相等的方法。我真正想要的是类似于scipy.qqplot(dataset1, dataset2)的东西,但不存在,Q-Q图只会将您的分布与已建立的分布进行比较(此问题已被要求为R:https://stats.stackexchange.com/questions/12392/how-to-compare-two-datasets-with-q-q-plot-using-ggplot2)。

本质上这等于比较两个直方图。我可以使用np.linspace强制完全相同的仓每个分发:

bins = 100 
mx = max(np.max(vector1), np.max(vector2)) 
mn = min(np.min(vector2), np.max(vector2)) 
boundaries = np.linspace(mn, mx, bins, endpoint=True) 
labels = [(boundaries[i]+boundaries[i+1])/2 for i in range(len(boundaries)-1)] 

我然后可以很容易地使用这些边界和标签,让两个直方图,由原始向量的长度加权。最简单的方法就是使用几个bin并将它们绘制在同一轴上的直方图上,就像这个问题一样:

但是,我真的想要更像是一个QQ图的东西,我想用很多的箱子,所以我可以看到即使是1对1线的小偏差。只绘制两个柱状图的问题是,他们是这样的:

histogram_example

两个地块都恰到好处彼此的顶部,我什么都看不到。

所以我想弄清楚的是如何比较这两个直方图同时保持bin标签。我可以很容易地画出两个对彼此的分布图,但最终由盒频率被索引:

definitely wrong

我真正想要的是什么,是只比较两个直方图,或使这是一个有关差异的QQ图,但我无法想出一个很好的统计方法。我找不到能让我用两个数据集而不是一个数据集和一个内置分布生成Q-Q图的方法,而且我找不到任何绘制两个不相等长度的分布的方法。

仅供参考,这里有两个柱状图是走进创建的情节,你可以看到,他们都非常相似:

histograms

我知道一定有这样做的一个很好的方式,因为看起来如此明显,但我对这种事情很陌生,而且对于scipy,pandas和statsmodels也是比较新的。

我故意没有在这里提供一个示例发布,因为我不确定如何创建一个非正态分布的最小集合并捕获我正在尝试执行的操作;加上要点是能够为任何两个重叠的不等长数组执行此操作。

我想知道的是什么是以统计学方式在python中处理这个问题的正确/最好的方法?是否有某种方法可以从排列后的数据中创建一个可用于statsmodels或scipy Q-Q图的分布?有没有办法像这样直观地比较两个直方图?有没有制作我不知道的概率图的方法?


编辑:尝试的累积和手动QQ图

感谢@ user333700的答案,我想通了,如何创建一个用于数据的手动QQ情节,也是一个累积概率曲线。我创建使用的数据有重叠的最小值/最大值以下发行的情节,但:

manufactured distributions

QQ情节:

q = np.linspace(0, 100, 101) 
fig, ax = plt.subplots() 
ax.scatter(np.percentile(ytest, q), np.percentile(xtest, q)) 

qqplot

因此,与简单的数据确实很好,累计情节是相似的:

# Pick bins 
x = ytest 
y = xtest 
boundaries = sorted(x)[::round(len(x)/bins)+1] 
labels = [(boundaries[i]+boundaries[i+1])/2 for i in range(len(boundaries)-1)] 

# Bin two series into equal bins 
xb = pd.cut(x, bins=boundaries, labels=labels) 
yb = pd.cut(y, bins=boundaries, labels=labels) 

# Get value counts for each bin and sort by bin 
xhist = xb.value_counts().sort_index(ascending=True)/len(xb) 
yhist = yb.value_counts().sort_index(ascending=True)/len(yb) 

# Make cumulative 
for ser in [xhist, yhist]: 
    ttl = 0 
    for idx, val in ser.iteritems(): 
     ttl += val 
     ser.loc[idx] = ttl 

# Plot it 
fig, ax = plt.subplots(figsize=(6,6)) 
ax.scatter(xhist, yhist) 
plt.show() 

cumulative plot

要回到我的实际偏斜数据(其中两个分布在不同的长度各方面极其相似),并加入1对1线,我得到这个对于那些二:

plots with real data

所以这两个工作很好,累积概率图很清楚地表明数据没有很大的差异,但QQ图表显示尾部有小的差异。

+0

为PP-积小的变化:直方图具有相等的长度箱(长度在原始值而言),所以PP-情节仍然不等间距。我们用于pp图的是等重量箱。例如,使用由每个第k个观测值x,bin都定义的箱边界与这些箱相连,然后绘图。在这种情况下,x累积直方图频率将在[0,1]中等间隔。 – user333700

+0

@ user333700:请你澄清一下吗?恐怕在这种情况下,我不会按照同等重量的垃圾箱来追踪你的意思。你能否提供一个伪代码来说明我将如何做到这一点? –

+1

在您的概率图你点的x坐标对应的累积概率每个箱。由于仓具有不同的频率或数量,x坐标的点被朝着端部,其中大部分的概率是,例如移动你只有中位数以下的两个垃圾箱。相反,如果你选择箱边界,这样的垃圾箱对x变量频率相等,则积点会是在x轴上等间隔。类似于'边界=排序(x)[:: k]'和调整端点。对于“相等的权重”,我的意思是在每个bin中x的频率相等。 – user333700

回答

2

在统计测试而言,SciPy的具有两个样品Kolmogorov-Smirnov检验用于连续变量。分箱直方图数据可以用于chisquare测试。 scipy.stats也有一个k样本Anderson-Darling测试。

为绘制:

的概率曲线图的两个直方图的等效将与对应于该箱边界每个轴的累积概率绘制累积频率对于两个样品,即。

statsmodels有QQ积了两个样品进行比较,然而,目前假设样本大小是相同的。如果样本量不同,那么分位数就需要计算相同的概率。 https://github.com/statsmodels/statsmodels/issues/2896 https://github.com/statsmodels/statsmodels/pull/3169 (我不记得是什么的这个状态。)

+0

谢谢@ user333700。你推荐的测试非常棒。我不确定如何做一个二元累积阴谋。我试着做一个非常简单的版本,最后我把大部分的点聚集在图表的右上角。我需要做一些特殊的魔术才能做出明智之举吗? –

+0

此外,我实际上很难理解为什么我们会使用分位数而不是设定的边界......如果两个分布不同,那么分位数就不那么有用了?如果分位数比较是要走的路线,是否有一个原因,我不能只是使用pandas.qcut创建两个相等长度的分位数组,然后将它们作为一个散点图彼此对比?或者,这不是Q-Q曲线实际上是什么? –

+1

我从来没有使用qcut,但它看起来像是返回类别而不是值。对每个轴上的q = np.linspace(0,100,101)绘制np.percentiles(x,q),np.percentiles(y,q)可能适用于qq图。一个实际的QQPlot会做同样的事情,但数据点而不是固定的网格。 – user333700

相关问题