多个 scikit 学习管道的奇怪行为
Posted
技术标签:
【中文标题】多个 scikit 学习管道的奇怪行为【英文标题】:Strange behaviour with multiple scikit learn pipelines 【发布时间】:2020-01-01 04:26:22 【问题描述】:我正在使用 sklearn 训练一个模型,我的训练序列需要运行两个不同的特征提取管道。
由于某种原因,每个管道都可以毫无问题地拟合数据,并且当它们按顺序出现时,它们也可以毫无问题地转换数据。
但是,当第二个管道已经安装后调用第一个管道时,第一个管道已被更改,这会导致尺寸不匹配错误。
在下面的代码中,您可以重新创建问题(我已经大大简化了它,实际上我的两个管道使用不同的参数,但这是一个最低限度可重现的示例)。
from sklearn.pipeline import Pipeline
from sklearn.decomposition import TruncatedSVD
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd
vectorizer = CountVectorizer()
data1 = ['foo bar', 'a foo bar duck', 'goose goose']
data2 = ['foo', 'duck duck swan', 'goose king queen goose']
pipeline1 = Pipeline([('vec', vectorizer),('svd', TruncatedSVD(n_components = 3))]).fit(data1)
print(pipeline1.transform(data1))
# Works fine
pipeline2 = Pipeline([('vec', vectorizer),('svd', TruncatedSVD(n_components = 3))]).fit(data2)
print(pipeline2.transform(data2))
# Works fine
print(pipeline1.transform(data1))
# ValueError: dimension mismatch
显然,“pipeline2”的安装在某种程度上干扰了“pipeline1”,但我不知道为什么。我希望能够同时使用它们。
【问题讨论】:
如果你在调用管道1之后重新初始化vectorizer = CountVectorizer()
会发生什么?
这是否解决了您遇到的问题?
来自文档:估计器的超参数可以在通过 set_params() 方法构建后更新。多次调用 fit() 将覆盖之前任何 fit() 学到的内容
【参考方案1】:
会发生什么:
当您首先定义vectorizer
时,会发生以下情况:
-
你创建
vectorizer
你适合第一个管道:
已安装矢量化器,输出昏暗度为 (3,4),例如 3 个元素,4 个单词:foo、bar、duck、goose svd 适合有 4 列作为输入你适合第二个管道:
再次安装矢量化器,这次输出 6 个单词(例如列):foo、duck、swan、goose、king、queen 其他 svd 已安装,此处不相关你回调第一个管道:
矢量化器输出一个 (3,6) 矩阵,使用上次拟合的单词,例如第二个管道 已安装 svd 以接受 4 列作为输入,引发异常。如何验证:
vectorizer = CountVectorizer()
data1 = ['foo bar', 'a foo bar duck', 'goose goose']
data2 = ['foo', 'duck duck swan', 'goose king queen goose']
pipeline1 = Pipeline([('vec', vectorizer)]).fit(data1)
print(pipeline1.transform(data1).shape)
(3, 4)
# Works fine
pipeline2 = Pipeline([('vec', vectorizer)]).fit(data2)
print(pipeline2.transform(data2).shape)
(3, 6)
# Works fine
# vectorizer = CountVectorizer()
print(pipeline1.transform(data1).shape)
(3, 6)
如何解决:
您只需在管道中包含矢量化器的定义,如下所示:
from sklearn.pipeline import Pipeline
from sklearn.decomposition import TruncatedSVD
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd
data1 = ['foo bar', 'a foo bar duck', 'goose goose']
data2 = ['foo', 'duck duck swan', 'goose king queen goose']
pipeline1 = Pipeline([('vec', CountVectorizer()),('svd', TruncatedSVD(n_components = 3))]).fit(data1)
print(pipeline1.transform(data1))
# Works fine
pipeline2 = Pipeline([('vec', CountVectorizer()),('svd', TruncatedSVD(n_components = 3))]).fit(data2)
print(pipeline2.transform(data2))
# Works fine
print(pipeline1.transform(data1))
【讨论】:
以上是关于多个 scikit 学习管道的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章
在 SwiftUI 视图中的 TextField 后面使用多个 SecureField 时的奇怪行为
Python学习系列二十四scikit-learn库逻辑回归实现唯品会用户购买行为预测
使用多线程处理多个http请求HttpListener导致奇怪的行为