内容简介:本文介绍scikit-learn 0.20版本中新增的假设现在有这样一个场景:有一个数据集,每个样本包含n个数值型(numeric)特征,m个标称型(categorical)特征,我们在使用这个数据集训练模型之前,需要对n个数值型特征做归一化,对m个标称型特征做one-hot编码?这个要如何实现?其实这个不难,但挺麻烦的。一般的方式是把数值型的特征数据列和标称型数据分别拿出来,然后分别做预处理,处理完之后再拼在一起训练模型。这样一方面是麻烦,另一方面比较难保证原来特征的顺序(虽然顺序一般没什么影响)。sc
本文介绍scikit-learn 0.20版本中新增的 sklearn.compose.ColumnTransformer
和有所改动的 sklearn.preprocessing.OneHotEncoder
。
ColumnTransformer
假设现在有这样一个场景:有一个数据集,每个样本包含n个数值型(numeric)特征,m个标称型(categorical)特征,我们在使用这个数据集训练模型之前,需要对n个数值型特征做归一化,对m个标称型特征做one-hot编码?这个要如何实现?
其实这个不难,但挺麻烦的。一般的方式是把数值型的特征数据列和标称型数据分别拿出来,然后分别做预处理,处理完之后再拼在一起训练模型。这样一方面是麻烦,另一方面比较难保证原来特征的顺序(虽然顺序一般没什么影响)。scikit-learn在0.20.0版本中新增了一个 sklearn.compose.ColumnTransformer
类,通过这个类我们可以对输入的特征分别做不同的预处理,并且最终的结果还在一个特征空间里面。描述太抽象,直接看官方的里一个 例子
:
# Author: Pedro Morales <part.morales@gmail.com> # # License: BSD 3 clause from __future__ import print_function import pandas as pd import numpy as np from sklearn.compose import ColumnTransformer from sklearn.pipeline import Pipeline from sklearn.impute import SimpleImputer from sklearn.preprocessing import StandardScaler, OneHotEncoder from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split, GridSearchCV np.random.seed(0) # Read data from Titanic dataset. titanic_url = ('https://raw.githubusercontent.com/amueller/' 'scipy-2017-sklearn/091d371/notebooks/datasets/titanic3.csv') data = pd.read_csv(titanic_url) # We will train our classifier with the following features: # Numeric Features: # - age: float. # - fare: float. # Categorical Features: # - embarked: categories encoded as strings {'C', 'S', 'Q'}. # - sex: categories encoded as strings {'female', 'male'}. # - pclass: ordinal integers {1, 2, 3}. # We create the preprocessing pipelines for both numeric and categorical data. numeric_features = ['age', 'fare'] numeric_transformer = Pipeline(steps=[ ('imputer', SimpleImputer(strategy='median')), ('scaler', StandardScaler())]) categorical_features = ['embarked', 'sex', 'pclass'] categorical_transformer = Pipeline(steps=[ ('imputer', SimpleImputer(strategy='constant', fill_value='missing')), ('onehot', OneHotEncoder(handle_unknown='ignore'))]) preprocessor = ColumnTransformer( transformers=[ ('num', numeric_transformer, numeric_features), ('cat', categorical_transformer, categorical_features)]) # Append classifier to preprocessing pipeline. # Now we have a full prediction pipeline. clf = Pipeline(steps=[('preprocessor', preprocessor), ('classifier', LogisticRegression(solver='lbfgs'))]) X = data.drop('survived', axis=1) y = data['survived'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) clf.fit(X_train, y_train) print("model score: %.3f" % clf.score(X_test, y_test)) # output: # model score: 0.790
例子很简单,里面的注释已经表述的比较清楚了:读入了 titanic3.csv 数据集,里面包含了2个数值型特征( age , fare )和3个标称型特征( embarked , sex , pclass ),然后对数值型特征做缺失值处理和归一化,对标称型特征做缺失值处理和One-Hot编码。例子里面使用Pipeline将这些操作串了起来。
我们看下 sklearn.compose.ColumnTransformer
的原型:
class sklearn.compose.ColumnTransformer(transformers, remainder=’drop’, sparse_threshold=0.3, n_jobs=None, transformer_weights=None)
简单介绍一下 transformers
和 remainder
两个参数:
-
transformers:该参数是一个由元组组成的列表(list of tuples),每个元组的结构为:(name, transformer, column):
- name: transformer的名字,随便起一个字符串即可;
-
transformer: 支持
fit
和transform
的estimator或者passthrough
或者drop
. passthrough表示透传,不对column指定的列做任何转换;drop表示丢弃指定column指定的列。 - column: 指定对哪些列做转换操作,所以可以是下标、列名等。
-
remainder:这个参数的值可以是支持
fit
和transform
的estimator或者passthrough
或者drop
,默认值是drop,其功能和transformers参数非常像:- drop:表示将column指定的列之外的其他列都丢弃;
- passthrough:表示将column指定的列之外的其他列透传;
- estimator:表示对column指定的列之外的其他列执行该estimator代表的转换。
新功能的使用还是非常容易的。
OneHotEncoder
scikit-learn 0.20版本里面另外一个比较重要的改动就是 sklearn.preprocessing.OneHotEncoder
除了支持整数外,还支持字符串。这样如果特征是字符串,就省去了原来需要做 sklearn.preprocessing.LabelEncoder
的步骤。
老的 sklearn.preprocessing.OneHotEncoder
原型:
class sklearn.preprocessing.OneHotEncoder(n_values=’auto’, categorical_features=’all’, dtype=<class ‘numpy.float64’>, sparse=True, handle_unknown=’error’)
新的 sklearn.preprocessing.OneHotEncoder
原型:
class sklearn.preprocessing.OneHotEncoder(n_values=None, categorical_features=None, categories=None, sparse=True, dtype=<class ‘numpy.float64’>, handle_unknown=’error’)
可以看到新老API的主要差别是新API增加了一个 categories
参数,这个参数是为了替换里面的 n_values
参数;后者在0.22版本中就去掉了。而且如果要OneHotEncoder支持字符串的话,就必须使用 categories
,不能使用 n_values
了。我们简单介绍一下 categories
这个参数,该参数的可取值为: 'auto'
( 默认值,表示根据训练数据自己决定categories;)或一个 list of list/array
。前者很容易理解,后者稍微难理解一些,我们通过例子来看。
>>> enc = preprocessing.OneHotEncoder() >>> X = [['male', 'from US', 'uses Safari'], ['female', 'from Europe', 'uses Firefox']] >>> enc.fit(X) OneHotEncoder(categorical_features=None, categories=None, dtype=<... 'numpy.float64'>, handle_unknown='error', n_values=None, sparse=True) >>> enc.transform([['female', 'from US', 'uses Safari'], ... ['male', 'from Europe', 'uses Safari']]).toarray() array([[1., 0., 0., 1., 0., 1.], [0., 1., 1., 0., 0., 1.]]) # 可以通过categories_属性查看所有类别 >>> enc.categories_ [array(['female', 'male'], dtype=object), array(['from Europe', 'from US'], dtype=object), array(['uses Firefox', 'uses Safari'], dtype=object)]
上例中, categories
采用默认值,如果我们需要使用list实现等效的效果的话,可以按照如下方式改写上面代码:
>>> enc_new = preprocessing.OneHotEncoder(categories=[['male', 'female'],['from Europe', 'from US'],['uses Firefox', 'uses Safari']]) >>> enc_new.fit(X) OneHotEncoder(categorical_features=None, categories=[['male', 'female'], ['from Europe', 'from US'], ['uses Firefox', 'uses Safari']], dtype=<class 'numpy.float64'>, handle_unknown='error', n_values=None, sparse=True) >>> enc_new.transform([['female', 'from US', 'uses Safari'], ... ['male', 'from Europe', 'uses Safari']]).toarray() array([[1., 0., 0., 1., 0., 1.], [0., 1., 1., 0., 0., 1.]]) >>> enc_new.categories_ [array(['male', 'female'], dtype=object), array(['from US', 'from Europe'], dtype=object), array(['uses Safari', 'uses Firefox'], dtype=object)]
例子已经展示的很清楚了, categories
的值取list of list/array时候,里面的 categories[i]
表示第i列特征的categories。同时需要注意:**在单个特征的list/array里面,其值要么是numeric要么是string,不能混用;如果是numeric,还需要是 排序 的。
Reference:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Introduction to Semi-Supervised Learning
Xiaojin Zhu、Andrew B. Goldberg / Morgan and Claypool Publishers / 2009-6-29 / USD 40.00
Semi-supervised learning is a learning paradigm concerned with the study of how computers and natural systems such as humans learn in the presence of both labeled and unlabeled data. Traditionally, le......一起来看看 《Introduction to Semi-Supervised Learning》 这本书的介绍吧!