Как выбрать оптимальный порог для вероятностей класса? - PullRequest
0 голосов
/ 30 августа 2018

Мой вывод нейронной сети представляет собой таблицу прогнозируемых вероятностей классов для мультимаркированной классификации :

print(probabilities)

|   |      1       |      3       | ... |     8354     |     8356     |     8357     |
|---|--------------|--------------|-----|--------------|--------------|--------------|
| 0 | 2.442745e-05 | 5.952136e-06 | ... | 4.254002e-06 | 1.894523e-05 | 1.033957e-05 |
| 1 | 7.685694e-05 | 3.252202e-06 | ... | 3.617730e-06 | 1.613792e-05 | 7.356643e-06 |
| 2 | 2.296657e-06 | 4.859554e-06 | ... | 9.934525e-06 | 9.244772e-06 | 1.377618e-05 |
| 3 | 5.163169e-04 | 1.044035e-04 | ... | 1.435158e-04 | 2.807420e-04 | 2.346930e-04 |
| 4 | 2.484626e-06 | 2.074290e-06 | ... | 9.958628e-06 | 6.002510e-06 | 8.434519e-06 |
| 5 | 1.297477e-03 | 2.211737e-04 | ... | 1.881772e-04 | 3.171079e-04 | 3.228884e-04 |

Я преобразовал его в метки классов, используя порог ( 0.2 ) для измерения точности моего прогноза:

predictions = (probabilities > 0.2).astype(np.int)
print(predictions)

|   | 1 | 3 | ... | 8354 | 8356 | 8357 |
|---|---|---|-----|------|------|------|
| 0 | 0 | 0 | ... |    0 |    0 |    0 |
| 1 | 0 | 0 | ... |    0 |    0 |    0 |
| 2 | 0 | 0 | ... |    0 |    0 |    0 |
| 3 | 0 | 0 | ... |    0 |    0 |    0 |
| 4 | 0 | 0 | ... |    0 |    0 |    0 |
| 5 | 0 | 0 | ... |    0 |    0 |    0 |

Также у меня есть набор тестов:

print(Y_test)

|   | 1 | 3 | ... | 8354 | 8356 | 8357 |
|---|---|---|-----|------|------|------|
| 0 | 0 | 0 | ... |    0 |    0 |    0 |
| 1 | 0 | 0 | ... |    0 |    0 |    0 |
| 2 | 0 | 0 | ... |    0 |    0 |    0 |
| 3 | 0 | 0 | ... |    0 |    0 |    0 |
| 4 | 0 | 0 | ... |    0 |    0 |    0 |
| 5 | 0 | 0 | ... |    0 |    0 |    0 |

Вопрос: Как построить алгоритм на Python, который выберет оптимальный порог, который максимизирует roc_auc_score(average = 'micro') или другую метрику?

Возможно, в Python можно построить ручную функцию, которая оптимизирует порог в зависимости от метрики точности.

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

Я предполагаю, что ваши метки истинности Y_test, а прогнозы predictions.

Оптимизация roc_auc_score(average = 'micro') в соответствии с прогнозом threshold, по-видимому, не имеет смысла, так как AUC рассчитываются на основе ранжирования прогнозов и, следовательно, требуют predictions в качестве значений с плавающей запятой в [0,1].

Поэтому я буду обсуждать accuracy_score.

Вы можете использовать scipy.optimize.fmin:

def thr_to_accuracy(thr, Y_test, predictions):
   return -accuracy_score(Y_test, np.array(predictions>thr, dtype=np.int))

best_thr = scipy.optimize.fmin(thr_to_accuracy, args=(Y_test, predictions), x0=0.5)
0 голосов
/ 30 августа 2018

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

Вам нужно обучить это, разделив тестовый набор на две части и использовать одну часть для обучения LR после прогнозирования выхода с помощью NN.

Это не единственный способ сделать это, но он прекрасно работает каждый раз.

у нас есть X_train_nn, X_valid_nn, X_test_NN, и мы подразделяем X_test_NN на X_train_LR, X_test_LR (или делаем стратифицированное K-разложение по вашему желанию) вот пример кода

X_train = NN.predict_proba(X_train_LR)
X_test = NN.predict_proba(X_test_LR)
logistic = linear_model.LogisticRegression(C=1.0, penalty = 'l2')
logistic.fit(X_train,Y_train)
logistic.score(X_test,Y_test)

Вы считаете, что вы выводите как новый набор данных, и обучаете LR на этом новом наборе данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...