{"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":[{"sourceType":"competition","sourceId":131114,"databundleVersionId":15740541}],"dockerImageVersionId":31287,"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-21T07:22:44.870583Z","iopub.execute_input":"2026-02-21T07:22:44.870900Z","iopub.status.idle":"2026-02-21T07:22:45.799069Z","shell.execute_reply.started":"2026-02-21T07:22:44.870877Z","shell.execute_reply":"2026-02-21T07:22:45.798324Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom sklearn.feature_extraction.text import TfidfVectorizer\nfrom sklearn.ensemble import RandomForestClassifier\nfrom sklearn.multioutput import MultiOutputClassifier, MultiOutputRegressor\nfrom sklearn.linear_model import LogisticRegression, Ridge\nimport warnings\nwarnings.filterwarnings('ignore')\n\n# 1. Load Data\nTRAIN_PATH = \"/kaggle/input/deep-pharma-multimodal-intelligence-challenge-data-hack-3-0/train.csv\"\nTEST_PATH = \"/kaggle/input/deep-pharma-multimodal-intelligence-challenge-data-hack-3-0/test.csv\"\nSUB_PATH = \"/kaggle/input/deep-pharma-multimodal-intelligence-challenge-data-hack-3-0/sample_submission.csv\"\n\nprint(\"Loading datasets...\")\ntrain = pd.read_csv(TRAIN_PATH)\ntest = pd.read_csv(TEST_PATH)\nsub = pd.read_csv(SUB_PATH)\n\n# 2. Extract Target Columns dynamically from the sample submission\ntarget_cols = sub.columns.drop('Pair_ID').tolist()\nbinary_targets = [col for col in target_cols if col.startswith('Target_Binary')]\nprr_targets = [col for col in target_cols if col.startswith('Target_PRR')]\n\n# 3. Quick Feature Engineering (Multimodal to Text)\n# We take all available feature columns in the test set (SMILES, Mechanism, Toxicity, etc.)\n# and concatenate them into a single giant text string per row for TF-IDF to process.\nfeature_cols = [c for c in test.columns if c != 'Pair_ID']\n\ndef create_text_feature(df):\n    # Fill missing values with empty strings to avoid errors\n    df_filled = df[feature_cols].fillna(\"\")\n    # Join all columns into one text document per interaction pair\n    text_series = df_filled.astype(str).agg(' '.join, axis=1)\n    return text_series\n\nprint(\"Concatenating multimodal features...\")\nX_train_text = create_text_feature(train)\nX_test_text = create_text_feature(test)\n\n# 4. Text Vectorization\nprint(\"Vectorizing text features via TF-IDF...\")\n# max_features=3000 ensures it runs fast on Kaggle without crashing memory\ntfidf = TfidfVectorizer(max_features=3000, stop_words='english')\nX_train_vec = tfidf.fit_transform(X_train_text)\nX_test_vec = tfidf.transform(X_test_text)\n\n# 5. Train Models for the 3 Different Tasks\nprint(\"Training Severity Classifier (Multiclass)...\")\n# Using balanced class weight since \"Contraindication\" might be a rare class\nclf_severity = RandomForestClassifier(n_estimators=100, random_state=42, n_jobs=-1, class_weight='balanced')\nclf_severity.fit(X_train_vec, train['Severity'])\n\nprint(\"Training Binary Side Effect Classifiers (50 Multi-labels)...\")\nclf_binary = MultiOutputClassifier(LogisticRegression(max_iter=500, class_weight='balanced', n_jobs=-1))\nclf_binary.fit(X_train_vec, train[binary_targets])\n\nprint(\"Training PRR Regressors (50 Continuous targets)...\")\n# Fill NaN PRRs with 0 for baseline regression\ny_train_prr = train[prr_targets].fillna(0)\nreg_prr = MultiOutputRegressor(Ridge(alpha=1.0))\nreg_prr.fit(X_train_vec, y_train_prr)\n\n# 6. Predict on Test Set\nprint(\"Generating predictions...\")\npred_severity = clf_severity.predict(X_test_vec)\npred_binary = clf_binary.predict(X_test_vec)\npred_prr = reg_prr.predict(X_test_vec)\n\n# Post-processing: PRR cannot be negative, so we clip any predictions below 0\npred_prr = np.clip(pred_prr, 0, None)\n\n# 7. Format Submission File\nprint(\"Formatting submission.csv...\")\nsubmission = pd.DataFrame({'Pair_ID': test['Pair_ID']})\nsubmission['Severity'] = pred_severity\n\n# Attach binary arrays\nbin_df = pd.DataFrame(pred_binary, columns=binary_targets)\nsubmission = pd.concat([submission, bin_df], axis=1)\n\n# Attach PRR arrays\nprr_df = pd.DataFrame(pred_prr, columns=prr_targets)\nsubmission = pd.concat([submission, prr_df], axis=1)\n\n# Ensure columns are exactly in the order expected by the Kaggle grader\nsubmission = submission[sub.columns]\n\n# 8. Save\nsubmission.to_csv(\"submission.csv\", index=False)\nprint(\"Done! Saved submission.csv successfully. You can now submit.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-21T07:24:24.461461Z","iopub.execute_input":"2026-02-21T07:24:24.461840Z","iopub.status.idle":"2026-02-21T07:27:06.530225Z","shell.execute_reply.started":"2026-02-21T07:24:24.461812Z","shell.execute_reply":"2026-02-21T07:27:06.529619Z"}},"outputs":[],"execution_count":null}]}