组件#
组件是 EvalML 中最低级别的构建块。每个组件代表一个应用于数据的基本操作。
所有组件都接受参数作为其 __init__
方法的关键字参数。这些参数可用于配置行为。
每个组件类定义都必须包含一个人类可读的组件 name
。此外,每个组件类可以通过定义一个包含相关参数的 hyperparameter_ranges
属性来暴露用于 AutoML 搜索的参数。
EvalML 将组件分为两类:转换器 (transformers) 和 估计器 (estimators)。
转换器 (Transformers)#
转换器继承自 Transformer
类,并定义了一个 fit
方法来从训练数据中学习信息,以及一个 transform
方法将学习到的转换应用于新数据。
例如,一个 填充器 (imputer) 配置了所需的填充策略,例如均值。填充器的 fit
方法会从训练数据中学习均值,而 transform
方法会将学习到的均值填充到新数据中的任何缺失值处。
所有转换器都可以单独执行 fit
和 transform
,或者通过调用 fit_transform
在一步中完成。在某些情况下,定义自定义的 fit_transform
方法可以实现有用的性能优化。
[1]:
import numpy as np
import pandas as pd
from evalml.pipelines.components import SimpleImputer
X = pd.DataFrame([[1, 2, 3], [1, np.nan, 3]])
display(X)
0 | 1 | 2 | |
---|---|---|---|
0 | 1 | 2.0 | 3 |
1 | 1 | NaN | 3 |
[2]:
import woodwork as ww
imp = SimpleImputer(impute_strategy="mean")
X.ww.init()
X = imp.fit_transform(X)
display(X)
0 | 1 | 2 | |
---|---|---|---|
0 | 1 | 2.0 | 3 |
1 | 1 | 2.0 | 3 |
下面是 EvalML 中包含的所有转换器的列表
[3]:
from evalml.pipelines.components.utils import all_components, Estimator, Transformer
for component in all_components():
if issubclass(component, Transformer):
print(f"Transformer: {component.name}")
Transformer: Time Series Regularizer
Transformer: Drop NaN Rows Transformer
Transformer: Replace Nullable Types Transformer
Transformer: Drop Rows Transformer
Transformer: URL Featurizer
Transformer: Email Featurizer
Transformer: Log Transformer
Transformer: STL Decomposer
Transformer: Polynomial Decomposer
Transformer: DFS Transformer
Transformer: Time Series Featurizer
Transformer: Natural Language Featurizer
Transformer: LSA Transformer
Transformer: Drop Null Columns Transformer
Transformer: DateTime Featurizer
Transformer: PCA Transformer
Transformer: Linear Discriminant Analysis Transformer
Transformer: Select Columns By Type Transformer
Transformer: Select Columns Transformer
Transformer: Drop Columns Transformer
Transformer: Oversampler
Transformer: Undersampler
Transformer: Standard Scaler
Transformer: Time Series Imputer
Transformer: Target Imputer
Transformer: Imputer
Transformer: KNN Imputer
Transformer: Per Column Imputer
Transformer: Simple Imputer
Transformer: RFE Selector with RF Regressor
Transformer: RFE Selector with RF Classifier
Transformer: RF Regressor Select From Model
Transformer: RF Classifier Select From Model
Transformer: Ordinal Encoder
Transformer: Label Encoder
Transformer: Target Encoder
Transformer: One Hot Encoder
估计器 (Estimators)#
每个估计器封装了一个机器学习算法。估计器继承自 Estimator
类,并定义了一个 fit
方法来从训练数据中学习信息,以及一个 predict
方法用于从新数据生成预测。分类估计器还应该定义一个 predict_proba
方法用于生成预测概率。
每个估计器类都定义了一个 model_family
属性,指示使用了哪种类型的模型。
这里是一个使用 LogisticRegressionClassifier 估计器在简单数据集上进行拟合和预测的示例
[4]:
from evalml.pipelines.components import LogisticRegressionClassifier
clf = LogisticRegressionClassifier()
X = X
y = [1, 0]
clf.fit(X, y)
clf.predict(X)
[4]:
0 0
1 0
dtype: int64
下面是 EvalML 中包含的所有估计器的列表
[5]:
from evalml.pipelines.components.utils import all_components, Estimator, Transformer
for component in all_components():
if issubclass(component, Estimator):
print(f"Estimator: {component.name}")
Estimator: Stacked Ensemble Regressor
Estimator: Stacked Ensemble Classifier
Estimator: VARMAX Regressor
Estimator: ARIMA Regressor
Estimator: Exponential Smoothing Regressor
Estimator: SVM Regressor
Estimator: Prophet Regressor
Estimator: Multiseries Time Series Baseline Regressor
Estimator: Time Series Baseline Estimator
Estimator: Decision Tree Regressor
Estimator: Baseline Regressor
Estimator: Extra Trees Regressor
Estimator: XGBoost Regressor
Estimator: CatBoost Regressor
Estimator: Random Forest Regressor
Estimator: LightGBM Regressor
Estimator: Linear Regressor
Estimator: Elastic Net Regressor
Estimator: SVM Classifier
Estimator: KNN Classifier
Estimator: Decision Tree Classifier
Estimator: LightGBM Classifier
Estimator: Baseline Classifier
Estimator: Extra Trees Classifier
Estimator: Elastic Net Classifier
Estimator: CatBoost Classifier
Estimator: XGBoost Classifier
Estimator: Random Forest Classifier
Estimator: Logistic Regression Classifier
定义自定义组件#
通过遵循以下步骤,EvalML 允许您轻松创建自己的自定义组件。
自定义转换器#
您的转换器必须继承自正确的子类。在本例中,对于转换数据的组件,应继承自 Transformer。接下来我们将使用 EvalML 的 DropNullColumns 作为示例。
[6]:
from evalml.pipelines.components import Transformer
from evalml.utils import (
infer_feature_types,
)
class DropNullColumns(Transformer):
"""Transformer to drop features whose percentage of NaN values exceeds a specified threshold"""
name = "Drop Null Columns Transformer"
hyperparameter_ranges = {}
def __init__(self, pct_null_threshold=1.0, random_seed=0, **kwargs):
"""Initalizes an transformer to drop features whose percentage of NaN values exceeds a specified threshold.
Args:
pct_null_threshold(float): The percentage of NaN values in an input feature to drop.
Must be a value between [0, 1] inclusive. If equal to 0.0, will drop columns with any null values.
If equal to 1.0, will drop columns with all null values. Defaults to 0.95.
"""
if pct_null_threshold < 0 or pct_null_threshold > 1:
raise ValueError(
"pct_null_threshold must be a float between 0 and 1, inclusive."
)
parameters = {"pct_null_threshold": pct_null_threshold}
parameters.update(kwargs)
self._cols_to_drop = None
super().__init__(
parameters=parameters, component_obj=None, random_seed=random_seed
)
def fit(self, X, y=None):
"""Fits DropNullColumns component to data
Args:
X (pd.DataFrame): The input training data of shape [n_samples, n_features]
y (pd.Series, optional): The target training data of length [n_samples]
Returns:
self
"""
pct_null_threshold = self.parameters["pct_null_threshold"]
X_t = infer_feature_types(X)
percent_null = X_t.isnull().mean()
if pct_null_threshold == 0.0:
null_cols = percent_null[percent_null > 0]
else:
null_cols = percent_null[percent_null >= pct_null_threshold]
self._cols_to_drop = list(null_cols.index)
return self
def transform(self, X, y=None):
"""Transforms data X by dropping columns that exceed the threshold of null values.
Args:
X (pd.DataFrame): Data to transform
y (pd.Series, optional): Ignored.
Returns:
pd.DataFrame: Transformed X
"""
X_t = infer_feature_types(X)
return X_t.drop(self._cols_to_drop)
必需字段#
name
: 人类可读的名称。modifies_features
: 一个布尔值,指定此组件在transform
期间是否修改(子集化或转换)特征变量。modifies_target
: 一个布尔值,指定此组件在transform
期间是否修改(子集化或转换)目标变量。
必需方法#
同样,由于 Transformer
是一个抽象基类,您需要重写一些方法
__init__()
: 您的转换器的__init__()
方法需要调用super().__init__()
并传入三个参数:一个包含组件参数的parameters
字典、component_obj
和random_seed
值。您可以看到上面component_obj
设置为None
,我们稍后将深入讨论component_obj
。fit()
:fit()
方法负责在训练数据上拟合您的组件。它应该返回组件对象。transform()
: 拟合组件后,transform()
方法将接收新数据并进行相应的转换。它应该返回一个初始化了 woodwork 的 pandas 数据框。注意:组件必须先调用fit()
,然后才能调用transform()
。
您也可以调用或重写将 fit()
和 transform()
合并到一个方法中的 fit_transform()
。
自定义估计器#
您的估计器必须继承自正确的子类。在本例中,对于预测新目标值的组件,应继承自 Estimator。接下来我们将使用 EvalML 的 BaselineRegressor 作为示例。
[7]:
import numpy as np
import pandas as pd
from evalml.model_family import ModelFamily
from evalml.pipelines.components.estimators import Estimator
from evalml.problem_types import ProblemTypes
class BaselineRegressor(Estimator):
"""Regressor that predicts using the specified strategy.
This is useful as a simple baseline regressor to compare with other regressors.
"""
name = "Baseline Regressor"
hyperparameter_ranges = {}
model_family = ModelFamily.BASELINE
supported_problem_types = [
ProblemTypes.REGRESSION,
ProblemTypes.TIME_SERIES_REGRESSION,
]
def __init__(self, strategy="mean", random_seed=0, **kwargs):
"""Baseline regressor that uses a simple strategy to make predictions.
Args:
strategy (str): Method used to predict. Valid options are "mean", "median". Defaults to "mean".
random_seed (int): Seed for the random number generator. Defaults to 0.
"""
if strategy not in ["mean", "median"]:
raise ValueError(
"'strategy' parameter must equal either 'mean' or 'median'"
)
parameters = {"strategy": strategy}
parameters.update(kwargs)
self._prediction_value = None
self._num_features = None
super().__init__(
parameters=parameters, component_obj=None, random_seed=random_seed
)
def fit(self, X, y=None):
if y is None:
raise ValueError("Cannot fit Baseline regressor if y is None")
X = infer_feature_types(X)
y = infer_feature_types(y)
if self.parameters["strategy"] == "mean":
self._prediction_value = y.mean()
elif self.parameters["strategy"] == "median":
self._prediction_value = y.median()
self._num_features = X.shape[1]
return self
def predict(self, X):
X = infer_feature_types(X)
predictions = pd.Series([self._prediction_value] * len(X))
return infer_feature_types(predictions)
@property
def feature_importance(self):
"""Returns importance associated with each feature. Since baseline regressors do not use input features to calculate predictions, returns an array of zeroes.
Returns:
np.ndarray (float): An array of zeroes
"""
return np.zeros(self._num_features)
必需字段#
name
: 人类可读的名称。model_family
- 此组件所属的 EvalML 模型族 (model_family)supported_problem_types
- 此组件支持的 EvalML 问题类型 (problem_types) 列表modifies_features
: 一个布尔值,指定是否应将predict
或predict_proba
的返回值用作特征。modifies_target
: 一个布尔值,指定是否应将predict
或predict_proba
的返回值用作目标变量。
模型族和问题类型包括
[8]:
from evalml.model_family import ModelFamily
from evalml.problem_types import ProblemTypes
print("Model Families:\n", [m.value for m in ModelFamily])
print("Problem Types:\n", [p.value for p in ProblemTypes])
Model Families:
['k_neighbors', 'random_forest', 'svm', 'xgboost', 'lightgbm', 'linear_model', 'catboost', 'extra_trees', 'ensemble', 'decision_tree', 'exponential_smoothing', 'arima', 'varmax', 'baseline', 'prophet', 'vowpal_wabbit', 'none']
Problem Types:
['binary', 'multiclass', 'regression', 'time series regression', 'time series binary', 'time series multiclass', 'multiseries time series regression']
必需方法#
__init__()
- 您的估计器的__init__()
方法需要调用super().__init__()
并传入三个参数:一个包含组件参数的parameters
字典、component_obj
和random_seed
值。fit()
-fit()
方法负责在训练数据上拟合您的组件。predict()
- 拟合组件后,predict()
方法将接收新数据并预测新的目标值。注意:组件必须先调用fit()
,然后才能调用predict()
。feature_importance
-feature_importance
是一个 Python property,它返回与每个特征相关的特征重要性列表。
如果您的估计器处理分类问题,它还需要一个额外的方法
predict_proba()
- 此方法预测分类标签的概率估计值
封装第三方对象的组件#
component_obj
参数用于封装第三方对象并在组件实现中使用它们。如果您使用 component_obj
,您需要定义 __init__()
并传入也实现了上述必需方法的相关对象。但是,如果 component_obj
不遵循 EvalML 组件约定,您可能需要根据需要重写方法。下面是 EvalML 的 LinearRegressor 示例。
[9]:
from sklearn.linear_model import LinearRegression as SKLinearRegression
from evalml.model_family import ModelFamily
from evalml.pipelines.components.estimators import Estimator
from evalml.problem_types import ProblemTypes
class LinearRegressor(Estimator):
"""Linear Regressor."""
name = "Linear Regressor"
model_family = ModelFamily.LINEAR_MODEL
supported_problem_types = [ProblemTypes.REGRESSION]
def __init__(
self, fit_intercept=True, normalize=False, n_jobs=-1, random_seed=0, **kwargs
):
parameters = {
"fit_intercept": fit_intercept,
"normalize": normalize,
"n_jobs": n_jobs,
}
parameters.update(kwargs)
linear_regressor = SKLinearRegression(**parameters)
super().__init__(
parameters=parameters,
component_obj=linear_regressor,
random_seed=random_seed,
)
@property
def feature_importance(self):
return self._component_obj.coef_
AutoML 的超参数范围#
hyperparameter_ranges
是一个字典,将参数名 (str) 映射到该参数的允许范围 (SkOpt Space)。对于类别空间,接受列表和 skopt.space.Categorical
值。
AutoML 将在每个参数的允许范围内执行搜索,以选择在这些范围内产生最佳性能的模型。AutoML 从组件的 hyperparameter_ranges
类属性中获取每个组件的允许范围。您在 hyperparameter_ranges
中为其添加条目的任何组件参数都将包含在 AutoML 搜索中。如果省略参数,AutoML 将在所有流水线中使用默认值。
生成组件代码#
在 EvalML 中定义组件后,您可以生成字符串 Python 代码来重新创建此组件,然后可以将其保存并在其他地方使用 EvalML 运行。generate_component_code
需要一个组件实例作为输入。此方法也适用于自定义组件,但它不会返回定义自定义组件所需的代码。
[10]:
from evalml.pipelines.components import LogisticRegressionClassifier
from evalml.pipelines.components.utils import generate_component_code
lr = LogisticRegressionClassifier(C=5)
code = generate_component_code(lr)
print(code)
from evalml.pipelines.components.estimators.classifiers.logistic_regression_classifier import LogisticRegressionClassifier
logisticRegressionClassifier = LogisticRegressionClassifier(**{'penalty': 'l2', 'C': 5, 'n_jobs': -1, 'multi_class': 'auto', 'solver': 'lbfgs'})
[11]:
# this string can then be copy and pasted into a separate window and executed as python code
exec(code)
[12]:
# We can also do this for custom components
from evalml.pipelines.components.utils import generate_component_code
myDropNull = DropNullColumns()
print(generate_component_code(myDropNull))
dropNullColumnsTransformer = DropNullColumns(**{'pct_null_threshold': 1.0})
自定义分类组件的期望#
EvalML 对自定义分类组件的实现有以下期望
分类目标范围为 0 到 n-1,并且是整数。
对于分类估计器,
predict_proba
的列顺序必须与目标的顺序匹配,并且列名必须是 0 到 n-1 的整数。