我正在使用Shogun Toolbox的Python版本。
我想使用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:使用RealFeatures直接使用LinearTimeMMD的附加代码。
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
答案 0 :(得分: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中所述)。考虑到这一点,也许您获得的不同数量样本的结果是有意义的。希望它有所帮助。