In [1]:
import polars as pl
import pandas as pd
pl.Config.set_tbl_rows(15)
pl.Config(float_precision=2)

import gc
import numpy as np
import matplotlib.pyplot as plt

from datetime import datetime, timedelta
from bs4 import BeautifulSoup
import requests
import math
In [2]:
days = '30'
In [26]:
from sklearn.compose import ColumnTransformer
# from sklearn.feature_selection import mutual_info_regression, SelectKBest
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, OneHotEncoder, MinMaxScaler, RobustScaler, FunctionTransformer
from tensorflow.keras.layers import Concatenate, Dense, Dropout, Embedding, Flatten, Input, IntegerLookup
from tensorflow.keras.models import Model
from tensorflow.keras.regularizers import l2
from tensorflow.keras.callbacks import EarlyStopping
2026-08-21 20:39:45.277052: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.
To enable the following instructions: SSE3 SSE4.1 SSE4.2 AVX AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.
In [39]:
# Define the ID input branch
penny_id_input = Input(shape=(1,), name='passthrough__id')

# Map raw sparse IDs (e.g., 12136) to contiguous integers (0, 1, 2...)
penny_lookup = IntegerLookup(vocabulary=penny_unique_ids, output_mode='int')(penny_id_input)

# Pass the contiguous integers into the Embedding layer
# input_dim needs to account for the vocab size + OOV (Out of Vocabulary) token
penny_id_embed = Embedding(input_dim=len(penny_unique_ids) + 1, output_dim=16)(penny_lookup)
penny_id_flat = Flatten()(penny_id_embed)

# Define the remaining continuous/binary feature branch
penny_features_input = Input(shape=(penny_train_features.shape[1],), name='numeric_features')

# Merge branches and pass through Dense layers
penny_merged = Concatenate()([penny_id_flat, penny_features_input])
penny_dense1 = Dense(64, activation='relu', kernel_regularizer=l2(1e-4))(penny_merged)
penny_drop1 = Dropout(0.3)(penny_dense1)
penny_dense2 = Dense(32, activation='relu', kernel_regularizer=l2(1e-4))(penny_drop1)
penny_drop2 = Dropout(0.2)(penny_dense2)
penny_output = Dense(1, activation='sigmoid')(penny_drop2) # Outputting target_3d

penny_model = Model(inputs=[penny_id_input, penny_features_input], outputs=penny_output)
penny_model.compile(optimizer='adam', loss='mae', metrics=['mae'])
penny_model.summary()

# Define the ID input branch
luxury_id_input = Input(shape=(1,), name='passthrough__id')

# Map raw sparse IDs (e.g., 12136) to contiguous integers (0, 1, 2...)
luxury_lookup = IntegerLookup(vocabulary=luxury_unique_ids, output_mode='int')(luxury_id_input)

# Pass the contiguous integers into the Embedding layer
# input_dim needs to account for the vocab size + OOV (Out of Vocabulary) token
luxury_id_embed = Embedding(input_dim=len(luxury_unique_ids) + 1, output_dim=16)(luxury_lookup)
luxury_id_flat = Flatten()(luxury_id_embed)

# Define the remaining continuous/binary feature branch
luxury_features_input = Input(shape=(luxury_train_features.shape[1],), name='numeric_features')

# Merge branches and pass through Dense layers
luxury_merged = Concatenate()([luxury_id_flat, luxury_features_input])
luxury_dense1 = Dense(64, activation='relu', kernel_regularizer=l2(1e-4))(luxury_merged)
luxury_drop1 = Dropout(0.3)(luxury_dense1)
luxury_dense2 = Dense(32, activation='relu', kernel_regularizer=l2(1e-4))(luxury_drop1)
luxury_drop2 = Dropout(0.2)(luxury_dense2)
luxury_output = Dense(1, activation='sigmoid')(luxury_drop2) # Outputting target_3d

luxury_model = Model(inputs=[luxury_id_input, luxury_features_input], outputs=luxury_output)
luxury_model.compile(optimizer='adam', loss='mae', metrics=['mae'])
luxury_model.summary()
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
I0000 00:00:1787344789.269789   21778 gpu_device.cc:2020] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 14978 MB memory:  -> device: 0, name: AMD Radeon Graphics, pci bus id: 0000:03:00.0
Model: "functional"
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ Layer (type)        ┃ Output Shape      ┃    Param # ┃ Connected to      ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ passthrough__id     │ (None, 1)         │          0 │ -                 │
│ (InputLayer)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ integer_lookup      │ (None, 1)         │          0 │ passthrough__id[… │
│ (IntegerLookup)     │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ embedding           │ (None, 1, 16)     │     23,456 │ integer_lookup[0… │
│ (Embedding)         │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ flatten (Flatten)   │ (None, 16)        │          0 │ embedding[0][0]   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ numeric_features    │ (None, 49)        │          0 │ -                 │
│ (InputLayer)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ concatenate         │ (None, 65)        │          0 │ flatten[0][0],    │
│ (Concatenate)       │                   │            │ numeric_features… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense (Dense)       │ (None, 64)        │      4,224 │ concatenate[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dropout (Dropout)   │ (None, 64)        │          0 │ dense[0][0]       │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense_1 (Dense)     │ (None, 32)        │      2,080 │ dropout[0][0]     │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dropout_1 (Dropout) │ (None, 32)        │          0 │ dense_1[0][0]     │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense_2 (Dense)     │ (None, 1)         │         33 │ dropout_1[0][0]   │
└─────────────────────┴───────────────────┴────────────┴───────────────────┘
 Total params: 29,793 (116.38 KB)
 Trainable params: 29,793 (116.38 KB)
 Non-trainable params: 0 (0.00 B)
Model: "functional_1"
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ Layer (type)        ┃ Output Shape      ┃    Param # ┃ Connected to      ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ passthrough__id     │ (None, 1)         │          0 │ -                 │
│ (InputLayer)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ integer_lookup_1    │ (None, 1)         │          0 │ passthrough__id[… │
│ (IntegerLookup)     │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ embedding_1         │ (None, 1, 16)     │      5,520 │ integer_lookup_1… │
│ (Embedding)         │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ flatten_1 (Flatten) │ (None, 16)        │          0 │ embedding_1[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ numeric_features    │ (None, 49)        │          0 │ -                 │
│ (InputLayer)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ concatenate_1       │ (None, 65)        │          0 │ flatten_1[0][0],  │
│ (Concatenate)       │                   │            │ numeric_features… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense_3 (Dense)     │ (None, 64)        │      4,224 │ concatenate_1[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dropout_2 (Dropout) │ (None, 64)        │          0 │ dense_3[0][0]     │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense_4 (Dense)     │ (None, 32)        │      2,080 │ dropout_2[0][0]   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dropout_3 (Dropout) │ (None, 32)        │          0 │ dense_4[0][0]     │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense_5 (Dense)     │ (None, 1)         │         33 │ dropout_3[0][0]   │
└─────────────────────┴───────────────────┴────────────┴───────────────────┘
 Total params: 11,857 (46.32 KB)
 Trainable params: 11,857 (46.32 KB)
 Non-trainable params: 0 (0.00 B)
In [40]:
# hist = model.fit(x_train, y_train, validation_data=(x_test, y_test), epochs=20, batch_size=256)
early_stopping = EarlyStopping(
    monitor='val_mae',         # Metric to watch
    patience=5,                 # Number of epochs to wait for improvement
    restore_best_weights=True,  # Roll back to the best weights at the end
    verbose=1                   # Print log message when stopping
)
In [41]:
penny_hist = penny_model.fit(
    x=[penny_train_id, penny_train_features],
    y=penny_y_train,
    validation_data=([penny_val_id, penny_val_features], penny_y_val),
    epochs=20,
    batch_size=256,
    callbacks=early_stopping
)
Epoch 1/20
3404/3404 ━━━━━━━━━━━━━━━━━━━━ 34s 9ms/step - loss: 0.0371 - mae: 0.0329 - val_loss: 0.0232 - val_mae: 0.0210
Epoch 2/20
3404/3404 ━━━━━━━━━━━━━━━━━━━━ 29s 8ms/step - loss: 0.0243 - mae: 0.0225 - val_loss: 0.0214 - val_mae: 0.0199
Epoch 3/20
3404/3404 ━━━━━━━━━━━━━━━━━━━━ 11s 3ms/step - loss: 0.0232 - mae: 0.0217 - val_loss: 0.0220 - val_mae: 0.0207
Epoch 4/20
3404/3404 ━━━━━━━━━━━━━━━━━━━━ 12s 4ms/step - loss: 0.0227 - mae: 0.0214 - val_loss: 0.0190 - val_mae: 0.0177
Epoch 5/20
3404/3404 ━━━━━━━━━━━━━━━━━━━━ 12s 3ms/step - loss: 0.0225 - mae: 0.0213 - val_loss: 0.0199 - val_mae: 0.0187
Epoch 6/20
3404/3404 ━━━━━━━━━━━━━━━━━━━━ 11s 3ms/step - loss: 0.0223 - mae: 0.0211 - val_loss: 0.0210 - val_mae: 0.0198
Epoch 7/20
3404/3404 ━━━━━━━━━━━━━━━━━━━━ 12s 4ms/step - loss: 0.0222 - mae: 0.0210 - val_loss: 0.0207 - val_mae: 0.0195
Epoch 8/20
3404/3404 ━━━━━━━━━━━━━━━━━━━━ 13s 4ms/step - loss: 0.0222 - mae: 0.0210 - val_loss: 0.0203 - val_mae: 0.0191
Epoch 9/20
3404/3404 ━━━━━━━━━━━━━━━━━━━━ 11s 3ms/step - loss: 0.0221 - mae: 0.0209 - val_loss: 0.0198 - val_mae: 0.0186
Epoch 9: early stopping
Restoring model weights from the end of the best epoch: 4.
In [42]:
luxury_hist = luxury_model.fit(
    x=[luxury_train_id, luxury_train_features],
    y=luxury_y_train,
    validation_data=([luxury_val_id, luxury_val_features], luxury_y_val),
    epochs=20,
    batch_size=256,
    callbacks=early_stopping
)
Epoch 1/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 7s 9ms/step - loss: 0.0513 - mae: 0.0442 - val_loss: 0.0230 - val_mae: 0.0177
Epoch 2/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 6s 10ms/step - loss: 0.0186 - mae: 0.0143 - val_loss: 0.0155 - val_mae: 0.0121
Epoch 3/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 7s 10ms/step - loss: 0.0146 - mae: 0.0117 - val_loss: 0.0139 - val_mae: 0.0114
Epoch 4/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 6s 10ms/step - loss: 0.0125 - mae: 0.0104 - val_loss: 0.0104 - val_mae: 0.0086
Epoch 5/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 7s 11ms/step - loss: 0.0112 - mae: 0.0096 - val_loss: 0.0104 - val_mae: 0.0090
Epoch 6/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 6s 9ms/step - loss: 0.0103 - mae: 0.0091 - val_loss: 0.0089 - val_mae: 0.0078
Epoch 7/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 7s 11ms/step - loss: 0.0097 - mae: 0.0087 - val_loss: 0.0090 - val_mae: 0.0080
Epoch 8/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 6s 9ms/step - loss: 0.0094 - mae: 0.0086 - val_loss: 0.0097 - val_mae: 0.0089
Epoch 9/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 7s 11ms/step - loss: 0.0093 - mae: 0.0085 - val_loss: 0.0091 - val_mae: 0.0084
Epoch 10/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 6s 10ms/step - loss: 0.0092 - mae: 0.0084 - val_loss: 0.0079 - val_mae: 0.0072
Epoch 11/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 7s 11ms/step - loss: 0.0091 - mae: 0.0084 - val_loss: 0.0084 - val_mae: 0.0077
Epoch 12/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 7s 11ms/step - loss: 0.0091 - mae: 0.0084 - val_loss: 0.0085 - val_mae: 0.0078
Epoch 13/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 6s 10ms/step - loss: 0.0090 - mae: 0.0083 - val_loss: 0.0094 - val_mae: 0.0088
Epoch 14/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 6s 9ms/step - loss: 0.0090 - mae: 0.0084 - val_loss: 0.0087 - val_mae: 0.0080
Epoch 15/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 6s 9ms/step - loss: 0.0090 - mae: 0.0084 - val_loss: 0.0078 - val_mae: 0.0072
Epoch 16/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 6s 10ms/step - loss: 0.0090 - mae: 0.0084 - val_loss: 0.0073 - val_mae: 0.0066
Epoch 17/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 6s 9ms/step - loss: 0.0090 - mae: 0.0083 - val_loss: 0.0095 - val_mae: 0.0089
Epoch 18/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 7s 11ms/step - loss: 0.0089 - mae: 0.0083 - val_loss: 0.0084 - val_mae: 0.0077
Epoch 19/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 6s 10ms/step - loss: 0.0089 - mae: 0.0083 - val_loss: 0.0073 - val_mae: 0.0067
Epoch 20/20
640/640 ━━━━━━━━━━━━━━━━━━━━ 6s 9ms/step - loss: 0.0089 - mae: 0.0083 - val_loss: 0.0098 - val_mae: 0.0092
Restoring model weights from the end of the best epoch: 16.
In [43]:
# 1. Generate predictions on the test set
penny_y_pred_scaled = penny_model.predict([penny_test_id, penny_test_features])
luxury_y_pred_scaled = luxury_model.predict([luxury_test_id, luxury_test_features])
16593/16593 ━━━━━━━━━━━━━━━━━━━━ 29s 2ms/step
3286/3286 ━━━━━━━━━━━━━━━━━━━━ 5s 2ms/step
In [44]:
penny_y_pred_full = penny_y_preprocess.inverse_transform(penny_y_pred_scaled)
penny_y_test_full = penny_y_preprocess.inverse_transform(penny_y_test)
luxury_y_pred_full = luxury_y_preprocess.inverse_transform(luxury_y_pred_scaled)
luxury_y_test_full = luxury_y_preprocess.inverse_transform(luxury_y_test)
print('Targets inverse transformed')
Targets inverse transformed
In [45]:
from sklearn.metrics import mean_absolute_error, mean_squared_error, median_absolute_error

mae = mean_absolute_error(penny_y_test_full, penny_y_pred_full)
medae = median_absolute_error(penny_y_test_full, penny_y_pred_full)
rmse = np.sqrt(mean_squared_error(penny_y_test_full, penny_y_pred_full))

print(f"Mean Absolute Error: {mae/10000:.4f} gold")
print(f"Median Absolute Error: {medae/10000:.4f} gold")
print(f"Root Mean Squared Error: {rmse/10000:.4f} gold")

# Calculate the naive baseline error for your chosen horizon
# (Assuming today's buy_high is the baseline prediction for the target horizon)
naive_mae = mean_absolute_error(penny_y_test_full, penny_raw_test_buy_high)

print()
print(f"--- Benchmark Comparison for Penny {days}d ---")
print(f"Neural Network MAE: {mae/10000:.4f} gold")
print(f"Naive Baseline MAE:   {naive_mae/10000:.4f} gold")

if mae < naive_mae:
    print("Success: Your Penny neural network is beating the naive baseline!")
else:
    print("Warning: Your Penny model is performing worse than or equal to a flat line prediction.")
Mean Absolute Error: 0.0240 gold
Median Absolute Error: 0.0015 gold
Root Mean Squared Error: 0.0666 gold

--- Benchmark Comparison for Penny 30d ---
Neural Network MAE: 0.0240 gold
Naive Baseline MAE:   0.0038 gold
Warning: Your Penny model is performing worse than or equal to a flat line prediction.
In [46]:
mae = mean_absolute_error(luxury_y_test_full, luxury_y_pred_full)
medae = median_absolute_error(luxury_y_test_full, luxury_y_pred_full)
rmse = np.sqrt(mean_squared_error(luxury_y_test_full, luxury_y_pred_full))

print(f"Mean Absolute Error: {mae/10000:.4f} gold")
print(f"Median Absolute Error: {medae/10000:.4f} gold")
print(f"Root Mean Squared Error: {rmse/10000:.4f} gold")

# Calculate the naive baseline error for your chosen horizon
# (Assuming today's buy_high is the baseline prediction for the target horizon)
naive_mae = mean_absolute_error(luxury_y_test_full, luxury_raw_test_buy_high)

print()
print(f"--- Benchmark Comparison for Luxury {days}d ---")
print(f"Neural Network MAE: {mae/10000:.4f} gold")
print(f"Naive Baseline MAE:   {naive_mae/10000:.4f} gold")

if mae < naive_mae:
    print("Success: Your Luxury neural network is beating the naive baseline!")
else:
    print("Warning: Your Luxury model is performing worse than or equal to a flat line prediction.")
Mean Absolute Error: 6.5239 gold
Median Absolute Error: 0.1699 gold
Root Mean Squared Error: 50.5485 gold

--- Benchmark Comparison for Luxury 30d ---
Neural Network MAE: 6.5239 gold
Naive Baseline MAE:   1.6318 gold
Warning: Your Luxury model is performing worse than or equal to a flat line prediction.
In [47]:
plt.figure(figsize=(12, 5))

# Plot 1: Actual vs Predicted
plt.subplot(1, 2, 1)
plt.scatter(penny_y_test_full, penny_y_pred_full, alpha=0.1, s=2)
plt.plot([penny_y_test_full.min(), penny_y_test_full.max()], [penny_y_test_full.min(), penny_y_test_full.max()], 'r--', lw=2)
plt.xscale('log')
plt.yscale('log')
plt.xlabel("Actual Price (Log Scale)")
plt.ylabel("Predicted Price (Log Scale)")
plt.title("Actual vs. Predicted Prices")

# Plot 2: Residuals (Error Distribution)
plt.subplot(1, 2, 2)
residuals = penny_y_pred_full - penny_y_test_full
plt.hist(residuals, bins=100, range=(-5000, 5000), edgecolor='k')
plt.xlabel("Prediction Error (Copper)")
plt.ylabel("Frequency")
plt.title("Residual Distribution (-50g to +50g)")

plt.tight_layout()
plt.show()
No description has been provided for this image
In [48]:
plt.figure(figsize=(12, 5))

# Plot 1: Actual vs Predicted
plt.subplot(1, 2, 1)
plt.scatter(luxury_y_test_full, luxury_y_pred_full, alpha=0.1, s=2)
plt.plot([luxury_y_test_full.min(), luxury_y_test_full.max()], [luxury_y_test_full.min(), luxury_y_test_full.max()], 'r--', lw=2)
plt.xscale('log')
plt.yscale('log')
plt.xlabel("Actual Price (Log Scale)")
plt.ylabel("Predicted Price (Log Scale)")
plt.title("Actual vs. Predicted Prices")

# Plot 2: Residuals (Error Distribution)
plt.subplot(1, 2, 2)
residuals = luxury_y_pred_full - luxury_y_test_full
plt.hist(residuals, bins=100, range=(-5000, 5000), edgecolor='k')
plt.xlabel("Prediction Error (Copper)")
plt.ylabel("Frequency")
plt.title("Residual Distribution (-50s to +50s)")

plt.tight_layout()
plt.show()
No description has been provided for this image
In [49]:
penny_x_train.columns
Out[49]:
Index(['num_scaler__supply_demand_ratio', 'num_scaler__level',
       'num_scaler__vendor_value', 'num_scaler__current_sell_price',
       'num_scaler__current_buy_price', 'cat_encode__type_CraftingMaterial',
       'cat_encode__type_Trophy', 'cat_encode__rarity_Ascended',
       'cat_encode__rarity_Basic', 'cat_encode__rarity_Exotic',
       'cat_encode__rarity_Fine', 'cat_encode__rarity_Legendary',
       'cat_encode__rarity_Masterwork', 'cat_encode__rarity_Rare',
       'passthrough__id', 'passthrough__lunar_new_year',
       'passthrough__lunar_new_year_next_week',
       'passthrough__lunar_new_year_last_week',
       'passthrough__super_adventure_festival',
       'passthrough__super_adventure_festival_next_week',
       'passthrough__super_adventure_festival_last_week',
       'passthrough__dragon_bash', 'passthrough__dragon_bash_next_week',
       'passthrough__dragon_bash_last_week',
       'passthrough__festival_of_the_four_winds',
       'passthrough__festival_of_the_four_winds_next_week',
       'passthrough__festival_of_the_four_winds_last_week',
       'passthrough__halloween', 'passthrough__halloween_next_week',
       'passthrough__halloween_last_week', 'passthrough__wintersday',
       'passthrough__wintersday_next_week',
       'passthrough__wintersday_last_week', 'passthrough__PvpLobby',
       'passthrough__Activity', 'passthrough__Wvw', 'passthrough__Dungeon',
       'passthrough__Pve', 'passthrough__NoSell', 'passthrough__NoSalvage',
       'passthrough__Unique', 'passthrough__NoMysticForge',
       'passthrough__DeleteWarning', 'passthrough__NotUpgradeable',
       'passthrough__sin_day_of_year', 'passthrough__cos_day_of_year',
       'passthrough__sin_day_of_week', 'passthrough__cos_day_of_week',
       'passthrough__sin_day_of_month', 'passthrough__cos_day_of_month'],
      dtype='str')
In [50]:
luxury_x_train.columns
Out[50]:
Index(['num_scaler__supply_demand_ratio', 'num_scaler__level',
       'num_scaler__vendor_value', 'num_scaler__current_sell_price',
       'num_scaler__current_buy_price', 'cat_encode__type_CraftingMaterial',
       'cat_encode__type_Trophy', 'cat_encode__rarity_Ascended',
       'cat_encode__rarity_Basic', 'cat_encode__rarity_Exotic',
       'cat_encode__rarity_Fine', 'cat_encode__rarity_Legendary',
       'cat_encode__rarity_Masterwork', 'cat_encode__rarity_Rare',
       'passthrough__id', 'passthrough__lunar_new_year',
       'passthrough__lunar_new_year_next_week',
       'passthrough__lunar_new_year_last_week',
       'passthrough__super_adventure_festival',
       'passthrough__super_adventure_festival_next_week',
       'passthrough__super_adventure_festival_last_week',
       'passthrough__dragon_bash', 'passthrough__dragon_bash_next_week',
       'passthrough__dragon_bash_last_week',
       'passthrough__festival_of_the_four_winds',
       'passthrough__festival_of_the_four_winds_next_week',
       'passthrough__festival_of_the_four_winds_last_week',
       'passthrough__halloween', 'passthrough__halloween_next_week',
       'passthrough__halloween_last_week', 'passthrough__wintersday',
       'passthrough__wintersday_next_week',
       'passthrough__wintersday_last_week', 'passthrough__PvpLobby',
       'passthrough__Activity', 'passthrough__Wvw', 'passthrough__Dungeon',
       'passthrough__Pve', 'passthrough__NoSell', 'passthrough__NoSalvage',
       'passthrough__Unique', 'passthrough__NoMysticForge',
       'passthrough__DeleteWarning', 'passthrough__NotUpgradeable',
       'passthrough__sin_day_of_year', 'passthrough__cos_day_of_year',
       'passthrough__sin_day_of_week', 'passthrough__cos_day_of_week',
       'passthrough__sin_day_of_month', 'passthrough__cos_day_of_month'],
      dtype='str')
In [51]:
import joblib
penny_model.save(f'Models/PennyLuxury/penny_model_{days}d.keras')
joblib.dump(penny_preprocess, f'Models/PennyLuxury/penny_preprocess_{days}d.joblib')
joblib.dump(penny_y_preprocess, f'Models/PennyLuxury/penny_y_preprocess_{days}d.joblib')

luxury_model.save(f'Models/PennyLuxury/luxury_model_{days}d.keras')
joblib.dump(luxury_preprocess, f'Models/PennyLuxury/luxury_preprocess_{days}d.joblib')
joblib.dump(luxury_y_preprocess, f'Models/PennyLuxury/luxury_y_preprocess_{days}d.joblib')
Out[51]:
['Models/PennyLuxury/luxury_y_preprocess_30d.joblib']
In [ ]: