{"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":"none","dataSources":[{"sourceId":116062,"databundleVersionId":14875579,"sourceType":"competition"},{"sourceId":14187577,"sourceType":"datasetVersion","datasetId":9045748},{"sourceId":287175447,"sourceType":"kernelVersion"},{"sourceId":292870115,"sourceType":"kernelVersion"}],"dockerImageVersionId":31234,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport networkx as nx\nfrom tqdm.auto import tqdm\n\n# ==========================================\n# CONFIGURATION\n# ==========================================\nDATA_DIR = \"/kaggle/input/cafa-6-protein-function-prediction\"\nOBO_PATH = os.path.join(DATA_DIR, \"Train/go-basic.obo\")\nIA_PATH = os.path.join(DATA_DIR, \"IA.tsv\")\n\n# YOUR INPUT FILE\nSUBMISSION_INPUT = '/kaggle/input/cafa6-protein-function-enhanced-nb-v2/submission.tsv'\nSUBMISSION_OUTPUT = 'submission.tsv'\n\n# ==========================================\n# 1. LOAD IA WEIGHTS & GRAPH\n# ==========================================\ndef load_resources(obo_path, ia_path):\n    print(\"Loading IA Weights and GO Hierarchy...\")\n    # IA weights are the secret to moving from 0.38 to 0.46\n    ia_df = pd.read_csv(ia_path, sep='\\t', header=None, names=['term', 'ia'])\n    ia_map = dict(zip(ia_df['term'], ia_df['ia']))\n    \n    graph = nx.DiGraph()\n    with open(obo_path, \"r\") as f:\n        cur_id = None\n        for line in f:\n            if line.startswith(\"id: \"):\n                cur_id = line.split(\"id: \")[1].strip()\n                graph.add_node(cur_id)\n            elif line.startswith(\"is_a: \") and cur_id:\n                parent = line.split(\"is_a: \")[1].split(\" ! \")[0].strip()\n                graph.add_edge(cur_id, parent)\n                \n    topo_order = list(nx.topological_sort(graph))\n    parents_map = {node: list(graph.successors(node)) for node in graph.nodes()}\n    return topo_order, parents_map, ia_map\n\n# ==========================================\n# 2. IA-OPTIMIZED PROPAGATION\n# ==========================================\ndef optimized_propagation(df, topo_order, parents_map, ia_map):\n    print(\"Applying Information Accretion Weighting...\")\n    \n    # Filter: Roots and generic terms (IA=0) are removed to boost Precision\n    valid_terms = {term for term, ia in ia_map.items() if ia > 0}\n    \n    results = []\n    for pid, group in tqdm(df.groupby('protein_id')):\n        scores = dict(zip(group['go_term'], group['score']))\n        \n        # True Path Rule: Ensure parent score >= child score\n        for child in topo_order:\n            if child in scores:\n                c_score = scores[child]\n                for parent in parents_map.get(child, []):\n                    scores[parent] = max(scores.get(parent, 0), c_score)\n        \n        # SELECTION STRATEGY FOR 0.46+ RANK:\n        # We calculate a 'Value Score' using IA weights\n        value_list = []\n        for term, score in scores.items():\n            if term in valid_terms and score >= 0.05:\n                ia_val = ia_map.get(term, 0.0)\n                # IA-Boost: Prioritize specific terms that give more points\n                rank_score = score * (1 + (ia_val / 10.0))\n                value_list.append((pid, term, round(score, 3), rank_score))\n        \n        # Keep top 150 most valuable terms per protein to avoid noise penalty\n        value_list.sort(key=lambda x: x[3], reverse=True)\n        for val in value_list[:150]:\n            results.append(val[:3])\n                \n    return pd.DataFrame(results, columns=['protein_id', 'go_term', 'score'])\n\n# ==========================================\n# 3. EXECUTION\n# ==========================================\ntopo, parents, ia = load_resources(OBO_PATH, IA_PATH)\n\n# Robust loading for submission files\nsub = pd.read_csv(SUBMISSION_INPUT, sep='\\t', header=None, \n                 names=['protein_id', 'go_term', 'score'], \n                 on_bad_lines='skip', engine='python')\n\nfinal_sub = optimized_propagation(sub, topo, parents, ia)\nfinal_sub.to_csv(SUBMISSION_OUTPUT, sep='\\t', index=False, header=False)\nprint(f\"Optimization complete! Saved {len(final_sub)} high-value predictions.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-31T13:05:49.781149Z","iopub.execute_input":"2026-01-31T13:05:49.781572Z","iopub.status.idle":"2026-01-31T13:43:54.765430Z","shell.execute_reply.started":"2026-01-31T13:05:49.781538Z","shell.execute_reply":"2026-01-31T13:43:54.762518Z"}},"outputs":[],"execution_count":null}]}