この練習では、レシピを作成して、モデルを使用し、Adobe Experience Platformで操作します。
レシピビルダーのノートブックは、モデルを自動的にパッケージ化して操作できるようにテンプレート化します。 ノートブックには、モデルコードを次の場所に合わせた複数のテンプレート化されたセルがあります。
モデルのトレーニング、評価、スコアリングを規模別に行い、Adobe Experience Platformでシームレスに1つのフローにパッケージ化できるので、モデルの運用に必要な手順を合理化しました。 また、レシピにパッケージ化すると、異なるデータセットを持つ同じコードを使用して、組織内の異なる使用例に電力を供給することもできます。 アドビの具体的な使用例は、Webサイトで購入する製品を検索するユーザーに対して、recommendationsモデルコードの使用に関するものです。
次のURLに移動してAdobe Experience Platformにログインします。 https://experience.adobe.com/platform.
ログインした後、Adobe Experience Platformのホームページに移動します。
続行する前に、 Sandboxを選択する必要があります。 選択するサンドボックスに名前が付けられ --aepSandboxId--
ます。 これを行うには、画面上の青い線で「 実稼働 」というテキストをクリックします。
適切なサンドボックスを選択すると、画面の変更が表示され、専用のサンドボックスに移動します。
Adobe Experience Platformで、画面の左側のメニューで [ノートブック] をクリックし、 JupyterLabに移動します。
「Jupyter Notebooks」で、タスクバーの + アイコンをクリックして「 Launcher 」ページを開きます。
次の図が表示されます。
ランチャーの「 レシピビルダー 」ボタンをクリックして、空のレシピビルダーノートブックを開きます。
その後、空の空の新しいRecipe Builderノートブックが作成されます。 続行する前に、ノートブックにわかりやすい名前を付けてください。 [Python 3] Recipe Builder.ipynb ファイルを右クリックし、「 名前の変更」をクリックします。
ノートブックの名前として mutual365-insurance-sales-propentity.ipynb を入力し、 Enterを押します。 その後、次の手順を実行します。
このノートブックでは、次の操作を行います。
すべての手順を詳細に設定します。
「 設定ファイル」が表示されるまで、Recipe Builderノートブック内を下にスクロールします。
次に、トレー ニング設定 および スコア設定のセルを更新する必要があります。
「 トレーニング設定」のセル内をクリックします。
何をする前に気をつけて!! 何を行っても、 %%writefileを使って開始を削除したり、上書きしたりしないでください。 この行は、Recipe Builderノートブックで必要です。
%%writefile ~/my-workspace/.recipes/recipe-tFgHWnuH5/training.conf
同じセルにも同様のコードが表示されます。
{
"trainingDataSetId": "<replace with training dataset id>",
"ACP_DSW_TRAINING_XDM_SCHEMA": "<replace with training xdm schema id>",
"tenantId": "_<tenant_id>",
"learning_rate": "0.1",
"n_estimators": "100",
"max_depth": "3"
}
そのコードを次のコードで置き換えます。
{
"trainingDataSetId": "--aepCarInsuranceInteractionsDatasetId--",
"ACP_DSW_TRAINING_XDM_SCHEMA": "https://ns.adobe.com/--aepTenantIdSchema--/schemas/--aepCarInsuranceInteractionsSchemaRef--",
"train_records_limit":1000000,
"n_estimators": "80",
"max_depth": "5",
"ten_id": "--aepTenantId--"
}
環境変数 aepCarInsuranceInteractionsDatasetId とaepCarInsuranceInteractionsSchemaRef は、Adobe Experience Platformインスタンスで作成されたデータセットのデータセットIDと、Adobe Experience Platformインスタンスで作成されたスキーマのスキーマ参照IDを参照します。
aepCarInsuranceInteractionsDatasetId は、Webサイトのデータセット デモシステム —イベントデータセット(グローバルv1.1)のデータセットIDを参照します。 aepCarInsuranceInteractionsSchemaRef は、スキーマ デモイベントスキーマ用のスキーマ参照IDを参照します。Webサイト(グローバルv1.1)。 ノートブックの「 トレーニング設定 」セルにコードを貼り付けるときは、環境変数をデータセットIDとスキーマ参照IDで置き換えます。
これで、「 Training Configuration 」セルに似たような内容になります。
「 スコアリング設定」のセル内をクリックします。
何をする前に気をつけて!! 何を行っても、 %%writefileを使って開始を削除したり、上書きしたりしないでください。 この行は、Recipe Builderノートブックで必要です。
%%writefile ~/my-workspace/.recipes/recipe-tFgHWnuH5/scoring.conf
同じセルにも同様のコードが表示されます。
{
"scoringDataSetId": "<replace with scoring input dataset id>",
"scoringResultsDataSetId": "<replace with scoring results dataset id>",
"ACP_DSW_SCORING_RESULTS_XDM_SCHEMA": "<replace with scoring results xdm schema id>",
"tenantId": "_<tenant_id>"
}
そのコードを次のコードで置き換えます。
{
"scoringDataSetId": "--aepCarInsuranceInteractionsDatasetId--",
"scoringResultsDataSetId": "--aepMlPredictionsDatasetId--",
"ACP_DSW_SCORING_RESULTS_XDM_SCHEMA": "https://ns.adobe.com/--aepTenantIdSchema--/schemas/--aepMlPredictionsSchemaRef--",
"ten_id": "--aepTenantId--"
}
環境変数 aepCarInsuranceInteractionsDatasetId、aepMlPredictionsDatasetId 、 aepMlPredictionsSchemaRef は、Adobe Experience Platformインスタンスで作成されたスキーマのデータセットIDとスキーマ参照IDを参照します。
aepCarInsuranceInteractionsDatasetId は、Webサイト(グローバルv1.1)のデータセット デモシステム —イベントデータセット(Global v1.1)のデータセットIDを参照します。 aepMlPredictionDatasetId は、MLのデ ータセットデモシステム —プロファイルデータセット予測(グローバルv1.1********, ML予測MlPredicationsep SchemaRefRefSystemスキーマスキーマRef ID IDの参照プロファイルML予測(グローバルv1)スキーマスキーマの ノートブックの「 スコアリング設定 」セルにコードを貼り付けるときは、環境変数をデータセットIDとスキーマ参照IDで置き換えます。
これで、「 スコアリング設定 」セルに似たような内容になります。
Recipe Builderノートブックを下にスクロールして、 トレーニングデータローダーファイルが表示されます。
次に、ト レーニングデータローダーファイルのコードを更新する必要があります。
何をする前に気をつけて!! 何を行っても、 %%writefileを使って開始を削除したり、上書きしたりしないでください。 この行は、Recipe Builderノートブックで必要です。
このセルには、次のようなコードが表示されます。
import pandas as pd
from datetime import datetime, timedelta
from platform_sdk.dataset_reader import DatasetReader
from .utils import get_client_context
def load(config_properties):
print("Training Data Load Start")
#########################################
# Load Data
#########################################
client_context = get_client_context(config_properties)
dataset_reader = DatasetReader(client_context, config_properties['trainingDataSetId'])
timeframe = config_properties.get("timeframe")
tenant_id = config_properties.get("tenant_id")
if (timeframe is not None):
date_before = datetime.utcnow().date()
date_after = date_before - timedelta(minutes=int(timeframe))
dataframe = dataset_reader.where(dataset_reader[tenant_id + '.date'].gt(str(date_after)).And(dataset_reader[tenant_id + '.date'].lt(str(date_before)))).read()
else:
dataframe = dataset_reader.read()
if '_id' in dataframe.columns:
#Rename columns to strip tenantId
dataframe = dataframe.rename(columns = lambda x : str(x)[str(x).find('.')+1:])
#Drop id and timestamp
dataframe.drop(['_id', 'timestamp'], axis=1, inplace=True)
#########################################
# Data Preparation/Feature Engineering
#########################################
dataframe.date = pd.to_datetime(dataframe.date)
dataframe['week'] = dataframe.date.dt.week
dataframe['year'] = dataframe.date.dt.year
dataframe = pd.concat([dataframe, pd.get_dummies(dataframe['storeType'])], axis=1)
dataframe.drop('storeType', axis=1, inplace=True)
dataframe['isHoliday'] = dataframe['isHoliday'].astype(int)
dataframe['weeklySalesAhead'] = dataframe.shift(-45)['weeklySales']
dataframe['weeklySalesLag'] = dataframe.shift(45)['weeklySales']
dataframe['weeklySalesDiff'] = (dataframe['weeklySales'] - dataframe['weeklySalesLag']) / dataframe['weeklySalesLag']
dataframe.dropna(0, inplace=True)
dataframe = dataframe.set_index(dataframe.date)
dataframe.drop('date', axis=1, inplace=True)
print("Training Data Load Finish")
return dataframe
このコードを( %%writefile 行を上書きせずに)次のコードで置き換えます。
import numpy as np
import pandas as pd
from datetime import datetime, timedelta
from platform_sdk.dataset_reader import DatasetReader
from .utils import get_client_context
def load(config_properties):
print("Training Data Load Start")
#########################################
# Load Data
#########################################
client_context = get_client_context(config_properties)
train_records_limit = config_properties['train_records_limit']
dataset_reader = DatasetReader(client_context, config_properties['trainingDataSetId'])
#timeframe = config_properties.get("timeframe")
#tenant_id = config_properties.get("tenant_id")
print('Reading Training Data')
df1 = dataset_reader.limit(train_records_limit).read()
df1.rename(columns = {config_properties['ten_id']+'.identification.core.ecid' : 'ecid',
config_properties['ten_id']+'.interactionDetails.insurance.car.numberKm': 'km',
config_properties['ten_id']+'.interactionDetails.insurance.car.type': 'cartype',
config_properties['ten_id']+'.interactionDetails.insurance.car.customerAge': 'age',
config_properties['ten_id']+'.interactionDetails.insurance.car.customerGender' : 'gender',
config_properties['ten_id']+'.interactionDetails.insurance.car.brand' : 'carbrand',
config_properties['ten_id']+'.interactionDetails.insurance.car.leasing' : 'leasing',
config_properties['ten_id']+'.interactionDetails.insurance.car.customerCity' : 'city',
config_properties['ten_id']+'.interactionDetails.insurance.car.customerCountry' : 'country',
config_properties['ten_id']+'.interactionDetails.insurance.car.customerNationality' : 'nationality',
config_properties['ten_id']+'.interactionDetails.insurance.car.isCustomerPrimaryDriver' : 'primaryuser',
config_properties['ten_id']+'.interactionDetails.insurance.car.hasCustomerPurchased' : 'purchase',
config_properties['ten_id']+'.interactionDetails.insurance.car.priceBasic' : 'pricequote'}, inplace=True)
df1 = df1[['ecid', 'km', 'cartype', 'age', 'gender', 'carbrand', 'leasing', 'city',
'country', 'nationality', 'primaryuser', 'purchase', 'pricequote', 'timestamp']]
df1 = df1.loc[df1['age'] != 0]
#########################################
# Data Rollup
#########################################
df1['timestamp'] = pd.to_datetime(df1.timestamp)
df1['hour'] = df1['timestamp'].dt.hour.astype(int)
df1['dayofweek'] = df1['timestamp'].dt.dayofweek
df1.loc[(df1['purchase'] == 'true'), 'purchase'] = 1
df1.loc[(df1['purchase'] == 'false'), 'purchase'] = 0
df1.loc[(df1['purchase'] == ''), 'purchase'] = 0
df1.purchase.fillna(0, inplace=True)
df1['purchase'] = df1['purchase'].astype(int)
df1.dropna(subset = ['ecid'], inplace=True)
df1['ecid'] = df1['ecid'].astype(str)
df_conv_dict = df1.groupby('ecid').max()[['purchase']]
df_conv_dict = df_conv_dict.to_dict()
idx = df1.groupby('ecid')['timestamp'].transform(max) == df1['timestamp']
df1 = df1[idx]
df1 = df1.drop_duplicates(subset = 'ecid', keep = 'last', inplace = False)
#df1['purchase'] = df1['ecid'].map(df_conv_dict['purchase'])
#########################################
# Data Preparation/Feature Engineering
#########################################
df1['carbrand'] = df1['carbrand'].str.lower()
df1['country'] = df1['country'].str.lower()
df1.loc[(df1['carbrand'] == 'vw'), 'carbrand'] = 'volkswagen'
df1.loc[(df1['carbrand'] == 'citroen'), 'carbrand'] = 'cadillac'
df1.loc[(df1['carbrand'] == 'opel'), 'carbrand'] = 'bmw'
df1.loc[(df1['carbrand'] == 'mini'), 'carbrand'] = 'volkswagen'
df1.loc[(df1['cartype'] == 'SUV / Geländewagen') | (df1['cartype'] == 'SUV / Tout terrain'), 'cartype'] = 'suv'
df1.loc[(df1['cartype'] == 'Kleinwagen') | (df1['cartype'] == 'Untere Mittelklasse') | (df1['cartype'] == 'Mikroklasse'), 'cartype'] = 'hatchback'
df1.loc[(df1['cartype'] == 'Mittelklasse') | (df1['cartype'] == 'Obere Mittelklasse'), 'cartype'] = 'sedan'
df1.loc[(df1['cartype'] == 'Kompaktvan / Minivan'), 'cartype'] = 'minivan'
df1.loc[(df1['cartype'] == 'Cabriolet / Roadster'), 'cartype'] = 'convertible'
df1.loc[(df1['cartype'] == 'Coupé / Sportwagen'), 'cartype'] = 'coupe'
df1.loc[(df1['cartype'] == 'dataLayerNull'), 'cartype'] = pd.np.nan
df1.loc[(df1['cartype'] == 'Luxusklasse'), 'cartype'] = 'luxury'
df1.loc[(df1['cartype'] == 'Strasse'), 'cartype'] = 'mpv'
df1.loc[(df1['leasing'] == 'false'), 'leasing'] = 'no'
df1.loc[df1['country'] == 'at', 'country'] = 'austria'
df1.loc[(df1['leasing'] == 'dataLayerNull'), 'leasing'] = pd.np.nan
df1.loc[(df1['gender'] == 'dataLayerNull'), 'gender'] = pd.np.nan
df1.loc[(df1['carbrand'] == 'dataLayerNull'), 'carbrand'] = pd.np.nan
df1['age'].fillna(df1['age'].median(), inplace=True)
df1['gender'].fillna('notgiven', inplace=True)
df1['leasing'].fillna('notgiven', inplace=True)
df1['carbrand'].fillna('bmw', inplace=True)
df1['country'].fillna('germany', inplace=True)
df1['cartype'].fillna('na', inplace=True)
df1['primaryuser'].fillna('na', inplace=True)
df1['nationality'].fillna('na', inplace=True)
df1['km'].fillna('na', inplace=True)
df1['city'] = df1.groupby('country')['city'].transform(lambda x : x.fillna(x.mode()))
#df1.dropna(subset = ['pricequote'], inplace=True)
#grouping
grouping_cols = ['carbrand', 'cartype', 'city', 'country']
for col in grouping_cols:
df_idx = pd.DataFrame(df1[col].value_counts().head(6))
def grouping(x):
if x in df_idx.index:
return x
else:
return "Others"
df1[col] = df1[col].apply(lambda x: grouping(x))
def age(x):
if x < 20:
return "u20"
elif x > 19 and x < 29:
return "20-28"
elif x > 28 and x < 43:
return "29-42"
elif x > 42 and x < 55:
return "43-54"
elif x > 54 and x < 65:
return "55-64"
elif x >= 65:
return "65+"
else:
return "Others"
df1['age'] = df1['age'].astype(int)
df1['age_bucket'] = df1['age'].apply(lambda x: age(x))
df_final = df1[['hour', 'dayofweek','age_bucket', 'gender', 'city',
'country', 'carbrand', 'cartype', 'leasing', 'pricequote', 'purchase']]
cat_cols = ['age_bucket', 'gender', 'city', 'dayofweek', 'country', 'carbrand', 'cartype', 'leasing']
df_final = pd.get_dummies(df_final, columns = cat_cols)
dataframe = df_final.copy()
df_final.head(20)
print("Training Data Load Finish")
return dataframe
これで、「 Training Data Loader File 」セルに似たような内容になりました。
「 スコアリングデータローダーファイル」が表示されるまで、Recipe Builderノートブック内を下にスクロールします。
次に、 スコアリングデータローダーファイルのコードを更新する必要があります。
何をする前に気をつけて!! 何を行っても、 %%writefileを使って開始を削除したり、上書きしたりしないでください。 この行は、Recipe Builderノートブックで必要です。
このセルには、次のようなコードが表示されます。
import pandas as pd
from datetime import datetime, timedelta
from .utils import get_client_context
from platform_sdk.dataset_reader import DatasetReader
def load(config_properties):
print("Scoring Data Load Start")
#########################################
# Load Data
#########################################
client_context = get_client_context(config_properties)
dataset_reader = DatasetReader(client_context, config_properties['scoringDataSetId'])
timeframe = config_properties.get("timeframe")
tenant_id = config_properties.get("tenant_id")
if (timeframe is not None):
date_before = datetime.utcnow().date()
date_after = date_before - timedelta(minutes=int(timeframe))
dataframe = dataset_reader.where(dataset_reader[tenant_id + '.date'].gt(str(date_after)).And(dataset_reader[tenant_id + '.date'].lt(str(date_before)))).read()
else:
dataframe = dataset_reader.read()
print(dataframe)
#########################################
# Data Preparation/Feature Engineering
#########################################
if '_id' in dataframe.columns:
#Rename columns to strip tenantId
dataframe = dataframe.rename(columns = lambda x : str(x)[str(x).find('.')+1:])
#Drop id and timestamp
dataframe.drop(['_id', 'timestamp'], axis=1, inplace=True)
dataframe.date = pd.to_datetime(dataframe.date)
dataframe['week'] = dataframe.date.dt.week
dataframe['year'] = dataframe.date.dt.year
dataframe = pd.concat([dataframe, pd.get_dummies(dataframe['storeType'])], axis=1)
dataframe.drop('storeType', axis=1, inplace=True)
dataframe['isHoliday'] = dataframe['isHoliday'].astype(int)
dataframe['weeklySalesAhead'] = dataframe.shift(-45)['weeklySales']
dataframe['weeklySalesLag'] = dataframe.shift(45)['weeklySales']
dataframe['weeklySalesDiff'] = (dataframe['weeklySales'] - dataframe['weeklySalesLag']) / dataframe['weeklySalesLag']
dataframe.dropna(0, inplace=True)
dataframe = dataframe.set_index(dataframe.date)
dataframe.drop('date', axis=1, inplace=True)
print("Scoring Data Load Finish")
return dataframe
このコードを( %%writefile 行を上書きせずに)次のコードで置き換えます。
import pandas as pd
from datetime import datetime, timedelta
from .utils import get_client_context
from platform_sdk.dataset_reader import DatasetReader
def load(config_properties):
print("Scoring Data Load Start")
#########################################
# Load Data
#########################################
client_context = get_client_context(config_properties)
dataset_reader = DatasetReader(client_context, config_properties['scoringDataSetId'])
#timeframe = config_properties.get("timeframe")
#tenant_id = config_properties.get("tenant_id")
df1 = dataset_reader.read()
df1.rename(columns = {config_properties['ten_id']+'.identification.core.ecid' : 'ecid',
config_properties['ten_id']+'.interactionDetails.insurance.car.numberKm': 'km',
config_properties['ten_id']+'.interactionDetails.insurance.car.type': 'cartype',
config_properties['ten_id']+'.interactionDetails.insurance.car.customerAge': 'age',
config_properties['ten_id']+'.interactionDetails.insurance.car.customerGender' : 'gender',
config_properties['ten_id']+'.interactionDetails.insurance.car.brand' : 'carbrand',
config_properties['ten_id']+'.interactionDetails.insurance.car.leasing' : 'leasing',
config_properties['ten_id']+'.interactionDetails.insurance.car.customerCity' : 'city',
config_properties['ten_id']+'.interactionDetails.insurance.car.customerCountry' : 'country',
config_properties['ten_id']+'.interactionDetails.insurance.car.customerNationality' : 'nationality',
config_properties['ten_id']+'.interactionDetails.insurance.car.isCustomerPrimaryDriver' : 'primaryuser',
config_properties['ten_id']+'.interactionDetails.insurance.car.hasCustomerPurchased' : 'purchase',
config_properties['ten_id']+'.interactionDetails.insurance.car.priceBasic' : 'pricequote'}, inplace=True)
df1 = df1[['ecid', 'km', 'cartype', 'age', 'gender', 'carbrand', 'leasing', 'city',
'country', 'nationality', 'primaryuser', 'purchase', 'pricequote', 'timestamp']]
df1 = df1.loc[df1['age'] != 0]
#########################################
# Data Rollup
#########################################
df1['timestamp'] = pd.to_datetime(df1.timestamp)
df1['hour'] = df1['timestamp'].dt.hour.astype(int)
df1['dayofweek'] = df1['timestamp'].dt.dayofweek
df1.loc[(df1['purchase'] == 'true'), 'purchase'] = 1
df1.loc[(df1['purchase'] == 'false'), 'purchase'] = 0
df1.loc[(df1['purchase'] == ''), 'purchase'] = 0
df1.purchase.fillna(0, inplace=True)
df1['purchase'] = df1['purchase'].astype(int)
df1.dropna(subset = ['ecid'], inplace=True)
df1['ecid'] = df1['ecid'].astype(str)
df_conv_dict = df1.groupby('ecid').max()[['purchase']]
df_conv_dict = df_conv_dict.to_dict()
idx = df1.groupby('ecid')['timestamp'].transform(max) == df1['timestamp']
df1 = df1[idx]
df1 = df1.drop_duplicates(subset = 'ecid', keep = 'last', inplace = False)
df1['purchase'] = df1['ecid'].map(df_conv_dict['purchase'])
#########################################
# Data Preparation/Feature Engineering
#########################################
df1['carbrand'] = df1['carbrand'].str.lower()
df1['country'] = df1['country'].str.lower()
df1.loc[(df1['carbrand'] == 'vw'), 'carbrand'] = 'volkswagen'
df1.loc[(df1['carbrand'] == 'citroen'), 'carbrand'] = 'cadillac'
df1.loc[(df1['carbrand'] == 'opel'), 'carbrand'] = 'bmw'
df1.loc[(df1['carbrand'] == 'mini'), 'carbrand'] = 'volkswagen'
df1.loc[(df1['cartype'] == 'SUV / Geländewagen') | (df1['cartype'] == 'SUV / Tout terrain'), 'cartype'] = 'suv'
df1.loc[(df1['cartype'] == 'Kleinwagen') | (df1['cartype'] == 'Untere Mittelklasse') | (df1['cartype'] == 'Mikroklasse'), 'cartype'] = 'hatchback'
df1.loc[(df1['cartype'] == 'Mittelklasse') | (df1['cartype'] == 'Obere Mittelklasse'), 'cartype'] = 'sedan'
df1.loc[(df1['cartype'] == 'Kompaktvan / Minivan'), 'cartype'] = 'minivan'
df1.loc[(df1['cartype'] == 'Cabriolet / Roadster'), 'cartype'] = 'convertible'
df1.loc[(df1['cartype'] == 'Coupé / Sportwagen'), 'cartype'] = 'coupe'
df1.loc[(df1['cartype'] == 'dataLayerNull'), 'cartype'] = pd.np.nan
df1.loc[(df1['cartype'] == 'Luxusklasse'), 'cartype'] = 'luxury'
df1.loc[(df1['cartype'] == 'Strasse'), 'cartype'] = 'mpv'
df1.loc[(df1['leasing'] == 'false'), 'leasing'] = 'no'
df1.loc[df1['country'] == 'at', 'country'] = 'austria'
df1.loc[(df1['leasing'] == 'dataLayerNull'), 'leasing'] = pd.np.nan
df1.loc[(df1['gender'] == 'dataLayerNull'), 'gender'] = pd.np.nan
df1.loc[(df1['carbrand'] == 'dataLayerNull'), 'carbrand'] = pd.np.nan
df1['age'].fillna(df1['age'].median(), inplace=True)
df1['gender'].fillna('notgiven', inplace=True)
df1['leasing'].fillna('notgiven', inplace=True)
df1['carbrand'].fillna('bmw', inplace=True)
df1['country'].fillna('germany', inplace=True)
df1['cartype'].fillna('na', inplace=True)
df1['primaryuser'].fillna('na', inplace=True)
df1['nationality'].fillna('na', inplace=True)
df1['km'].fillna('na', inplace=True)
df1['city'] = df1.groupby('country')['city'].transform(lambda x : x.fillna(x.mode()))
df1.dropna(subset = ['pricequote'], inplace=True)
#grouping
grouping_cols = ['carbrand', 'cartype', 'city', 'country']
for col in grouping_cols:
df_idx = pd.DataFrame(df1[col].value_counts().head(6))
def grouping(x):
if x in df_idx.index:
return x
else:
return "Others"
df1[col] = df1[col].apply(lambda x: grouping(x))
def age(x):
if x < 20:
return "u20"
elif x > 19 and x < 29:
return "20-28"
elif x > 28 and x < 43:
return "29-42"
elif x > 42 and x < 55:
return "43-54"
elif x > 54 and x < 65:
return "55-64"
elif x >= 65:
return "65+"
else:
return "Others"
df1['age'] = df1['age'].astype(int)
df1['age_bucket'] = df1['age'].apply(lambda x: age(x))
df_final = df1[['ecid', 'hour', 'dayofweek','age_bucket', 'gender', 'city',
'country', 'carbrand', 'cartype', 'leasing', 'pricequote']]
#cat_cols = ['age_bucket', 'gender', 'city', 'dayofweek', 'country', 'carbrand', 'cartype', 'leasing']
#df_final = pd.get_dummies(df_final, columns = cat_cols)
dataframe = df_final.copy()
print("Scoring Data Load Finish")
return dataframe
これで、 スコアリングデータローダーファイル 」セルに似たような内容になります。
Pipeline File (パイプラインファイル)が表示されるまでRecipe Builderノートブック内を下にスクロールします。
次に、 パイプラインファイルのコードを更新する必要があります。
何をする前に気をつけて!! 何を行っても、 %%writefileを使って開始を削除したり、上書きしたりしないでください。 この行は、Recipe Builderノートブックで必要です。
このセルには、次のようなコードが表示されます。
from sklearn.ensemble import GradientBoostingRegressor
def train(config_properties, data):
print("Train Start")
#########################################
# Extract fields from configProperties
#########################################
learning_rate = float(config_properties['learning_rate'])
n_estimators = int(config_properties['n_estimators'])
max_depth = int(config_properties['max_depth'])
#########################################
# Fit model
#########################################
X_train = data.drop('weeklySalesAhead', axis=1).values
y_train = data['weeklySalesAhead'].values
seed = 1234
model = GradientBoostingRegressor(learning_rate=learning_rate,
n_estimators=n_estimators,
max_depth=max_depth,
random_state=seed)
model.fit(X_train, y_train)
print("Train Complete")
return model
def score(config_properties, data, model):
print("Score Start")
X_test = data.drop('weeklySalesAhead', axis=1).values
y_test = data['weeklySalesAhead'].values
y_pred = model.predict(X_test)
data['prediction'] = y_pred
data = data[['store', 'prediction']].reset_index()
data['date'] = data['date'].astype(str)
print("Score Complete")
return data
このコードを( %%writefile 行を上書きせずに)次のコードで置き換えます。
import pandas as pd
import numpy as np
from sklearn import metrics
from sklearn.metrics import roc_curve, auc, mean_squared_error
from sklearn.ensemble import RandomForestClassifier
import os
def underSample(data):
conv = data[data['purchase'] > 0]
non_conv = data[data['purchase'] == 0]
sample_size = len(conv)
non_sample = non_conv.sample(n = sample_size)
frames = [conv, non_sample]
result = pd.concat(frames)
return result
class RandomForest():
def __init__(self, config_properties, X, y):
print("initiating model")
self.n_estimators = int(config_properties['n_estimators'])
self.max_depth = int(config_properties['max_depth'])
self.X = X
self.y = y
self.features = X.columns.values.tolist()
self.model = RandomForestClassifier(n_estimators=self.n_estimators, max_depth=self.max_depth, random_state=32)
self.trained_model = self.model.fit(self.X,self.y)
def train_model(self):
print('fitting model')
return self.model.fit(self.X,self.y)
def make_tarfile(self, output_filename, source_dir):
with tarfile.open(output_filename, "w:gz") as tar:
tar.add(source_dir, arcname=os.path.basename(source_dir))
#for generating onnx
def generate_onnx_resources(self):
install_dir = os.path.expanduser('~/my-workspace')
print("Generating Onnx")
try:
subprocess.check_call(["conda", "uninstall", "-y", "protobuf"])
except:
print("protobuf not installed via conda")
subprocess.check_call(["python", '-m', 'pip', 'install', 'skl2onnx'])
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType
# ONNX-ification
initial_type = [('float_input', FloatTensorType([None, self.feature_len]))]
print("Converting Model to Onnx")
onx = convert_sklearn(self.model, initial_types=initial_type)
with open("model_new.onnx", "wb") as f:
f.write(onx.SerializeToString())
self.make_tarfile('model_new.tar.gz', 'model.onnx')
print("Model onnx created")
def train(config_properties, data):
print("Train Start")
y_train = data['purchase']
X_train = data.drop('purchase', axis=1)
# Fit model
lead_score = RandomForest(config_properties, X_train, y_train)
lead_score.train_model()
print("Train Complete")
return lead_score
def score(config_properties, data, model):
print("Score Start")
cat_cols = ['age_bucket', 'gender', 'city', 'dayofweek', 'country', 'carbrand', 'cartype', 'leasing']
data = pd.get_dummies(data, columns = cat_cols)
X_score = data.drop('ecid', axis=1)
train_feats = model.features
print(train_feats)
trained_model = model.trained_model
score_feats = X_score.columns.values.tolist()
missing_feats = list(set(train_feats) - set(score_feats))
extra_feats = list(set(score_feats) - set(train_feats))
for c in extra_feats:
X_score.drop(c, axis=1, inplace=True)
for c in missing_feats:
X_score[c] = 0
X_score = X_score[train_feats]
print(X_score.columns.values.tolist())
y_preds = trained_model.predict_proba(X_score)[:,1]
data.rename(columns = {'ecid' : config_properties['ten_id']+'.identification.core.ecid'}, inplace=True)
data[config_properties['ten_id']+'.individualScoring.insurance.carInsuranceSalesPrediction'] = y_preds
data = data[[config_properties['ten_id']+'.identification.core.ecid', config_properties['ten_id']+'.individualScoring.insurance.carInsuranceSalesPrediction']]
print("Score Complete")
return data
これで、「 パイプラインファイル 」(Pipeline File)セルに似たようなものが存在するはずです。
Recipe Builderノートブックを下にスクロールして、 評価元ファイルが表示されます。
ここで、 エバリュエーターファイルのコードを更新する必要があります。
何をする前に気をつけて!! 何を行っても、 %%writefileを使って開始を削除したり、上書きしたりしないでください。 この行は、Recipe Builderノートブックで必要です。
このセルには、次のようなコードが表示されます。
from ml.runtime.python.core.regressionEvaluator import RegressionEvaluator
import numpy as np
class Evaluator(RegressionEvaluator):
def __init__(self):
print ("Initiate")
def split(self, config={}, dataframe=None):
train_start = '2010-02-12'
train_end = '2012-01-27'
val_start = '2012-02-03'
train = dataframe[train_start:train_end]
val = dataframe[val_start:]
return train, val
def evaluate(self, data=[], model={}, config={}):
print ("Evaluation evaluate triggered")
val = data.drop('weeklySalesAhead', axis=1)
y_pred = model.predict(val)
y_actual = data['weeklySalesAhead'].values
mape = np.mean(np.abs((y_actual - y_pred) / y_actual))
mae = np.mean(np.abs(y_actual - y_pred))
rmse = np.sqrt(np.mean((y_actual - y_pred) ** 2))
metric = [{"name": "MAPE", "value": mape, "valueType": "double"},
{"name": "MAE", "value": mae, "valueType": "double"},
{"name": "RMSE", "value": rmse, "valueType": "double"}]
print(metric)
return metric
このコードを( %%writefile 行を上書きせずに)次のコードで置き換えます。
from ml.runtime.python.core.regressionEvaluator import RegressionEvaluator
import numpy as np
from sklearn import metrics
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import train_test_split
class Evaluator(RegressionEvaluator):
def __init__(self):
print ("Initiate")
def split(self, config={}, dataframe=None):
train, val = train_test_split(dataframe, test_size = 0.2, random_state = 32)
return train, val
def evaluate(self, data=[], model={}, config={}):
model = model.trained_model
print ("Evaluation evaluate triggered")
val = data.drop('purchase', axis=1)
y_pred = model.predict(val)
y_actual = data['purchase']
y_pred_proba = model.predict_proba(val)[:,1]
accuracy = metrics.accuracy_score(y_actual, y_pred, normalize=True, sample_weight=None)
recall = metrics.recall_score(y_actual, y_pred, labels=None, pos_label=1, average='binary', sample_weight=None)
precision = metrics.precision_score(y_actual, y_pred, labels=None, pos_label=1, average='binary', sample_weight=None)
val_fpr, val_tpr, _ = roc_curve(y_actual, y_pred_proba)
roc_auc = auc(val_fpr, val_tpr)
metric = [{"name": "Accuracy", "value": accuracy, "valueType": "double"},
{"name": "Recall", "value": recall, "valueType": "double"},
{"name": "Precision", "value": precision, "valueType": "double"}]
print(metric)
return metric
これで、 評価基準ファイル セルに似たような要素が表示されます。
Recipe Builderノートブックを下にスクロールして、[ Data Saver File]が表示されるまで下にスクロールします。
次に、 データセーバーファイルのコードを更新する必要があります。
何をする前に気をつけて!! 何を行っても、 %%writefileを使って開始を削除したり、上書きしたりしないでください。 この行は、Recipe Builderノートブックで必要です。
このセルには、次のようなコードが表示されます。
import pandas as pd
from .utils import get_client_context
from platform_sdk.models import Dataset
from platform_sdk.dataset_writer import DatasetWriter
def save(config_properties, prediction):
print("Datasaver Start")
client_context = get_client_context(config_properties)
tenant_id = config_properties.get("tenantId")
prediction = prediction.add_prefix(tenant_id+".")
prediction = prediction.join(pd.DataFrame(
{
'_id': "",
'timestamp': '2019-01-01T00:00:00',
'eventType': ""
}, index=prediction.index))
dataset = Dataset(client_context).get_by_id(config_properties['scoringResultsDataSetId'])
dataset_writer = DatasetWriter(client_context, dataset)
dataset_writer.write(prediction, file_format='json')
print("Datasaver Finish")
print(prediction)
このコードを( %%writefile 行を上書きせずに)次のコードで置き換えます。
from .utils import get_client_context
from platform_sdk.models import Dataset
from platform_sdk.dataset_writer import DatasetWriter
def save(config_properties, prediction):
print("Datasaver Start")
client_context = get_client_context(config_properties)
dataset = Dataset(client_context).get_by_id(config_properties['scoringResultsDataSetId'])
dataset_writer = DatasetWriter(client_context, dataset)
dataset_writer.write(prediction, file_format='json')
print("Datasaver Finish")
print(prediction)
これで、[ Data Saver File ]セルに似たような内容が表示されます。
これで、ノートブックの実行に必要なすべてのコードが構成されました。
モデルのトレーニングは、[トレ イン ]ボタンをクリックして行います。
上部のツールバーにある[ トレーニング ]をクリックして、ノートブックにトレーニングを作成します。 これにより、トレーニングデータローダー、パイプラインセル、評価基準セルが実行され、モデルのパフォーマンスを測定する評価指標が生成されます。 トレーニングスクリプトのコマンドと出力のログがノートブック(エバリュエーター — セルの下)に表示されます。
「 Train」をクリックすると、トレーニングランが開始し、完了するまでに数分かかります。
…
…
「トレ イン」をクリックすると、次のセルが実行されます。
モデルのスコアは、「 スコア 」ボタンをクリックして実行します。
上部のツールバーにある スコア (Score)をクリックして、セルにトレーニングの実行を作成します。 これにより、スコアリングデータローダー、パイプラインセルおよび評価基準セルが実行され、モデルのパフォーマンスを測定する評価指標が生成されます。 A log of commands and outputs from the training script will appear in the notebook (under the pipeline.py cell).
「 スコア」をクリックすると、トレーニングの実行が開始し、完了するまでに数分かかります。
…
…
「 スコア」をクリックすると、次のセルが実行されます。
さらに、スコアリング実行の最後に、傾向スコアの出力がAdobe Experience PlatformのML予測(グローバルv1.1)データセットの デモシステム —プロファイルデータセットに保存されます 。
これは ここで確認できます。
レシピの作成は、「レシピを 作成 」ボタンをクリックして行います。
トレーニングとスコアの出力結果に満足したら、レシピを作成できます。 「 レシピを作成 」ボタンをクリックして、プロセスを開始します。
レシピを作成すると、モデルを尺度でテストできます。
「 レシピを作成 」ボタンをクリックした後に、レシピの名前を入力する必要があります。
命名規則として、次を使用してください。
ldap をldapに置き換えます 。
例:ldap vangeluwの場合、レシピの名前は次のようになります。 vangeluwCarInsurancePropentity。
「レシピ名」を入力した後、「 OK」をクリックします。
2つ目のポップアップが表示され、レシピが作成中であることを示します。 この処理には最大5分かかる場合があります。処理が終了するまでお待ちください。
レシピ作成プロセスの進行状況は、ジュピター・ノートブックの右上隅に表示できます。
他に何もしないでください。レシピ作成処理を続行する場合は、このブラウザウィンドウをノートブックで開いたままにしておく必要があります。
数分後に、レシピの作成が完了します。
ポップアップ・ウィンドウで[ 表示レシピ ]をクリックします。
次に、使用可能なすべてのレシピが表示されます。この中には、レシピも含まれています。
レシピの作成が完了したら、次の練習に進みましょう。ここでは、開始の拡張性に優れたトレーニングと実験を行います。
次の手順: 15.4レシピのトレーニングとスコアリング