Как измерить точность предсказаний с помощью Python / Pandas?

я использовал рейтинговые системы Elo и Glicko вместе с результатами матчей для создания рейтингов для игроков. Перед каждым матчем, я могу генерировать ожидание (тип float между 0 и 1) для каждого игрока на основе их соответствующих оценок. Я хотел бы проверить, насколько точно это ожидание, по двум причинам:

  • Для сравнения разница систем
  • для настройки переменных (например, kfactor в Elo), используемых для вычисления рейтинги

есть несколько отличий от шахмат, о которых стоит знать:

  • возможные результаты-победы (которые я рассматриваю как 1.0), потери (0.0), с очень случайными (
  • игроки имеют меньше матчей -- многие имеют меньше, чем 10, немногие идут более 25, Макс 75

думая, что соответствующая функция - "корреляция", я попытался создать Фрейм данных, содержащий прогноз в одном столбце (float между 0, 1) и результат в другом (1/0.5/0) и использование corr(), но на основе вывода я не уверен, что это правильно.

Если я создаю фрейм данных, содержащий ожидания и результаты только для первого игрока в матче (результаты всегда будут 1.0 или 0.5, так как из-за моего источника данных проигравшие никогда не отображаются первыми), corr () возвращает очень низкий:

Если это помогает, вот некоторые реальные (не случайные) данные выборки:http://pastebin.com/eUzAdNij

2 ответов


на самом деле, то, что вы наблюдаете, имеет смысл. Если бы не было ничьих, и вы всегда показывали бы ожидание победителя в первой строке, тогда не было бы никакой корреляции со второй строкой вообще! Потому что независимо от того, насколько велико или мало ожидание, число во второй строке всегда 1.0, т. е. он вообще не зависит от числа в первой строке.

из-за низкого процента ничьих (ничьи, вероятно, коррелируют со значениями вокруг 0.5) вы можете наблюдать небольшую корреляцию.

возможно, корреляция не является лучшей мерой для точности предсказаний здесь.

одна из проблем заключается в том, что Elo не предсказывает единственный результат, а ожидаемое количество очков. Есть по крайней мере один неизвестный фактор: вероятность ничьей. Вы должны добавить дополнительные знания о вероятности розыгрыша в свои модели. Эта вероятность зависит от разницы в прочности между игроки: чем больше разница, тем меньше вероятность ничьей. Можно попробовать следующие подходы:

  1. отображение ожидаемых точек на ожидаемые результаты, например 0...0.4 означает потерю, 0.4..0.6 - ничья и 0.6...1.0 - победа и посмотреть, сколько результатов угаданных.
  2. для игрока и кучу игр, мера для точности будет |predicted_score-score|/number_of_games в среднем по игрокам. Чем меньше разница, тем лучше.
  3. вид Байесовский подход: если для игры предсказанное количество очков x чем оценка предиктора x если игра была выиграна и 1-x если игра была потеряна (возможно, вам придется пропустить розыгрыши или забить их как (1-x)*x/4 - таким образом, предсказание 0.5 будет иметь счет в 1). Общий балл предиктора по всем играм будет являться продуктом одного игрового балла. Чем больше счет, тем лучше.

стандартный способ оценки точности прогнозирования-это рабочая характеристика приемника (ROC). Вы можете создать его из своих данных с помощью sklearn и matplotlib с помощью этого кода ниже.

ROC-это 2-D график истинных положительных и ложных положительных скоростей. Вы хотите, чтобы линия была выше диагонали, чем выше, тем лучше. Площадь под кривой (AUC) является стандартной мерой точности: чем больше, тем точнее ваш классификатор.

import pandas as pd

# read data
df = pd.read_csv('sample_data.csv', header=None, names=['classifier','category'])

# remove values that are not 0 or 1 (two of those)
df = df.loc[(df.category==1.0) | (df.category==0.0),:]

# examine data frame
df.head()

from matplotlib import pyplot as plt
# add this magic if you're in a notebook
# %matplotlib inline

from sklearn.metrics import roc_curve, auc
# matplot figure
figure, ax1 = plt.subplots(figsize=(8,8))

# create ROC itself
fpr,tpr,_ = roc_curve(df.category,df.classifier)

# compute AUC
roc_auc = auc(fpr,tpr)

# plotting bells and whistles
ax1.plot(fpr,tpr, label='%s (area = %0.2f)' % ('Classifier',roc_auc))
ax1.plot([0, 1], [0, 1], 'k--')
ax1.set_xlim([0.0, 1.0])
ax1.set_ylim([0.0, 1.0])
ax1.set_xlabel('False Positive Rate', fontsize=18)
ax1.set_ylabel('True Positive Rate', fontsize=18)
ax1.set_title("Receiver Operating Characteristic", fontsize=18)
plt.tick_params(axis='both', labelsize=18)
ax1.legend(loc="lower right", fontsize=14)
plt.grid(True)
figure.show()

из ваших данных, вы должен быть такой сюжет, как этот.: enter image description here