2017-04-07 270 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

相關問題