如何使用H2OGeneralizedLowRankEstimator GLRM转换新数据?

时间:2017-07-19 15:03:26

标签: h2o

看起来像H2OGeneralizedLowRankEstimator(GLRM)正是我想要的。我过去常常转换训练集数据。我的想法是基于新功能(原型)构建​​分类器

在查看文档和示例之后,不清楚的是如何将训练好的GLRM模型应用于新数据以使新数据帧传递到使用原型数据训练的分类器模型。尝试以明显的方式使用GLRM预测似乎不起作用。

我的预感是必须的。基于线性代数方程(其中A是原始数据,X是新原型的矩阵,Y是变换矩阵):

A = XY

那样

A * inverse(Y)= X

[抱歉,我没有足够的积分来添加 GLRM 作为标签]

glrm = h2o.estimators.glrm.H2OGeneralizedLowRankEstimator(
    k = 100,  # Reduce to top 100 features
                                           transform = "STANDARDIZE",
                                           loss = "Quadratic",
                                           regularization_x = "Quadratic",
                                           regularization_y = "L1",
                                           gamma_x = 0.25,
                                           gamma_y = 0.5,
                                           max_iterations = 100


)

glrm.train(
    training_frame = df
)

# Try to transform the original data with the trained GLRM
pg = glrm.predict(df)

导致此错误:

EnvironmentError: Job with key $03017f00000132d4ffffffff$_96037b3ddc5e3e48d5273428d2fa43ee failed with an exception: java.lang.IllegalArgumentException: Can not make vectors of different length compatible!
stacktrace: 
java.lang.IllegalArgumentException: Can not make vectors of different length compatible!
at water.fvec.Frame.makeCompatible(Frame.java:1390)
at water.fvec.Frame.makeCompatible(Frame.java:1378)
at water.fvec.Frame.bulkAdd(Frame.java:591)
at water.fvec.Frame.add(Frame.java:576)
at water.fvec.Frame.add(Frame.java:630)
at hex.glrm.GLRMModel.reconstruct(GLRMModel.java:225)
at hex.glrm.GLRMModel.predictScoreImpl(GLRMModel.java:247)
at hex.Model.score(Model.java:1118)
at water.api.ModelMetricsHandler$1.compute2(ModelMetricsHandler.java:352)
at water.H2O$H2OCountedCompleter.compute(H2O.java:1256)
at jsr166y.CountedCompleter.exec(CountedCompleter.java:468)
at jsr166y.ForkJoinTask.doExec(ForkJoinTask.java:263)
at jsr166y.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:974)
at jsr166y.ForkJoinPool.runWorker(ForkJoinPool.java:1477)
at jsr166y.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:104)

1 个答案:

答案 0 :(得分:1)

你的直觉是正确的。使用GLRM,您可以分解矩阵A = XY并在X上执行聚类。对于新数据集,ANew,您需要获得新的XNew。为此,执行XNew = ANew * inverse(Y)。但是,如果数据集包含分类列,则GLRM将首先使用一个热编码扩展分类列,这将增加原始数据集中的列数。此外,它会将所有分类列移到前面,然后执行一个热编码。然后,它将在AOneHot = XY上执行GLRM。因此,当您尝试XNew = ANew * inverse(Y)时,您的尺寸不匹配。执行此操作的方法是在ANew上的分类列上执行一个热编码,然后应用反向(Y)。希望这可以帮助。温迪