【问题标题】:Possible to make a ROC plot from SVM with precomputed kernel in scikit-learn?可以使用 scikit-learn 中的预计算内核从 SVM 制作 ROC 图吗?
【发布时间】:2013-05-19 03:04:09
【问题描述】:

我正在使用此示例从 SVM 分类结果创建 ROC 图:http://scikit-learn.org/0.13/auto_examples/plot_roc.html

但是,每个数据点实际上由 4 个长度为 d 的特征向量组成,使用不符合特定 K(X, X) 范式的自定义核函数组合。因此,我必须为 scikit-learn 提供一个预先计算好的内核来进行分类。它看起来像这样:

K = numpy.zeros(shape = (n, n))

# w1 + w2 + w3 + w4 = 1.0

# v1: array, shape (n, d)
# w1: float in [0, 1)
chi = sklearn.metrics.pairwise.chi2_kernel(v1, v1)
mu = 1.0 / numpy.mean(chi)
K += w1 * numpy.exp(-mu * chi)

# v2: array, shape (n, d)
# w2: float in [0, 1)
chi = sklearn.metrics.pairwise.chi2_kernel(v2, v2)
mu = 1.0 / numpy.mean(chi)
K += w2 * numpy.exp(-mu * chi)

# v3: array, shape (n, d)
# w3: float in [0, 1)
chi = sklearn.metrics.pairwise.chi2_kernel(v3, v3)
mu = 1.0 / numpy.mean(chi)
K += w3 * numpy.exp(-mu * chi)

# v4: array, shape (n, d)
# w4: float in [0, 1)
chi = sklearn.metrics.pairwise.chi2_kernel(v4, v4)
mu = 1.0 / numpy.mean(chi)
K += w4 * numpy.exp(-mu * chi)

return K

生成 ROC 图的主要障碍(来自上面的链接)似乎是将数据分成两组,然后在测试集上调用 predict_proba() 的过程。 是否可以在 scikit-learn 中使用预计算内核来做到这一点?

【问题讨论】:

    标签: python machine-learning svm scikit-learn roc


    【解决方案1】:

    简短的回答是“也许不是”。 您是否尝试过以下类似的方法?

    基于http://scikit-learn.org/stable/modules/svm.html 的示例,您需要以下内容:

        import numpy as np
    
        from sklearn import svm
        X = np.array([[0, 0], [1, 1]])
        y = [0, 1]
        clf = svm.SVC(kernel='precomputed')
    
        # kernel computation
        K = numpy.zeros(shape = (n, n))
    
        # "At the moment, the kernel values between all training vectors 
        #  and the test vectors must be provided." 
        #  according to scikit learn web page. 
        #  -- This is the problem!
        # v1: array, shape (n, d)
        # w1: float in [0, 1)
        chi = sklearn.metrics.pairwise.chi2_kernel(v1, v1)
        mu = 1.0 / numpy.mean(chi)
        K += w1 * numpy.exp(-mu * chi)
    
        # v2: array, shape (n, d)
        # w2: float in [0, 1)
        chi = sklearn.metrics.pairwise.chi2_kernel(v2, v2)
        mu = 1.0 / numpy.mean(chi)
        K += w2 * numpy.exp(-mu * chi)
    
        # v3: array, shape (n, d)
        # w3: float in [0, 1)
        chi = sklearn.metrics.pairwise.chi2_kernel(v3, v3)
        mu = 1.0 / numpy.mean(chi)
        K += w3 * numpy.exp(-mu * chi)
    
        # v4: array, shape (n, d)
        # w4: float in [0, 1)
        chi = sklearn.metrics.pairwise.chi2_kernel(v4, v4)
        mu = 1.0 / numpy.mean(chi)
        K += w4 * numpy.exp(-mu * chi)
    
        # scikit-learn is a wrapper LIBSVM and looking at the LIBSVM Readme file
        # it seems you need kernel values for test data something like this:    
    
        Kt = numpy.zeros(shape = (nt, n))
        # t1: array, shape (nt, d)
        # w1: float in [0, 1)
        chi = sklearn.metrics.pairwise.chi2_kernel(t1, v1)
        mu = 1.0 / numpy.mean(chi)
        Kt += w1 * numpy.exp(-mu * chi)
    
        # v2: array, shape (n, d)
        # w2: float in [0, 1)
        chi = sklearn.metrics.pairwise.chi2_kernel(t2, v2)
        mu = 1.0 / numpy.mean(chi)
        Kt += w2 * numpy.exp(-mu * chi)
    
        # v3: array, shape (n, d)
        # w3: float in [0, 1)
        chi = sklearn.metrics.pairwise.chi2_kernel(t3, v3)
        mu = 1.0 / numpy.mean(chi)
        Kt += w3 * numpy.exp(-mu * chi)
    
        # v4: array, shape (n, d)
        # w4: float in [0, 1)
        chi = sklearn.metrics.pairwise.chi2_kernel(t4, v4)
        mu = 1.0 / numpy.mean(chi)
        Kt += w4 * numpy.exp(-mu * chi)
    
        clf.fit(K, y) 
    
        # predict on testing examples
        probas_ = clf.predict_proba(Kt)
    

    从这里开始复制http://scikit-learn.org/0.13/auto_examples/plot_roc.html的底部

    【讨论】:

    • 对,但问题是您使用了X_test,由于每个数据点都由 4 个不同的 n 维特征向量组成,这些特征向量组合在核函数中,因此我无法创建它。我无法将数据拆分为训练和测试,除非您提倡创建两个 gram 矩阵,而 scikit-learn 实际上禁止这样做(“结果将出乎意料”)。
    • 因此,如果我没看错的话,提供一个与用于训练 SVM 的语法矩阵 K 不同的语法矩阵 Ktpredict_proba() 是完全可以接受的? (需要将Kt 中的测试向量与训练向量进行比较)
    • 如果它们是从同一个内核中计算出来的——一个必须是 K(train,train),另一个是 K(test,train)。上面的一些计算让我担心 - 例如所有这些 mu 的处理是否正确。
    • 我没有意识到这一点!我只是假设——同样来自 scikit-learn 文档——你只能在相同的相同 gram 矩阵上进行测试/训练。至于计算,我使用的公式(来自 Nilsback et al 2008)是:K(i, j) = SUM_f{w_f * exp{-mu_f * chi^2{x_f(i), x_f(j)} } } 。 “f”的范围为 1-4,每个功能集一个。形式上它是一个 Mercer 内核,或者是加权的 Mercer 内核的总和 (w_f),总和为 1。mu_f 是该特征集的所有 chi^2 距离的 1/平均值。我在实施过程中遗漏了什么吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    • 2015-10-14
    • 2014-04-15
    • 2020-09-17
    • 2014-03-15
    • 2015-09-29
    • 2013-07-21
    相关资源
    最近更新 更多