Можно ли сделать график ROC из SVM с предварительно вычисленным ядром в scikit-learn?

Я использую этот пример для создания графика ROC из результатов классификации SVM: 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, используя предварительно вычисленное ядро?


person Magsol    schedule 23.05.2013    source источник


Ответы (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

person Bull    schedule 24.05.2013
comment
Верно, но проблема в том, что вы использовали X_test, который я не могу создать из-за того, что каждая точка данных состоит из 4 различных n-мерных векторов признаков, которые объединены в функции ядра. Я не могу разделить данные на обучение и тестирование, если вы не выступаете за создание двух граммовых матриц, что на самом деле scikit-learn запрещает делать (результаты будут неожиданными). - person Magsol; 24.05.2013
comment
Итак, если я правильно это читаю, вполне приемлемо предоставить матрицу граммов от Kt до predict_proba(), которая отличается от матрицы граммов K, используемой для обучения SVM? (с учетом того, что тестовые векторы в Kt нужно сравнивать с обучающими векторами) - person Magsol; 24.05.2013
comment
Если они рассчитываются на основе одного и того же ядра - одно должно быть K (поезд, обучение), а другое - K (тест, обучение). Однако некоторые из приведенных выше расчетов меня беспокоят - например, Правильно ли обращаются со всеми этими му? - person Bull; 24.05.2013
comment
Я этого не осознавал! Я просто предположил - из документации scikit-learn - что вы можете тестировать / тренировать только на одной и той же идентичной матрице граммов. Что касается расчетов, то формула, которую я использую (из 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 - это 1 / среднее значение всех расстояний chi ^ 2 для этого набора функций. Я что-то упустил в своей реализации? - person Magsol; 24.05.2013