Deployment#

Deployment of machine learning models requires repeating feature engineering steps on new data. In some cases, these steps need to be performed in near real-time. Featuretools has capabilities to ease the deployment of feature engineering.

Saving Features#

First, let’s build some generate some training and test data in the same format. We use a random seed to generate different data for the test.

Note

Features saved in one version of Featuretools are not guaranteed to load in another. This means the features might need to be re-created after upgrading Featuretools.

[1]:
import featuretools as ft

es_train = ft.demo.load_mock_customer(return_entityset=True)
es_test = ft.demo.load_mock_customer(return_entityset=True, random_seed=33)

Now let’s build some features definitions using DFS. Because we have categorical features, we also encode them with one hot encoding based on the values in the training data.

[2]:
feature_matrix, feature_defs = ft.dfs(
    entityset=es_train, target_dataframe_name="customers"
)

feature_matrix_enc, features_enc = ft.encode_features(feature_matrix, feature_defs)
feature_matrix_enc
[2]:
COUNT(sessions) NUM_UNIQUE(sessions.device) COUNT(transactions) MAX(transactions.amount) MEAN(transactions.amount) MIN(transactions.amount) NUM_UNIQUE(transactions.product_id) SKEW(transactions.amount) STD(transactions.amount) SUM(transactions.amount) ... MODE(sessions.MODE(transactions.product_id)) is unknown MODE(sessions.MONTH(session_start)) = 1 MODE(sessions.MONTH(session_start)) is unknown MODE(sessions.WEEKDAY(session_start)) = 2 MODE(sessions.WEEKDAY(session_start)) is unknown MODE(sessions.YEAR(session_start)) = 2014 MODE(sessions.YEAR(session_start)) is unknown MODE(transactions.sessions.device) = mobile MODE(transactions.sessions.device) = desktop MODE(transactions.sessions.device) is unknown
customer_id
5 6 3 79 149.02 80.375443 7.55 5 -0.025941 44.095630 6349.66 ... False True False True False True False True False False
4 8 3 109 149.95 80.070459 5.73 5 -0.036348 45.068765 8727.68 ... False True False True False True False True False False
1 8 3 126 139.43 71.631905 5.81 5 0.019698 40.442059 9025.62 ... False True False True False True False True False False
3 6 3 93 149.15 67.060430 5.89 5 0.418230 43.683296 6236.62 ... False True False True False True False False True False
2 7 3 93 146.81 77.422366 8.73 5 0.098259 37.705178 7200.28 ... False True False True False True False False True False

5 rows × 121 columns

Now, we can use featuretools.save_features to save a list features to a json file

[3]:
ft.save_features(features_enc, "feature_definitions.json")

Calculating Feature Matrix for New Data#

We can use featuretools.load_features to read in a list of saved features to calculate for our new entity set.

[4]:
saved_features = ft.load_features("feature_definitions.json")

After we load the features back in, we can calculate the feature matrix.

[5]:
feature_matrix = ft.calculate_feature_matrix(saved_features, es_test)
feature_matrix
[5]:
zip_code = 60091 zip_code = 13244 zip_code is unknown COUNT(sessions) MODE(sessions.device) = mobile MODE(sessions.device) = desktop MODE(sessions.device) is unknown NUM_UNIQUE(sessions.device) COUNT(transactions) MAX(transactions.amount) ... SUM(sessions.MAX(transactions.amount)) SUM(sessions.MEAN(transactions.amount)) SUM(sessions.MIN(transactions.amount)) SUM(sessions.NUM_UNIQUE(transactions.product_id)) SUM(sessions.SKEW(transactions.amount)) SUM(sessions.STD(transactions.amount)) MODE(transactions.sessions.device) = mobile MODE(transactions.sessions.device) = desktop MODE(transactions.sessions.device) is unknown NUM_UNIQUE(transactions.sessions.device)
customer_id
1 True False False 6 False True False 3 73 147.64 ... 834.08 524.919674 198.92 25.0 -1.546156 217.064024 True False False 3
4 False True False 9 False True False 3 126 147.55 ... 1180.90 733.862898 193.08 43.0 -1.797214 319.497611 False True False 3
3 True False False 5 True False False 2 64 148.09 ... 715.80 407.390549 108.69 23.0 0.353061 215.417211 True False False 2
2 False True False 8 False True False 3 129 148.34 ... 1100.82 615.714934 136.01 39.0 -0.082021 315.817331 False True False 3
5 True False False 7 False True False 3 108 149.53 ... 997.48 584.302915 137.50 33.0 -0.595128 261.535265 False True False 3

5 rows × 121 columns

As you can see above, we have the exact same features as before, but calculated using the test data.

Exporting Feature Matrix#

Save as csv#

The feature matrix is a pandas DataFrame that we can save to disk

[6]:
feature_matrix.to_csv("feature_matrix.csv")

We can also read it back in as follows:

[7]:
import pandas as pd

saved_fm = pd.read_csv("feature_matrix.csv", index_col="customer_id")
saved_fm
[7]:
zip_code = 60091 zip_code = 13244 zip_code is unknown COUNT(sessions) MODE(sessions.device) = mobile MODE(sessions.device) = desktop MODE(sessions.device) is unknown NUM_UNIQUE(sessions.device) COUNT(transactions) MAX(transactions.amount) ... SUM(sessions.MAX(transactions.amount)) SUM(sessions.MEAN(transactions.amount)) SUM(sessions.MIN(transactions.amount)) SUM(sessions.NUM_UNIQUE(transactions.product_id)) SUM(sessions.SKEW(transactions.amount)) SUM(sessions.STD(transactions.amount)) MODE(transactions.sessions.device) = mobile MODE(transactions.sessions.device) = desktop MODE(transactions.sessions.device) is unknown NUM_UNIQUE(transactions.sessions.device)
customer_id
1 True False False 6 False True False 3 73 147.64 ... 834.08 524.919674 198.92 25.0 -1.546156 217.064024 True False False 3
4 False True False 9 False True False 3 126 147.55 ... 1180.90 733.862898 193.08 43.0 -1.797214 319.497611 False True False 3
3 True False False 5 True False False 2 64 148.09 ... 715.80 407.390549 108.69 23.0 0.353061 215.417211 True False False 2
2 False True False 8 False True False 3 129 148.34 ... 1100.82 615.714934 136.01 39.0 -0.082021 315.817331 False True False 3
5 True False False 7 False True False 3 108 149.53 ... 997.48 584.302915 137.50 33.0 -0.595128 261.535265 False True False 3

5 rows × 121 columns