如何在Spark管道中获取特征向量列的长度

5

我有一个有趣的问题。

我正在使用Pipeline对象来运行一个机器学习任务。

这是我的Pipeline对象的样子。

jpsa_mlp.pipeline.getStages()
Out[244]:
[StringIndexer_479d82259c10308d0587,
 Tokenizer_4c5ca5ea35544bb835cb,
 StopWordsRemover_4641b68e77f00c8fbb91,
 CountVectorizer_468c96c6c714b1000eef,
 IDF_465eb809477c6c986ef9,
 MultilayerPerceptronClassifier_4a67befe93b015d5bd07]

这个管道对象中的所有估计器和转换器都被编码为类方法,其中JPSA是类对象。

现在我想添加一个超参数调整的方法。因此我使用以下代码:

 self.paramGrid = ParamGridBuilder()\
            .addGrid(self.pipeline.getStages()[5].layers, [len(self.pipeline.getStages()[3].vocab),10,3])\
            .addGrid(self.pipeline.getStages()[5].maxIter, [100,300])\
            .build()

问题是神经网络分类器的一个超参数就是隐藏层大小。 MLP分类器的layers属性需要输入层,隐藏层和输出层的大小。输入和输出是固定的(基于我们有的数据)。因此,我想将输入层大小设置为我的特征向量的大小。然而,我不知道我的特征向量的大小,因为创建特征向量的管道对象内的估计器(Count Vectorizer,IDF)尚未适配数据。

通过使用Spark的交叉验证器对象,管道对象将在交叉验证期间拟合数据。然后,我才能够使用CountVectorizerModel来知道特征向量的大小。

如果我已经有了Countvectorizer,则可以使用countvectorizerModel.vocab来获取特征向量的长度,并将其作为mlp的layers属性中输入层值的参数。

那么,如何为mlp添加层的超参数(包括隐藏层和输入层大小)呢?

2个回答

2
你可以从数据框架的元数据中找到这些信息。
Scala代码:
val length = datasetAfterPipe.schema(datasetAfterPipe.schema.fieldIndex("columnName"))
    .metadata.getMetadata("ml_attr").getLong("num_attrs")

1

由于请求了PySpark代码:

您可以看到它们“导航”元数据:datasetAfterPipe.schema["features"].metadata["ml_attr"]

这是示例输出(xxx是所有特征制成的特征列,最终结果是大小):

Out: 
    {'attrs': {'numeric': [{'idx': xxxxxxx }]}, 'num_attrs': 337}

所以你要切片元数据:
lenFeatureVect = datasetAfterPipe.schema["features"].metadata["ml_attr"]["num_attrs"]

print('Len feature vector:', lenFeatureVect)
Out: 
   337

注意:如果您有“缩放特征”,则需要使用“预缩放”列中的特征,以获取属性信息(假设您在向量化后进行缩放,否则不会应用限制,如果您将原始列提供给它,则不会应用限制),因为您将特征向量提供给管道中的该步骤。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接