Start

In this guide, we’ll show how you can use EvalML to automatically find the best pipeline for predicting whether a patient has breast cancer. Along the way, we’ll highlight EvalML’s built-in tools and features for understanding and interacting with the search process.

[1]:
import evalml
from evalml import AutoMLSearch

First, we load in the features and outcomes we want to use to train our model.

[2]:
X, y = evalml.demos.load_breast_cancer()

EvalML has many options to configure the pipeline search. At the minimum, we need to define an objective function. For simplicity, we will use the F1 score in this example. However, the real power of EvalML is in using domain-specific objective functions or building your own.

Below EvalML utilizes Bayesian optimization (EvalML’s default optimizer) to search and find the best pipeline defined by the given objective.

EvalML provides a number of parameters to control the search process. max_batches is one of the parameters which controls the stopping criterion for the AutoML search. It indicates the maximum number of rounds of AutoML to evaluate, where each round may train and score a variable number of pipelines. In this example, max_batches is set to 1.

** Graphing methods, like AutoMLSearch, on Jupyter Notebook and Jupyter Lab require ipywidgets to be installed.

** If graphing on Jupyter Lab, jupyterlab-plotly required. To download this, make sure you have npm installed.

[3]:
automl = AutoMLSearch(problem_type="binary", objective="f1", max_batches=1)

In order to validate the results of the pipeline creation and optimization process, we will save some of our data as a holdout set.

[4]:
X_train, X_holdout, y_train, y_holdout = evalml.preprocessing.split_data(X, y, test_size=.2)

To provide data to EvalML, it is recommended that you create a DataTable object using the Woodwork project.

EvalML also accepts and works well with pandas DataFrames. But using the DataTable makes it easy to control how EvalML will treat each feature, as a numeric feature, a categorical feature, a text feature or other type of feature. Woodwork’s DataTable includes features like inferring when a categorical feature should be treated as a text feature. For this reason, if you don’t provide Woodwork objects, EvalML will raise a warning.

[5]:
import woodwork as ww
X_train_dt = ww.DataTable(X_train)
y_train_dc = ww.DataColumn(y_train)

When we call search(), the search for the best pipeline will begin. There is no need to wrangle with missing data or categorical variables as EvalML includes various preprocessing steps (like imputation, one-hot encoding, feature selection) to ensure you’re getting the best results. As long as your data is in a single table, EvalML can handle it. If not, you can reduce your data to a single table by utilizing Featuretools and its Entity Sets.

You can find more information on pipeline components and how to integrate your own custom pipelines into EvalML here.

[6]:
automl.search(X_train_dt, y_train_dc)
Generating pipelines to search over...
*****************************
* Beginning pipeline search *
*****************************

Optimizing for F1.
Greater score is better.

Searching up to 1 batches for a total of 9 pipelines.
Allowed model families: linear_model, extra_trees, random_forest, decision_tree, xgboost, catboost, lightgbm

Batch 1: (1/9) Mode Baseline Binary Classification P... Elapsed:00:00
        Starting cross validation
        Finished cross validation - mean F1: 0.000
Batch 1: (2/9) Decision Tree Classifier w/ Imputer      Elapsed:00:00
        Starting cross validation
        Finished cross validation - mean F1: 0.902
Batch 1: (3/9) LightGBM Classifier w/ Imputer           Elapsed:00:00
        Starting cross validation
        Finished cross validation - mean F1: 0.943
Batch 1: (4/9) Extra Trees Classifier w/ Imputer        Elapsed:00:01
        Starting cross validation
        Finished cross validation - mean F1: 0.927
Batch 1: (5/9) Elastic Net Classifier w/ Imputer + S... Elapsed:00:02
        Starting cross validation
        Finished cross validation - mean F1: 0.611
Batch 1: (6/9) CatBoost Classifier w/ Imputer           Elapsed:00:02
        Starting cross validation
        Finished cross validation - mean F1: 0.918
Batch 1: (7/9) XGBoost Classifier w/ Imputer            Elapsed:00:03
        Starting cross validation
        Finished cross validation - mean F1: 0.958
Batch 1: (8/9) Random Forest Classifier w/ Imputer      Elapsed:00:03
        Starting cross validation
        Finished cross validation - mean F1: 0.949
Batch 1: (9/9) Logistic Regression Classifier w/ Imp... Elapsed:00:05
        Starting cross validation
        Finished cross validation - mean F1: 0.961

Search finished after 00:07
Best pipeline: Logistic Regression Classifier w/ Imputer + Standard Scaler
Best pipeline F1: 0.961064

After the search is finished we can view all of the pipelines searched, ranked by score. Internally, EvalML performs cross validation to score the pipelines. If it notices a high variance across cross validation folds, it will warn you. EvalML also provides additional data checks to analyze your data to assist you in producing the best performing pipeline.

[7]:
automl.rankings
[7]:
id pipeline_name score validation_score percent_better_than_baseline high_variance_cv parameters
0 8 Logistic Regression Classifier w/ Imputer + St... 0.961064 0.973451 NaN False {'Imputer': {'categorical_impute_strategy': 'm...
1 6 XGBoost Classifier w/ Imputer 0.958438 0.982456 NaN False {'Imputer': {'categorical_impute_strategy': 'm...
2 7 Random Forest Classifier w/ Imputer 0.949047 0.954955 NaN False {'Imputer': {'categorical_impute_strategy': 'm...
3 2 LightGBM Classifier w/ Imputer 0.942557 0.936937 NaN False {'Imputer': {'categorical_impute_strategy': 'm...
4 3 Extra Trees Classifier w/ Imputer 0.926529 0.936937 NaN False {'Imputer': {'categorical_impute_strategy': 'm...
5 5 CatBoost Classifier w/ Imputer 0.917976 0.924528 NaN False {'Imputer': {'categorical_impute_strategy': 'm...
6 1 Decision Tree Classifier w/ Imputer 0.901777 0.885246 NaN False {'Imputer': {'categorical_impute_strategy': 'm...
7 4 Elastic Net Classifier w/ Imputer + Standard S... 0.611155 0.626506 NaN False {'Imputer': {'categorical_impute_strategy': 'm...
8 0 Mode Baseline Binary Classification Pipeline 0.000000 0.000000 NaN False {'Baseline Classifier': {'strategy': 'mode'}}

If we are interested in see more details about the pipeline, we can view a summary description using the id from the rankings table:

[8]:
automl.describe_pipeline(3)
*************************************
* Extra Trees Classifier w/ Imputer *
*************************************

Problem Type: binary
Model Family: Extra Trees

Pipeline Steps
==============
1. Imputer
         * categorical_impute_strategy : most_frequent
         * numeric_impute_strategy : mean
         * categorical_fill_value : None
         * numeric_fill_value : None
2. Extra Trees Classifier
         * n_estimators : 100
         * max_features : auto
         * max_depth : 6
         * min_samples_split : 2
         * min_weight_fraction_leaf : 0.0
         * n_jobs : -1

Training
========
Training for binary problems.
Total training time (including CV): 1.3 seconds

Cross Validation
----------------
               F1  MCC Binary  Log Loss Binary   AUC  Precision  Balanced Accuracy Binary  Accuracy Binary # Training # Testing
0           0.937       0.902            0.131 0.996      0.963                     0.946            0.954    303.000   152.000
1           0.897       0.846            0.165 0.987      0.960                     0.911            0.928    303.000   152.000
2           0.945       0.915            0.138 0.997      0.963                     0.954            0.960    304.000   151.000
mean        0.927       0.887            0.144 0.994      0.962                     0.937            0.947          -         -
std         0.026       0.036            0.018 0.005      0.002                     0.023            0.017          -         -
coef of var 0.028       0.041            0.124 0.005      0.002                     0.025            0.018          -         -

We can also view the pipeline parameters directly:

[9]:
pipeline = automl.get_pipeline(3)
print(pipeline.parameters)
{'Imputer': {'categorical_impute_strategy': 'most_frequent', 'numeric_impute_strategy': 'mean', 'categorical_fill_value': None, 'numeric_fill_value': None}, 'Extra Trees Classifier': {'n_estimators': 100, 'max_features': 'auto', 'max_depth': 6, 'min_samples_split': 2, 'min_weight_fraction_leaf': 0.0, 'n_jobs': -1}}

We can now select the best pipeline and score it on our holdout data:

[10]:
pipeline = automl.best_pipeline
pipeline.fit(X_train, y_train)
pipeline.score(X_holdout, y_holdout, ["f1"])
[10]:
OrderedDict([('F1', 0.9879518072289156)])

We can also visualize the structure of the components contained by the pipeline:

[11]:
pipeline.graph()
[11]:
_images/start_22_0.svg