Jam*_*ong 12 python scikit-learn
我很困惑,因为如果你第一次这样做会成为一个问题OneHotEncoder然后StandardScaler因为缩放器也将缩放之前转换过的列OneHotEncoder.有没有办法同时执行编码和缩放,然后将结果连接在一起?
Max*_*wer 17
当然可以.只需根据需要单独缩放和单独编码单独的列:
# Import libraries and download example data
from sklearn.preprocessing import StandardScaler, OneHotEncoder
dataset = pd.read_csv("https://stats.idre.ucla.edu/stat/data/binary.csv")
print(dataset.head(5))
# Define which columns should be encoded vs scaled
columns_to_encode = ['rank']
columns_to_scale = ['gre', 'gpa']
# Instantiate encoder/scaler
scaler = StandardScaler()
ohe = OneHotEncoder(sparse=False)
# Scale and Encode Separate Columns
scaled_columns = scaler.fit_transform(dataset[columns_to_scale])
encoded_columns = ohe.fit_transform(dataset[columns_to_encode])
# Concatenate (Column-Bind) Processed Columns Back Together
processed_data = np.concatenate([scaled_columns, encoded_columns], axis=1)
Run Code Online (Sandbox Code Playgroud)
0.20 版的 Scikit-learn 提供sklearn.compose.ColumnTransformer了使用 Mixed Types来做Column Transformer。您可以缩放数字特征并将分类特征进行单热编码。以下是官方示例(您可以在此处找到代码):
# 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))
Run Code Online (Sandbox Code Playgroud)
注意:此方法是实验性的,在不弃用的情况下,某些行为可能会在不同版本之间发生变化。
目前有多种方法可以实现 OP 所需的结果。有 3 种方法可以做到这一点
np.concatenate()- 请参阅已发布的OP问题的答案
使用@Max Power在这里发布的示例,下面是一个最小的工作片段,它执行OP正在寻找的操作,并将转换后的列汇集到单个 Pandas 数据框中。显示了所有 3 种方法的输出
所有 3 种方法的通用代码是
import numpy as np
import pandas as pd
# Import libraries and download example data
from sklearn.preprocessing import StandardScaler, OneHotEncoder
dataset = pd.read_csv("https://stats.idre.ucla.edu/stat/data/binary.csv")
# Define which columns should be encoded vs scaled
columns_to_encode = ['rank']
columns_to_scale = ['gre', 'gpa']
# Instantiate encoder/scaler
scaler = StandardScaler()
ohe = OneHotEncoder(sparse=False)
Run Code Online (Sandbox Code Playgroud)
方法1.看这里的代码。要显示输出,可以使用
print(pd.DataFrame(processed_data).head())
Run Code Online (Sandbox Code Playgroud)
方法 1 的输出。
0 1 2 3 4 5
0 -1.800263 0.579072 0.0 0.0 1.0 0.0
1 0.626668 0.736929 0.0 0.0 1.0 0.0
2 1.840134 1.605143 1.0 0.0 0.0 0.0
3 0.453316 -0.525927 0.0 0.0 0.0 1.0
4 -0.586797 -1.209974 0.0 0.0 0.0 1.0
Run Code Online (Sandbox Code Playgroud)
方法2.
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
p = Pipeline(
[("coltransformer", ColumnTransformer(
transformers=[
("assessments", Pipeline([("scale", scaler)]), columns_to_scale),
("ranks", Pipeline([("encode", ohe)]), columns_to_encode),
]),
)]
)
print(pd.DataFrame(p.fit_transform(dataset)).head())
Run Code Online (Sandbox Code Playgroud)
方法 2 的输出。
0 1 2 3 4 5
0 -1.800263 0.579072 0.0 0.0 1.0 0.0
1 0.626668 0.736929 0.0 0.0 1.0 0.0
2 1.840134 1.605143 1.0 0.0 0.0 0.0
3 0.453316 -0.525927 0.0 0.0 0.0 1.0
4 -0.586797 -1.209974 0.0 0.0 0.0 1.0
Run Code Online (Sandbox Code Playgroud)
方法3.
from sklearn.pipeline import Pipeline
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.pipeline import FeatureUnion
class ItemSelector(BaseEstimator, TransformerMixin):
def __init__(self, key):
self.key = key
def fit(self, x, y=None):
return self
def transform(self, df):
return df[self.key]
p = Pipeline([("union", FeatureUnion(
transformer_list=[
("assessments", Pipeline([
("selector", ItemSelector(key=columns_to_scale)),
("scale", scaler)
]),
),
("ranks", Pipeline([
("selector", ItemSelector(key=columns_to_encode)),
("encode", ohe)
]),
),
]))
])
print(pd.DataFrame(p.fit_transform(dataset)).head())
Run Code Online (Sandbox Code Playgroud)
方法 3 的输出。
0 1 2 3 4 5
0 -1.800263 0.579072 0.0 0.0 1.0 0.0
1 0.626668 0.736929 0.0 0.0 1.0 0.0
2 1.840134 1.605143 1.0 0.0 0.0 0.0
3 0.453316 -0.525927 0.0 0.0 0.0 1.0
4 -0.586797 -1.209974 0.0 0.0 0.0 1.0
Run Code Online (Sandbox Code Playgroud)
解释
方法1.已经解释过了。
方法 2. 和 3. 接受完整数据集,但仅对数据子集执行特定操作。修改/处理的子集被汇集(组合)成最终输出。
细节
pandas==0.23.4
numpy==1.15.2
scikit-learn==0.20.0
Run Code Online (Sandbox Code Playgroud)
补充笔记
这里显示的 3 种方法可能不是唯一的可能性......我确信还有其他方法可以做到这一点。
使用的来源
| 归档时间: |
|
| 查看次数: |
9737 次 |
| 最近记录: |