{"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":116062,"databundleVersionId":14084779,"sourceType":"competition"}],"dockerImageVersionId":31192,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# Cell 1: Import libraries\nimport pandas as pd\nimport numpy as np\nimport os\nfrom pathlib import Path","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-11-15T16:55:26.133321Z","iopub.execute_input":"2025-11-15T16:55:26.134002Z","iopub.status.idle":"2025-11-15T16:55:26.138144Z","shell.execute_reply.started":"2025-11-15T16:55:26.133974Z","shell.execute_reply":"2025-11-15T16:55:26.137267Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Cell 2: Set blending parameters\nW_A = 0.80\nW_B = 0.20\nBONUS_DIVERSITY = 0.05\nMIN_SCORE = 0.01","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-15T16:55:26.140886Z","iopub.execute_input":"2025-11-15T16:55:26.141475Z","iopub.status.idle":"2025-11-15T16:55:26.158353Z","shell.execute_reply.started":"2025-11-15T16:55:26.141447Z","shell.execute_reply":"2025-11-15T16:55:26.157655Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Cell 3: Load Model A predictions with error handling\ndef load_predictions(file_path, model_name):\n    \"\"\"Load prediction file with error handling\"\"\"\n    try:\n        if os.path.exists(file_path):\n            df = pd.read_csv(\n                file_path,\n                sep='\\t',\n                header=None,\n                names=['protein', 'go_term', 'score']\n            )\n            df['entry_id'] = df['protein'] + '|' + df['go_term']\n            df['score'] = np.clip(df['score'], 0, 1)\n            print(f\"✓ Loaded {model_name}: {len(df)} predictions\")\n            return df\n        else:\n            print(f\"✗ File not found: {file_path}\")\n            return None\n    except Exception as e:\n        print(f\"✗ Error loading {model_name}: {str(e)}\")\n        return None\n\n# Try to load Model A predictions\nmodel_a_path = '/kaggle/input/cafa-6-blend-goa-negative-propagation/submission.tsv'\ndf_a = load_predictions(model_a_path, \"Model A\")\n\n# Try to load Model B predictions\nmodel_b_path = '/kaggle/input/cafa-6-protein-function-starter-eda-model/submission.tsv'\ndf_b = load_predictions(model_b_path, \"Model B\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-15T16:55:26.159791Z","iopub.execute_input":"2025-11-15T16:55:26.160151Z","iopub.status.idle":"2025-11-15T16:55:26.178100Z","shell.execute_reply.started":"2025-11-15T16:55:26.160128Z","shell.execute_reply":"2025-11-15T16:55:26.177366Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Cell 4: Check available inputs\nprint(\"\\nAvailable input files:\")\ninput_dir = Path('/kaggle/input')\nif input_dir.exists():\n    for dataset in input_dir.iterdir():\n        if dataset.is_dir():\n            print(f\"\\nDataset: {dataset.name}\")\n            for file in dataset.iterdir():\n                print(f\"  - {file.name}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-15T16:55:26.179146Z","iopub.execute_input":"2025-11-15T16:55:26.179541Z","iopub.status.idle":"2025-11-15T16:55:26.203609Z","shell.execute_reply.started":"2025-11-15T16:55:26.179508Z","shell.execute_reply":"2025-11-15T16:55:26.202865Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Cell 5: Create ensemble only if both models are loaded\nif df_a is not None and df_b is not None:\n    # Create dictionaries mapping entry_id to scores\n    score_a_map = dict(zip(df_a['entry_id'], df_a['score']))\n    score_b_map = dict(zip(df_b['entry_id'], df_b['score']))\n    \n    # Ensemble prediction\n    all_entries = set(score_a_map.keys()).union(score_b_map.keys())\n    ensemble_rows = []\n    \n    for entry in all_entries:\n        prot, go = entry.split('|')\n        score_a = score_a_map.get(entry, 0)\n        score_b = score_b_map.get(entry, 0)\n        \n        # Weighted blend\n        blend_score = score_a * W_A + score_b * W_B\n        \n        # Bonus for diversity (both models agree)\n        if score_a > 0 and score_b > 0:\n            blend_score = min(blend_score + BONUS_DIVERSITY, 1)\n        \n        ensemble_rows.append({\n            'protein': prot,\n            'go_term': go,\n            'score': blend_score\n        })\n    \n    # Create final dataframe\n    ensemble_df = pd.DataFrame(ensemble_rows)\n    ensemble_df = ensemble_df.sort_values('score', ascending=False)\n    ensemble_df = ensemble_df[ensemble_df['score'] >= MIN_SCORE]\n    \n    # Save submission\n    ensemble_df[['protein', 'go_term', 'score']].to_csv(\n        'submission.tsv',\n        sep='\\t',\n        index=False,\n        header=False\n    )\n    \n    print(f\"\\n✓ Ensemble created: {len(ensemble_df)} predictions\")\n    print(f\"✓ Saved to: submission.tsv\")\n    \nelse:\n    print(\"\\n⚠ Cannot create ensemble - missing input files\")\n    print(\"\\nTo fix this:\")\n    print(\"1. Click 'Add Input' in the right panel\")\n    print(\"2. Search for and add the required datasets:\")\n    print(\"   - cafa-6-blend-goa-negative-propagation\")\n    print(\"   - cafa-6-protein-function-starter-eda-model\")\n    print(\"3. Re-run the notebook\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-15T16:55:26.204953Z","iopub.execute_input":"2025-11-15T16:55:26.205202Z","iopub.status.idle":"2025-11-15T16:55:26.214420Z","shell.execute_reply.started":"2025-11-15T16:55:26.205170Z","shell.execute_reply":"2025-11-15T16:55:26.213522Z"}},"outputs":[],"execution_count":null}]}