{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":129859,"databundleVersionId":15575527,"sourceType":"competition"}],"dockerImageVersionId":31260,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-02-10T07:10:23.688651Z","iopub.execute_input":"2026-02-10T07:10:23.688913Z","iopub.status.idle":"2026-02-10T07:10:24.781988Z","shell.execute_reply.started":"2026-02-10T07:10:23.688859Z","shell.execute_reply":"2026-02-10T07:10:24.780582Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score, classification_report\nimport glob\nimport os\n\n# ==========================================\n# 1. CONFIGURATION & FILE PATHS\n# ==========================================\n# Competition 02 Paths\nTRAIN_FEAT_PATH = '/kaggle/input/dartmouth-cosc-74-w26-competition-02/train_feature.npy'\nTEST_FEAT_PATH = '/kaggle/input/dartmouth-cosc-74-w26-competition-02/test_feature.npy'\nTRAIN_LABEL_PATH = '/kaggle/input/dartmouth-cosc-74-w26-competition-02/train_label.npy'\n\n# Output File\nOUTPUT_FILENAME = 'submission_multiclass_baseline.csv'\n\n# ==========================================\n# 2. LOAD DATA\n# ==========================================\nprint(\"Loading data...\")\nX_train_raw = np.load(TRAIN_FEAT_PATH)\ny_train_raw = np.load(TRAIN_LABEL_PATH)\nX_test_raw = np.load(TEST_FEAT_PATH)\n\n# Flatten labels\ny_train_full = y_train_raw.ravel()\n\n# ==========================================\n# 3. PREPROCESS: MEAN POOLING\n# ==========================================\n# Check if data is 3D (Samples, Frames, Features) and reshape to 2D\nif X_train_raw.ndim == 3:\n    print(f\"Raw Train Shape: {X_train_raw.shape} - Applying Mean Pooling...\")\n    X_train_full = np.mean(X_train_raw, axis=1)\n    X_test = np.mean(X_test_raw, axis=1)\nelse:\n    print(f\"Raw Train Shape: {X_train_raw.shape} - No reshaping needed.\")\n    X_train_full = X_train_raw\n    X_test = X_test_raw\n\nprint(f\"Processed Train Shape: {X_train_full.shape}\")\nprint(f\"Processed Test Shape:  {X_test.shape}\")\n\n# ==========================================\n# 4. TRAIN MODEL (Logistic Regression)\n# ==========================================\nprint(\"\\nTraining Multi-Class Logistic Regression...\")\n\n# 'multinomial' minimizes the cross-entropy loss across all 30 classes\nclf = LogisticRegression(\n    solver='lbfgs',          # Good for multiclass\n    multi_class='multinomial', \n    max_iter=1000,           # Increase if not converging\n    class_weight='balanced', # Handles potential class imbalance\n    random_state=42,\n    n_jobs=-1                # Use all CPU cores\n)\n\n# Optional: Validation Split to estimate Accuracy\nX_train, X_val, y_train, y_val = train_test_split(\n    X_train_full, y_train_full, test_size=0.2, random_state=42, stratify=y_train_full\n)\n\nclf.fit(X_train, y_train)\n\n# Evaluate\nval_preds = clf.predict(X_val)\nval_acc = accuracy_score(y_val, val_preds)\nprint(f\"Validation Accuracy: {val_acc:.4f}\")\n\n# ==========================================\n# 5. GENERATE SUBMISSION\n# ==========================================\nprint(\"\\nRetraining on full dataset...\")\nclf.fit(X_train_full, y_train_full)\n\nprint(\"Generating test predictions...\")\ntest_preds = clf.predict(X_test)\n\n# Verify Column Names from Sample Submission (if available)\n# Standard Kaggle format usually 'Id' and 'Category' or 'label'\n# We will use 'id' and 'Category' based on common formats.\nsample_files = glob.glob('/kaggle/input/**/sample_submission.csv', recursive=True)\ncol_names = ['id', 'Category'] # Default\nif sample_files:\n    sample_df = pd.read_csv(sample_files[0])\n    col_names = list(sample_df.columns)\n    print(f\"Found sample submission. Using columns: {col_names}\")\n\n# Create DataFrame\ntest_ids = np.arange(len(test_preds))\nsubmission_df = pd.DataFrame({\n    col_names[0]: test_ids,\n    col_names[1]: test_preds\n})\n\n# Save\nsubmission_df.to_csv(OUTPUT_FILENAME, index=False)\nprint(f\"Submission saved to {OUTPUT_FILENAME}\")\nprint(submission_df.head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-10T07:11:12.590395Z","iopub.execute_input":"2026-02-10T07:11:12.590926Z","iopub.status.idle":"2026-02-10T07:11:25.611515Z","shell.execute_reply.started":"2026-02-10T07:11:12.590878Z","shell.execute_reply":"2026-02-10T07:11:25.609887Z"}},"outputs":[],"execution_count":null}]}