Building models with scikit-learn

On this page
  1. The one idea: everything is an estimator
  2. Preprocessing belongs inside the pipeline
  3. Scores: accuracy is the wrong one here
  4. Cross-validation: do not shuffle time
  5. Grid search, on the right splitter
  6. Inspection: what did it learn?
  7. Saving the model
  8. Where it stops
  9. Why banks use it
  10. Summary
  11. References

scikit-learn is where machine learning on a table of numbers happens in Python. Linear models, trees, forests, boosting, support-vector machines, clustering, dimensionality reduction, and around them the parts that matter more than the algorithm: preprocessing, cross-validation, hyperparameter search, metrics. It began as a Google Summer of Code project in 2007 and became what it is when a group at INRIA in France took it over in 2010 (about). The Python stack post placed it among its neighbours; this post is about using it well.

The example is the one the Machine Learning Series 1 used: five tickers, daily features computed from prices (recent returns, recent volatility, distance from the moving average), and the question will the next 20 trading days be a stress month, volatility above 30% a year. Train on 2020 to 2023, test on 2024 to 2025. Every number below comes from one script on that data.

The one idea: everything is an estimator

scikit-learn has one interface, and once you know it you know the library. Every object is an estimator: you construct it with its settings (hyperparameters), you call fit(X, y) to learn from data, and afterwards it has learned attributes whose names end in an underscore (coef_, feature_importances_, classes_). Beyond that, three kinds (Table 1):

Table 1. The three kinds of estimator and their methods
KindMethodsExamples
Predictorfit, predict, predict_proba, scoreLogisticRegression, RandomForestClassifier
Transformerfit, transform, fit_transformStandardScaler, OneHotEncoder, SimpleImputer, PCA
Meta-estimatorwraps estimators, exposes the same methodsPipeline, ColumnTransformer, GridSearchCV

The design was a deliberate choice, written up by the core developers in 2013 (Buitinck et al.): a shared interface for every unit, composition over inheritance, and sensible defaults so that a model works before it is tuned. Géron’s Hands-On Machine Learning summarises the same principles as consistency, inspection, non-proliferation of classes, composition and sensible defaults. The practical consequence is that swapping a model is a one-line change, and the code around it (splitting, scaling, scoring, searching) does not care which model it holds.

The code below runs as pasted, in order, in one Python session (pip install numpy pandas scikit-learn). This first block builds the data from the blog’s price file. Each row is one ticker on one trading day; X_train holds the seven features and the ticker, y_train the answer (1 if a stress month followed); X_test and y_test are the same for 2024 to 2025.

import numpy as np
import pandas as pd

URL = "https://raw.githubusercontent.com/ankurtrapasiya/examples/main/data/prices.csv"
prices = pd.read_csv(URL, index_col="date", parse_dates=True)

FEATURES = ["ret_1d", "ret_5d", "ret_20d", "vol_5d", "vol_20d", "sma_ratio", "bollinger"]
rows = []
for ticker in prices.columns:                    # one block of rows per ticker
    p = prices[ticker]
    r = p.pct_change()                           # daily returns
    sma = p.rolling(20).mean()                   # 20-day average price
    rows.append(pd.DataFrame({
        "ret_1d": r, "ret_5d": p / p.shift(5) - 1, "ret_20d": p / p.shift(20) - 1,
        "vol_5d": r.rolling(5).std(), "vol_20d": r.rolling(20).std(),
        "sma_ratio": p / sma - 1, "bollinger": (p - sma) / (2 * p.rolling(20).std()),
        "next_vol": r[::-1].rolling(20).std()[::-1].shift(-1),   # volatility of the NEXT 20 days
        "ticker": ticker,
    }).dropna())
df = pd.concat(rows).rename_axis("date").reset_index().sort_values(["date", "ticker"])
df["stress"] = (df["next_vol"] * np.sqrt(252) * 100 > 30).astype(int)   # 1 = stress month ahead

train, test = df[df["date"] < "2024-01-01"], df[df["date"] >= "2024-01-01"]   # time order
X_train, y_train = train[FEATURES + ["ticker"]], train["stress"]
X_test, y_test = test[FEATURES + ["ticker"]], test["stress"]
print(len(X_train), len(X_test), round(y_train.mean(), 3), round(y_test.mean(), 3))   # 4930 2205 0.368 0.241

It prints 4930 2205 0.368 0.241: the training and test rows, and the share of each with a stress month ahead. r[::-1].rolling(20).std()[::-1].shift(-1) turns the series round, takes the 20-day volatility, and turns it back, which gives the volatility of the next 20 days. Now the four models:

from sklearn.compose import ColumnTransformer
from sklearn.dummy import DummyClassifier
from sklearn.ensemble import HistGradientBoostingClassifier, RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler

def prep():                       # a fresh preprocessor per pipeline (see below)
    return ColumnTransformer([("num", StandardScaler(), FEATURES),
                              ("ticker", OneHotEncoder(handle_unknown="ignore"), ["ticker"])])

models = {
    "always 'calm'": DummyClassifier(strategy="prior"),
    "logistic regression": Pipeline([
        ("prep", prep()), ("model", LogisticRegression(max_iter=1000))]),
    "random forest": Pipeline([
        ("prep", prep()), ("model", RandomForestClassifier(
            n_estimators=300, max_features=3, min_samples_leaf=20, random_state=0))]),
    "gradient boosting": Pipeline([
        ("prep", prep()), ("model", HistGradientBoostingClassifier(
            max_depth=3, learning_rate=0.05, max_iter=200, random_state=0))]),
}
for name, m in models.items():
    m.fit(X_train, y_train)                       # the same two calls for every model
    p = m.predict_proba(X_test)[:, 1]             # chance of a stress month, per test row
    print(f"{name:20} accuracy {m.score(X_test, y_test):.3f}  AUC {roc_auc_score(y_test, p):.3f}")
Table 2. Four models on the test months: accuracy, AUC and average precision
ModelAccuracyAUCAverage precision
Always “calm” (DummyClassifier)0.7590.5000.241
Logistic regression0.8700.8900.824
Random forest0.8740.8930.819
Gradient boosting0.8730.8910.782

Four models, one loop. Two things in Table 2 before going further. First, the dummy classifier that always answers “calm” scores 76% accuracy, because 76% of test rows have a calm month ahead; accuracy is the wrong score for this problem, and the next section says what to use. Second, the plain logistic regression sits within 0.003 of AUC of the random forest, leads all three on average precision, and loses to the tree models on accuracy by 0.003 and 0.004. A linear model with scaled inputs is the baseline to beat. Do not skip it.

Preprocessing belongs inside the pipeline

The ColumnTransformer above scales the seven numeric columns and one-hot encodes the ticker, and the Pipeline glues that to the model. The glue is not there for tidiness. A transformer fitted on the whole dataset has seen the test set. StandardScaler learns a mean and a standard deviation; fit it on all the rows and the test rows’ statistics leak into training. Inside a pipeline, fit runs the scaler on the training rows only and predict reuses those numbers on the test rows, and the same holds inside every cross-validation fold. The same reasoning covers SimpleImputer (the fill value for missing data is learned) and OneHotEncoder (the set of categories is learned; handle_unknown="ignore" is what keeps a ticker that was not in training from crashing prediction).

Two things the library does not do for you:

  • Estimators are stateful, and a pipeline fits its steps in place. The first version of the script built one ColumnTransformer and passed the same object to four pipelines. Each fit refitted it, which was harmless while every pipeline saw the same columns, and then a fifth pipeline fed it rescaled columns and silently broke the other four: their test AUC dropped a dozen points with no error. Build a fresh object per pipeline, or use sklearn.base.clone. Meta-estimators such as GridSearchCV and cross_val_score clone for you; Pipeline does not.
  • Custom steps are a small class. Anything with fit and transform can go in a pipeline; inheriting from BaseEstimator and TransformerMixin gives it fit_transform, get_params and a sensible repr for free. Here is one that turns daily volatility into the yearly percentage the rest of the site quotes, so that the numbers mean something when the model is inspected:
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.pipeline import make_pipeline

class Annualise(BaseEstimator, TransformerMixin):
    def __init__(self, columns=("vol_5d", "vol_20d")):
        self.columns = columns        # stored as given, never changed

    def fit(self, X, y=None):
        return self                   # nothing to learn

    def transform(self, X):
        X = X.copy()                  # never change the caller's table
        X[list(self.columns)] = X[list(self.columns)] * (252 ** 0.5) * 100   # daily -> % a year
        return X

pipe = make_pipeline(Annualise(), prep(), LogisticRegression(max_iter=1000))
pipe.fit(X_train, y_train)
print(round(roc_auc_score(y_test, pipe.predict_proba(X_test)[:, 1]), 3))   # 0.890, as before

It prints 0.890. The constructor stores its arguments untouched; that is the one rule the library’s developer guide insists on, because get_params and set_params (which grid search uses) read and write those attributes by name. The model with this step scores the same 0.890\key{0.890} as before, since the scaler undoes a constant factor; the step is there so that vol_20d reads as “31% a year” rather than “0.0195” when you look inside.

Scores: accuracy is the wrong one here

The confusion matrix of the logistic regression on the test rows, at the default cut-off of 0.5 (Table 3):

Table 3. Confusion matrix of the logistic regression on the test rows
ItemPredicted calmPredicted stress
Actually calm (1,673)1,532141
Actually stress (532)145387

TP, stress cases caughtFN, stress cases missedFP, false alarms

precision=TPTP+FP=387387+141=0.73\text{precision} = \frac{\good{TP}}{\good{TP} + \risk{FP}} = \frac{387}{387 + 141} = 0.73 recall=TPTP+FN=387387+145=0.73\text{recall} = \frac{\good{TP}}{\good{TP} + \bad{FN}} = \frac{387}{387 + 145} = 0.73

When the model says “stress” it is right 73%\key{73\%} of the time, and it catches 73%\key{73\%} of the stress months. The 0.5 cut-off is a default, not a decision. A risk desk that wants to catch most stress months accepts more false alarms and moves the cut-off down. class_weight="balanced" does that at training time by weighting the rare class up: recall rises to 76%\key{76\%} (404 of 532 caught) and precision falls to 69%\key{69\%}, with the AUC unchanged (0.890 both ways), because AUC measures the ranking of the probabilities, not the cut-off. The move is small on this data because stress months are 37% of the training rows, so the classes are not far from balanced before any weighting. That is why the tables here report AUC and average precision, not accuracy alone: both score how well the model separates the classes, whatever cut-off is chosen later. classification_report prints precision, recall and F1 per class in one call; use it before quoting an accuracy.

{"panels":[{"x0":58.04,"x1":555.72,"y0":29.16,"y1":196.67,"title":"1. Cross-validated AUC on 2020-2023, shuffled folds vs time-ordered folds","xlabel":"Validation fold (1 to 5)","ylabel":"AUC on the validation fold (0.5 = coin flip)","xlog":false},{"x0":58.04,"x1":555.72,"y0":342.26,"y1":509.77,"title":"2. Grid search: validation AUC for each learning rate and tree depth","xlabel":"Learning rate (log scale)","ylabel":"Mean validation AUC over 5 time-ordered folds","xlog":true},{"x0":58.04,"x1":555.72,"y0":655.37,"y1":822.88,"title":"3. ROC curves on the 2024-2025 test months","xlabel":"Calm months wrongly flagged as stress (% of calm months)","ylabel":"Stress months caught (% of stress months)","xlog":false}],"series":[{"panel":0,"label":"KFold, shuffled (future rows leak into training)","color":"var(--chart-amber, #c0781a)","kind":"line","x":[1.0,2.0,3.0,4.0,5.0],"y":[0.91906,0.946535,0.920138,0.923201,0.935283],"sx":[80.66,193.77,306.88,419.99,533.1],"sy":[103.92,61.47,102.25,97.52,78.85]},{"panel":0,"label":"TimeSeriesSplit (train on the past, validate on what follows)","color":"var(--chart-maroon, #b6262c)","kind":"line","x":[1.0,2.0,3.0,4.0,5.0],"y":[0.875533,0.900147,0.863956,0.894029,0.962518],"sx":[80.66,193.77,306.88,419.99,533.1],"sy":[171.17,133.14,189.05,142.59,36.77]},{"panel":0,"label":"the real test, 2024-2025","color":"var(--chart-blue, #3b6ea5)","kind":"line","x":[0.0,1.0],"y":[0.890645,0.890645],"sx":[-32.44,80.66],"sy":[147.82,147.82]},{"panel":1,"label":"trees of depth 2","color":"var(--chart-grey, #a3a19c)","kind":"line","x":[0.01,0.03,0.1,0.3],"y":[0.905462,0.907276,0.900742,0.889586],"sx":[80.66,226.8,386.96,533.1],"sy":[377.97,366.1,408.84,481.8]},{"panel":1,"label":"trees of depth 3","color":"var(--chart-maroon, #b6262c)","kind":"line","x":[0.01,0.03,0.1,0.3],"y":[0.909757,0.901306,0.89606,0.886829],"sx":[80.66,226.8,386.96,533.1],"sy":[349.88,405.15,439.45,499.83]},{"panel":1,"label":"trees of depth 5","color":"var(--chart-blue, #3b6ea5)","kind":"line","x":[0.01,0.03,0.1,0.3],"y":[0.897413,0.896941,0.890957,0.886473],"sx":[80.66,226.8,386.96,533.1],"sy":[430.61,433.69,472.83,502.16]},{"panel":2,"label":"logistic regression (AUC 0.890)","color":"var(--chart-purple, #7c5fd3)","kind":"line","x":[0.0,0.0,0.0,0.0597729,0.0597729,0.119546,0.119546,0.179319,0.179319,0.239091,0.239091,0.298864,0.298864,0.358637,0.358637,0.41841,0.41841,0.478183,0.478183,0.537956,0.537956,0.657501,0.657501,0.717274,0.717274,0.83682,0.83682,0.896593,0.896593,1.07591,1.07591,1.13568,1.13568,1.25523,1.25523,1.315,1.315,1.37478,1.37478,1.43455,1.43455,1.49432,1.49432,1.55409,1.55409,1.67364,1.67364,1.79319,1.79319,1.85296,1.85296,1.9725,1.9725,2.03228,2.03228,2.27137,2.27137,2.33114,2.33114,2.45069,2.45069,2.51046,2.51046,2.63001,2.63001,2.68978,2.68978,2.74955,2.74955,2.98864,2.98864,3.04842,3.04842,3.16796,3.16796,3.5266,3.5266,3.70592,3.70592,3.76569,3.76569,3.94501,3.94501,4.00478,4.00478,4.30365,4.30365,4.42319,4.42319,4.48296,4.48296,4.54274,4.54274,4.72206,4.72206,5.14047,5.14047,5.79797,5.79797,6.33592,6.33592,6.57501,6.57501,6.69456,6.69456,6.93365,6.93365,8.00956,8.00956,8.30843,8.30843,8.3682,8.3682,8.42797,8.42797,8.54752,8.54752,8.72684,8.72684,9.14525,9.14525,9.20502,9.20502,9.38434,9.38434,9.74298,9.74298,9.86252,9.86252,10.5798,10.5798,10.8189,10.8189,10.9384,10.9384,12.3132,12.3132,12.4925,12.4925,13.15,13.15,13.3293,13.3293,13.4489,13.4489,13.6282,13.6282,14.6444,14.6444,14.7639,14.7639,15.3019,15.3019,15.8398,15.8398,16.4973,16.4973,16.6169,16.6169,19.3066,19.3066,19.6653,19.6653,20.0837,20.0837,20.263,20.263,21.1596,21.1596,21.5182,21.5182,21.578,21.578,21.9366,21.9366,22.2355,22.2355,23.7896,23.7896,24.746,24.746,24.9253,24.9253,25.1644,25.1644,25.2839,25.2839,25.4035,25.4035,25.6426,25.6426,26.3001,26.3001,26.4794,26.4794,27.6151,27.6151,27.7944,27.7944,27.9737,27.9737,28.8105,28.8105,29.1094,29.1094,30.1853,30.1853,31.5601,31.5601,32.1578,32.1578,33.3533,33.3533,33.8314,33.8314,35.1464,35.1464,35.2062,35.2062,35.4453,35.4453,35.7442,35.7442,37.5971,37.5971,37.7764,37.7764,38.673,38.673,40.1674,40.1674,40.6455,40.6455,40.8249,40.8249,41.0042,41.0042,41.2433,41.2433,41.9605,41.9605,42.8571,42.8571,42.9767,42.9767,43.0365,43.0365,43.2756,43.2756,43.3353,43.3353,43.8135,43.8135,43.9331,43.9331,44.1124,44.1124,44.5906,44.5906,44.8894,44.8894,45.009,45.009,45.2481,45.2481,46.3837,46.3837,46.6826,46.6826,49.0735,49.0735,49.1333,49.1333,49.1931,49.1931,49.731,49.731,50.269,50.269,50.4483,50.4483,51.3449,51.3449,51.8231,51.8231,51.8828,51.8828,51.9426,51.9426,52.0622,52.0622,52.1219,52.1219,52.2415,52.2415,52.361,52.361,52.5403,52.5403,52.6001,52.6001,52.7197,52.7197,52.7794,52.7794,52.8392,52.8392,52.9588,52.9588,53.6163,53.6163,54.0347,54.0347,58.9958,58.9958,63.957,63.957,64.2558,64.2558,64.4949,64.4949,65.5111,65.5111,74.5368,74.5368,88.7627,88.7627,89.1213,89.1213,89.4202,89.4202,89.8386,89.8386,92.1698,92.1698,94.5009,94.5009,95.0986,95.0986,95.9354,95.9354,96.8918,96.8918,97.1309,97.1309,98.4459,98.4459,100.0],"y":[0.0,0.18797,11.4662,11.4662,26.1278,26.1278,30.8271,30.8271,32.7068,32.7068,35.1504,35.1504,44.9248,44.9248,47.3684,47.3684,49.2481,49.2481,50.188,50.188,50.3759,50.3759,50.9398,50.9398,51.6917,51.6917,52.8195,52.8195,56.203,56.203,56.5789,56.5789,56.7669,56.7669,56.9549,56.9549,57.5188,57.5188,57.8947,57.8947,58.0827,58.0827,58.4586,58.4586,59.5865,59.5865,59.9624,59.9624,60.3383,60.3383,60.5263,60.5263,60.7143,60.7143,60.9023,60.9023,61.0902,61.0902,61.2782,61.2782,62.0301,62.0301,62.782,62.782,63.7218,63.7218,63.9098,63.9098,64.2857,64.2857,65.7895,65.7895,66.1654,66.1654,66.3534,66.3534,66.5414,66.5414,66.9173,66.9173,67.2932,67.2932,67.8571,67.8571,68.4211,68.4211,68.985,68.985,69.5489,69.5489,69.7368,69.7368,69.9248,69.9248,70.3008,70.3008,70.6767,70.6767,70.8647,70.8647,71.4286,71.4286,71.6165,71.6165,71.8045,71.8045,71.9925,71.9925,72.1805,72.1805,72.3684,72.3684,72.7444,72.7444,73.8722,73.8722,74.0602,74.0602,74.2481,74.2481,74.6241,74.6241,75.0,75.0,75.3759,75.3759,75.5639,75.5639,75.7519,75.7519,75.9398,75.9398,76.1278,76.1278,76.3158,76.3158,76.5038,76.5038,76.6917,76.6917,76.8797,76.8797,77.0677,77.0677,77.2556,77.2556,77.4436,77.4436,78.0075,78.0075,78.1955,78.1955,78.3835,78.3835,78.5714,78.5714,78.9474,78.9474,79.1353,79.1353,79.3233,79.3233,79.5113,79.5113,79.6992,79.6992,79.8872,79.8872,80.0752,80.0752,80.4511,80.4511,80.8271,80.8271,81.015,81.015,81.203,81.203,81.391,81.391,81.5789,81.5789,81.7669,81.7669,82.1429,82.1429,82.3308,82.3308,82.5188,82.5188,82.7068,82.7068,82.8947,82.8947,83.0827,83.0827,83.2707,83.2707,83.6466,83.6466,83.8346,83.8346,84.0226,84.0226,84.2105,84.2105,84.3985,84.3985,84.7744,84.7744,84.9624,84.9624,85.1504,85.1504,85.3383,85.3383,85.7143,85.7143,85.9023,85.9023,86.0902,86.0902,86.2782,86.2782,86.4662,86.4662,86.6541,86.6541,87.0301,87.0301,87.218,87.218,87.406,87.406,87.594,87.594,87.782,87.782,87.9699,87.9699,88.1579,88.1579,88.3459,88.3459,88.5338,88.5338,88.7218,88.7218,89.0977,89.0977,89.6617,89.6617,89.8496,89.8496,90.0376,90.0376,90.2256,90.2256,90.6015,90.6015,90.7895,90.7895,90.9774,90.9774,91.3534,91.3534,91.5414,91.5414,91.7293,91.7293,91.9173,91.9173,92.1053,92.1053,92.2932,92.2932,92.4812,92.4812,92.6692,92.6692,92.8571,92.8571,93.0451,93.0451,93.797,93.797,93.985,93.985,94.1729,94.1729,94.3609,94.3609,94.5489,94.5489,94.7368,94.7368,94.9248,94.9248,95.1128,95.1128,95.4887,95.4887,95.6767,95.6767,95.8647,95.8647,96.0526,96.0526,96.2406,96.2406,96.4286,96.4286,96.6165,96.6165,96.8045,96.8045,96.9925,96.9925,97.1805,97.1805,97.3684,97.3684,97.5564,97.5564,97.7444,97.7444,97.9323,97.9323,98.1203,98.1203,98.3083,98.3083,98.4962,98.4962,98.6842,98.6842,98.8722,98.8722,99.0602,99.0602,99.2481,99.2481,99.4361,99.4361,99.812,99.812,100.0,100.0],"sx":[80.66,80.66,80.66,80.93,80.93,81.21,81.21,81.48,81.48,81.75,81.75,82.02,82.02,82.29,82.29,82.56,82.56,82.83,82.83,83.1,83.1,83.64,83.64,83.91,83.91,84.45,84.45,84.72,84.72,85.53,85.53,85.8,85.8,86.34,86.34,86.61,86.61,86.88,86.88,87.15,87.15,87.42,87.42,87.7,87.7,88.24,88.24,88.78,88.78,89.05,89.05,89.59,89.59,89.86,89.86,90.94,90.94,91.21,91.21,91.75,91.75,92.02,92.02,92.56,92.56,92.83,92.83,93.1,93.1,94.19,94.19,94.46,94.46,95.0,95.0,96.62,96.62,97.43,97.43,97.7,97.7,98.51,98.51,98.78,98.78,100.14,100.14,100.68,100.68,100.95,100.95,101.22,101.22,102.03,102.03,103.92,103.92,106.9,106.9,109.33,109.33,110.41,110.41,110.95,110.95,112.03,112.03,116.9,116.9,118.25,118.25,118.52,118.52,118.8,118.8,119.34,119.34,120.15,120.15,122.04,122.04,122.31,122.31,123.12,123.12,124.74,124.74,125.29,125.29,128.53,128.53,129.61,129.61,130.15,130.15,136.37,136.37,137.18,137.18,140.16,140.16,140.97,140.97,141.51,141.51,142.32,142.32,146.92,146.92,147.46,147.46,149.9,149.9,152.33,152.33,155.3,155.3,155.84,155.84,168.01,168.01,169.64,169.64,171.53,171.53,172.34,172.34,176.4,176.4,178.02,178.02,178.29,178.29,179.91,179.91,181.27,181.27,188.3,188.3,192.62,192.62,193.44,193.44,194.52,194.52,195.06,195.06,195.6,195.6,196.68,196.68,199.66,199.66,200.47,200.47,205.6,205.6,206.42,206.42,207.23,207.23,211.01,211.01,212.37,212.37,217.23,217.23,223.45,223.45,226.16,226.16,231.57,231.57,233.73,233.73,239.68,239.68,239.95,239.95,241.03,241.03,242.38,242.38,250.77,250.77,251.58,251.58,255.63,255.63,262.4,262.4,264.56,264.56,265.37,265.37,266.18,266.18,267.26,267.26,270.51,270.51,274.57,274.57,275.11,275.11,275.38,275.38,276.46,276.46,276.73,276.73,278.89,278.89,279.43,279.43,280.24,280.24,282.41,282.41,283.76,283.76,284.3,284.3,285.38,285.38,290.52,290.52,291.87,291.87,302.69,302.69,302.96,302.96,303.23,303.23,305.67,305.67,308.1,308.1,308.91,308.91,312.97,312.97,315.13,315.13,315.4,315.4,315.67,315.67,316.21,316.21,316.48,316.48,317.02,317.02,317.56,317.56,318.38,318.38,318.65,318.65,319.19,319.19,319.46,319.46,319.73,319.73,320.27,320.27,323.24,323.24,325.14,325.14,347.58,347.58,370.03,370.03,371.38,371.38,372.46,372.46,377.06,377.06,417.9,417.9,482.26,482.26,483.88,483.88,485.23,485.23,487.13,487.13,497.67,497.67,508.22,508.22,510.92,510.92,514.71,514.71,519.04,519.04,520.12,520.12,526.07,526.07,533.1],"sy":[815.26,814.98,797.8,797.8,775.48,775.48,768.32,768.32,765.46,765.46,761.74,761.74,746.85,746.85,743.13,743.13,740.27,740.27,738.84,738.84,738.55,738.55,737.69,737.69,736.55,736.55,734.83,734.83,729.68,729.68,729.1,729.1,728.82,728.82,728.53,728.53,727.67,727.67,727.1,727.1,726.81,726.81,726.24,726.24,724.52,724.52,723.95,723.95,723.38,723.38,723.09,723.09,722.81,722.81,722.52,722.52,722.23,722.23,721.95,721.95,720.8,720.8,719.66,719.66,718.23,718.23,717.94,717.94,717.37,717.37,715.08,715.08,714.51,714.51,714.22,714.22,713.93,713.93,713.36,713.36,712.79,712.79,711.93,711.93,711.07,711.07,710.21,710.21,709.35,709.35,709.07,709.07,708.78,708.78,708.21,708.21,707.64,707.64,707.35,707.35,706.49,706.49,706.21,706.21,705.92,705.92,705.63,705.63,705.35,705.35,705.06,705.06,704.49,704.49,702.77,702.77,702.48,702.48,702.2,702.2,701.63,701.63,701.05,701.05,700.48,700.48,700.19,700.19,699.91,699.91,699.62,699.62,699.34,699.34,699.05,699.05,698.76,698.76,698.48,698.48,698.19,698.19,697.9,697.9,697.62,697.62,697.33,697.33,696.47,696.47,696.19,696.19,695.9,695.9,695.61,695.61,695.04,695.04,694.76,694.76,694.47,694.47,694.18,694.18,693.9,693.9,693.61,693.61,693.32,693.32,692.75,692.75,692.18,692.18,691.89,691.89,691.61,691.61,691.32,691.32,691.03,691.03,690.75,690.75,690.18,690.18,689.89,689.89,689.6,689.6,689.32,689.32,689.03,689.03,688.74,688.74,688.46,688.46,687.89,687.89,687.6,687.6,687.31,687.31,687.03,687.03,686.74,686.74,686.17,686.17,685.88,685.88,685.6,685.6,685.31,685.31,684.74,684.74,684.45,684.45,684.16,684.16,683.88,683.88,683.59,683.59,683.31,683.31,682.73,682.73,682.45,682.45,682.16,682.16,681.87,681.87,681.59,681.59,681.3,681.3,681.02,681.02,680.73,680.73,680.44,680.44,680.16,680.16,679.58,679.58,678.73,678.73,678.44,678.44,678.15,678.15,677.87,677.87,677.29,677.29,677.01,677.01,676.72,676.72,676.15,676.15,675.86,675.86,675.58,675.58,675.29,675.29,675.0,675.0,674.72,674.72,674.43,674.43,674.15,674.15,673.86,673.86,673.57,673.57,672.43,672.43,672.14,672.14,671.86,671.86,671.57,671.57,671.28,671.28,671.0,671.0,670.71,670.71,670.42,670.42,669.85,669.85,669.57,669.57,669.28,669.28,668.99,668.99,668.71,668.71,668.42,668.42,668.13,668.13,667.85,667.85,667.56,667.56,667.28,667.28,666.99,666.99,666.7,666.7,666.42,666.42,666.13,666.13,665.84,665.84,665.56,665.56,665.27,665.27,664.99,664.99,664.7,664.7,664.41,664.41,664.13,664.13,663.84,663.84,663.27,663.27,662.98,662.98]},{"panel":2,"label":"random forest (AUC 0.893)","color":"var(--chart-blue, #3b6ea5)","kind":"line","x":[0.0,0.0,0.0,0.0597729,0.0597729,0.119546,0.119546,0.179319,0.179319,0.239091,0.239091,0.298864,0.298864,0.358637,0.358637,0.41841,0.41841,0.478183,0.478183,0.537956,0.537956,0.597729,0.597729,0.657501,0.657501,0.717274,0.717274,0.83682,0.83682,0.896593,0.896593,0.956366,0.956366,1.01614,1.01614,1.07591,1.07591,1.13568,1.13568,1.19546,1.19546,1.25523,1.25523,1.315,1.315,1.37478,1.37478,1.49432,1.49432,1.55409,1.55409,1.67364,1.67364,1.73341,1.73341,1.79319,1.79319,1.85296,1.85296,2.09205,2.09205,2.39091,2.39091,2.92887,2.92887,2.98864,2.98864,3.04842,3.04842,3.10819,3.10819,3.16796,3.16796,3.22773,3.22773,3.34728,3.34728,3.58637,3.58637,3.64614,3.64614,3.82546,3.82546,3.88524,3.88524,4.06455,4.06455,4.12433,4.12433,4.1841,4.1841,4.36342,4.36342,4.42319,4.42319,4.48296,4.48296,4.54274,4.54274,4.60251,4.60251,4.78183,4.78183,5.02092,5.02092,5.08069,5.08069,5.20024,5.20024,5.26001,5.26001,5.43933,5.43933,5.67842,5.67842,6.27615,6.27615,6.33592,6.33592,6.3957,6.3957,6.69456,6.69456,6.75433,6.75433,6.81411,6.81411,6.87388,6.87388,6.93365,6.93365,7.17274,7.17274,7.41184,7.41184,7.89002,7.89002,7.94979,7.94979,8.00956,8.00956,8.3682,8.3682,8.66707,8.66707,8.84638,8.84638,9.0257,9.0257,9.26479,9.26479,9.44411,9.44411,9.80275,9.80275,9.86252,9.86252,10.1614,10.1614,10.3407,10.3407,10.4005,10.4005,10.6396,10.6396,10.8189,10.8189,11.4764,11.4764,11.5362,11.5362,11.7155,11.7155,11.9546,11.9546,12.0143,12.0143,13.0903,13.0903,13.7478,13.7478,14.1662,14.1662,14.7041,14.7041,15.6007,15.6007,16.6169,16.6169,18.2307,18.2307,18.4698,18.4698,19.0675,19.0675,19.4262,19.4262,19.6653,19.6653,20.0837,20.0837,20.5619,20.5619,20.8607,20.8607,20.9205,20.9205,21.04,21.04,21.578,21.578,22.7137,22.7137,22.7735,22.7735,22.9528,22.9528,24.8057,24.8057,24.9851,24.9851,25.3437,25.3437,26.2403,26.2403,26.4196,26.4196,26.7185,26.7185,27.1369,27.1369,27.1967,27.1967,28.0335,28.0335,28.5117,28.5117,29.1094,29.1094,30.2451,30.2451,30.3048,30.3048,31.0221,31.0221,31.9187,31.9187,32.5762,32.5762,32.6958,32.6958,32.8751,32.8751,33.1739,33.1739,33.7717,33.7717,35.7442,35.7442,36.043,36.043,36.9994,36.9994,38.1949,38.1949,38.8524,38.8524,38.9121,38.9121,39.8087,39.8087,39.9283,39.9283,40.7053,40.7053,40.7651,40.7651,40.8249,40.8249,41.3628,41.3628,42.1399,42.1399,43.0962,43.0962,43.4549,43.4549,43.5744,43.5744,43.7537,43.7537,44.1721,44.1721,44.2319,44.2319,44.7101,44.7101,45.3676,45.3676,46.2642,46.2642,47.1608,47.1608,47.8781,47.8781,48.0574,48.0574,48.6551,48.6551,48.7747,48.7747,49.8506,49.8506,50.0299,50.0299,50.269,50.269,51.584,51.584,51.7035,51.7035,51.7633,51.7633,52.3013,52.3013,52.4806,52.4806,53.4967,53.4967,53.9151,53.9151,54.2738,54.2738,55.1106,55.1106,55.4692,55.4692,55.529,55.529,56.4256,56.4256,56.6049,56.6049,56.7244,56.7244,57.3819,57.3819,57.621,57.621,58.2785,58.2785,58.5176,58.5176,58.5774,58.5774,59.3545,59.3545,60.9085,60.9085,61.0281,61.0281,64.1363,64.1363,65.9295,65.9295,66.3479,66.3479,67.6629,67.6629,67.7824,67.7824,67.8422,67.8422,68.5595,68.5595,71.0102,71.0102,71.9068,71.9068,72.2654,72.2654,74.1781,74.1781,74.5368,74.5368,75.4931,75.4931,79.8565,79.8565,98.5057,98.6252,99.0436,99.1632,99.223,99.3425,99.5816,99.7011,100.0],"y":[0.0,0.18797,5.07519,5.07519,23.4962,23.4962,24.0602,24.0602,31.9549,31.9549,33.8346,33.8346,34.5865,34.5865,38.9098,38.9098,39.2857,39.2857,41.9173,41.9173,42.6692,42.6692,43.985,43.985,45.3008,45.3008,45.6767,45.6767,47.9323,47.9323,50.9398,50.9398,53.3835,53.3835,54.3233,54.3233,55.2632,55.2632,55.8271,55.8271,56.9549,56.9549,57.5188,57.5188,57.7068,57.7068,57.8947,57.8947,58.2707,58.2707,58.8346,58.8346,59.5865,59.5865,59.7744,59.7744,60.1504,60.1504,60.9023,60.9023,61.0902,61.0902,61.2782,61.2782,61.4662,61.4662,61.6541,61.6541,61.8421,61.8421,62.218,62.218,62.406,62.406,62.594,62.594,62.9699,62.9699,63.1579,63.1579,63.5338,63.5338,63.7218,63.7218,64.4737,64.4737,64.6617,64.6617,64.8496,64.8496,65.0376,65.0376,65.7895,65.7895,66.7293,66.7293,67.1053,67.1053,67.6692,67.6692,68.4211,68.4211,68.797,68.797,68.985,68.985,69.3609,69.3609,69.9248,69.9248,70.1128,70.1128,70.4887,70.4887,70.6767,70.6767,70.8647,70.8647,71.4286,71.4286,71.8045,71.8045,71.9925,71.9925,72.1805,72.1805,72.3684,72.3684,72.7444,72.7444,72.9323,72.9323,73.1203,73.1203,73.3083,73.3083,73.4962,73.4962,73.6842,73.6842,73.8722,73.8722,74.0602,74.0602,74.2481,74.2481,74.4361,74.4361,74.6241,74.6241,74.812,74.812,75.3759,75.3759,75.7519,75.7519,76.1278,76.1278,76.3158,76.3158,76.5038,76.5038,76.6917,76.6917,76.8797,76.8797,77.0677,77.0677,77.2556,77.2556,77.4436,77.4436,77.6316,77.6316,78.0075,78.0075,78.1955,78.1955,78.3835,78.3835,78.5714,78.5714,78.7594,78.7594,78.9474,78.9474,79.1353,79.1353,79.3233,79.3233,79.5113,79.5113,79.8872,79.8872,80.0752,80.0752,80.2632,80.2632,80.4511,80.4511,80.6391,80.6391,80.8271,80.8271,81.015,81.015,81.203,81.203,81.391,81.391,81.5789,81.5789,81.7669,81.7669,81.9549,81.9549,82.1429,82.1429,82.3308,82.3308,82.5188,82.5188,82.7068,82.7068,82.8947,82.8947,83.0827,83.0827,83.2707,83.2707,83.4586,83.4586,83.6466,83.6466,83.8346,83.8346,84.0226,84.0226,84.2105,84.2105,84.5865,84.5865,84.7744,84.7744,84.9624,84.9624,85.1504,85.1504,85.3383,85.3383,85.5263,85.5263,85.7143,85.7143,85.9023,85.9023,86.0902,86.0902,86.2782,86.2782,86.6541,86.6541,86.8421,86.8421,87.0301,87.0301,87.218,87.218,87.406,87.406,87.594,87.594,87.782,87.782,87.9699,87.9699,88.1579,88.1579,88.3459,88.3459,88.5338,88.5338,88.7218,88.7218,88.9098,88.9098,89.0977,89.0977,89.2857,89.2857,89.4737,89.4737,89.6617,89.6617,89.8496,89.8496,90.0376,90.0376,90.2256,90.2256,90.4135,90.4135,90.6015,90.6015,90.7895,90.7895,90.9774,90.9774,91.1654,91.1654,91.3534,91.3534,91.5414,91.5414,91.7293,91.7293,91.9173,91.9173,92.1053,92.1053,92.2932,92.2932,92.6692,92.6692,93.0451,93.0451,93.2331,93.2331,93.4211,93.4211,93.609,93.609,94.1729,94.1729,94.3609,94.3609,94.5489,94.5489,94.7368,94.7368,94.9248,94.9248,95.1128,95.1128,95.3008,95.3008,95.4887,95.4887,95.6767,95.6767,95.8647,95.8647,96.0526,96.0526,96.2406,96.2406,96.4286,96.4286,96.6165,96.6165,96.8045,96.8045,96.9925,96.9925,97.1805,97.1805,97.3684,97.3684,97.7444,97.7444,97.9323,97.9323,98.1203,98.1203,98.3083,98.3083,98.4962,98.4962,98.8722,98.8722,99.0602,99.0602,99.4361,99.4361,99.6241,99.6241,99.812,99.812,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0],"sx":[80.66,80.66,80.66,80.93,80.93,81.21,81.21,81.48,81.48,81.75,81.75,82.02,82.02,82.29,82.29,82.56,82.56,82.83,82.83,83.1,83.1,83.37,83.37,83.64,83.64,83.91,83.91,84.45,84.45,84.72,84.72,84.99,84.99,85.26,85.26,85.53,85.53,85.8,85.8,86.07,86.07,86.34,86.34,86.61,86.61,86.88,86.88,87.42,87.42,87.7,87.7,88.24,88.24,88.51,88.51,88.78,88.78,89.05,89.05,90.13,90.13,91.48,91.48,93.92,93.92,94.19,94.19,94.46,94.46,94.73,94.73,95.0,95.0,95.27,95.27,95.81,95.81,96.89,96.89,97.16,97.16,97.97,97.97,98.24,98.24,99.05,99.05,99.32,99.32,99.59,99.59,100.41,100.41,100.68,100.68,100.95,100.95,101.22,101.22,101.49,101.49,102.3,102.3,103.38,103.38,103.65,103.65,104.19,104.19,104.46,104.46,105.27,105.27,106.36,106.36,109.06,109.06,109.33,109.33,109.6,109.6,110.95,110.95,111.22,111.22,111.49,111.49,111.76,111.76,112.03,112.03,113.12,113.12,114.2,114.2,116.36,116.36,116.63,116.63,116.9,116.9,118.52,118.52,119.88,119.88,120.69,120.69,121.5,121.5,122.58,122.58,123.39,123.39,125.02,125.02,125.29,125.29,126.64,126.64,127.45,127.45,127.72,127.72,128.8,128.8,129.61,129.61,132.59,132.59,132.86,132.86,133.67,133.67,134.75,134.75,135.02,135.02,139.89,139.89,142.86,142.86,144.76,144.76,147.19,147.19,151.25,151.25,155.84,155.84,163.15,163.15,164.23,164.23,166.93,166.93,168.56,168.56,169.64,169.64,171.53,171.53,173.69,173.69,175.05,175.05,175.32,175.32,175.86,175.86,178.29,178.29,183.43,183.43,183.7,183.7,184.51,184.51,192.89,192.89,193.71,193.71,195.33,195.33,199.38,199.38,200.2,200.2,201.55,201.55,203.44,203.44,203.71,203.71,207.5,207.5,209.66,209.66,212.37,212.37,217.5,217.5,217.77,217.77,221.02,221.02,225.08,225.08,228.05,228.05,228.59,228.59,229.4,229.4,230.75,230.75,233.46,233.46,242.38,242.38,243.74,243.74,248.06,248.06,253.47,253.47,256.45,256.45,256.72,256.72,260.77,260.77,261.31,261.31,264.83,264.83,265.1,265.1,265.37,265.37,267.8,267.8,271.32,271.32,275.65,275.65,277.27,277.27,277.81,277.81,278.62,278.62,280.51,280.51,280.79,280.79,282.95,282.95,285.92,285.92,289.98,289.98,294.04,294.04,297.28,297.28,298.09,298.09,300.8,300.8,301.34,301.34,306.21,306.21,307.02,307.02,308.1,308.1,314.05,314.05,314.59,314.59,314.86,314.86,317.29,317.29,318.11,318.11,322.7,322.7,324.6,324.6,326.22,326.22,330.0,330.0,331.63,331.63,331.9,331.9,335.95,335.95,336.77,336.77,337.31,337.31,340.28,340.28,341.36,341.36,344.34,344.34,345.42,345.42,345.69,345.69,349.21,349.21,356.24,356.24,356.78,356.78,370.84,370.84,378.95,378.95,380.85,380.85,386.8,386.8,387.34,387.34,387.61,387.61,390.85,390.85,401.94,401.94,406.0,406.0,407.62,407.62,416.27,416.27,417.9,417.9,422.22,422.22,441.96,441.96,526.34,526.88,528.77,529.31,529.58,530.13,531.21,531.75,533.1],"sy":[815.26,814.98,807.54,807.54,779.48,779.48,778.62,778.62,766.6,766.6,763.74,763.74,762.59,762.59,756.01,756.01,755.44,755.44,751.43,751.43,750.29,750.29,748.28,748.28,746.28,746.28,745.71,745.71,742.27,742.27,737.69,737.69,733.97,733.97,732.54,732.54,731.11,731.11,730.25,730.25,728.53,728.53,727.67,727.67,727.39,727.39,727.1,727.1,726.53,726.53,725.67,725.67,724.52,724.52,724.24,724.24,723.67,723.67,722.52,722.52,722.23,722.23,721.95,721.95,721.66,721.66,721.38,721.38,721.09,721.09,720.52,720.52,720.23,720.23,719.94,719.94,719.37,719.37,719.09,719.09,718.51,718.51,718.23,718.23,717.08,717.08,716.8,716.8,716.51,716.51,716.22,716.22,715.08,715.08,713.65,713.65,713.07,713.07,712.22,712.22,711.07,711.07,710.5,710.5,710.21,710.21,709.64,709.64,708.78,708.78,708.49,708.49,707.92,707.92,707.64,707.64,707.35,707.35,706.49,706.49,705.92,705.92,705.63,705.63,705.35,705.35,705.06,705.06,704.49,704.49,704.2,704.2,703.92,703.92,703.63,703.63,703.34,703.34,703.06,703.06,702.77,702.77,702.48,702.48,702.2,702.2,701.91,701.91,701.63,701.63,701.34,701.34,700.48,700.48,699.91,699.91,699.34,699.34,699.05,699.05,698.76,698.76,698.48,698.48,698.19,698.19,697.9,697.9,697.62,697.62,697.33,697.33,697.05,697.05,696.47,696.47,696.19,696.19,695.9,695.9,695.61,695.61,695.33,695.33,695.04,695.04,694.76,694.76,694.47,694.47,694.18,694.18,693.61,693.61,693.32,693.32,693.04,693.04,692.75,692.75,692.47,692.47,692.18,692.18,691.89,691.89,691.61,691.61,691.32,691.32,691.03,691.03,690.75,690.75,690.46,690.46,690.18,690.18,689.89,689.89,689.6,689.6,689.32,689.32,689.03,689.03,688.74,688.74,688.46,688.46,688.17,688.17,687.89,687.89,687.6,687.6,687.31,687.31,687.03,687.03,686.45,686.45,686.17,686.17,685.88,685.88,685.6,685.6,685.31,685.31,685.02,685.02,684.74,684.74,684.45,684.45,684.16,684.16,683.88,683.88,683.31,683.31,683.02,683.02,682.73,682.73,682.45,682.45,682.16,682.16,681.87,681.87,681.59,681.59,681.3,681.3,681.02,681.02,680.73,680.73,680.44,680.44,680.16,680.16,679.87,679.87,679.58,679.58,679.3,679.3,679.01,679.01,678.73,678.73,678.44,678.44,678.15,678.15,677.87,677.87,677.58,677.58,677.29,677.29,677.01,677.01,676.72,676.72,676.44,676.44,676.15,676.15,675.86,675.86,675.58,675.58,675.29,675.29,675.0,675.0,674.72,674.72,674.15,674.15,673.57,673.57,673.29,673.29,673.0,673.0,672.71,672.71,671.86,671.86,671.57,671.57,671.28,671.28,671.0,671.0,670.71,670.71,670.42,670.42,670.14,670.14,669.85,669.85,669.57,669.57,669.28,669.28,668.99,668.99,668.71,668.71,668.42,668.42,668.13,668.13,667.85,667.85,667.56,667.56,667.28,667.28,666.99,666.99,666.42,666.42,666.13,666.13,665.84,665.84,665.56,665.56,665.27,665.27,664.7,664.7,664.41,664.41,663.84,663.84,663.55,663.55,663.27,663.27,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98]},{"panel":2,"label":"gradient boosting (AUC 0.891)","color":"var(--chart-maroon, #b6262c)","kind":"line","x":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0597729,0.0597729,0.119546,0.119546,0.179319,0.179319,0.239091,0.239091,0.298864,0.298864,0.358637,0.358637,0.41841,0.41841,0.41841,0.41841,0.478183,0.478183,0.597729,0.597729,0.657501,0.657501,0.717274,0.717274,0.777047,0.777047,0.83682,0.83682,0.896593,0.896593,1.01614,1.01614,1.07591,1.07591,1.13568,1.13568,1.19546,1.19546,1.315,1.315,1.37478,1.37478,1.43455,1.43455,1.49432,1.49432,1.55409,1.55409,1.61387,1.61387,1.67364,1.67364,1.73341,1.73341,1.79319,1.79319,1.85296,1.85296,2.03228,2.03228,2.09205,2.09205,2.27137,2.27137,2.33114,2.33114,2.39091,2.39091,2.45069,2.45069,2.51046,2.51046,2.63001,2.63001,2.68978,2.68978,2.74955,2.74955,2.80932,2.80932,2.8691,2.8691,2.92887,2.92887,2.92887,2.98864,2.98864,3.10819,3.10819,3.10819,3.16796,3.16796,3.22773,3.22773,3.22773,3.28751,3.28751,3.34728,3.34728,3.46683,3.46683,3.58637,3.58637,3.70592,3.70592,3.82546,3.82546,3.88524,3.88524,3.94501,3.94501,4.12433,4.24387,4.24387,4.36342,4.36342,4.48296,4.48296,4.60251,4.60251,4.66228,4.66228,4.72206,4.72206,4.78183,4.78183,4.8416,4.8416,4.96115,4.96115,5.02092,5.02092,5.08069,5.08069,5.14047,5.14047,5.20024,5.20024,5.26001,5.26001,5.37956,5.37956,5.43933,5.43933,5.4991,5.4991,5.73819,5.73819,5.91751,5.91751,5.97729,5.97729,6.1566,6.1566,6.27615,6.3957,6.45547,6.45547,6.57501,6.57501,6.63479,6.63479,6.75433,6.75433,7.11297,7.11297,7.23252,7.41184,7.41184,7.59115,7.7107,7.77047,7.77047,7.83025,7.83025,8.00956,8.00956,8.12911,8.12911,8.18888,8.18888,8.54752,8.54752,8.72684,8.72684,8.90616,8.90616,9.14525,9.14525,9.32457,9.32457,9.44411,9.44411,9.80275,9.80275,9.86252,9.86252,9.98207,9.98207,10.6993,10.6993,11.5362,11.5362,11.7753,11.7753,11.8948,12.3132,12.3132,12.6718,12.7914,13.2098,13.2098,13.4489,14.1064,14.1064,14.3455,14.5846,14.7041,14.7639,14.8834,14.8834,15.0628,15.3019,15.4214,15.4214,15.5409,15.78,15.9594,16.1984,16.1984,16.2582,16.318,16.4973,16.4973,16.9755,16.9755,17.6928,17.6928,17.7525,17.7525,17.8721,17.8721,17.9916,17.9916,18.6491,18.6491,19.1273,19.1273,19.1871,19.2469,19.3664,19.3664,19.6653,19.7848,19.9044,19.9044,20.4423,20.5619,21.04,21.04,21.8171,21.8171,21.9964,22.116,22.1757,22.6539,22.7137,22.8332,23.0126,23.0126,23.431,23.431,23.9689,24.0885,24.9851,24.9851,25.1046,25.1046,25.1644,25.2839,25.3437,25.3437,25.3437,25.5828,25.5828,25.8816,25.9414,26.6587,26.838,27.1369,27.2564,27.3162,27.3162,27.6748,27.7944,27.8542,27.8542,28.2726,28.2726,28.3323,28.3323,28.3921,28.3921,28.691,28.7507,29.0496,29.1692,29.4082,29.4082,29.5876,29.5876,29.7669,29.7669,30.2451,30.4244,30.5439,30.5439,30.6635,30.783,30.8428,30.8428,31.321,31.321,31.4405,31.9187,32.0383,32.1578,32.1578,32.3969,32.3969,32.5164,32.636,32.9348,32.9348,33.0544,33.0544,33.7119,33.8314,34.0705,34.0705,34.3694,34.4889,34.5487,34.5487,34.7878,34.9074,35.0269,35.1464,35.3855,35.3855,35.8637,35.8637,35.9833,36.1028,36.1028,36.2821,36.4017,36.581,36.581,36.7005,36.7005,36.8201,36.8201,36.9396,37.0592,37.1787,37.2983,37.4776,37.6569,37.7167,37.7167,37.896,37.896,38.0753,38.0753,38.1949,38.1949,38.7328,38.7328,38.9719,39.0915,39.211,39.211,39.8685,39.8685,41.0042,41.0042,41.7812,41.7812,41.841,41.841,42.379,42.4985,42.4985,43.2756,43.2756,43.4549,43.4549,43.8733,43.9928,44.2319,44.2319,45.0687,45.0687,45.1285,45.1285,45.3676,45.3676,45.4274,45.4274,45.4871,45.4871,45.6067,45.6067,45.7262,45.7262,46.2044,46.2044,46.324,46.8022,46.8022,46.9217,47.101,47.2206,47.3401,47.3999,47.3999,47.5792,47.5792,47.9976,48.2367,49.3126,49.3126,49.4322,49.4322,49.4919,49.6115,49.7908,50.0299,50.1494,50.1494,51.4644,51.4644,51.5242,51.7035,51.8828,52.1219,52.4806,52.4806,52.5403,52.5403,52.6599,52.7794,52.8392,52.9588,53.5565,53.5565,54.6324,54.6324,55.2301,55.2301,55.529,55.529,55.5888,55.5888,56.5451,56.6647,57.0233,57.1429,58.3981,58.5176,58.9958,59.0556,59.2947,59.4142,61.6258,61.7454,63.0604,63.2397,63.7179,63.7179,64.2558,64.2558,65.3915,65.5111,65.8099,65.8099,66.049,66.2881,66.3479,66.4674,66.5272,66.5272,67.1847,67.3042,67.4836,67.6629,68.3802,68.4997,69.0377,69.1572,69.217,69.3365,69.3963,69.5158,69.7549,69.9342,70.0538,70.2929,70.4124,70.532,70.6515,70.7711,70.8906,70.9504,71.1895,71.3688,71.3688,71.6079,71.6079,71.9665,72.0861,72.2056,72.2654,72.624,72.7436,72.8033,72.9229,73.162,73.162,73.2815,73.4011,73.6999,73.8195,74.477,74.5965,74.8356,74.8356,74.8954,75.0149,75.6724,75.6724,75.9115,76.1506,76.6886,76.8081,76.9874,77.2265,77.3461,77.7047,78.1231,78.3622,78.3622,78.4818,78.6611,78.7209,78.9002,79.0197,79.1393,79.4381,79.6175,79.737,80.0956,80.3347,80.4543,80.9325,81.052,81.2313,81.4106,81.7693,81.8888,82.8452,82.9647,83.9211,84.1602,85.0568,85.2959,85.5947,85.7143,85.8338,86.0132,86.1925,86.312,86.3718,86.4913,86.9695,87.0891,87.2684,87.3879,87.5672,87.6868,88.2247,88.4041,88.5236,88.7029,89.48,89.8386,90.1973,90.3168,90.3766,90.4961,91.3927,91.5123,91.572,92.0502,92.1698,92.2295,92.2295,92.5882,92.7077,92.7675,93.0663,93.1261,93.2457,93.3652,93.4848,93.6641,93.9032,94.0227,94.1423,94.3216,94.3814,94.5009,94.5607,94.9193,94.9791,95.1584,95.2779,95.3975,95.5768,95.6366,95.7561,95.8159,95.9354,96.1745,96.2941,96.5332,96.5929,96.9516,97.1907,97.3102,97.4298,97.5493,97.6689,97.7884,97.9677,98.2068,98.5655,98.6252,98.7448,99.0436,99.3425,99.462,99.5816,100.0],"y":[0.0,0.18797,0.37594,0.75188,1.12782,1.50376,4.88722,5.26316,6.95489,6.95489,8.83459,8.83459,9.77444,9.77444,10.3383,10.3383,12.0301,12.0301,23.1203,23.1203,26.5038,26.5038,26.8797,27.2556,27.6316,27.6316,27.8195,27.8195,28.5714,28.5714,30.0752,30.0752,30.6391,30.6391,31.203,31.203,32.1429,32.1429,32.5188,32.5188,33.4586,33.4586,34.5865,34.5865,35.9023,35.9023,36.2782,36.2782,37.782,37.782,39.0977,39.0977,39.4737,39.4737,39.6617,39.6617,39.8496,39.8496,40.0376,40.0376,40.6015,40.6015,40.7895,40.7895,41.7293,41.7293,41.9173,41.9173,42.2932,42.2932,43.0451,43.0451,44.3609,44.3609,44.7368,44.7368,46.0526,46.0526,46.4286,46.4286,47.3684,47.3684,49.2481,49.2481,50.188,50.188,50.7519,50.7519,51.5038,51.5038,51.6917,51.6917,52.0677,53.1955,53.1955,53.5714,53.5714,54.1353,54.5113,54.5113,54.8872,54.8872,55.2632,56.015,56.015,56.391,56.391,56.5789,56.5789,57.5188,57.5188,58.2707,58.2707,58.6466,58.6466,59.3985,59.3985,59.7744,59.7744,59.9624,59.9624,59.9624,60.1504,60.1504,60.3383,60.3383,60.7143,60.7143,60.9023,60.9023,61.0902,61.0902,61.4662,61.4662,63.1579,63.1579,63.3459,63.3459,64.0977,64.0977,64.2857,64.2857,64.4737,64.4737,64.6617,64.6617,65.4135,65.4135,66.1654,66.1654,66.3534,66.3534,68.0451,68.0451,68.2331,68.2331,68.4211,68.4211,68.609,68.609,68.985,68.985,69.1729,69.1729,69.1729,69.1729,69.3609,69.3609,70.6767,70.6767,70.8647,70.8647,71.0526,71.0526,71.2406,71.2406,71.2406,71.6165,71.6165,71.6165,71.6165,72.3684,72.3684,72.5564,72.5564,72.7444,72.7444,73.1203,73.1203,73.3083,73.3083,73.6842,73.6842,73.8722,73.8722,74.2481,74.2481,74.4361,74.4361,74.812,74.812,75.0,75.0,75.3759,75.3759,75.5639,75.5639,75.7519,75.7519,75.9398,75.9398,76.1278,76.1278,76.3158,76.3158,76.3158,76.6917,76.6917,76.6917,76.6917,76.8797,76.8797,76.8797,77.0677,77.0677,77.0677,77.0677,77.0677,77.0677,77.2556,77.2556,77.2556,77.2556,77.4436,77.4436,77.4436,77.4436,77.4436,77.6316,77.6316,77.8195,77.8195,78.0075,78.0075,78.1955,78.1955,78.3835,78.3835,78.5714,78.5714,78.9474,78.9474,79.1353,79.1353,79.5113,79.5113,79.6992,79.6992,79.8872,79.8872,80.0752,80.0752,80.0752,80.0752,80.2632,80.2632,80.2632,80.2632,80.4511,80.4511,80.6391,80.6391,80.6391,80.6391,80.6391,80.6391,80.6391,80.6391,80.8271,80.8271,81.203,81.203,81.203,81.203,81.391,81.391,81.5789,81.5789,81.5789,81.5789,81.7669,82.1429,82.1429,82.3308,82.3308,82.5188,82.5188,82.5188,82.5188,82.5188,82.5188,82.7068,82.7068,82.7068,82.7068,82.8947,82.8947,83.0827,83.0827,83.4586,83.4586,83.8346,83.8346,84.2105,84.2105,84.2105,84.2105,84.3985,84.3985,84.5865,84.5865,84.7744,84.7744,84.7744,84.7744,84.9624,84.9624,84.9624,84.9624,85.1504,85.1504,85.5263,85.5263,85.5263,85.5263,85.5263,85.7143,85.7143,85.9023,85.9023,85.9023,85.9023,86.0902,86.0902,86.4662,86.4662,86.4662,86.4662,86.6541,86.6541,86.6541,86.6541,86.8421,86.8421,86.8421,86.8421,86.8421,86.8421,87.0301,87.0301,87.218,87.218,87.218,87.782,87.782,87.782,87.782,88.1579,88.1579,88.3459,88.3459,88.5338,88.5338,88.5338,88.5338,88.5338,88.5338,88.5338,88.5338,88.7218,88.7218,88.9098,88.9098,89.2857,89.2857,89.4737,89.4737,89.8496,89.8496,89.8496,89.8496,90.0376,90.0376,90.2256,90.2256,90.4135,90.4135,90.6015,90.6015,90.7895,90.7895,90.7895,91.1654,91.1654,91.5414,91.5414,91.7293,91.7293,91.7293,91.7293,91.9173,91.9173,92.2932,92.2932,92.4812,92.4812,92.6692,92.6692,93.0451,93.0451,93.2331,93.2331,93.4211,93.4211,93.609,93.609,93.797,93.797,93.797,93.985,93.985,93.985,93.985,93.985,93.985,94.1729,94.1729,94.7368,94.7368,94.7368,94.7368,94.9248,94.9248,95.1128,95.1128,95.1128,95.1128,95.1128,95.1128,95.3008,95.3008,95.4887,95.4887,95.4887,95.4887,95.4887,95.4887,95.6767,95.6767,96.0526,96.0526,96.0526,96.0526,96.0526,96.0526,96.2406,96.2406,96.4286,96.4286,96.6165,96.6165,96.8045,96.8045,96.9925,96.9925,96.9925,96.9925,96.9925,96.9925,96.9925,96.9925,97.1805,97.1805,97.1805,97.1805,97.1805,97.1805,97.1805,97.1805,97.3684,97.3684,97.5564,97.5564,97.5564,97.5564,97.7444,97.7444,97.7444,97.7444,97.7444,97.7444,97.9323,97.9323,97.9323,97.9323,97.9323,97.9323,97.9323,97.9323,97.9323,97.9323,97.9323,97.9323,97.9323,97.9323,97.9323,98.4962,98.4962,98.4962,98.4962,98.4962,98.4962,98.4962,98.4962,98.4962,98.4962,98.6842,98.6842,98.8722,98.8722,98.8722,98.8722,99.0602,99.0602,99.0602,99.0602,99.0602,99.0602,99.2481,99.2481,99.2481,99.2481,99.2481,99.2481,99.2481,99.2481,99.4361,99.4361,99.4361,99.4361,99.6241,99.6241,99.6241,99.6241,99.6241,99.6241,99.6241,99.6241,99.6241,99.6241,99.6241,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,99.812,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0],"sx":[80.66,80.66,80.66,80.66,80.66,80.66,80.66,80.66,80.66,80.93,80.93,81.21,81.21,81.48,81.48,81.75,81.75,82.02,82.02,82.29,82.29,82.56,82.56,82.56,82.56,82.83,82.83,83.37,83.37,83.64,83.64,83.91,83.91,84.18,84.18,84.45,84.45,84.72,84.72,85.26,85.26,85.53,85.53,85.8,85.8,86.07,86.07,86.61,86.61,86.88,86.88,87.15,87.15,87.42,87.42,87.7,87.7,87.97,87.97,88.24,88.24,88.51,88.51,88.78,88.78,89.05,89.05,89.86,89.86,90.13,90.13,90.94,90.94,91.21,91.21,91.48,91.48,91.75,91.75,92.02,92.02,92.56,92.56,92.83,92.83,93.1,93.1,93.37,93.37,93.64,93.64,93.92,93.92,93.92,94.19,94.19,94.73,94.73,94.73,95.0,95.0,95.27,95.27,95.27,95.54,95.54,95.81,95.81,96.35,96.35,96.89,96.89,97.43,97.43,97.97,97.97,98.24,98.24,98.51,98.51,99.32,99.86,99.86,100.41,100.41,100.95,100.95,101.49,101.49,101.76,101.76,102.03,102.03,102.3,102.3,102.57,102.57,103.11,103.11,103.38,103.38,103.65,103.65,103.92,103.92,104.19,104.19,104.46,104.46,105.0,105.0,105.27,105.27,105.54,105.54,106.63,106.63,107.44,107.44,107.71,107.71,108.52,108.52,109.06,109.6,109.87,109.87,110.41,110.41,110.68,110.68,111.22,111.22,112.85,112.85,113.39,114.2,114.2,115.01,115.55,115.82,115.82,116.09,116.09,116.9,116.9,117.44,117.44,117.71,117.71,119.34,119.34,120.15,120.15,120.96,120.96,122.04,122.04,122.85,122.85,123.39,123.39,125.02,125.02,125.29,125.29,125.83,125.83,129.07,129.07,132.86,132.86,133.94,133.94,134.48,136.37,136.37,138.0,138.54,140.43,140.43,141.51,144.49,144.49,145.57,146.65,147.19,147.46,148.0,148.0,148.81,149.9,150.44,150.44,150.98,152.06,152.87,153.95,153.95,154.22,154.49,155.3,155.3,157.47,157.47,160.71,160.71,160.98,160.98,161.52,161.52,162.06,162.06,165.04,165.04,167.2,167.2,167.47,167.74,168.28,168.28,169.64,170.18,170.72,170.72,173.15,173.69,175.86,175.86,179.37,179.37,180.18,180.72,181.0,183.16,183.43,183.97,184.78,184.78,186.67,186.67,189.11,189.65,193.71,193.71,194.25,194.25,194.52,195.06,195.33,195.33,195.33,196.41,196.41,197.76,198.03,201.28,202.09,203.44,203.98,204.25,204.25,205.88,206.42,206.69,206.69,208.58,208.58,208.85,208.85,209.12,209.12,210.47,210.74,212.1,212.64,213.72,213.72,214.53,214.53,215.34,215.34,217.5,218.32,218.86,218.86,219.4,219.94,220.21,220.21,222.37,222.37,222.91,225.08,225.62,226.16,226.16,227.24,227.24,227.78,228.32,229.67,229.67,230.21,230.21,233.19,233.73,234.81,234.81,236.16,236.7,236.97,236.97,238.06,238.6,239.14,239.68,240.76,240.76,242.92,242.92,243.47,244.01,244.01,244.82,245.36,246.17,246.17,246.71,246.71,247.25,247.25,247.79,248.33,248.87,249.41,250.23,251.04,251.31,251.31,252.12,252.12,252.93,252.93,253.47,253.47,255.91,255.91,256.99,257.53,258.07,258.07,261.04,261.04,266.18,266.18,269.7,269.7,269.97,269.97,272.4,272.94,272.94,276.46,276.46,277.27,277.27,279.16,279.7,280.79,280.79,284.57,284.57,284.84,284.84,285.92,285.92,286.19,286.19,286.46,286.46,287.01,287.01,287.55,287.55,289.71,289.71,290.25,292.41,292.41,292.95,293.77,294.31,294.85,295.12,295.12,295.93,295.93,297.82,298.9,303.77,303.77,304.31,304.31,304.58,305.12,305.94,307.02,307.56,307.56,313.51,313.51,313.78,314.59,315.4,316.48,318.11,318.11,318.38,318.38,318.92,319.46,319.73,320.27,322.97,322.97,327.84,327.84,330.55,330.55,331.9,331.9,332.17,332.17,336.49,337.04,338.66,339.2,344.88,345.42,347.58,347.85,348.93,349.48,359.48,360.02,365.97,366.78,368.95,368.95,371.38,371.38,376.52,377.06,378.41,378.41,379.49,380.58,380.85,381.39,381.66,381.66,384.63,385.17,385.98,386.8,390.04,390.58,393.02,393.56,393.83,394.37,394.64,395.18,396.26,397.07,397.61,398.69,399.24,399.78,400.32,400.86,401.4,401.67,402.75,403.56,403.56,404.64,404.64,406.27,406.81,407.35,407.62,409.24,409.78,410.05,410.59,411.68,411.68,412.22,412.76,414.11,414.65,417.62,418.17,419.25,419.25,419.52,420.06,423.03,423.03,424.12,425.2,427.63,428.17,428.98,430.06,430.61,432.23,434.12,435.2,435.2,435.74,436.56,436.83,437.64,438.18,438.72,440.07,440.88,441.42,443.05,444.13,444.67,446.83,447.37,448.18,449.0,450.62,451.16,455.49,456.03,460.35,461.44,465.49,466.57,467.93,468.47,469.01,469.82,470.63,471.17,471.44,471.98,474.15,474.69,475.5,476.04,476.85,477.39,479.82,480.64,481.18,481.99,485.5,487.13,488.75,489.29,489.56,490.1,494.16,494.7,494.97,497.13,497.67,497.94,497.94,499.57,500.11,500.38,501.73,502.0,502.54,503.08,503.62,504.43,505.52,506.06,506.6,507.41,507.68,508.22,508.49,510.11,510.38,511.19,511.74,512.28,513.09,513.36,513.9,514.17,514.71,515.79,516.33,517.41,517.69,519.31,520.39,520.93,521.47,522.01,522.55,523.09,523.91,524.99,526.61,526.88,527.42,528.77,530.13,530.67,531.21,533.1],"sy":[815.26,814.98,814.69,814.12,813.55,812.97,807.82,807.25,804.67,804.67,801.81,801.81,800.38,800.38,799.52,799.52,796.94,796.94,780.06,780.06,774.9,774.9,774.33,773.76,773.19,773.19,772.9,772.9,771.75,771.75,769.46,769.46,768.61,768.61,767.75,767.75,766.32,766.32,765.74,765.74,764.31,764.31,762.59,762.59,760.59,760.59,760.02,760.02,757.73,757.73,755.73,755.73,755.15,755.15,754.87,754.87,754.58,754.58,754.29,754.29,753.44,753.44,753.15,753.15,751.72,751.72,751.43,751.43,750.86,750.86,749.71,749.71,747.71,747.71,747.14,747.14,745.13,745.13,744.56,744.56,743.13,743.13,740.27,740.27,738.84,738.84,737.98,737.98,736.83,736.83,736.55,736.55,735.97,734.26,734.26,733.68,733.68,732.83,732.25,732.25,731.68,731.68,731.11,729.96,729.96,729.39,729.39,729.1,729.1,727.67,727.67,726.53,726.53,725.96,725.96,724.81,724.81,724.24,724.24,723.95,723.95,723.95,723.67,723.67,723.38,723.38,722.81,722.81,722.52,722.52,722.23,722.23,721.66,721.66,719.09,719.09,718.8,718.8,717.65,717.65,717.37,717.37,717.08,717.08,716.8,716.8,715.65,715.65,714.51,714.51,714.22,714.22,711.64,711.64,711.36,711.36,711.07,711.07,710.78,710.78,710.21,710.21,709.93,709.93,709.93,709.93,709.64,709.64,707.64,707.64,707.35,707.35,707.06,707.06,706.78,706.78,706.78,706.21,706.21,706.21,706.21,705.06,705.06,704.77,704.77,704.49,704.49,703.92,703.92,703.63,703.63,703.06,703.06,702.77,702.77,702.2,702.2,701.91,701.91,701.34,701.34,701.05,701.05,700.48,700.48,700.19,700.19,699.91,699.91,699.62,699.62,699.34,699.34,699.05,699.05,699.05,698.48,698.48,698.48,698.48,698.19,698.19,698.19,697.9,697.9,697.9,697.9,697.9,697.9,697.62,697.62,697.62,697.62,697.33,697.33,697.33,697.33,697.33,697.05,697.05,696.76,696.76,696.47,696.47,696.19,696.19,695.9,695.9,695.61,695.61,695.04,695.04,694.76,694.76,694.18,694.18,693.9,693.9,693.61,693.61,693.32,693.32,693.32,693.32,693.04,693.04,693.04,693.04,692.75,692.75,692.47,692.47,692.47,692.47,692.47,692.47,692.47,692.47,692.18,692.18,691.61,691.61,691.61,691.61,691.32,691.32,691.03,691.03,691.03,691.03,690.75,690.18,690.18,689.89,689.89,689.6,689.6,689.6,689.6,689.6,689.6,689.32,689.32,689.32,689.32,689.03,689.03,688.74,688.74,688.17,688.17,687.6,687.6,687.03,687.03,687.03,687.03,686.74,686.74,686.45,686.45,686.17,686.17,686.17,686.17,685.88,685.88,685.88,685.88,685.6,685.6,685.02,685.02,685.02,685.02,685.02,684.74,684.74,684.45,684.45,684.45,684.45,684.16,684.16,683.59,683.59,683.59,683.59,683.31,683.31,683.31,683.31,683.02,683.02,683.02,683.02,683.02,683.02,682.73,682.73,682.45,682.45,682.45,681.59,681.59,681.59,681.59,681.02,681.02,680.73,680.73,680.44,680.44,680.44,680.44,680.44,680.44,680.44,680.44,680.16,680.16,679.87,679.87,679.3,679.3,679.01,679.01,678.44,678.44,678.44,678.44,678.15,678.15,677.87,677.87,677.58,677.58,677.29,677.29,677.01,677.01,677.01,676.44,676.44,675.86,675.86,675.58,675.58,675.58,675.58,675.29,675.29,674.72,674.72,674.43,674.43,674.15,674.15,673.57,673.57,673.29,673.29,673.0,673.0,672.71,672.71,672.43,672.43,672.43,672.14,672.14,672.14,672.14,672.14,672.14,671.86,671.86,671.0,671.0,671.0,671.0,670.71,670.71,670.42,670.42,670.42,670.42,670.42,670.42,670.14,670.14,669.85,669.85,669.85,669.85,669.85,669.85,669.57,669.57,668.99,668.99,668.99,668.99,668.99,668.99,668.71,668.71,668.42,668.42,668.13,668.13,667.85,667.85,667.56,667.56,667.56,667.56,667.56,667.56,667.56,667.56,667.28,667.28,667.28,667.28,667.28,667.28,667.28,667.28,666.99,666.99,666.7,666.7,666.7,666.7,666.42,666.42,666.42,666.42,666.42,666.42,666.13,666.13,666.13,666.13,666.13,666.13,666.13,666.13,666.13,666.13,666.13,666.13,666.13,666.13,666.13,665.27,665.27,665.27,665.27,665.27,665.27,665.27,665.27,665.27,665.27,664.99,664.99,664.7,664.7,664.7,664.7,664.41,664.41,664.41,664.41,664.41,664.41,664.13,664.13,664.13,664.13,664.13,664.13,664.13,664.13,663.84,663.84,663.84,663.84,663.55,663.55,663.55,663.55,663.55,663.55,663.55,663.55,663.55,663.55,663.55,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,663.27,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98,662.98]}]} 2026-10-31T01:56:14.864126 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ 1 2 3 4 5 Validation fold (1 to 5) 0.86 0.88 0.90 0.92 0.94 0.96 AUC on the validation fold (0.5 = coin flip) 1. Cross-validated AUC on 2020-2023, shuffled folds vs time-ordered folds KFold, shuffled (future rows leak into training) TimeSeriesSplit (train on the past, validate on what follows) the real test, 2024-2025 1 0 − 2 1 0 − 1 Learning rate (log scale) 0.890 0.895 0.900 0.905 0.910 Mean validation AUC over 5 time-ordered folds 2. Grid search: validation AUC for each learning rate and tree depth trees of depth 2 trees of depth 3 trees of depth 5 0 20 40 60 80 100 Calm months wrongly flagged as stress (% of calm months) 0 20 40 60 80 100 Stress months caught (% of stress months) 3. ROC curves on the 2024-2025 test months logistic regression (AUC 0.890) random forest (AUC 0.893) gradient boosting (AUC 0.891)
Figure 1. Fold AUCs by splitter, the boosting grid, and ROC curves on the test months

Cross-validation: do not shuffle time

Cross-validation is how a score is estimated without touching the test set: split the training rows into folds, fit on all but one, score on the held-out one, repeat. The default splitter, KFold with shuffling, assigns rows to folds at random. On a time series that is a leak. Rows from the same week share almost everything (the same market, nearly the same 20-day volatility), so a model validated on a random Tuesday has trained on the Monday and Wednesday around it. The honest splitter is TimeSeriesSplit: every fold trains on the past and validates on the block that follows.

from sklearn.model_selection import KFold, TimeSeriesSplit, cross_val_score

gb = models["gradient boosting"]
shuffled = KFold(5, shuffle=True, random_state=0)                  # random folds: leaks
for name, cv in [("shuffled", shuffled), ("time order", TimeSeriesSplit(5))]:
    scores = cross_val_score(gb, X_train, y_train, cv=cv, scoring="roc_auc")
    print(f"{name:10} folds {scores.round(3)}  mean {scores.mean():.3f}")   # 0.929 / 0.899

It prints each splitter’s five fold scores and their mean, the rows of Table 4:

Table 4. Fold AUCs under a shuffled and a time-ordered splitter, against the test AUC
SplitterFold AUCsMeanActual test AUC, 2024–2025
KFold, shuffled0.92, 0.95, 0.92, 0.92, 0.940.9290.891
TimeSeriesSplit0.88, 0.90, 0.86, 0.89, 0.960.8990.891

Panel 1 of Figure 1 shows the two. The shuffled folds agree with each other and promise 0.93\key{0.93}; the model then delivers 0.89\key{0.89} on real future data. The time-ordered folds promise less, 0.90\key{0.90}, and spread more (0.86 to 0.96), and that is useful information: the lowest fold, the third, trained on 2020 and 2021 and was asked about January to September 2022, the year the market fell without a crash; the highest, the fifth, was asked about the calm May to December of 2023. No fold is a disaster on this window, because the March 2020 crash sits inside the first training block, so every fold has seen one. The gap between the two means is still the shuffled splitter’s optimism, and it is the shuffled number that is wrong.

Note. The rule is older than scikit-learn: validate on data that comes after the data you trained on, the way the real test will. The library will happily shuffle time series for you, because KFold has no idea the rows are dated. Choosing the splitter is your job, and it is the single setting that most changes what a cross-validated score means.

Grid search, on the right splitter

GridSearchCV takes an estimator, a dictionary of settings to try, a splitter and a scoring rule, fits every combination on every fold, and keeps the best. The model__learning_rate syntax (double underscore) reaches into a pipeline step by name, which is why pipelines and grid search fit together. The search below tries 12 combinations for the boosting model, and a second search tries 11 values of the regularisation strength C for the logistic regression.

from sklearn.model_selection import GridSearchCV

settings = {"model__learning_rate": [0.01, 0.03, 0.1, 0.3],       # 4 x 3 = 12 combinations
            "model__max_depth": [2, 3, 5]}
grid = GridSearchCV(gb, settings, cv=TimeSeriesSplit(5), scoring="roc_auc", n_jobs=-1)
grid.fit(X_train, y_train)
print(grid.best_params_, round(grid.best_score_, 3))               # chosen on validation folds only
p = grid.best_estimator_.predict_proba(X_test)[:, 1]
print(round(roc_auc_score(y_test, p), 3))                          # looked at once, after the choice

It prints the chosen settings with their validation AUC, then the test AUC, the first row of Table 5 (the logistic regression search is the same pattern with model__C):

Table 5. Grid search results: settings chosen on validation and their test AUC
Model and searchChosen on validationValidation AUCTest AUC
Gradient boosting, 12 combinationsrate 0.01, depth 30.9100.897
Logistic regression, 11 values of CC = 0.10.9180.891

Panel 2 of Figure 1 shows the boosting grid: the slowest learning rate won, with shallow trees (depth 3, and depth 2 a hair behind), which is the usual answer on small noisy data, and the whole surface spans 0.886 to 0.910 with fold standard deviations around 0.03, so the differences between neighbours are inside the noise. The tuned boosting model reaches 0.897\key{0.897} on the test set, 0.006 above untuned; the tuned logistic regression reaches 0.891\key{0.891}, 0.001 above untuned. Tuning bought almost nothing here, and the grid says why: every cell is within one standard deviation of every other. The test numbers were looked at once, after the choice was made. That is what makes them test numbers. cv_results_ holds every combination’s mean and spread, and reading it is more useful than reading best_params_.

Two habits from the same section of the library. RandomizedSearchCV samples settings instead of trying all of them, and usually finds as good an answer in a fraction of the fits once the grid has more than two or three dimensions. And n_jobs=-1 runs the folds on every core; scikit-learn has no GPU support, and parallel folds is where its speed comes from.

Inspection: what did it learn?

The learned attributes with the trailing underscore are the first place to look (coef_ for a linear model, feature_importances_ for trees). The better tool is permutation importance: shuffle one column of the test set, score again, and see how much was lost. For the tuned boosting model, shuffling the 20-day volatility costs 0.152\risk{0.152} of AUC and shuffling the ticker costs 0.054\risk{0.054}; no other column costs more than 0.002\risk{0.002}. The model is close to a function of two things: this month’s volatility predicts next month’s, and the name does too, because NVDA is above the 30% line in 83% of its test months and SPY in 5%, so the one-hot ticker column is a volatility level in disguise. The random forests post uses the same tool. Panel 3 of Figure 1 shows the three models’ ROC curves on the test rows, close enough that the choice between them comes down to simplicity.

Saving the model

pickle and joblib write any fitted estimator to disk, and the library’s persistence guide gives the two warnings that matter. There is no supported way to load a model into a different version of scikit-learn, so record the version next to the file. And a pickle executes code when loaded, so never load one from a source you do not trust; skops is the format for that case, and ONNX for serving predictions without Python. Save the training script, the data snapshot and the cross-validation score with the model. Without them the file is a number with no history.

Where it stops

scikit-learn works on a table that fits in memory, on CPU, with classical methods. That covers more real problems than the attention paid to the alternatives suggests. The Python stack post says where to go when it is not enough: XGBoost and LightGBM for the last few points of accuracy on a table (both plug into pipelines and grid search unchanged), PyTorch when the input is images, text or audio, Dask or Spark when the table does not fit one machine. Two more limits are not in the manual: there is no time-series forecasting in the library (you build the lagged features yourself, as this example did, and then it is a table), and the defaults are tuned for independent rows, so every splitter, every shuffle and every importance measure needs a second look when the rows are dated.

Why banks use it

  • The interface is auditable: a pipeline is a list of named steps with stored settings, and get_params() prints the whole thing. A model-risk reviewer can read it.
  • Determinism: random_state everywhere, so a result reproduces.
  • Linear models and trees, the methods a regulator will accept an explanation for, are first-class, with the inspection tools beside them.
  • It runs on the machine the data is already on. No cluster, no GPU, no new infrastructure to approve.
The script behind all the numbers

Every table and the chart come from examples/scikit-learn/stress_month.py, which also holds the confusion matrix, the balanced class weights, the logistic regression search and the permutation importance. To run it yourself, clone the examples repo: its README has a three-command Docker setup, or run uv run scikit-learn/stress_month.py.

Summary

Table 6 is the list of habits.

Table 6. Seven habits for a scikit-learn model and the reason for each
HabitWhy
Preprocessing inside the Pipelinethe scaler, imputer and encoder learn from training rows only, in every fold
A fresh preprocessor per pipeline, or cloneestimators are stateful and Pipeline fits in place
TimeSeriesSplit on dated rowsshuffled folds leak neighbours and promised 0.93 where the test gave 0.89
AUC or average precision, and the confusion matrixaccuracy rewards saying “calm”; the cut-off is a decision, not a default
Grid search on validation folds, test oncethe test score is only a test score if the choice never saw it
Permutation importancethe model here is nearly two features, volatility and ticker, and you should know that
Baseline firstDummyClassifier, then a scaled linear model, which stayed within 0.003 of AUC of the forest here

References

Tagged python, machine-learning, scikit-learn, tooling← Home