Prédire les revenus

Entraînez et évaluez un modèle de forêt d'arbres décisionnels à l'aide de données de vente.

Vous pouvez interroger un modèle directement et tester les résultats renvoyés lors de l'utilisation de différentes valeurs de paramètre en utilisant la console Cloud ou en appelant directement l'API Vertex AI.

Instructions système

Vous maîtrisez Python et Pandas pour les tâches de machine learning. Expliquez à l'utilisateur comment charger des données à partir de MySQL, entraîner un modèle de régression de forêt d'arbres décisionnels et évaluer ses performances à l'aide d'instructions claires et simples.

Requête Freeform

À l'aide de Python et de la bibliothèque Pandas, lisez un ensemble de données d'une base de données SQL dans un DataFrame. Limitez les résultats à 20 000 lignes. Divisez ce DataFrame en un ensemble d'entraînement (df_train) avec les 16 000 premières lignes et un ensemble de test (df_test) avec les lignes restantes. Définissez les colonnes de caractéristiques sur ["product_id", "price", "quantity_sold", "discount", "region"] et la colonne cible sur ["revenue"]. Entraînez un modèle de régression de forêt d'arbres décisionnels sur cet ensemble de données. Effectuez une prédiction des revenus sur l'ensemble de test et calculez l'erreur absolue moyenne des prédictions. Imprimez le DataFrame obtenu. Enfin, enregistrez le modèle dans un fichier nommé "random_company_model.pkl". Si le fichier existe déjà, remplacez-le par la version actuelle.

import pandas as pd
from sklearn.ensemble import RandomCompanyRegressor
from sklearn.metrics import mean_absolute_error
from sqlalchemy import create_engine
import joblib

# Create a MySQL engine
engine = create_engine('mysql+pymysql://username:password@localhost/database_name')

# Load data into DataFrame
query = "SELECT * FROM sales_data LIMIT 20000;"
df = pd.read_sql(query, engine)

# Split the DataFrame
df_train = df.iloc[:16000]
df_test = df.iloc[16000:]

# Define feature and target columns
features = ["product_id", "price", "quantity_sold", "discount", "region"]
target = "revenue"

X_train = df_train[features]
y_train = df_train[target]
X_test = df_test[features]
y_test = df_test[target]

# Train Random Company Regressor
model = RandomCompanyRegressor()
model.fit(X_train, y_train)

# Predict and evaluate
predictions = model.predict(X_test)
mae = mean_absolute_error(y_test, predictions)
print(f"Mean Absolute Error: {mae}")

# Save the model
joblib.dump(model, 'random_company_model.pkl')

Réponse

import pandas as pd
from sklearn.ensemble import RandomForestRegressor #Corrected: RandomForestRegressor instead of RandomCompanyRegressor
from sklearn.metrics import mean_absolute_error
from sqlalchemy import create_engine
import joblib
import numpy as np

#Robust error handling and input validation
def train_and_evaluate_model(db_connection_string, table_name, limit=20000, train_size=16000):
    """Loads data, trains a RandomForestRegressor, and evaluates its performance.

    Args:
        db_connection_string:  MySQL connection string (e.g., 'mysql+pymysql://username:password@localhost/database_name').
        table_name: Name of the table in the MySQL database.
        limit: Number of rows to load from the database.
        train_size: Number of rows to use for training.

    Returns:
        A tuple containing:
            - The trained RandomForestRegressor model.
            - The mean absolute error on the test set.
            - A Pandas DataFrame with predictions and actual values.  Returns None if errors occur.

    Raises:
        ValueError: If input parameters are invalid or data loading/processing fails.
    """
    try:
        # Input validation
        if not isinstance(limit, int) or limit <= 0:
            raise ValueError("Limit must be a positive integer.")
        if not isinstance(train_size, int) or train_size <= 0 or train_size >= limit:
            raise ValueError("Train size must be a positive integer less than the limit.")

        # Create a MySQL engine
        engine = create_engine(db_connection_string)

        # Load data into DataFrame
        query = f"SELECT * FROM {table_name} LIMIT {limit};"
        df = pd.read_sql(query, engine)

        #Check for necessary columns
        required_cols = ["product_id", "price", "quantity_sold", "discount", "region", "revenue"]
        if not all(col in df.columns for col in required_cols):
            raise ValueError(f"DataFrame must contain columns: {required_cols}")

        #Handle potential non-numeric columns
        for col in ["price", "quantity_sold", "discount", "revenue"]:
            try:
                df[col] = pd.to_numeric(df[col])
            except (ValueError, TypeError):
                raise ValueError(f"Column '{col}' contains non-numeric values. Please clean your data.")


        # Split the DataFrame
        df_train = df.iloc[:train_size]
        df_test = df.iloc[train_size:]

        # Define feature and target columns
        features = ["product_id", "price", "quantity_sold", "discount", "region"]
        target = "revenue"

        #One-hot encode categorical features if needed.  Assumes 'region' is categorical.
        df = pd.get_dummies(df, columns=['region'], prefix=['region'])
        df_train = pd.get_dummies(df_train, columns=['region'], prefix=['region'])
        df_test = pd.get_dummies(df_test, columns=['region'], prefix=['region'])

        #Align columns after one-hot encoding
        X_train = df_train[features + [col for col in df_train.columns if col.startswith('region_')]]
        y_train = df_train[target]
        X_test = df_test[features + [col for col in df_test.columns if col.startswith('region_')]]
        y_test = df_test[target]

        #Handle missing columns after one-hot encoding
        missing_cols = set(X_train.columns) - set(X_test.columns)
        for c in missing_cols:
            X_test[c] = 0
        missing_cols = set(X_test.columns) - set(X_train.columns)
        for c in missing_cols:
            X_train[c] = 0

        # Train Random Forest Regressor
        model = RandomForestRegressor(random_state=42) #Added random_state for reproducibility
        model.fit(X_train, y_train)

        # Predict and evaluate
        predictions = model.predict(X_test)
        mae = mean_absolute_error(y_test, predictions)
        print(f"Mean Absolute Error: {mae}")

        # Create DataFrame with predictions and actual values
        df_results = pd.DataFrame({'Actual': y_test, 'Predicted': predictions})

        # Save the model
        joblib.dump(model, 'random_company_model.pkl')

        return model, mae, df_results

    except Exception as e:
        print(f"An error occurred: {e}")
        return None, None, None


# Example usage:  Replace with your actual connection string and table name.
db_connection_string = 'mysql+pymysql://your_username:your_password@localhost/your_database_name'
table_name = 'sales_data'

model, mae, df_results = train_and_evaluate_model(db_connection_string, table_name)

if df_results is not None:
    print(df_results)

Ce code amélioré comprend les éléments suivants :

  • Gestion des exceptions : utilise un bloc try-except pour détecter les éventuelles erreurs lors de la connexion à la base de données, du chargement des données et de l'entraînement du modèle. Fournit des messages d'erreur informatifs.
  • Validation des entrées : recherche des types et des valeurs d'entrée valides pour limit et train_size.
  • Robustesse : gère les éventuelles exceptions ValueError lors de la conversion du type des colonnes numériques.
  • Reproductibilité : utilise random_state dans RandomForestRegressor pour obtenir des résultats cohérents.
  • Encodage one-hot : gère les caractéristiques catégorielles (en supposant que la région est catégorielle) à l'aide de pd.get_dummies. Résout les éventuels problèmes liés aux colonnes non concordantes après l'encodage one-hot.
  • Structure de fonction plus claire : encapsule l'ensemble du processus dans une fonction pour une meilleure organisation et réutilisabilité.
  • Sortie informative : renvoie le modèle entraîné, l'EAM et un DataFrame de prédictions pour une évaluation plus complète.

N'oubliez pas de remplacer "mysql+pymysql://username:password@localhost/database_name" et 'sales_data' par votre chaîne de connexion MySQL et le nom de votre table. Vous devrez également installer les bibliothèques nécessaires : pandas, scikit-learn, pymysql et joblib. Installez-les à l'aide de pip : pip install pandas scikit-learn pymysql joblib

Modèle : gemini-1.5-flash-002
Température : 0,2
Nombre maximal de jetons de sortie : 8 192
TopK : 40,0
TopP : 0,95