{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":59156,"databundleVersionId":13874099,"sourceType":"competition"}],"dockerImageVersionId":31089,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Define","metadata":{}},{"cell_type":"code","source":"%%time\nfrom pathlib import Path\nimport pandas as pd\n\nTRAIN_ANNOTATION_DIR = Path(\"../input/MABe-mouse-behavior-detection/train_annotation\")\nTRAIN_TRACKING_DIR = Path(\"../input/MABe-mouse-behavior-detection/train_tracking\")\n\ntrain_files = list(TRAIN_ANNOTATION_DIR.glob(\"**/*.parquet\"))\ntrack_files = list(TRAIN_TRACKING_DIR.glob(\"**/*.parquet\"))\n\nprint(f\"✅ Found {len(train_files)} annotation files\")\nprint(f\"✅ Found {len(track_files)} tracking files\")\n\nsample = pd.read_parquet(train_files[0])\ndisplay(sample.head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-10T05:44:05.535542Z","iopub.execute_input":"2025-10-10T05:44:05.535976Z","iopub.status.idle":"2025-10-10T05:44:10.123967Z","shell.execute_reply.started":"2025-10-10T05:44:05.535949Z","shell.execute_reply":"2025-10-10T05:44:10.123095Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# EDA","metadata":{}},{"cell_type":"markdown","source":"1️⃣ Action distribution\n\nCount how many times each action occurs in the training annotations.\n\nIdentify rare vs frequent actions.","metadata":{}},{"cell_type":"code","source":"%%time\nfrom collections import Counter\nimport matplotlib.pyplot as plt\n\n# Gather all actions\nall_actions = []\nfor f in train_files:\n    df = pd.read_parquet(f)\n    all_actions.extend(df['action'].tolist())\n\naction_counts = Counter(all_actions)\nactions, counts = zip(*action_counts.most_common())\n\nplt.figure(figsize=(12,5))\nplt.bar(actions, counts)\nplt.xticks(rotation=45, ha='right')\nplt.title(\"Action Frequency Distribution in Training Set\")\nplt.ylabel(\"Count\")\nplt.tight_layout()\nplt.show()\n\nprint(f\"✅ Total unique actions: {len(actions)}\")\nprint(f\"Most frequent: {actions[0]} ({counts[0]} samples)\")\nprint(f\"Least frequent: {actions[-1]} ({counts[-1]} samples)\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-10T05:44:10.126076Z","iopub.execute_input":"2025-10-10T05:44:10.126788Z","iopub.status.idle":"2025-10-10T05:44:13.190397Z","shell.execute_reply.started":"2025-10-10T05:44:10.126759Z","shell.execute_reply":"2025-10-10T05:44:13.189359Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"🧪 3️⃣ Per-Lab Action Distribution","metadata":{}},{"cell_type":"code","source":"%%time\nimport seaborn as sns\n\nlab_action_data = []\nfor f in train_files:\n    lab = f.parent.name\n    df = pd.read_parquet(f)\n    action_counts = df['action'].value_counts()\n    for act, count in action_counts.items():\n        lab_action_data.append((lab, act, count))\n\nlab_df = pd.DataFrame(lab_action_data, columns=[\"lab\", \"action\", \"count\"])\n\nplt.figure(figsize=(12,6))\nsns.barplot(data=lab_df, x=\"action\", y=\"count\", hue=\"lab\", estimator=sum)\nplt.xticks(rotation=45, ha='right')\nplt.title(\"Action Distribution Across Labs\")\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-10T05:44:13.191628Z","iopub.execute_input":"2025-10-10T05:44:13.192406Z","iopub.status.idle":"2025-10-10T05:44:21.815639Z","shell.execute_reply.started":"2025-10-10T05:44:13.192373Z","shell.execute_reply":"2025-10-10T05:44:21.814626Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"2️⃣ Video lengths\n\nCompute number of frames per video and duration in seconds.\n\nCheck variability across labs.","metadata":{}},{"cell_type":"code","source":"%%time\nvideo_lengths = []\nfor f in train_files:\n    df = pd.read_parquet(f)\n    video_lengths.append(df['stop_frame'].max())\n\nplt.figure(figsize=(8,4))\nplt.hist(video_lengths, bins=40)\nplt.xlabel(\"Frames per video\")\nplt.ylabel(\"Count\")\nplt.title(\"Distribution of Video Lengths\")\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-10T05:44:21.816685Z","iopub.execute_input":"2025-10-10T05:44:21.816993Z","iopub.status.idle":"2025-10-10T05:44:24.668060Z","shell.execute_reply.started":"2025-10-10T05:44:21.816970Z","shell.execute_reply":"2025-10-10T05:44:24.666747Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"🧍 5️⃣ Tracking Coverage (Body Parts per Video)","metadata":{}},{"cell_type":"code","source":"%%time\ntracking_summary = []\nfor f in track_files[:10]:\n    df = pd.read_parquet(f)\n    tracking_summary.append({\n        \"file\": f.stem,\n        \"bodyparts\": df['bodypart'].nunique(),\n        \"frames\": df['video_frame'].nunique()\n    })\n\ntracking_df = pd.DataFrame(tracking_summary)\ndisplay(tracking_df)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-10T05:44:24.670977Z","iopub.execute_input":"2025-10-10T05:44:24.671801Z","iopub.status.idle":"2025-10-10T05:44:24.871476Z","shell.execute_reply.started":"2025-10-10T05:44:24.671770Z","shell.execute_reply":"2025-10-10T05:44:24.870283Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"add Codeadd Markdown\narrow_upwardarrow_downwarddelete\n\n🧩 6️⃣ Pair Interactions","metadata":{}},{"cell_type":"code","source":"%%time\nfrom collections import Counter\n\npairs = []\nfor f in train_files:\n    df = pd.read_parquet(f)\n    pairs.extend(zip(df['agent_id'], df['target_id']))\n\npair_counts = Counter(pairs)\ntop_pairs = pair_counts.most_common(10)\n\nprint(\"Top 10 agent-target pairs:\")\nfor (a, t), c in top_pairs:\n    print(f\"  {a} → {t}: {c}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-10T05:44:24.872565Z","iopub.execute_input":"2025-10-10T05:44:24.872976Z","iopub.status.idle":"2025-10-10T05:44:27.798145Z","shell.execute_reply.started":"2025-10-10T05:44:24.872951Z","shell.execute_reply":"2025-10-10T05:44:27.797113Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"4️⃣ Missing data in tracking\n\nCheck which body parts are missing in each video.\n\nSome labs track different points — important for features.","metadata":{}},{"cell_type":"code","source":"%%time\nTRACKING_DIR = Path(\"../input/MABe-mouse-behavior-detection/train_tracking\")\ntracking_files = list(TRACKING_DIR.glob(\"**/*.parquet\"))\n\nfor f in tracking_files[:5]:  # just first 5 for quick check\n    df = pd.read_parquet(f)\n    print(f\"{f.stem}: {df['bodypart'].nunique()} body parts tracked\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-10T05:44:27.799274Z","iopub.execute_input":"2025-10-10T05:44:27.799547Z","iopub.status.idle":"2025-10-10T05:44:28.017050Z","shell.execute_reply.started":"2025-10-10T05:44:27.799520Z","shell.execute_reply":"2025-10-10T05:44:28.015911Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"🧠 1️⃣ Compute Global + Per-Lab Most Frequent Actions","metadata":{}},{"cell_type":"code","source":"%%time\nfrom collections import Counter\nfrom pathlib import Path\nimport pandas as pd\n\nTRAIN_ANNOTATION_DIR = Path(\"../input/MABe-mouse-behavior-detection/train_annotation\")\ntrain_files = list(TRAIN_ANNOTATION_DIR.glob(\"**/*.parquet\"))\n\nglobal_counts = Counter()\nlab_major_action = {}\n\nfor f in train_files:\n    lab = f.parent.name\n    df = pd.read_parquet(f)\n    counts = Counter(df['action'])\n    global_counts.update(counts)\n    lab_major_action[lab] = counts.most_common(1)[0][0]\n\nglobal_top3 = [a for a, _ in global_counts.most_common(3)]\nprint(\"Top 3 global actions:\", global_top3)\nprint(\"Per-lab most frequent actions:\", lab_major_action)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-10T05:44:28.018082Z","iopub.execute_input":"2025-10-10T05:44:28.018731Z","iopub.status.idle":"2025-10-10T05:44:30.617887Z","shell.execute_reply.started":"2025-10-10T05:44:28.018699Z","shell.execute_reply":"2025-10-10T05:44:30.616671Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Generate baseline predictions","metadata":{}},{"cell_type":"code","source":"%%time\nfrom tqdm.auto import tqdm\nimport random\n\nTEST_TRACKING_DIR = Path(\"../input/MABe-mouse-behavior-detection/test_tracking\")\ntest_files = list(TEST_TRACKING_DIR.glob(\"**/*.parquet\"))\nprint(f\"🔍 Found {len(test_files)} test tracking files\")\n\nrows = []\nrow_id = 0\n\nfor f in tqdm(test_files, desc=\"Generating V2 predictions\"):\n    df = pd.read_parquet(f)\n    video_id = int(f.stem)\n    \n    # infer lab name if directory structure allows\n    lab = f.parent.name\n    if lab in lab_major_action:\n        predicted_action = lab_major_action[lab]\n    else:\n        predicted_action = random.choice(global_top3)\n    \n    mice_ids = df['mouse_id'].unique()\n    start_frame = int(df['video_frame'].min())\n    stop_frame = int(df['video_frame'].max())\n    \n    for agent in mice_ids:\n        for target in mice_ids:\n            t_id = \"mouseself\" if agent == target else f\"mouse{target}\"\n            a_id = f\"mouse{agent}\"\n            rows.append([row_id, video_id, a_id, t_id, predicted_action, start_frame, stop_frame])\n            row_id += 1","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-10T05:44:30.619135Z","iopub.execute_input":"2025-10-10T05:44:30.619418Z","iopub.status.idle":"2025-10-10T05:44:30.742246Z","shell.execute_reply.started":"2025-10-10T05:44:30.619398Z","shell.execute_reply":"2025-10-10T05:44:30.741240Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Submision","metadata":{}},{"cell_type":"code","source":"%%time\nsubmission_df = pd.DataFrame(rows, columns=[\n    \"row_id\", \"video_id\", \"agent_id\", \"target_id\", \"action\", \"start_frame\", \"stop_frame\"\n])\nsubmission_df.to_csv(\"submission.csv\", index=False)\nprint(f\"✅ Baseline submission.csv written: {submission_df.shape[0]} rows\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-10T05:44:30.743311Z","iopub.execute_input":"2025-10-10T05:44:30.743635Z","iopub.status.idle":"2025-10-10T05:44:30.753043Z","shell.execute_reply.started":"2025-10-10T05:44:30.743576Z","shell.execute_reply":"2025-10-10T05:44:30.751950Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%time\nimport pandas as pd\n\n# Load the submission file\nsubmission = pd.read_csv('submission.csv')\n\n# Display the first few rows\nsubmission.head()  ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-10T05:44:30.754114Z","iopub.execute_input":"2025-10-10T05:44:30.754371Z","iopub.status.idle":"2025-10-10T05:44:30.783214Z","shell.execute_reply.started":"2025-10-10T05:44:30.754352Z","shell.execute_reply":"2025-10-10T05:44:30.782207Z"}},"outputs":[],"execution_count":null}]}