Набор инструментов 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). Имея это в виду, возможно, результаты, которые вы получаете за разное количество образцов, имеют смысл.
Надеюсь, поможет.