{"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":14484594,"sourceType":"datasetVersion","datasetId":9251535}],"dockerImageVersionId":31234,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom collections import defaultdict\nimport warnings\n\nwarnings.filterwarnings(\"ignore\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-01-13T11:23:21.663848Z","iopub.execute_input":"2026-01-13T11:23:21.664161Z","iopub.status.idle":"2026-01-13T11:23:21.669157Z","shell.execute_reply.started":"2026-01-13T11:23:21.664137Z","shell.execute_reply":"2026-01-13T11:23:21.668183Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"OBO_PATH = \"/kaggle/input/cafa-6-protein-function-prediction/Train/go-basic.obo\"\n\nterm_parents = defaultdict(set)\nroots = {\n    \"GO:0003674\",\n    \"GO:0008150\",\n    \"GO:0005575\"\n}\n\ncurrent_term = None\n\nwith open(OBO_PATH, \"r\") as f:\n    for line in f:\n        line = line.strip()\n\n        if line == \"[Term]\":\n            current_term = None\n\n        elif line.startswith(\"id:\"):\n            current_term = line.split(\"id:\")[1].strip()\n\n        elif line.startswith(\"is_a:\") and current_term:\n            parent = line.split()[1]\n            term_parents[current_term].add(parent)\n\n        elif line.startswith(\"relationship: part_of\") and current_term:\n            parent = line.split()[2]\n            term_parents[current_term].add(parent)\n\nprint(len(term_parents))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-13T11:23:21.670861Z","iopub.execute_input":"2026-01-13T11:23:21.671190Z","iopub.status.idle":"2026-01-13T11:23:22.104130Z","shell.execute_reply.started":"2026-01-13T11:23:21.671165Z","shell.execute_reply":"2026-01-13T11:23:22.102986Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ancestor_map = {}\n\ndef get_ancestors(term):\n    if term in ancestor_map:\n        return ancestor_map[term]\n\n    parents = term_parents.get(term, set())\n    ancestors = set(parents)\n\n    for p in parents:\n        ancestors |= get_ancestors(p)\n\n    ancestor_map[term] = ancestors\n    return ancestors\n\nfor term in term_parents:\n    get_ancestors(term)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-13T11:23:22.105286Z","iopub.execute_input":"2026-01-13T11:23:22.105558Z","iopub.status.idle":"2026-01-13T11:23:22.454287Z","shell.execute_reply.started":"2026-01-13T11:23:22.105533Z","shell.execute_reply":"2026-01-13T11:23:22.453300Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"INPUT1 = \"/kaggle/input/protein-go-annotations/Protein GO Annotations v227.csv\"\nINPUT2 = \"/kaggle/input/protein-go-annotations/Protein GO Annotations v228.tsv\"\n\ndf1 = pd.read_csv(INPUT1)\ndf2 = pd.read_csv(INPUT2, sep=\"\\t\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-13T11:23:22.456526Z","iopub.execute_input":"2026-01-13T11:23:22.456853Z","iopub.status.idle":"2026-01-13T11:23:25.408209Z","shell.execute_reply.started":"2026-01-13T11:23:22.456827Z","shell.execute_reply":"2026-01-13T11:23:25.407327Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df1 = df1[[\"protein_id\", \"go_term\"]]\ndf1[\"score\"] = 1.0\n\ndf2 = df2[[\"protein_id\", \"go_term\"]]\ndf2[\"score\"] = 1.0","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-13T11:23:25.409329Z","iopub.execute_input":"2026-01-13T11:23:25.409698Z","iopub.status.idle":"2026-01-13T11:23:25.640830Z","shell.execute_reply.started":"2026-01-13T11:23:25.409672Z","shell.execute_reply":"2026-01-13T11:23:25.639753Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = pd.concat(\n    [df1, df2],\n    ignore_index=True\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-13T11:23:25.642083Z","iopub.execute_input":"2026-01-13T11:23:25.642436Z","iopub.status.idle":"2026-01-13T11:23:25.848534Z","shell.execute_reply.started":"2026-01-13T11:23:25.642401Z","shell.execute_reply":"2026-01-13T11:23:25.847516Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = submission.groupby(\n    [\"protein_id\", \"go_term\"],\n    as_index=False\n)[\"score\"].max()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-13T11:23:25.849419Z","iopub.execute_input":"2026-01-13T11:23:25.849693Z","iopub.status.idle":"2026-01-13T11:23:29.329414Z","shell.execute_reply.started":"2026-01-13T11:23:25.849668Z","shell.execute_reply":"2026-01-13T11:23:29.328315Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission.head()\nsubmission[\"score\"].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-13T11:23:29.330539Z","iopub.execute_input":"2026-01-13T11:23:29.330848Z","iopub.status.idle":"2026-01-13T11:23:29.380599Z","shell.execute_reply.started":"2026-01-13T11:23:29.330824Z","shell.execute_reply":"2026-01-13T11:23:29.379546Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"protein_map = defaultdict(dict)\n\nfor _, row in submission.iterrows():\n    protein_map[row[\"protein_id\"]][row[\"go_term\"]] = float(row[\"score\"])\n\nprint(len(protein_map))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-13T11:23:29.383394Z","iopub.execute_input":"2026-01-13T11:23:29.383913Z","iopub.status.idle":"2026-01-13T11:25:20.797234Z","shell.execute_reply.started":"2026-01-13T11:23:29.383883Z","shell.execute_reply":"2026-01-13T11:25:20.796052Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"rows = []\n\nfor protein_id, term_scores in protein_map.items():\n\n    final_scores = term_scores.copy()\n\n    for term, score in term_scores.items():\n        if term in ancestor_map:\n            for parent in ancestor_map[term]:\n                final_scores[parent] = max(\n                    final_scores.get(parent, 0.0),\n                    score\n                )\n\n    for root in roots:\n        final_scores[root] = 1.0\n\n    non_root_scores = [\n        s for t, s in final_scores.items() if t not in roots\n    ]\n\n    if len(non_root_scores) > 0:\n        max_score = max(non_root_scores)\n\n        if max_score < 0.95:\n            scale = 0.95 / max_score\n            for t in final_scores:\n                if t not in roots:\n                    final_scores[t] = min(1.0, final_scores[t] * scale)\n\n    for go_term, score in final_scores.items():\n        if score >= 0.001:\n            rows.append((protein_id, go_term, score))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-13T11:25:20.798640Z","iopub.execute_input":"2026-01-13T11:25:20.799014Z","iopub.status.idle":"2026-01-13T11:25:37.341104Z","shell.execute_reply.started":"2026-01-13T11:25:20.798976Z","shell.execute_reply":"2026-01-13T11:25:37.339992Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"final_df = pd.DataFrame(\n    rows,\n    columns=[\"protein_id\", \"go_term\", \"score\"]\n)\n\nfinal_df.sort_values(\n    [\"protein_id\", \"score\"],\n    ascending=[True, False],\n    inplace=True\n)\n\nfinal_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-13T11:25:37.342188Z","iopub.execute_input":"2026-01-13T11:25:37.342474Z","iopub.status.idle":"2026-01-13T11:25:42.129398Z","shell.execute_reply.started":"2026-01-13T11:25:37.342443Z","shell.execute_reply":"2026-01-13T11:25:42.128635Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"OUTPUT_PATH = \"submission.tsv\"\n\nfinal_df.to_csv(\n    OUTPUT_PATH,\n    sep=\"\\t\",\n    index=False,\n    header=False\n)\n\nprint(OUTPUT_PATH)\nprint(len(final_df))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-13T11:25:42.130592Z","iopub.execute_input":"2026-01-13T11:25:42.130956Z","iopub.status.idle":"2026-01-13T11:26:03.708118Z","shell.execute_reply.started":"2026-01-13T11:25:42.130919Z","shell.execute_reply":"2026-01-13T11:26:03.707233Z"}},"outputs":[],"execution_count":null}]}