В течение последних нескольких недель я работал над созданием модели склонности на уровне пользователя, которую мы можем использовать в нашем процессе автоматического назначения ставок Google PPC. В настоящее время у нас есть Exponea/Bloomreach в качестве нашего CDXP, однако возможности прогнозной аналитики этого инструмента слишком ограничены, на мой вкус. Преимущество этого инструмента (на мой взгляд) заключается в том, что он легко подключается к различным рекламным платформам, если вы можете вводить свои данные и отслеживать события на своем веб-сайте. В любом случае, этот блог не об Exponea или моделировании на уровне пользователя — он о матрице путаницы.
Матрица путаницы — отличный способ понять производительность модели. Вы можете получить много диагностической статистики из 4 ячеек. В стандартной задаче бинарной классификации у вас есть два состояния — Фактическое и Прогнозируемое, и в каждом из них есть Истина или Ложь.
Я использую Exponea для создания модели конверсии на уровне пользователя. Однако статистика, которую я использовал для оценки производительности модели, там не была доступна. Поэтому я решил написать функцию Python, которая вычисляла бы все возможные статистические данные, которые мне понадобятся, из матрицы путаницы, если я ввожу в нее матрицу путаницы. Я мог бы использовать sklearn, но тогда мне нужно было бы импортировать метрики, а затем ссылаться на функцию для каждой статистики, и, давайте будем честными, почему нет только одной функции, которая выдает всю статистику, пока вы нажимаете y и y_pred или матрица путаницы?!
Итак, пока у вас есть матрица путаницы, которая представляет собой массив и выглядит так, как показано ниже (я использовал модели статистики pred_table), мой код будет работать нормально и возвращать словарь со статистикой из матрицы путаницы.
def model_diagnostic_stats(confusion_matrix): tp = confusion_matrix[1,1] tn = confusion_matrix[0,0] fp = confusion_matrix[0,1] fn = confusion_matrix[1,0] p = tp + fn n = fp + tn pp = tp + fp pn = fn + tn diagnostic_dict = { 'recall' : tp/p, 'false_neg_rate' : fn/p, 'false_pos_rate' : fp/n, 'true_neg_rate' : tn/n, 'positive_liklihood_ratio' : (tp/p)/(fp/n), 'neg_liklihood_rate' : (fn/p)/(tn/n), 'precision' : tp/pp, 'false_omission_rate' : fn/pn, 'false_discovery_rate' : fp/pp, 'neg_pred_value' : tn/pn, 'markedness' : (tp/pp)+(tn/pn)-1, 'diagnostic_odds_ration' : ((tp/p)/(fp/n))/( (fn/p)/(tn/n)), 'informedness' : (tp/p)+(tn/n)-1, 'prevalence_threshold' : (sqrt((tp/p)*(fp/n))-(fp/n))/((tp/p)-(fp/n)), 'prevalence' : p/(p+n), 'accuracy' : (tp+tn)/(p+n), 'balanced_accuracy' : ((tp/p)+(tn/n))/2, 'F1_score' : 2*tp/(2*tp+fp+fn), 'fowlkes_mallows_index' : sqrt((tp/pp)*(tp/p)), 'jaccard_index' : tp/(tp+fn+fp), } return diagnostic_dict
Теперь, когда у меня есть диагностическая статистика модели, я могу судить, насколько моя модель лучше или хуже той, которую я построил в Exponea.