簡體   English   中英

具有非唯一 bin 邊緣的 qcut 會產生錯誤的分位數

[英]qcut with non-unique bin edges produces wrong number of quantiles

我有這個簡單的方法來獲得我的十分位數:

def output_deciles(model, X, y, order='predictions'):
    results = pd.DataFrame(model.predict(X), index=X.index, columns=['predictions'])
    results['actual'] = y
    results['deciles'] = pd.qcut(results[order], 10, labels=False, duplicates='drop')
    return results

如果我根據我的預測在十分位數上使用它,一切正常:

out = output_deciles(pipeline, X, y)
out.groupby('deciles')[['actual', 'predictions']].mean()

來自預測的分組

這是在大約 9400 條記錄上。

但如果我試圖得到我的實際值的十分位數,我只會得到 7 而不是 10 十分位數。 這是因為我在這個目標中大約一半的值是 0:

out = output_deciles(pipeline, X, y, order='actual')
out.groupby('deciles')[['actual', 'predictions']].mean()

groupby 來自實際

盡管有大量的獨特價值:

print(len(out['actual'].unique()))

4593

這是違反直覺的——它幾乎就像是丟棄了整個垃圾箱,而不僅僅是一些重復的值。 但是,如果我將重復設置更改為“raise”,它會拋出:

ValueError: Bin 邊緣必須是唯一的:array([-4.60517019, 0. , 0. , 0. , 0. , 3.47630251, 8.40045698, 10.11776099, 11.46706716, 12.86027487, 17.7007044 ])。

當我的意思是十分位數時,我如何得到十分位數,給定非唯一的 bin 邊緣?

您可能正在尋找的是一種自己構建“分位數”的方法。 您可以通過排序然后使用 integer 划分來定義組來執行此操作。

我將在 0 處創建質量過大的數據,這樣pd.qcut就會抱怨重復。

import pandas as pd
import numpy as np

np.random.seed(410012)
s = pd.Series(np.random.normal(0, 4, 1000))
s = pd.concat([s, pd.Series([0]*500)])
s = s.to_frame('vals')

N = 10
s = s.sort_values('vals')
s['q'] = np.arange(len(s)) // (len(s)/N)

有了 q,我們現在得到 10 個 bin。

s.groupby('q').describe()
#      vals                                                          
#     count    mean     std      min     25%     50%     75%      max
#q                                                                   
#0.0  150.0 -6.5934  1.9208 -12.6041 -7.7703 -6.1546 -5.1073  -4.3421
#1.0  150.0 -3.1922  0.5621  -4.3287 -3.6605 -3.1293 -2.7377  -2.2718
#2.0  150.0 -1.4932  0.4203  -2.2561 -1.8196 -1.5262 -1.1364  -0.7451
#3.0  150.0 -0.1831  0.2400  -0.7425 -0.3371 -0.0110  0.0000   0.0000
#4.0  150.0  0.0000  0.0000   0.0000  0.0000  0.0000  0.0000   0.0000
#5.0  150.0  0.0000  0.0000   0.0000  0.0000  0.0000  0.0000   0.0000
#6.0  150.0  0.0238  0.0678   0.0000  0.0000  0.0000  0.0000   0.2856
#7.0  150.0  1.1555  0.4833   0.3353  0.7615  1.1837  1.5819   1.9513
#8.0  150.0  2.9430  0.6016   1.9660  2.4385  2.9665  3.4764   4.0277
#9.0  150.0  6.1692  1.6616   4.0336  4.8805  5.8176  6.9019  12.3437

不與問題值重疊的 bin 是相同的,但 0 是邊緣的兩個 bin 不同(因為它們已被折疊)

s.groupby(pd.qcut(s['vals'], 10, duplicates='drop'))['vals'].describe()
#                              count    mean     std      min     25%     50%     75%      max
#vals                                                                                         
#(-12.604999999999999, -4.33]  150.0 -6.5934  1.9208 -12.6041 -7.7703 -6.1546 -5.1073  -4.3421
#(-4.33, -2.259]               150.0 -3.1922  0.5621  -4.3287 -3.6605 -3.1293 -2.7377  -2.2718
#(-2.259, -0.743]              150.0 -1.4932  0.4203  -2.2561 -1.8196 -1.5262 -1.1364  -0.7451
#(-0.743, 0.0]                 576.0 -0.0477  0.1463  -0.7425  0.0000  0.0000  0.0000   0.0000
#(0.0, 0.301]                   24.0  0.1490  0.1016   0.0024  0.0457  0.1497  0.2485   0.2856
#(0.301, 1.954]                150.0  1.1555  0.4833   0.3353  0.7615  1.1837  1.5819   1.9513
#(1.954, 4.028]                150.0  2.9430  0.6016   1.9660  2.4385  2.9665  3.4764   4.0277
#(4.028, 12.344]               150.0  6.1692  1.6616   4.0336  4.8805  5.8176  6.9019  12.3437

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM