<jupyter_start><jupyter_text>Pipeline and Export* _Pipelines_ allow to have a well defined sequence of processing steps shared for training and production  * have the same interface as a pure classifier, easy replacement for pure classfier* _ColumnTransformer_ bundle transformations for each column individually  Links* https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.Pipeline.html* https://scikit-learn.org/0.21/modules/compose.htmlcolumn-transformer* https://scikit-learn.org/stable/modules/model_persistence.html* https://scikit-learn.org/0.21/modules/generated/sklearn.compose.ColumnTransformer.html<jupyter_code>!rm -rf data && mkdir data && cd data && curl https://raw.githubusercontent.com/DJCordhose/ml-workshop/master/data/insurance-customers-1500.csv -O && cd -
!ls -l data
import pandas as pd
df = pd.read_csv('data/insurance-customers-1500.csv', sep=';')
stats = df.describe()
stats
y=df['group']
df.drop('group', axis='columns', inplace=True)
X = df.values
X
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
X_train.shape, y_train.shape, X_test.shape, y_test.shape
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

from sklearn.compose import make_column_transformer
from sklearn.compose import ColumnTransformer

from sklearn.pipeline import Pipeline
column_trans = ColumnTransformer([], remainder=StandardScaler())
column_trans.fit_transform(X)
pca = PCA()
pca
from sklearn.ensemble import RandomForestClassifier
rf_clf = clf = RandomForestClassifier(max_depth=9, min_samples_leaf=9, min_samples_split=3, n_estimators=7, n_jobs=-1)
clf = Pipeline([('standardise', column_trans), ('reduce_dim', PCA()), ('clf', rf_clf)])
%time clf.fit(X_train, y_train)
train_score = clf.score(X_train, y_train)
train_score
test_score = clf.score(X_test, y_test)
test_score
from sklearn.model_selection import cross_val_score
cross_val_scores = cross_val_score(clf, X_train, y_train, n_jobs=-1, cv=10)
cross_val_scores
# mean score and the 95% confidence interval (2 standard deviations assuming normal distribution)
print("Accuracy: %0.2f (+/- %0.2f)" % (cross_val_scores.mean(), cross_val_scores.std() * 2))
scores = {
    'cross_val_scores': cross_val_scores,
    'train_score': train_score,
    'test_score': test_score
}
scores
!rm -rf models && mkdir models
import pickle

pickle.dump(clf, open('models/model.pickle', 'wb'))
!rm -rf stats && mkdir stats
# has the distribution of the data changed substantially?
pickle.dump(stats, open('stats/describe.pickle', 'wb'))
# has the score descread since last time or is suspiciously different?
pickle.dump(scores, open('stats/scores.pickle', 'wb'))
import numpy, sklearn, pandas

model_name = 'pipeline_pca_std_rf'
model_version = 2

versions = {
    'numpy': numpy.__version__,
    'sklearn': sklearn.__version__, 
    'pandas': pandas.__version__,
    'model': model_version,
    'model_name': model_name
}
versions
# we need to have exactly the same versions for serving
pickle.dump(versions, open('stats/versions.pickle', 'wb'))
!ls -l stats
!ls -l
# we also need the code that created this to have it reproduceable
!cd models
!curl https://raw.githubusercontent.com/DJCordhose/ml-workshop/master/notebooks/process/export-pipeline.ipynb -O
!cd -
!ls -l models
file_name = 'prod_{0}_{1}.tgz'.format(model_name, model_version)
file_name
# have everything we need to reproduce and compare to other versions here
# better to version this 
# often versioning data is a challenge simply because of its size
!tar -czf $file_name models stats data
!ls -l
!date<jupyter_output>Sat Aug  3 16:38:45 UTC 2019<jupyter_text>Exercise: Export your favorite model* run this notebook* modify to choose any strategy you like* chain together different / additional steps in a pipeline* can you add a normaizer?* PCA to less dimensions?* rather use T-SNE or UMAP?finally download the complete archieve for production for the next step<jupyter_code><jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10824742268041238, 'fraction_numerical': 0.011782032400589101, 'mean_word_length': 5.883445945945946, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '608231', 'license': 'MIT', 'n_tokens_mistral': 1375, 'n_tokens_neox': 1320, 'n_words': 375, 'path': 'notebooks/process/export-pipeline.ipynb', 'repo_name': 'kmunve/ml-workshop', 'size': '4074'}