{"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":14875579,"sourceType":"competition"},{"sourceId":14187577,"sourceType":"datasetVersion","datasetId":9045748}],"dockerImageVersionId":31153,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install biopython","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-21T13:38:17.360396Z","iopub.execute_input":"2026-01-21T13:38:17.360752Z","iopub.status.idle":"2026-01-21T13:38:21.579918Z","shell.execute_reply.started":"2026-01-21T13:38:17.360725Z","shell.execute_reply":"2026-01-21T13:38:21.578843Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nfrom Bio import SeqIO, Align\nfrom Bio.Align import PairwiseAligner","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-21T13:38:21.581888Z","iopub.execute_input":"2026-01-21T13:38:21.582221Z","iopub.status.idle":"2026-01-21T13:38:21.588095Z","shell.execute_reply.started":"2026-01-21T13:38:21.582195Z","shell.execute_reply":"2026-01-21T13:38:21.586898Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Training Set","metadata":{}},{"cell_type":"code","source":"GO = pd.read_csv('/kaggle/input/protein-go-annotations/goa_uniprot_ver227.csv')\nGO.rename(columns={'protein_id' : 'Train_ID'}, inplace = True)\n\nGO_negative = GO[GO.qualifier.str.contains(\"NOT\")]\nGO_positive = GO[~GO.qualifier.str.contains(\"NOT\")]\nGO_positive.go_term.value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-21T13:38:21.589259Z","iopub.execute_input":"2026-01-21T13:38:21.589574Z","iopub.status.idle":"2026-01-21T13:38:25.074336Z","shell.execute_reply.started":"2026-01-21T13:38:21.589545Z","shell.execute_reply":"2026-01-21T13:38:25.073280Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"seqs = SeqIO.parse(\"/kaggle/input/cafa-6-protein-function-prediction/Train/train_sequences.fasta\", \"fasta\")\n\nentries = []\nfor entry in seqs:\n    EntryID = entry.id.split('|')[1] \n    entries.append({\n        \"Train_ID\": EntryID,\n        \"train_sequence\": str(entry.seq),\n        \"seq_len\": len(entry.seq)\n    })\n\nfasta_df = pd.DataFrame(entries)\n\ntrain_taxonomy = pd.read_csv(\"/kaggle/input/cafa-6-protein-function-prediction/Train/train_taxonomy.tsv\",sep=\"\\t\", names=[\"Train_ID\", \"OX\"]) \n\ntrain_df = pd.merge(train_taxonomy, fasta_df, on=\"Train_ID\")\ndisplay(train_df[:3])\ntrain_df.seq_len.describe()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-21T13:38:25.076648Z","iopub.execute_input":"2026-01-21T13:38:25.077030Z","iopub.status.idle":"2026-01-21T13:38:25.968117Z","shell.execute_reply.started":"2026-01-21T13:38:25.077002Z","shell.execute_reply":"2026-01-21T13:38:25.967036Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#removing duplicates in aa sequences\nclean_train_df = train_df.drop_duplicates(subset='train_sequence')\nprint(\"Clean Train Entries:\", clean_train_df.shape[0])\ntrain_df_duplicated = train_df[~train_df.index.isin(clean_train_df.index)]\nprint(\"Train Entries Duplicates:\", train_df_duplicated.shape[0])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-21T13:38:25.969059Z","iopub.execute_input":"2026-01-21T13:38:25.969488Z","iopub.status.idle":"2026-01-21T13:38:26.041314Z","shell.execute_reply.started":"2026-01-21T13:38:25.969451Z","shell.execute_reply":"2026-01-21T13:38:26.040148Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Test Set","metadata":{}},{"cell_type":"code","source":"test_seqs = SeqIO.parse(\"/kaggle/input/cafa-6-protein-function-prediction/Test/testsuperset.fasta\", \"fasta\")\n\nentries = []\n\nfor entry in test_seqs:\n    entries.append({\n        \"Test_ID\": entry.id,\n        \"OX\": entry.description.split(' ')[1] ,\n        \"test_sequence\": str(entry.seq),\n        \"seq_len\": len(entry.seq)\n        })\n\ntest_df = pd.DataFrame(entries)\nprint(\"Test Entries:\", test_df.shape[0])\ndisplay(test_df.head())\ntest_df.seq_len.describe()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-21T13:38:26.042523Z","iopub.execute_input":"2026-01-21T13:38:26.042886Z","iopub.status.idle":"2026-01-21T13:38:27.669637Z","shell.execute_reply.started":"2026-01-21T13:38:26.042847Z","shell.execute_reply":"2026-01-21T13:38:27.668502Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#removing duplicates in aa sequences\nclean_test_df = test_df.drop_duplicates(subset='test_sequence')\nprint(\"Clean Test Entries:\", clean_test_df.shape[0])\ntest_df_duplicated = test_df[test_df.duplicated(subset=['test_sequence'])]\nprint(\"Test Entries Duplicates:\", test_df_duplicated.shape[0])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-21T14:00:39.681228Z","iopub.execute_input":"2026-01-21T14:00:39.681565Z","iopub.status.idle":"2026-01-21T14:00:39.788440Z","shell.execute_reply.started":"2026-01-21T14:00:39.681541Z","shell.execute_reply":"2026-01-21T14:00:39.787133Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Homology","metadata":{}},{"cell_type":"markdown","source":"### Small sequenses/Motifs","metadata":{}},{"cell_type":"code","source":"small_test_df = clean_test_df[clean_test_df.seq_len <= 10000]\nmotif_df = clean_train_df[clean_train_df.seq_len <= 20]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-21T14:55:37.255694Z","iopub.execute_input":"2026-01-21T14:55:37.256099Z","iopub.status.idle":"2026-01-21T14:55:37.297791Z","shell.execute_reply.started":"2026-01-21T14:55:37.256073Z","shell.execute_reply":"2026-01-21T14:55:37.296390Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"aligner = PairwiseAligner(mismatch_score = -0.4, open_deletion_score = -1, open_insertion_score = -1, extend_insertion_score = -1, mode=\"local\")\nsmall_homology_results = []\n\nfor ref_seq in small_test_df.test_sequence:\n    results = []\n    for tr_seq in motif_df.train_sequence:\n        if len(ref_seq) >= len(tr_seq)/2:\n            target, query = sorted((ref_seq, tr_seq), key=len)\n            alignment = aligner.align(target, query)\n            al = next(iter(alignment), None)\n            if al is not None:            \n                counts = al.counts()\n                identities = counts.identities\n                length = len(target)\n                if identities > length/2 and al.length > 3:\n                    homology = ((identities - 1.1*counts.gaps - 0.4*counts.mismatches)/length)\n                    if homology >= 0.35: \n                        results.append({'test_sequence': ref_seq, \n                                        'train_sequence': tr_seq, \n                                        'len_test': len(ref_seq),\n                                        'homology degree': homology,\n                                       })\n    #print(tr_seq)    \n    best = sorted(results, key=lambda x: x['homology degree'], reverse=True)[:20]\n    small_homology_results = small_homology_results + best\n\nsmall_homology_results = pd.DataFrame(small_homology_results)\nprint(small_homology_results.len_test.max())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-21T15:06:54.579647Z","iopub.execute_input":"2026-01-21T15:06:54.579935Z","iopub.status.idle":"2026-01-21T15:06:59.444660Z","shell.execute_reply.started":"2026-01-21T15:06:54.579917Z","shell.execute_reply":"2026-01-21T15:06:59.443556Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Submission","metadata":{}},{"cell_type":"code","source":"merged_test = pd.merge(test_df, small_homology_results, on='test_sequence', how=\"left\")\nmerged = pd.merge(merged_test, train_df, on='train_sequence', how=\"left\")\nclean_merged = merged[['Test_ID', 'Train_ID', 'homology degree']]\n\nresults = pd.merge(clean_merged, GO_positive, on=\"Train_ID\", how=\"left\")\ngo_term_isnull = results.go_term.isnull()\nresults.loc[go_term_isnull, \"go_term\"] = 'GO:0005576'\nresults.loc[go_term_isnull, \"Probability\"] = 0.8\n\nresults['max_probability'] = results.groupby(['Test_ID', 'go_term'])['homology degree'].transform('max')\nresults['dublicate_count'] = results.groupby(['Test_ID', 'go_term'])['homology degree'].transform('count')\nresults['Probability'] = (results['max_probability'] + 0.1 + (results['dublicate_count'] - 1) * 0.05).clip(upper=1)\n\nresults_no_duplicates = results.drop_duplicates(subset=['Test_ID','go_term'])\n\nsubmission = results_no_duplicates[['Test_ID', 'go_term', 'Probability']]\ngo_term_isnull = submission.go_term.isnull()\n\nsubmission.shape[0]","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission.to_csv('submission.tsv', sep='\\t', header=None, index=False)\nprint(\"File created 🥳\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"-----------------------------","metadata":{}}]}