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是数据科学项目的强大工具,尤其是那些要放在生产环境中的项目。它们的附加价值不仅在于清晰和方便,还在于安全和防止数据泄漏。