Что я делаю не так при вычислении квартилей?

#python #numpy

#python #numpy

Вопрос:

 x = np.array([1, 3, 7, 11])
print(np.quantile(x, 0.75))
print(np.quantile(x, 0.25))
  
 8.0
2.5
  

Как я получаю эти ответы? Что я делаю не так? Я действительно тупой или q1 и q3 9 и 2?

Ответ №1:

Что вы делаете неправильно, так это не читаете документацию. Интерполяция по умолчанию — linear ; вы, кажется, ожидаете midpoint .

 x = np.array([1, 3, 7, 11])
print(np.quantile(x, 0.75, interpolation="midpoint"))
print(np.quantile(x, 0.25, interpolation="midpoint"))
  

Вывод:

 9.0
2.0
  

В вашей первоначальной попытке вы использовали «линейную» интерполяцию по умолчанию, которая использует долю диапазона, представленную двумя ближайшими точками. Я потратил около часа на изучение этой доли. В документации NumPy говорится:

линейный: i (j — i) * дробь, где дробь — это дробная часть индекса, окруженная i и j .

Термин index не определен на этой странице, и я не могу найти его где-либо еще в нескольких связанных методах. Гипотеза, которую я впервые опубликовал в этом ответе, неверна — теперь удалена. В конце концов я сдался и попытался перепроектировать концепцию, вычислив значение index как (j - i) / fraction :

 print(f'{" q":3} {" val":4} {" i":3} {"j":3} {"frac"}  {"index"}')
x = np.array([0, 1, 3, 6, 10])
lo = [0, 0, 0, 1, 1, 3, 3, 3,  6,  6, 10]
hi = [0, 1, 1, 3, 3, 3, 6, 6, 10, 10, 10]
for q in range(0, 11):
    interp = np.quantile(x, q/10)
    i, j = lo[q], hi[q]
    fraction = 0 if i == j else (interp - i) / (j - i)
    index    = 0 if i == j else (j - i) / fraction
    print(f'{round(q/10, 1):3} {round(interp, 1):4} {i:2} {j:2}   {round(fraction, 1):<3}  {round(index, 2):6.2f}')
  

Вывод:

  q   val  i  j   frac  index
0.0  0.0  0  0   0      0.00   # i == j
0.1  0.4  0  1   0.4    2.50
0.2  0.8  0  1   0.8    1.25
0.3  1.4  1  3   0.2   10.00
0.4  2.2  1  3   0.6    3.33
0.5  3.0  3  3   0      0.00   # i == j
0.6  4.2  3  6   0.4    7.50
0.7  5.4  3  6   0.8    3.75
0.8  6.8  6 10   0.2   20.00
0.9  8.4  6 10   0.6    6.67
1.0 10.0 10 10   0      0.00   # i == j
  

На данный момент я затрудняюсь объяснить концепцию «фракции». Я понимаю, что это статистическая попытка дать наилучшую оценку значения квантиля, предполагая, что в коллекцию будет добавлено больше наблюдений x , полученных из того же базового (и неизвестного) распределения.

Если кто-нибудь видит, где мои вычисления неверны, или может каким-либо образом осветить это, пожалуйста, отредактируйте этот ответ, комментарий и т.д. Сегодня я примерно на один длинный шаг вышел из зоны своего понимания.

Комментарии:

1. Можете ли вы объяснить, как вы получаете дробь? Также я вижу, что 8 — это 25% пути от 7 до 11, но 2.5 — это 75% пути от 1 до 3.

2. Я получаю дробь, применяя формулу, приведенную в документации. Где вы не понимаете контекстуальное определение дроби ?

3. Наверное, я не понимаю, что означает «где дробь — это дробная часть индекса, окруженная i и j».

4. Ах, ха! Теперь я вижу; так получилось, что я понимаю это, но простофили не определили термин на этой странице. Это займет несколько минут; мне нужно будет заняться этим после обеда. В то же время, вы хотите midpoint , чтобы я не боялся за ваш личный прогресс.

5. Честно говоря, я не до конца понимаю, что вы сделали. Однако я получил ответ на другом сайте и решил поделиться им, чтобы узнать, что вы думаете. Основанный на нуле индекс того, где должен находиться первый квартиль, равен index = (n — 1) * q, или index = 0,75. Для третьего квартиля это было бы 2,25. Fraction = index — int (индекс), поэтому fraction = 0.25 для q3.

Ответ №2:

Режим интерполяции по умолчанию для np.quantile является линейным (см. Документацию).

Вы можете получить ожидаемый результат, передав интерполяцию=’midpoint’.