Как измерить точность предсказаний с помощью 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 не предсказывает единственный результат, а ожидаемое количество очков. Есть по крайней мере один неизвестный фактор: вероятность ничьей. Вы должны добавить дополнительные знания о вероятности розыгрыша в свои модели. Эта вероятность зависит от разницы в прочности между игроки: чем больше разница, тем меньше вероятность ничьей. Можно попробовать следующие подходы:
- отображение ожидаемых точек на ожидаемые результаты, например
0...0.4
означает потерю,0.4..0.6
- ничья и0.6...1.0
- победа и посмотреть, сколько результатов угаданных. - для игрока и кучу игр, мера для точности будет
|predicted_score-score|/number_of_games
в среднем по игрокам. Чем меньше разница, тем лучше. - вид Байесовский подход: если для игры предсказанное количество очков
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()