{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":71549,"databundleVersionId":8561470,"sourceType":"competition"}],"dockerImageVersionId":31041,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# Cell 1: Install all dependencies once\n%pip install ultralytics==8.0.111 torch torchvision pandas numpy pydicom albumentations scikit-learn tqdm\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T09:41:45.810241Z","iopub.execute_input":"2025-06-07T09:41:45.810496Z","iopub.status.idle":"2025-06-07T09:41:49.180414Z","shell.execute_reply.started":"2025-06-07T09:41:45.810478Z","shell.execute_reply":"2025-06-07T09:41:49.179655Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Point to the RSNA CSVs in your Kaggle dataset\nData_path = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification'\n\nimport os\nimport pandas as pd\n\n# 1) Read train_label_coordinates.csv and train_series_descriptions.csv\ntrain_label_coordinates = pd.read_csv(os.path.join(Data_path, 'train_label_coordinates.csv'))\ntrain_series_descriptions = pd.read_csv(os.path.join(Data_path, 'train_series_descriptions.csv'))\n\n# 2) Merge on ['study_id', 'series_id'] to pull in series_description\nmerged_csv = pd.merge(\n    train_label_coordinates,\n    train_series_descriptions[['study_id', 'series_id', 'series_description']],\n    on=['study_id', 'series_id'],\n    how='left'\n)\n\n# 3) Read train.csv (holds the severity scores)\ntrain_df = pd.read_csv(os.path.join(Data_path, 'train.csv'))\n\n# 4) Helper to look up the correct column (e.g. 'neural_foraminal_narrowing_l1_l2') and fetch its value\ndef get_score(row):\n    study_id = row['study_id']\n    condition = row['condition']\n    level = row['level']  # like \"L1/L2\" or \"R3/R4\"\n\n    # Split \"L1/L2\" → \"L1\", \"L2\" so we can build a column name same as in train.csv\n    level_1, level_2 = level.split('/')\n    condition_level = f\"{condition}_{level_1}_{level_2}\".replace(' ', '_').lower()\n    # e.g., \"neural_foraminal_narrowing_l1_l2\"\n\n    if condition_level in train_df.columns and study_id in train_df['study_id'].values:\n        return train_df.loc[train_df['study_id'] == study_id, condition_level].values[0]\n    else:\n        return None\n\n# 5) Apply it to every row\nmerged_csv['score'] = merged_csv.apply(get_score, axis=1)\n\n# 6) Save the merged result into /kaggle/working so downstream steps can consume it\nout_path = '/kaggle/working/dataset_description.csv'\nmerged_csv.to_csv(out_path, index=False)\nprint(f\"✅ Wrote merged CSV with scores to: {out_path}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-03T12:25:40.420754Z","iopub.execute_input":"2025-07-03T12:25:40.420996Z","iopub.status.idle":"2025-07-03T12:25:53.821900Z","shell.execute_reply.started":"2025-07-03T12:25:40.420964Z","shell.execute_reply":"2025-07-03T12:25:53.821303Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport pandas as pd\n\n# 1) Path to the merged file you created earlier\ninput_csv = '/kaggle/working/dataset_description.csv'\n\n# 2) Load the full dataset_description.csv\ndf = pd.read_csv(input_csv)\n\n# 3) Define which 'condition' values belong to each output group\ncondition_groups = {\n    'Spinal Canal Stenosis': ['Spinal Canal Stenosis'],\n    'Neural Foraminal Narrowing': ['Right Neural Foraminal Narrowing', 'Left Neural Foraminal Narrowing'],\n    'Subarticular Stenosis': ['Right Subarticular Stenosis', 'Left Subarticular Stenosis']\n}\n\n# 4) For each group, filter and save a separate CSV\nfor group_name, conditions in condition_groups.items():\n    filtered_df = df[df['condition'].isin(conditions)].copy()\n    # Make a filesystem‐friendly name, e.g. \"Spinal_Canal_Stenosis.csv\"\n    out_name = group_name.replace(' ', '_') + '.csv'\n    out_path = os.path.join('/kaggle/working', out_name)\n    filtered_df.to_csv(out_path, index=False)\n    print(f\"→ Wrote {len(filtered_df)} rows to {out_name}\")\n\nprint(\"✅ Done splitting into three CSVs.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-03T12:26:22.682226Z","iopub.execute_input":"2025-07-03T12:26:22.682960Z","iopub.status.idle":"2025-07-03T12:26:23.090848Z","shell.execute_reply.started":"2025-07-03T12:26:22.682937Z","shell.execute_reply":"2025-07-03T12:26:23.090261Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport pandas as pd\nfrom sklearn.model_selection import StratifiedKFold\n\ndef cross_validation_5fold(csv_path, output_name):\n    \"\"\"\n    Reads a condition‐specific CSV, creates 'class_id' from condition+level,\n    performs a 2‐fold stratified split, and writes out a new CSV with a 'fold' column.\n    \"\"\"\n    df = pd.read_csv(csv_path)\n\n    # Create a combined “condition_level” string\n    df['condition_level'] = df['condition'] + '_' + df['level']\n\n    # Convert to numeric class IDs for stratification\n    df['class_id'] = df['condition_level'].astype('category').cat.codes\n\n    # Use 2 splits instead of 5\n    skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)\n\n    df['fold'] = -1\n    for fold_number, (_, val_idx) in enumerate(skf.split(df, df['class_id'])):\n        df.loc[val_idx, 'fold'] = fold_number\n\n    output_path = os.path.join('/kaggle/working', f\"{output_name}.csv\")\n    df.to_csv(output_path, index=False)\n    print(f\"Saved 5‐fold CSV to: {output_path}\")\n\n\n# Paths to the condition‐specific CSVs (from the “split by condition” step)\nspinal_csv = '/kaggle/working/Spinal_Canal_Stenosis.csv'\nneural_csv = '/kaggle/working/Neural_Foraminal_Narrowing.csv'\nsubart_csv = '/kaggle/working/Subarticular_Stenosis.csv'\n\n# Run 2‐fold stratified splitting for each condition\ncross_validation_5fold(spinal_csv, 'Spinal_Canal_Stenosis_5folds')\ncross_validation_5fold(neural_csv, 'Neural_Foraminal_Narrowing_5folds')\ncross_validation_5fold(subart_csv, 'Subarticular_Stenosis_5folds')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-03T12:26:49.809949Z","iopub.execute_input":"2025-07-03T12:26:49.810538Z","iopub.status.idle":"2025-07-03T12:26:50.315712Z","shell.execute_reply.started":"2025-07-03T12:26:49.810515Z","shell.execute_reply":"2025-07-03T12:26:50.314924Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\nprint(os.listdir('/kaggle/working'))\n# You should see:\n# [\n#   'dataset_description.csv',\n#   'Spinal_Canal_Stenosis.csv',\n#   'Neural_Foraminal_Narrowing.csv',\n#   'Subarticular_Stenosis.csv',\n#   'Spinal_Canal_Stenosis_folds.csv',\n#   'Neural_Foraminal_Narrowing_folds.csv',\n#   'Subarticular_Stenosis_folds.csv',\n#   … (any other files)\n# ]\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"CLASSIFER ","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}