Библиотека в python для нейронных сетей для построения ROC, AUC, DET

Я новичок в механическом обучении на питоне, поэтому прощаю свой наивный вопрос. Есть ли библиотека в python для реализации нейронных сетей, так что она также дает мне кривые ROC и AUC. Я знаю о библиотеках в python, которые реализуют нейронные сети, но я ищу библиотеку, которая также помогает мне в построении кривых ROC, DET и AUC.

Ответ 1

В этом случае имеет смысл разделить ваш вопрос на 2 темы, так как нейронные сети вряд ли непосредственно связаны с кривыми ROC.

Нейронные сети

Я думаю, что нет ничего лучше, чтобы научиться на примере, поэтому я покажу вам подход к вашей проблеме, используя проблему двоичной классификации, обученную нейронной сетью Feed-Forward, и вдохновленная этот учебник из pybrain.

Прежде всего, нужно определить набор данных. Самый простой способ визуализации - использовать бинарный набор данных на 2D-плоскости с точками, генерируемыми из нормальных распределений, каждый из которых принадлежит к одному из двух классов. В этом случае это будет линейно отделимо.

from pybrain.datasets            import ClassificationDataSet
from pybrain.utilities           import percentError
from pybrain.tools.shortcuts     import buildNetwork
from pybrain.supervised.trainers import BackpropTrainer
from pybrain.structure.modules   import SoftmaxLayer

from pylab import ion, ioff, figure, draw, contourf, clf, show, hold, plot
from scipy import diag, arange, meshgrid, where
from numpy.random import multivariate_normal

means = [(-1,0),(2,4),(3,1)]
cov = [diag([1,1]), diag([0.5,1.2]), diag([1.5,0.7])]
n_klass = 2
alldata = ClassificationDataSet(2, 1, nb_classes=n_klass)
for n in xrange(400):
    for klass in range(n_klass):
        input = multivariate_normal(means[klass],cov[klass])
        alldata.addSample(input, [klass])

Чтобы визуализировать, он выглядит примерно так: dataset

Теперь вы хотите разбить его на тренировочный и тестовый набор:

tstdata, trndata = alldata.splitWithProportion(0.25)

trndata._convertToOneOfMany()
tstdata._convertToOneOfMany()

И для создания вашей сети:

fnn = buildNetwork( trndata.indim, 5, trndata.outdim, outclass=SoftmaxLayer )

trainer = BackpropTrainer( fnn, dataset=trndata, momentum=0.1, verbose=True,             weightdecay=0.01)

ticks = arange(-3.,6.,0.2)
X, Y = meshgrid(ticks, ticks)
# need column vectors in dataset, not arrays
griddata = ClassificationDataSet(2,1, nb_classes=n_klass)
for i in xrange(X.size):
    griddata.addSample([X.ravel()[i],Y.ravel()[i]], [0])
griddata._convertToOneOfMany()  # this is still needed to make the fnn feel comfy

Теперь вам нужно обучить свою сеть и посмотреть, какие результаты вы получите в конце:

for i in range(20):
    trainer.trainEpochs( 1 )
    trnresult = percentError( trainer.testOnClassData(),
                              trndata['class'] )
    tstresult = percentError( trainer.testOnClassData(
           dataset=tstdata ), tstdata['class'] )

    print "epoch: %4d" % trainer.totalepochs, \
          "  train error: %5.2f%%" % trnresult, \
          "  test error: %5.2f%%" % tstresult

    out = fnn.activateOnDataset(griddata)
    out = out.argmax(axis=1)  # the highest output activation gives the class
    out = out.reshape(X.shape)

    figure(1)
    ioff()  # interactive graphics off
    clf()   # clear the plot
    hold(True) # overplot on
    for c in range(n_klass):
        here, _ = where(tstdata['class']==c)
        plot(tstdata['input'][here,0],tstdata['input'][here,1],'o')
    if out.max()!=out.min():  # safety check against flat field
        contourf(X, Y, out)   # plot the contour
    ion()   # interactive graphics on
    draw()  # update the plot

Это дает вам очень плохую границу в начале: train-start

Но в итоге довольно хороший результат:

train-end

Кривые ROC

Что касается кривых ROC, здесь - это хорошая и простая библиотека Python, чтобы сделать это по случайной проблеме игрушек:

from pyroc import *
random_sample  = random_mixture_model()  # Generate a custom set randomly

#Example instance labels (first index) with the decision function , score (second index)
#-- positive class should be +1 and negative 0.
roc = ROCData(random_sample)  #Create the ROC Object
roc.auc() #get the area under the curve
roc.plot(title='ROC Curve') #Create a plot of the ROC curve

Что дает вам одну кривую ROC: ROC-single

Конечно, вы можете также построить несколько кривых ROC на одном и том же графике:

x = random_mixture_model()
r1 = ROCData(x)
y = random_mixture_model()
r2 = ROCData(y)
lista = [r1,r2]
plot_multiple_roc(lista,'Multiple ROC Curves',include_baseline=True)

ROC-multiple

(помните, что диагональ просто означает, что ваш классификатор случайен и что вы, вероятно, что-то не так)

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

Теперь, чтобы получить класс/вероятность, необходимую для построения кривой ROC из вашей нейронной сети, вам просто нужно посмотреть на активацию вашей нейронной сети: activateOnDataset в pybrain даст вам вероятность для обоих классов (в моем пример выше, мы просто берем максимум вероятностей, чтобы определить, какой класс рассмотреть). Оттуда просто преобразуйте его в формат, ожидаемый PyroC, как для random_mixture_model, и он должен дать вам вашу кривую ROC.

Ответ 2

Конечно. Сначала проверьте этот

https://stackoverflow.com/info/2276933/good-open-source-neural-network-python-library

Это моя общая идея, я набросаю, как я мог бы подходить к этому, ни один из них не был протестирован

С http://pybrain.org/docs/tutorial/netmodcon.html#feed-forward-networks

>>> from pybrain.structure import FeedForwardNetwork
>>> n = FeedForwardNetwork()
>>> n.activate((2, 2))
array([-0.1959887])

Мы строим нейронную сеть, тренируем ее (не показан) и получаем результат. У вас есть тестовый набор, верно? Вы используете тестовый набор для генерации данных для кривой ROC. Для единственной выходной нейронной сети вы хотите создать порог для выходных значений, чтобы перевести их в да или нет ответов, которые получают максимальную степень специфичности/чувствительности для вашей задачи.

Это хороший учебник http://webhome.cs.uvic.ca/~mgbarsky/DM_LABS/LAB_5/Lab5_ROC_weka.pdf

Затем вы просто замышляете их. Или вы можете попробовать найти библиотеку, которая сделает это за вас.

Я видел это http://pypi.python.org/pypi/yard

Дело в том, что генерация на кривой ROC не является специфической для нейронных сетей, поэтому вы не можете найти библиотеку, которая сделает это за вас. Я предоставил приведенное выше, чтобы показать, что он довольно простой, чтобы свернуть свой собственный

* Подробнее *

Ваша нейронная сеть будет иметь выход, который вам придется перевести на классификацию (вероятно, да/нет). Чтобы вычислить кривую ROC, вы получите несколько пороговых значений для да/нет (другими словами,.75 > да, <.75 нет). С этого порога вы переводите результаты своей нейронной сети в классификации. Сравнивая эти классификации с истинными классификациями, вы получаете ложную положительную и истинную положительную оценку. Затем вы настраиваете ложную положительную ставку и истинную положительную ставку при настройке этого порога.