Spaces:
Sleeping
Sleeping
| # train_model.py | |
| # ============================================================================== | |
| # 1. SETUP AND IMPORTS | |
| # ============================================================================== | |
| import pandas as pd | |
| import os | |
| import re | |
| import pickle | |
| from sklearn.model_selection import train_test_split | |
| from sklearn.preprocessing import LabelEncoder | |
| from sklearn.feature_extraction.text import TfidfVectorizer | |
| from sklearn.linear_model import LogisticRegression | |
| from sklearn.metrics import accuracy_score, classification_report # NEW IMPORTS | |
| print("--- Starting Model Training and Evaluation Pipeline ---") | |
| # ============================================================================== | |
| # 2. DEFINE FILE PATHS AND MAPPINGS | |
| # ============================================================================== | |
| BASE_DIRECTORY = '.' # Assumes all files are in the same folder | |
| INSTACART_PRODUCTS_FILE = os.path.join(BASE_DIRECTORY, 'products.csv') | |
| INSTACART_DEPARTMENTS_FILE = os.path.join(BASE_DIRECTORY, 'departments.csv') | |
| KAGGLE_RETAIL_FILE = os.path.join(BASE_DIRECTORY, 'train.csv') | |
| FINAL_TRAINING_DATA_FILE = os.path.join(BASE_DIRECTORY, 'final_training_dataset.csv') | |
| # --- Mappings --- | |
| instacart_department_map = { | |
| 'produce': 'Food & Beverage', 'meat seafood': 'Food & Beverage', 'dairy eggs': 'Food & Beverage', | |
| 'bakery': 'Food & Beverage', 'frozen': 'Food & Beverage', 'pantry': 'Food & Beverage', | |
| 'canned goods': 'Food & Beverage', 'international': 'Food & Beverage', 'bulk': 'Food & Beverage', | |
| 'dry goods pasta': 'Food & Beverage', 'snacks': 'Food & Beverage', 'breakfast': 'Food & Beverage', | |
| 'beverages': 'Food & Beverage', 'alcohol': 'Food & Beverage', 'deli': 'Food & Beverage', | |
| 'personal care': 'Health & Beauty', 'household': 'Home & Garden', 'babies': 'Babies', | |
| 'pets': 'Pets', 'other': 'Miscellaneous', 'missing': 'Miscellaneous' | |
| } | |
| kaggle_category_map = { | |
| 'Clothing, Shoes & Jewelry': 'Apparel & Accessories', 'Electronics': 'Electronics & Media', | |
| 'Cell Phones & Accessories': 'Electronics & Media', 'Automotive': 'Automotive & Fuel', | |
| 'Health & Personal Care': 'Health & Beauty', 'Beauty': 'Health & Beauty', | |
| 'Tools & Home Improvement': 'Home & Garden', 'Patio, Lawn & Garden': 'Home & Garden', | |
| 'Grocery & Gourmet Food': 'Food & Beverage', 'Pet Supplies': 'Pets', 'Baby': 'Babies' | |
| } | |
| # ============================================================================== | |
| # 3. LOAD, MAP, AND COMBINE DATASETS | |
| # ============================================================================== | |
| print("Step 1: Loading and combining datasets...") | |
| # (This section creates the final_training_dataset.csv file) | |
| try: | |
| products_df = pd.read_csv(INSTACART_PRODUCTS_FILE) | |
| departments_df = pd.read_csv(INSTACART_DEPARTMENTS_FILE) | |
| instacart_df = pd.merge(products_df, departments_df, on='department_id') | |
| instacart_df['category'] = instacart_df['department'].map(instacart_department_map) | |
| instacart_df.rename(columns={'product_name': 'description'}, inplace=True) | |
| instacart_labeled = instacart_df[['description', 'category']].dropna() | |
| kaggle_df = pd.read_csv(KAGGLE_RETAIL_FILE, usecols=['title', 'categories']) | |
| kaggle_df['category'] = kaggle_df['categories'].map(kaggle_category_map) | |
| kaggle_df.rename(columns={'title': 'description'}, inplace=True) | |
| kaggle_labeled = kaggle_df[['description', 'category']].dropna() | |
| combined_df = pd.concat([instacart_labeled, kaggle_labeled], ignore_index=True) | |
| combined_df.drop_duplicates(subset=['description'], inplace=True) | |
| combined_df.to_csv(FINAL_TRAINING_DATA_FILE, index=False) | |
| print(f"-> Combined dataset created with {len(combined_df)} items.") | |
| except Exception as e: | |
| print(f"❌ ERROR: Failed to create the dataset. Make sure all raw CSV files are in the folder. Details: {e}") | |
| exit() | |
| # ============================================================================== | |
| # 4. TRAIN THE MODEL | |
| # ============================================================================== | |
| print("\nStep 2: Training the model...") | |
| df = pd.read_csv(FINAL_TRAINING_DATA_FILE) | |
| def clean_text(text): | |
| if not isinstance(text, str): text = '' | |
| text = text.strip('"').lower() | |
| text = re.sub(r'[^a-z\s]', '', text) | |
| return ' '.join(text.split()) | |
| df['cleaned_description'] = df['description'].apply(clean_text) | |
| df.dropna(subset=['cleaned_description', 'category'], inplace=True) | |
| df = df[df['cleaned_description'] != ''] | |
| le = LabelEncoder() | |
| df['category_encoded'] = le.fit_transform(df['category']) | |
| X = df['cleaned_description'] | |
| y = df['category_encoded'] | |
| X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y) | |
| tfidf = TfidfVectorizer(ngram_range=(1, 2)) | |
| X_train_tfidf = tfidf.fit_transform(X_train) | |
| model = LogisticRegression(random_state=42, max_iter=2000) | |
| model.fit(X_train_tfidf, y_train) | |
| print("-> Model training complete.") | |
| # --- NEW SECTION: EVALUATE THE MODEL --- | |
| print("\nStep 3: Evaluating the model...") | |
| # Vectorize the test data | |
| X_test_tfidf = tfidf.transform(X_test) | |
| # Make predictions on the test set | |
| y_pred = model.predict(X_test_tfidf) | |
| # Calculate and print the accuracy | |
| accuracy = accuracy_score(y_test, y_pred) | |
| print(f"-> Overall Model Accuracy: {accuracy:.2%}") | |
| # Print the full classification report | |
| print("\n--- Classification Report: ---") | |
| report = classification_report(y_test, y_pred, target_names=le.classes_) | |
| print(report) | |
| # --- END NEW SECTION --- | |
| # ============================================================================== | |
| # 5. SAVE THE MODEL FILES | |
| # ============================================================================== | |
| print("\nStep 4: Saving model files...") | |
| with open('tfidf_vectorizer.pkl', 'wb') as f: | |
| pickle.dump(tfidf, f) | |
| with open('category_classifier.pkl', 'wb') as f: | |
| pickle.dump(model, f) | |
| with open('label_encoder.pkl', 'wb') as f: | |
| pickle.dump(le, f) | |
| print("✅ Success! Your three .pkl model files have been saved to this folder.") | |
| print("--- Model Training and Evaluation Pipeline Finished ---") | |