10

我是 python 机器学习的新手,因此请原谅我的幼稚问题。python 中是否有一个用于实现神经网络的库,这样它也可以为我提供 ROC 和 AUC 曲线。我知道 python 中实现神经网络的库,但我正在寻找一个库,它也可以帮助我绘制 ROC、DET 和 AUC 曲线。

4

2 回答 2

30

在这种情况下,将您的问题分为 2 个主题是有意义的,因为神经网络与 ROC 曲线几乎没有直接关系。

神经网络

我认为没有什么比通过示例学习更好的方法了,所以我将向您展示一种使用由前馈神经网络训练的二进制分类问题的方法来解决您的问题,并受到pybrain的本教程的启发。

首先是定义一个数据集。最简单的可视化方法是在 2D 平面上使用二进制数据集,其中的点由正态分布生成,每个点都属于 2 个类之一。在这种情况下,这将是线性可分的。

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])

为了形象化,它看起来像这样: 数据集

现在你想把它分成训练集和测试集:

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

这在开始时给你一个非常糟糕的边界: 火车开始

但最后还是一个不错的结果:

火车头

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-单

当然你也可以在同一张图上绘制多条 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-多重

(请记住,对角线只是意味着您的分类器是随机的,并且您可能做错了什么)

您可能可以轻松地在任何分类任务中使用您的模块(不限于神经网络),它会为您生成 ROC 曲线。

现在要从神经网络中获取绘制 ROC 曲线所需的类/概率,您只需要查看神经网络的激活:activateOnDataset在 pybrain 中将为您提供两个类的概率(在我上面的示例中,我们只取确定要考虑哪个类别的最大概率)。从那里,只需将其转换为 PyROC 所期望的格式,就像 for 一样random_mixture_model,它应该会给你你的 ROC 曲线。

于 2012-04-27T22:27:07.830 回答
5

当然。首先,看看这个

https://stackoverflow.com/questions/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 曲线,您需要为是/否设置几个阈值(换句话说,0.75> 是,<.75 否)。从这个阈值开始,您将神经网络的输出转换为分类。通过将这些分类与真实分类进行比较,您可以获得假阳性率和真阳性率。然后,当您调整该阈值时,您将绘制误报率和真阳性率。

于 2012-04-25T15:30:41.640 回答