Набор инструментов Python/Shogun: конвертируйте RealFeatures в StreamingRealFeatures

Я использую Python-версию Shogun Toolbox. Я хочу использовать LinearTimeMMD, который принимает данные под потоковым интерфейсом CStreamingFeatures, У меня есть данные в виде двух RealFeatures объекты: feat_p а также feat_q, Они прекрасно работают с QuadraticTimeMMD,

Чтобы использовать его с LinearTimeMMD, мне нужно создать StreamingFeatures объекты из них - в этом случае они будут StreamingRealFeatures, насколько я знаю.

Мой первый подход был использовать это:

gen_p, gen_q = StreamingRealFeatures(feat_p), StreamingRealFeatures(feat_q)

Однако это, похоже, не работает: LinearTimeMMD выдает предупреждения и нереалистичный результат (постоянно растущий с увеличением количества выборок) и вызов gen_p.get_dim_feature_space() возвращается -1, Также, если я попытаюсь позвонить gen_p.get_streamed_features(100) это приводит к ошибке доступа к памяти.

Я попробовал другой подход, используя StreamingFileFromFeatures:

streamFile_p = sg.StreamingFileFromRealFeatures()
streamFile_p.set_features(feat_p)
streamFile_q = sg.StreamingFileFromRealFeatures()
streamFile_q.set_features(feat_q)

gen_p = StreamingRealFeatures(streamFile_p, False, 100)
gen_q = StreamingRealFeatures(streamFile_q, False, 100)

Но это приводит к той же ситуации с теми же описанными проблемами. Похоже, что в обоих случаях содержание RealFeatures объект передан StreamingRealFeatures объект не может быть доступен Что я делаю неправильно?

РЕДАКТИРОВАТЬ: меня попросили небольшой рабочий пример, чтобы показать ошибку:

import os
SHOGUN_DATA_DIR=os.getenv('SHOGUN_DATA_DIR', '../../../data')
import shogun as sg
from shogun import StreamingRealFeatures
import numpy as np

from matplotlib import pyplot as plt

from scipy.stats import laplace, norm

def sample_gaussian_vs_laplace(n=220, mu=0.0, sigma2=1, b=np.sqrt(0.5)):    
    # sample from both distributions
    X=norm.rvs(size=n)*np.sqrt(sigma2)+mu
    Y=laplace.rvs(size=n, loc=mu, scale=b)

    return X,Y


# Main Script
mu=0.0
sigma2=1
b=np.sqrt(0.5)
n=220
X,Y=sample_gaussian_vs_laplace(n, mu, sigma2, b)

# turn data into Shogun representation (columns vectors)
feat_p=sg.RealFeatures(X.reshape(1,len(X)))
feat_q=sg.RealFeatures(Y.reshape(1,len(Y)))

gen_p, gen_q = StreamingRealFeatures(feat_p), StreamingRealFeatures(feat_q)

print("Dimensions: ", gen_p.get_dim_feature_space())
print("Number of features: ", gen_p.get_num_features())
print("Number of vectors: ", gen_p.get_num_vectors())

test_features = gen_p.get_streamed_features(1)

print("success")

РЕДАКТИРОВАТЬ 2: Вывод рабочего примера:

Dimensions:  -1
Number of features:  -1
Number of vectors:  1
Speicherzugriffsfehler (Speicherabzug geschrieben)

РЕДАКТИРОВАТЬ 3: Дополнительный код с LinearTimeMMD, используя RealFeatures напрямую.

mmd = sg.LinearTimeMMD()
kernel = sg.GaussianKernel(10, 1)
mmd.set_kernel(kernel)
mmd.set_p(feat_p)
mmd.set_q(feat_q)
mmd.set_num_samples_p(1000)
mmd.set_num_samples_q(1000)
alpha = 0.05

# Code taken from notebook example on
# http://www.shogun-toolbox.org/notebook/latest/mmd_two_sample_testing.html
# Location on page: In[16]

block_size=100
mmd.set_num_blocks_per_burst(block_size)

# compute an unbiased estimate in linear time
statistic=mmd.compute_statistic()
print("MMD_l[X,Y]^2=%.2f" % statistic)

РЕДАКТИРОВАТЬ 4: Дополнительный пример кода, показывающий растущую проблему MMD:

import os
SHOGUN_DATA_DIR=os.getenv('SHOGUN_DATA_DIR', '../../../data')
import shogun as sg
from shogun import StreamingRealFeatures
import numpy as np

from matplotlib import pyplot as plt

def mmd(n):

    X = [(1.0,i) for i in range(n)]
    Y = [(2.0,i) for i in range(n)]

    X = np.array(X)
    Y = np.array(Y)

    # turn data into Shogun representation (columns vectors)
    feat_p=sg.RealFeatures(X.reshape(2, len(X)))
    feat_q=sg.RealFeatures(Y.reshape(2, len(Y)))

    mmd = sg.LinearTimeMMD()
    kernel = sg.GaussianKernel(10, 1)
    mmd.set_kernel(kernel)
    mmd.set_p(feat_p)
    mmd.set_q(feat_q)
    mmd.set_num_samples_p(100)
    mmd.set_num_samples_q(100)
    alpha = 0.05
    block_size=100
    mmd.set_num_blocks_per_burst(block_size)

    # compute an unbiased estimate in linear time
    statistic=mmd.compute_statistic()
    print("N =", n)
    print("MMD_l[X,Y]^2=%.2f" % statistic)
    print()

for n in [1000, 10000, 15000, 20000, 25000, 30000]:
    mmd(n)

Выход:

N = 1000
MMD_l[X,Y]^2=-12.69

N = 10000
MMD_l[X,Y]^2=-40.14

N = 15000
MMD_l[X,Y]^2=-49.16

N = 20000
MMD_l[X,Y]^2=-56.77

N = 25000
MMD_l[X,Y]^2=-63.47

N = 30000
MMD_l[X,Y]^2=-69.52

1 ответ

Почему-то pythonenv в моей машине не работает. Итак, я не мог дать фрагмент на Python. Но позвольте мне указать на рабочий пример в C++, который пытается решить проблемы ( https://gist.github.com/lambday/983830beb0afeb38b9447fd91a143e67).

  • Я думаю, что самый простой способ - это создать StreamingRealFeatures экземпляр непосредственно из RealFeatures экземпляр (как вы попробовали в первый раз). Проверьте test1() а также test2() методы в сущности, которая показывает эквивалентность использования RealFeatures а также StreamingRealFeatures в рассматриваемом случае использования. Причина, по которой вы получили странные результаты при потоковой передаче напрямую, заключается в том, что для запуска процесса потоковой передачи нам нужно вызвать start_parser метод в StreamingRealFeatures учебный класс. Мы занимаемся этими техническими вопросами внутри MMD классы. Но когда мы пытаемся использовать его напрямую, нам нужно вызывать его отдельно (см. test3() метод в моем прилагаемом примере).
  • Обратите внимание, что compute_statistic() Метод не возвращает MMD напрямую, а возвращает \frac{n_x\times n_y}{n_x+n_y}\times MMD^2 (как упомянуто в документе http://shogun.ml/api/latest/classshogun_1_1CMMD.html). Имея это в виду, возможно, результаты, которые вы получаете за разное количество образцов, имеют смысл.

Надеюсь, поможет.

Другие вопросы по тегам