4个Scikit-Learn工具
2021-02-13 08:30·人工智能遇见磐创
数据科学项目往往包括预处理、特征工程、特征选择、训练、测试……在尝试多种选择甚至在生产环境中处理这些步骤时,可能会很快变得混乱。幸运的是,scikitlearn提供了一些选项,允许我们将多个estimator连成一个estimator。换句话说,像fit或predict这样的特定操作只需要在整个estimator序列上应用一次。
在本文中,我们将通过一个具体的项目与你分享其中的四种工具以及用例示例。
目录
- Pipelines
- Function Transformer
- Column Transformer
- Feature Union
- 另一种语法:make_[composite_estimator]
- 额外:可视化管道
热身
在我们开始探索scikit learn的工具之前,先获取一个可以使用的数据集。
这只是为了示范,所以你不一定要下载它(除非你想自己尝试代码)。
实际上我们偶然发现了一个名为datasets的python包,它允许你轻松下载500多个数据集:
importpandasaspdfromdatasetsimportload_datasetdataset=load_dataset("amazon_us_reviews",'Video_Games_v1_00',split='train')df=pd.DataFrame(dataset)
我们将使用亚马逊美国评论。它包含数字和文本特征(例如评论和获得的有用票数),目标特征是获得的星星数:https://huggingface.co/datasets/viewer/?dataset=amazon_us_reviews&config=Video_Games_v1_00
1-Pipelines
什么是Pipelines(管道)?
管道是为了方便起见,将estimator序列封装成单个序列的工具。
什么使它有用?
管道之所以方便,有多种原因:
- 紧凑性:避免编写多行代码和担心estimator的顺序;
- 清晰:易于阅读和可视化;
- 易于处理:只需一个单一的行动就可以fit或者predict整个序列;
- 联合参数选择:使用管道可以通过网格搜索一次性优化所有estimator的参数。
我如何在实践中使用它?
实际上,管道是由一组transformer和一个estimator组成的。
如果你不知道什么是transformer,你可以认为它是一个包含fit和transform方法的对象。
在本示例中,我们将使用TfidfVectorizer将评论从文本数据转换为数字数据,然后尝试使用RandomForestClassifier进行预测:
fromsklearn.pipelineimportPipelinefromsklearn.ensembleimportRandomForestClassifierfromsklearn.feature_extraction.textimportTfidfVectorizermodel=Pipeline([('vectorizer',TfidfVectorizer()),('clf',RandomForestClassifier())])model.fit(df['review_body'],df['star_rating'])
2.Function Transformer
什么是Function Transformer?
如前一节所述,transformer需要包含fit和transform方法。
FunctionTransformer是一个无状态的transformer,它是由你创建的callable构造的。
什么使它有用?
在某些情况下,需要执行不进行任何参数拟合的转换。在这种情况下,创建fit方法是没有用的。在这些情况下,FunctionTransformer将是最有用的。
我如何在实践中使用它?
数据集包含一个日期格式的特征。我们可以对日期进行转换的一个例子是提取年份。
以下是如何使用FunctionTransformer:
fromsklearn.preprocessingimportFunctionTransformertr=FunctionTransformer(lambdax:pd.to_datetime(x['review_date']).dt.year)
注意:如果lambda函数与FunctionTransformer一起使用,则生成的transformer将不可pickle。要知道的一件好事是,你可以通过使用cloudpickle包来解决这个问题。
3.Column Transformer
什么是Column Transformer?
根据数据集的不同,可能需要对数组或数据帧的不同列应用不同的转换。
Column Transformer允许在连接结果特征之前应用单独的转换。
什么使它有用?
这种estimator对于异构数据特别有用。在这种情况下,需要自定义特征提取机制或对列或列子集的数据类型进行转换。
我如何在实践中使用它?
在本例中,我们有文本数据和数字数据。下面是如何使用Column Transformer根据数据类型应用单独的转换:
fromsklearn.composeimportColumnTransformerfromsklearn.feature_extraction.textimportTfidfVectorizerfromsklearn.preprocessingimportNormalizerct=ColumnTransformer([("vectorizer",TfidfVectorizer(max_features=100),'review_body'),("normalizer",Normalizer(norm='l1'),['total_votes','helpful_votes'])])
正如预期的那样,ColumnTransformer的输出数据有102列:100列来自TF-IDFtransformer,2列来自Normalizer。
4-Feature Union
什么是Feature Union?
与ColumnTransformer类似,FeatureUnion将多个Transformer的结果连接起来。只是有些不同,因为每个transformer都将整个数据集作为其输入,而不是ColumnTransformer中的列子集。
就使用它们所能做的事情而言,这两种方法是相当等效的,但根据情况,其中一种可能更适合使用,并且需要的代码行数更少。
什么时候使用它?
FeatureUnion允许你将不同的特征提取变换器组合到一个Transformer中。
我如何在实践中使用它?
与前一种情况等效,我们可以使用由ColumnSelector和给定的transformer组成的管道来构造FeatureUnion。
我们将构造一个FeatureUnion,它执行与先前实现的ColumnTransformer相同的转换。
为此,我们将两个管道封装成一个FeatureUnion。每个管道链接一个ColumnSelector和一个给定的transformer。
scikit learn中没有预先实现的ColumnSelector,因此我们将使用FunctionTransformer构建自己的ColumnSelector:
fromsklearn.feature_extraction.textimportTfidfVectorizerfromsklearn.pipelineimportFeatureUnionfromsklearn.pipelineimportPipelinefromsklearn.preprocessingimportFunctionTransformerfromsklearn.preprocessingimportNormalizervectorizer=Pipeline([('selector',FunctionTransformer(lambdax:df['review_body'])),('vectorizer',TfidfVectorizer(max_features=100))])normalizer=Pipeline([('selector',FunctionTransformer(lambdadf:df[['total_votes','helpful_votes']])),("normalizer",Normalizer(norm='l1'))])fu=FeatureUnion([("vectorizer",vectorizer),("normalizer",normalizer)])
另一种语法:make_[composite_estimator]
除了前面提到的方法之外,还有一些语法稍有不同的方法(Function Transformer除外)。
这些方法是:
- make_pipeline(https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.make_pipeline.html#sklearn.pipeline.make_pipeline)
- make_column_transformer(https://scikit-learn.org/stable/modules/generated/sklearn.compose.make_column_selector.html#sklearn.compose.make_column_selector)
- make_union(https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.make_union.html#sklearn.pipeline.make_union)
这些是以前构造函数的简写。主要的区别是它们不要求,也不允许命名estimator。相反,组件名将自动设置为其类型的小写。
在大多数情况下,使用速记版本更简单、更清晰、更易读。但是,例如,如果需要执行网格搜索,则可能需要自定义estimator的名称。在这种情况下,为了清晰和紧凑,分配简短的可分辨名称可能很有用。
如果你不熟悉使用网格搜索进行参数优化,我们将很快就此撰写一篇文章。
你可以在下面看到应用于管道案例的两个版本之间的差异:
- 管道语法:
pipe=Pipeline([('vec',TfidfVectorizer()),('clf',LogisticRegression()])param_grid={'clf__C':[1,10,100]}grid_search=GridSearchCV(pipe,param_grid)grid_search.fit(X,y)
- make_pipeline相比:
pipe=make_pipeline(TfidfVectorizer(),LogisticRegression())param_grid={'logisticregression__C':[1,10,100]}grid_search=GridSearchCV(pipe,param_grid)grid_search.fit(X,y)
额外:可视化你的管道
Scikit Learn提供了一种使用以下代码行可视化你创建的复合estimator的简洁方法:
fromsklearn.pipelineimportPipelinefromsklearn.linear_modelimportLogisticRegressionfromsklearn.preprocessingimportFunctionTransformerfromsklearn.utilsimportestimator_html_repr#定义一个示例管道model=Pipeline([('transformer',FunctionTransformer(lambdax:2*x)),('clf',LogisticRegression())])withopen('model.html','w')asf:f.write(estimator_html_repr(model))
这将有效地创建一个以清晰的方式表示管道的交互式HTML文件。
如果你使用notebook,另一种方法是使用以下代码:
fromIPython.displayimportdisplayfromsklearn.pipelineimportPipelinefromsklearn.linear_modelimportLogisticRegressionfromsklearn.preprocessingimportFunctionTransformerfromsklearnimportset_configset_config(display='diagram')#定义一个示例管道model=Pipeline([('transformer',FunctionTransformer(lambdax:2*x)),('clf',LogisticRegression())])display(model)
结尾
管道和复合estimator是数据科学项目的强大工具,尤其是那些要放在生产环境中的项目。它们的附加价值不仅在于清晰和方便,还在于安全和防止数据泄漏。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.