Änderung ML auf neue Branche

This commit is contained in:
2025-06-18 13:40:52 +00:00
parent 106bfd5b15
commit 411f33ac4f

View File

@@ -54,6 +54,7 @@ import unicodedata # Fuer Text-Normalisierung
# Bibliotheken fuer Datenanalyse und ML
import pandas as pd
import numpy as np
from imblearn.over_sampling import SMOTE
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.impute import SimpleImputer
@@ -8942,7 +8943,7 @@ class DataProcessor:
# und weisen ihnen interne, einfachere Namen zu, die im DataFrame verwendet werden.
col_keys_mapping = {
"name": "CRM Name", # Zur Identifikation, wird spaeter entfernt
"branche_crm": "CRM Branche", # Fuer One-Hot Encoding
"branche_ki": "Chat Vorschlag Branche", # Fuer One-Hot Encoding
"umsatz_crm": "CRM Umsatz", # Fuer Konsolidierung
"umsatz_wiki": "Wiki Umsatz", # Fuer Konsolidierung
"ma_crm": "CRM Anzahl Mitarbeiter", # Fuer Konsolidierung
@@ -9098,8 +9099,8 @@ class DataProcessor:
# --- Kategoriale Features vorbereiten (Branche) ---
self.logger.info("Verarbeite kategoriales Feature 'branche_crm' fuer One-Hot Encoding...")
branche_col_internal = "branche_crm"
df_filtered.loc[:, 'branche_crm'] = df_filtered['branche_crm'].astype(str).fillna('Unbekannt').str.strip()
branche_col_internal = "branche_ki"
df_filtered.loc[:, 'branche_ki'] = df_filtered['branche_crm'].astype(str).fillna('Unbekannt').str.strip()
df_encoded = pd.get_dummies(df_filtered, columns=[branche_col_internal], prefix='Branche', dummy_na=False)
# --- Finale Auswahl der Features fuer das Modell ---
@@ -9206,6 +9207,22 @@ class DataProcessor:
X_test_imputed = imputer.transform(X_test)
X_train_imputed = pd.DataFrame(X_train_imputed, columns=feature_columns_ml) # feature_columns_ml verwenden
X_test_imputed = pd.DataFrame(X_test_imputed, columns=feature_columns_ml) # feature_columns_ml verwenden
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# +++ NEU: Klassen-Balancierung mit SMOTE auf den Trainingsdaten ++++++++
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
self.logger.info("Führe Klassen-Balancierung mit SMOTE auf den Trainingsdaten durch...")
self.logger.info(f"Klassenverteilung VOR SMOTE:\n{y_train.value_counts()}")
smote = SMOTE(random_state=42)
# Wichtig: SMOTE wird auf die imputierten Trainingsdaten angewendet
X_train_resampled, y_train_resampled = smote.fit_resample(X_train_imputed, y_train)
self.logger.info(f"Klassenverteilung NACH SMOTE:\n{y_train_resampled.value_counts()}")
self.logger.info(f"Größe des Trainingssets nach Resampling: {len(X_train_resampled)} Zeilen.")
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# +++ ENDE SMOTE-BLOCK ++++++++++++++++++++++++++++++++++++++++++++++++++
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# +++ ANPASSUNG HIER: RandomForest statt Decision Tree ++++++++++++++++++