我不确定完成我想要的最好/最统计合理的方法是什么,但我基本上是在尝试获取 p 值的分布,并将其与通过排列我的原始数据创建的更大的 p 值分布进行比较.我正在处理小的 p 值,所以我实际上是在比较 p 值的 log10。
我一直在试图找出一种很好的通用方法来比较具有相似值但长度不等的两个数组。我真正想要的是 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 为每个分布强制使用完全相同的 bin:
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 并将它们绘制为同一轴上的直方图,就像在这个问题中一样:
但是,我真的想要更像 Q-Q 图的东西,并且我想使用很多 bin,这样我甚至可以看到与 1 比 1 线的微小偏差。仅绘制两个直方图的问题在于它们看起来像这样:
两个地块正好在彼此的顶部,我什么也看不到。
所以我想弄清楚的是,如何在保持 bin 标签的同时比较这两个直方图。我可以轻松地将两者相互绘制为散点图,但最终由 bin 频率索引:
我真正想要的是比较两个直方图,或者制作差异的 Q-Q 图,但我无法想出一个很好的统计方法来做到这一点。我找不到任何方法可以让我用两个数据集而不是一个数据集和一个内置分布来制作 Q-Q 图,而且我找不到任何方法来绘制彼此不等长的两个分布。
作为引用,以下是创建该图的两个直方图,您可以看到它们非常相似:
我知道必须有一个很好的方法来做到这一点,因为它看起来很明显,但我对这种事情很陌生,对 scipy、pandas 和 statsmodels 也相对较新。
我故意没有在这里提供示例分布,因为我不确定如何制作非正态分布的最小数组集并捕获我想要做的事情;另外一点是能够对任何两个重叠的不等长数组执行此操作。
我想知道的是,以统计上合理的方式在 python 中解决这个问题的正确/最佳方法是什么?是否有某种方法可以从可用于 statsmodels 或 scipy Q-Q 图的置换数据中创建分布?有没有办法像这样直观地比较两个直方图?有没有办法制作我不知道的概率图?
编辑:尝试累积和手动 Q-Q 图
感谢@user333700 的回答,我想出了如何为数据创建手动 QQ 图,以及累积概率图。我使用具有重叠最小值/最大值但以下分布的数据创建了图:
QQ剧情:
q = np.linspace(0, 100, 101)
fig, ax = plt.subplots()
ax.scatter(np.percentile(ytest, q), np.percentile(xtest, q))
所以对于简单的数据来说效果很好,累积图是相似的:
# 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()
回到我的实际偏斜数据(这两个分布在各个方面都非常相似,除了长度)并添加了 1 比 1 的线,我得到了这两个:
所以两者都有效,这很好,累积概率图很清楚地显示数据没有大的差异,但Q-Q图显示尾部有很小的差异。
最佳答案
在统计检验方面,scipy 对连续变量有两个样本 Kolmogorov-Smirnov 检验。分箱直方图数据可用于卡方检验。 scipy.stats 也有一个 k 样本 Anderson-Darling 检验。
用于绘图:
两个直方图的概率图等效于绘制两个样本的累积频率,即每个轴上的累积概率对应于 bin 边界。
statsmodels 有一个用于两个样本比较的 qq-plot,但是它目前假设样本大小相同。如果样本大小不同,则需要为相同的概率计算分位数。
https://github.com/statsmodels/statsmodels/issues/2896
https://github.com/statsmodels/statsmodels/pull/3169
(我不记得这是什么状态。)
关于两个不等长分布的 Python Q-Q 和 P-P 图,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43285752/