0

我正在使用 Shogun Toolbox 的 Python 版本。我想使用LinearTimeMMD,它在流接口下接受数据CStreamingFeatures。我有两个RealFeatures对象形式的数据:feat_pfeat_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
4

1 回答 1

1

由于某种原因,我机器中的 pythonenv 坏了。所以,我无法在 Python 中给出一个片段。但是让我指出一个 C++ 中的工作示例,它试图解决这些问题(https://gist.github.com/lambday/983830beb0afeb38b9447fd91a143e67)。

  • StreamingRealFeatures我认为最简单的方法是直接从实例创建一个RealFeatures实例(就像你第一次尝试一样)。要点中的检查test1()test2()方法显示了使用RealFeaturesStreamingRealFeatures相关用例中的等效性。直接流式传输时得到奇怪结果的原因是为了启动流式传输过程,我们需要调用类start_parser中的方法StreamingRealFeaturesMMD我们在课堂内部处理这些技术性问题。但是当尝试直接使用它时,我们需要单独调用它(参见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中所述)。考虑到这一点,也许您从不同数量的样本中获得的结果是有意义的。

希望能帮助到你。

于 2018-04-16T21:25:13.363 回答