如何将scikit学习管道的步骤之间传递值?
问题描述:
我想用一个管道,使用一个矢量器,然后通过LDA预处理步骤。 LDA预处理步骤需要Vectorizer的词汇表。如何将scikit学习管道的步骤之间传递值?
如何传递从而配合矢量器步到下一LDA步骤vocabulary_?我试图将管道本身传递给LDA步骤,但不幸的是这不起作用。
pipe_full = Pipeline(
[('vect', StemmedCountVectorizer(strip_accents='unicode', analyzer='word')),
('lda', SklLdaModel_mod()),
('clf', SGDClassifier(loss='log', penalty='elasticnet', n_iter=5, random_state=42, class_weight={0: 1, 1: 2}))])
param_grid_full = [{'vect__ngram_range': ((1, 1), (1, 2)), 'vect__stop_words': (None, 'english'),
'vect__token_pattern': (r'(?u)\b\w\w+\b', r'(?u)\b([a-zA-Z]{3,})\b'),
'vect__stemmer': (None, SnowCastleStemmer(mode='NLTK_EXTENSIONS')),
'lda': (None, SklLdaModel_mod(id2word=pipe_full, num_topics=10), SklLdaModel_mod(id2word=pipe_full, num_topics=20)),
# 'lda__topics': (100, 200),
# 'lda__topics': (10, 20), # for testing purposes only
'clf__alpha': (1e-4, 5e-4)}]
...在SklLdaModel_mod拟合方法,我有:
if isinstance(self.id2word, Pipeline):
try:
self.id2word = {v: k for k, v in self.id2word.named_steps['vect'].vocabulary_.items()}
任何建议,如何做到这一点?
答
@Vivek,
不幸的是,这并不工作,因为矢量器也应该在管道内进行优化。看到不同的参数。
我想出了解决的办法是有点哈克:
class XAmplifierForLDA(TransformerMixin, BaseEstimator):
"""
This class amplifies the return value of the transform method of a model to include the vocab information for the
id2word parameter of the LDA model
"""
def __init__(self, model=None):
self.model = model
def fit(self, *args, **kwargs):
self.model.fit(*args, **kwargs)
return self
def transform(self, X, **transform_params):
"""
This assumes model has a vocabulary
:param X:
:param transform_params:
:return:
"""
return {'transformed': self.model.transform(X), 'vocab': self.model.vocabulary_}
def set_params(self, **parameters):
self.model.set_params(**parameters)
return self
def get_params(self, deep=True):
""" return the parameters of the inner model """
return {'model': self.model}
然后我用这个XAmplifierLDA内CountVectorizer,然后会返回一个字典的转化X除了词汇!
pipe_full = Pipeline(
[('vect', XAmplifierForLDA(model=StemmedCountVectorizer(strip_accents='unicode', analyzer='word'))),
('lda', SklLdaModel_mod()),
('clf', SGDClassifier(loss='log', penalty='elasticnet', n_iter=5, random_state=42, class_weight={0: 1, 1: 2}))])
然后SklLdaModel_mod类正确地解释字典。
如何实现这种更清洁也许任何其他的想法?
答
我们开发PipeGraph,管道扩展,允许用户定义复杂的图形像Scikit,学习的对象链。特别是,我相信它可以解决这个问题,因为您可以将结果从一个步骤注入到另一个步骤。您可以在https://mcasl.github.io/PipeGraph/auto_examples/index.html
看到的例子画廊如果矢量化是您的管道的第一个步骤,你可以尝试移动它管道上,然后将数据,并使用管道内的'vocabulary_'。 –