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 = '3'
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:16:54.339415: 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:1787343418.259744   13093 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,472 │ 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,809 (116.44 KB)
 Trainable params: 29,809 (116.44 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
2841/2841 ━━━━━━━━━━━━━━━━━━━━ 14s 4ms/step - loss: 0.0421 - mae: 0.0372 - val_loss: 0.0256 - val_mae: 0.0226
Epoch 2/20
2841/2841 ━━━━━━━━━━━━━━━━━━━━ 11s 4ms/step - loss: 0.0269 - mae: 0.0245 - val_loss: 0.0238 - val_mae: 0.0217
Epoch 3/20
2841/2841 ━━━━━━━━━━━━━━━━━━━━ 11s 4ms/step - loss: 0.0242 - mae: 0.0225 - val_loss: 0.0230 - val_mae: 0.0214
Epoch 4/20
2841/2841 ━━━━━━━━━━━━━━━━━━━━ 11s 4ms/step - loss: 0.0232 - mae: 0.0218 - val_loss: 0.0245 - val_mae: 0.0231
Epoch 5/20
2841/2841 ━━━━━━━━━━━━━━━━━━━━ 11s 4ms/step - loss: 0.0229 - mae: 0.0216 - val_loss: 0.0240 - val_mae: 0.0227
Epoch 6/20
2841/2841 ━━━━━━━━━━━━━━━━━━━━ 11s 4ms/step - loss: 0.0227 - mae: 0.0215 - val_loss: 0.0219 - val_mae: 0.0207
Epoch 7/20
2841/2841 ━━━━━━━━━━━━━━━━━━━━ 11s 4ms/step - loss: 0.0225 - mae: 0.0213 - val_loss: 0.0232 - val_mae: 0.0220
Epoch 8/20
2841/2841 ━━━━━━━━━━━━━━━━━━━━ 11s 4ms/step - loss: 0.0224 - mae: 0.0213 - val_loss: 0.0219 - val_mae: 0.0207
Epoch 9/20
2841/2841 ━━━━━━━━━━━━━━━━━━━━ 11s 4ms/step - loss: 0.0223 - mae: 0.0211 - val_loss: 0.0222 - val_mae: 0.0210
Epoch 10/20
2841/2841 ━━━━━━━━━━━━━━━━━━━━ 11s 4ms/step - loss: 0.0222 - mae: 0.0211 - val_loss: 0.0231 - val_mae: 0.0219
Epoch 11/20
2841/2841 ━━━━━━━━━━━━━━━━━━━━ 11s 4ms/step - loss: 0.0222 - mae: 0.0210 - val_loss: 0.0217 - val_mae: 0.0206
Epoch 12/20
2841/2841 ━━━━━━━━━━━━━━━━━━━━ 11s 4ms/step - loss: 0.0222 - mae: 0.0210 - val_loss: 0.0196 - val_mae: 0.0185
Epoch 13/20
2841/2841 ━━━━━━━━━━━━━━━━━━━━ 11s 4ms/step - loss: 0.0221 - mae: 0.0210 - val_loss: 0.0240 - val_mae: 0.0229
Epoch 14/20
2841/2841 ━━━━━━━━━━━━━━━━━━━━ 11s 4ms/step - loss: 0.0221 - mae: 0.0209 - val_loss: 0.0226 - val_mae: 0.0215
Epoch 15/20
2841/2841 ━━━━━━━━━━━━━━━━━━━━ 11s 4ms/step - loss: 0.0220 - mae: 0.0209 - val_loss: 0.0223 - val_mae: 0.0211
Epoch 16/20
2841/2841 ━━━━━━━━━━━━━━━━━━━━ 11s 4ms/step - loss: 0.0220 - mae: 0.0209 - val_loss: 0.0245 - val_mae: 0.0234
Epoch 17/20
2841/2841 ━━━━━━━━━━━━━━━━━━━━ 11s 4ms/step - loss: 0.0220 - mae: 0.0208 - val_loss: 0.0217 - val_mae: 0.0206
Epoch 17: early stopping
Restoring model weights from the end of the best epoch: 12.
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
532/532 ━━━━━━━━━━━━━━━━━━━━ 6s 10ms/step - loss: 0.0674 - mae: 0.0599 - val_loss: 0.0260 - val_mae: 0.0201
Epoch 2/20
532/532 ━━━━━━━━━━━━━━━━━━━━ 5s 10ms/step - loss: 0.0211 - mae: 0.0161 - val_loss: 0.0170 - val_mae: 0.0128
Epoch 3/20
532/532 ━━━━━━━━━━━━━━━━━━━━ 5s 10ms/step - loss: 0.0163 - mae: 0.0128 - val_loss: 0.0149 - val_mae: 0.0119
Epoch 4/20
532/532 ━━━━━━━━━━━━━━━━━━━━ 5s 10ms/step - loss: 0.0141 - mae: 0.0115 - val_loss: 0.0128 - val_mae: 0.0105
Epoch 5/20
532/532 ━━━━━━━━━━━━━━━━━━━━ 5s 10ms/step - loss: 0.0126 - mae: 0.0106 - val_loss: 0.0117 - val_mae: 0.0099
Epoch 6/20
532/532 ━━━━━━━━━━━━━━━━━━━━ 5s 10ms/step - loss: 0.0114 - mae: 0.0099 - val_loss: 0.0102 - val_mae: 0.0088
Epoch 7/20
532/532 ━━━━━━━━━━━━━━━━━━━━ 5s 10ms/step - loss: 0.0105 - mae: 0.0093 - val_loss: 0.0097 - val_mae: 0.0086
Epoch 8/20
532/532 ━━━━━━━━━━━━━━━━━━━━ 6s 11ms/step - loss: 0.0100 - mae: 0.0090 - val_loss: 0.0102 - val_mae: 0.0093
Epoch 9/20
532/532 ━━━━━━━━━━━━━━━━━━━━ 5s 10ms/step - loss: 0.0097 - mae: 0.0088 - val_loss: 0.0093 - val_mae: 0.0085
Epoch 10/20
532/532 ━━━━━━━━━━━━━━━━━━━━ 5s 10ms/step - loss: 0.0095 - mae: 0.0087 - val_loss: 0.0087 - val_mae: 0.0079
Epoch 11/20
532/532 ━━━━━━━━━━━━━━━━━━━━ 5s 10ms/step - loss: 0.0094 - mae: 0.0087 - val_loss: 0.0082 - val_mae: 0.0074
Epoch 12/20
532/532 ━━━━━━━━━━━━━━━━━━━━ 5s 10ms/step - loss: 0.0093 - mae: 0.0086 - val_loss: 0.0088 - val_mae: 0.0081
Epoch 13/20
532/532 ━━━━━━━━━━━━━━━━━━━━ 5s 10ms/step - loss: 0.0093 - mae: 0.0086 - val_loss: 0.0097 - val_mae: 0.0090
Epoch 14/20
532/532 ━━━━━━━━━━━━━━━━━━━━ 5s 10ms/step - loss: 0.0092 - mae: 0.0085 - val_loss: 0.0091 - val_mae: 0.0084
Epoch 15/20
532/532 ━━━━━━━━━━━━━━━━━━━━ 5s 10ms/step - loss: 0.0092 - mae: 0.0085 - val_loss: 0.0095 - val_mae: 0.0088
Epoch 16/20
532/532 ━━━━━━━━━━━━━━━━━━━━ 5s 10ms/step - loss: 0.0091 - mae: 0.0084 - val_loss: 0.0087 - val_mae: 0.0081
Epoch 16: early stopping
Restoring model weights from the end of the best epoch: 11.
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])
16299/16299 ━━━━━━━━━━━━━━━━━━━━ 28s 2ms/step
3225/3225 ━━━━━━━━━━━━━━━━━━━━ 6s 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.0256 gold
Median Absolute Error: 0.0015 gold
Root Mean Squared Error: 0.0737 gold

--- Benchmark Comparison for Penny 3d ---
Neural Network MAE: 0.0256 gold
Naive Baseline MAE:   0.0039 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: 5.8301 gold
Median Absolute Error: 0.2242 gold
Root Mean Squared Error: 46.8481 gold

--- Benchmark Comparison for Luxury 3d ---
Neural Network MAE: 5.8301 gold
Naive Baseline MAE:   1.6303 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_3d.joblib']
In [ ]: