python - GridsearchCV:尝试在参数中传递 lambda 时无法腌制函数错误
问题描述
我已经在 stackoverflow 和其他地方进行了广泛的研究,但我似乎无法找到以下问题的答案。
我正在尝试修改一个函数的参数,该参数本身就是GridSearchCV function of sklearn. More specifically, I want to change parameters (here
preserve_case = ) inside the
Falsecasual_tokenize function that is passed to the parameter
tokenizer of the function
CountVectorizer`中的参数。
这是具体的代码:
from sklearn.datasets import fetch_20newsgroups
from sklearn.pipeline import Pipeline
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.model_selection import GridSearchCV
from nltk import casual_tokenize
从 20newsgroup 生成虚拟数据
categories = ['alt.atheism', 'comp.graphics', 'sci.med',
'soc.religion.christian']
twenty_train = fetch_20newsgroups(subset='train',
categories=categories,
shuffle=True,
random_state=42)
创建分类管道。
请注意,可以使用lambda
. 我想知道是否有另一种方法可以做到这一点,因为它不适用于GridSearchCV
.
text_clf = Pipeline([('vect',
CountVectorizer(tokenizer=lambda text:
casual_tokenize(text,
preserve_case=False))),
('tfidf', TfidfTransformer()),
('clf', MultinomialNB()),
])
text_clf.fit(twenty_train.data, twenty_train.target) # this works fine
然后,我想将默认标记CountVectorizer
器与 nltk 中的标记器进行比较。请注意,我问这个问题是因为我想比较多个标记器,每个标记器都有需要指定的特定参数。
parameters = {'vect':[CountVectorizer(),
CountVectorizer(tokenizer=lambda text:
casual_tokenize(text,
preserve_case=False))]}
gs_clf = GridSearchCV(text_clf, parameters, n_jobs=-1, cv=5)
gs_clf = gs_clf.fit(twenty_train.data[:100], twenty_train.target[:100])
gs_clf.fit
给出以下错误:PicklingError: Can't pickle at 0x1138c5598>: attribute lookup on main failed
所以我的问题是:
1)有没有人知道如何专门处理这个问题GridSearchCV
。
2)是否有更好的pythonic方法来处理将参数传递给也将是参数的函数?
解决方案
1) 有谁知道如何专门用 GridSearchCV 处理这个问题。
您可以使用partial
而不是lambda
from functools import partial
from sklearn.externals.joblib import dump
def add(a, b):
return a + b
plus_one = partial(add, b=1)
plus_one_lambda = lambda a: a + 1
dump(plus_one, 'add.pkl') # No problem
dump(plus_one_lambda, 'add.pkl') # Pickling error
对于您的情况:
tokenizer=partial(casual_tokenize, preserve_case=False)
2)是否有更好的pythonic方法来处理将参数传递给也将是参数的函数?
我认为使用lambda
orpartial
都是“pythonic方式”。
这里的问题是GridSearchCV
使用多处理。这意味着它可能会启动多个进程,它必须序列化一个进程中的参数并将它们传递给其他进程(然后目标进程反序列化以获得相同的参数)。
GridSearchCVjoblib
用于多处理/序列化。Joblib 无法处理lambda
函数。
推荐阅读
- java - 适用于 android 的自定义 materila 日期范围选择器
- visual-studio-code - Visual Studio Code - Techer 的扩展问题“在浏览器中打开”无法使用
- swift - SwiftUI 应用程序中上下文保存的核心数据 Objective-C 异常
- sql-server - 同步性能位置
- php - 未定义的函数“视图”laravel
- html - 我需要在标题描述中留出空间
- android - 在 Android 上通过 USB 直播视频
- javascript - Jquery 中是否有任何名为 followFrom() 的函数?
- html -
- laravel - 命令“备份:运行”不存在。在使用控制器执行命令时