{"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":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-11-24T17:22:45.379888Z","iopub.execute_input":"2025-11-24T17:22:45.380173Z","iopub.status.idle":"2025-11-24T17:22:47.297207Z","shell.execute_reply.started":"2025-11-24T17:22:45.380145Z","shell.execute_reply":"2025-11-24T17:22:47.296186Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Dependencies","metadata":{}},{"cell_type":"code","source":"!pip install -q biopython networkx goatools","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T18:15:54.057418Z","iopub.execute_input":"2025-11-24T18:15:54.057743Z","iopub.status.idle":"2025-11-24T18:16:32.496026Z","shell.execute_reply.started":"2025-11-24T18:15:54.05772Z","shell.execute_reply":"2025-11-24T18:16:32.494995Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"root_path = \"/kaggle/input/cafa-6-protein-function-prediction/\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T17:22:54.111623Z","iopub.execute_input":"2025-11-24T17:22:54.112038Z","iopub.status.idle":"2025-11-24T17:22:54.117334Z","shell.execute_reply.started":"2025-11-24T17:22:54.111999Z","shell.execute_reply":"2025-11-24T17:22:54.116436Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom pathlib import Path\nfrom collections import Counter, defaultdict\nfrom Bio import SeqIO\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom tqdm.auto import tqdm\n\npd.set_option('display.max_columns', None)\nsns.set_style('whitegrid')\n\nDATA_DIR = Path(root_path)\nTRAIN_DIR = DATA_DIR / \"Train\"\nTEST_DIR = DATA_DIR / \"Test\"\nMODELS_DIR = Path(\"models\")\nMODELS_DIR.mkdir(exist_ok=True)\n\nprint(\" Libraries imported successfully\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T17:22:54.118285Z","iopub.execute_input":"2025-11-24T17:22:54.118478Z","iopub.status.idle":"2025-11-24T17:22:55.157408Z","shell.execute_reply.started":"2025-11-24T17:22:54.118461Z","shell.execute_reply":"2025-11-24T17:22:55.156389Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# EDA","metadata":{}},{"cell_type":"code","source":"train_terms = pd.read_csv(TRAIN_DIR / \"train_terms.tsv\", sep=\"\\t\")\n\nprint(f\"Total annotations: {len(train_terms):,}\")\nprint(f\"Unique proteins: {train_terms['EntryID'].nunique():,}\")\nprint(f\"Unique GO terms: {train_terms['term'].nunique():,}\")\nprint(\"\\nFirst few rows:\")\ntrain_terms.head(10)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T17:24:58.036568Z","iopub.execute_input":"2025-11-24T17:24:58.037435Z","iopub.status.idle":"2025-11-24T17:24:58.520546Z","shell.execute_reply.started":"2025-11-24T17:24:58.0374Z","shell.execute_reply":"2025-11-24T17:24:58.519814Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Analyze ontology distribution\nprint(\"Ontology Distribution:\")\naspect_counts = train_terms['aspect'].value_counts()\nprint(aspect_counts)\nprint(\"\\nAspect meanings:\")\nprint(\"  F = Molecular Function\")\nprint(\"  P = Biological Process\")\nprint(\"  C = Cellular Component\")\n\n# Visualize\nplt.figure(figsize=(8, 5))\naspect_counts.plot(kind='bar', color=['#2ecc71', '#3498db', '#e74c3c'])\nplt.title('GO Term Distribution by Ontology')\nplt.xlabel('Ontology (F=Function, P=Process, C=Component)')\nplt.ylabel('Number of Annotations')\nplt.xticks(rotation=0)\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T17:57:59.906883Z","iopub.execute_input":"2025-11-24T17:57:59.911102Z","iopub.status.idle":"2025-11-24T17:58:00.372569Z","shell.execute_reply.started":"2025-11-24T17:57:59.91088Z","shell.execute_reply":"2025-11-24T17:58:00.371448Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(f\"Most common term: {term_freq.index[0]} ({term_freq.iloc[0]:,} occurrences)\")\nprint(f\"Median frequency: {term_freq.median():.0f}\")\nprint(f\"Terms appearing only once: {(term_freq == 1).sum():,}\")\nprint(\"\\nTop 15 most common GO terms:\")\nprint(term_freq.head(15))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T17:58:37.288451Z","iopub.execute_input":"2025-11-24T17:58:37.289234Z","iopub.status.idle":"2025-11-24T17:58:37.29657Z","shell.execute_reply.started":"2025-11-24T17:58:37.289196Z","shell.execute_reply":"2025-11-24T17:58:37.29544Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Visualize term frequency distribution\nfig, axes = plt.subplots(1, 2, figsize=(14, 5))\n\n# Log scale histogram\naxes[0].hist(term_freq.values, bins=50, color='steelblue', edgecolor='black')\naxes[0].set_yscale('log')\naxes[0].set_xlabel('Number of Occurrences')\naxes[0].set_ylabel('Number of GO Terms (log scale)')\naxes[0].set_title('GO Term Frequency Distribution')\naxes[0].grid(True, alpha=0.3)\n\n# Top 20 terms\nterm_freq.head(20).plot(kind='barh', ax=axes[1], color='coral')\naxes[1].set_xlabel('Number of Proteins')\naxes[1].set_title('Top 20 Most Common GO Terms')\naxes[1].invert_yaxis()\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T17:58:57.084826Z","iopub.execute_input":"2025-11-24T17:58:57.085228Z","iopub.status.idle":"2025-11-24T17:58:58.156254Z","shell.execute_reply.started":"2025-11-24T17:58:57.085199Z","shell.execute_reply":"2025-11-24T17:58:58.155181Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"terms_per_protein = train_terms.groupby('EntryID').size()\n\nprint(f\"Mean: {terms_per_protein.mean():.1f}\")\nprint(f\"Median: {terms_per_protein.median():.0f}\")\nprint(f\"Min: {terms_per_protein.min()}\")\nprint(f\"Max: {terms_per_protein.max()}\")\n\nplt.figure(figsize=(10, 5))\nplt.hist(terms_per_protein.values, bins=50, color='mediumseagreen', edgecolor='black')\nplt.xlabel('Number of GO Terms per Protein')\nplt.ylabel('Number of Proteins')\nplt.title('Distribution of GO Terms per Protein')\nplt.axvline(terms_per_protein.mean(), color='red', linestyle='--', label=f'Mean: {terms_per_protein.mean():.1f}')\nplt.legend()\nplt.grid(True, alpha=0.3)\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T18:04:47.795034Z","iopub.execute_input":"2025-11-24T18:04:47.795444Z","iopub.status.idle":"2025-11-24T18:04:48.301347Z","shell.execute_reply.started":"2025-11-24T18:04:47.795418Z","shell.execute_reply":"2025-11-24T18:04:48.30048Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sequence_stats = []\n\nfor record in tqdm(SeqIO.parse(TRAIN_DIR / \"train_sequences.fasta\", \"fasta\")):\n    header_parts = record.id.split('|')\n    protein_id = header_parts[1] if len(header_parts) > 1 else record.id\n    \n    sequence = str(record.seq)\n    sequence_stats.append({\n        'protein_id': protein_id,\n        'length': len(sequence),\n        'organism': header_parts[2] if len(header_parts) > 2 else 'unknown'\n    })\nseq_df = pd.DataFrame(sequence_stats)\nprint(f\"\\n✓ Successfully analyzed all {len(seq_df):,} protein sequences\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T18:08:54.589051Z","iopub.execute_input":"2025-11-24T18:08:54.589529Z","iopub.status.idle":"2025-11-24T18:08:55.77487Z","shell.execute_reply.started":"2025-11-24T18:08:54.5895Z","shell.execute_reply":"2025-11-24T18:08:55.774056Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Sequence Length Statistics:\")\nprint(f\"Mean: {seq_df['length'].mean():.0f} amino acids\")\nprint(f\"Median: {seq_df['length'].median():.0f} amino acids\")\nprint(f\"Min: {seq_df['length'].min()} amino acids\")\nprint(f\"Max: {seq_df['length'].max()} amino acids\")\n\nplt.figure(figsize=(10, 5))\nplt.hist(seq_df['length'], bins=50, color='mediumpurple', edgecolor='black')\nplt.xlabel('Sequence Length (amino acids)')\nplt.ylabel('Number of Proteins')\nplt.title('Protein Sequence Length Distribution')\nplt.axvline(seq_df['length'].mean(), color='red', linestyle='--', label=f'Mean: {seq_df[\"length\"].mean():.0f}')\nplt.legend()\nplt.grid(True, alpha=0.3)\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T18:09:06.34127Z","iopub.execute_input":"2025-11-24T18:09:06.341554Z","iopub.status.idle":"2025-11-24T18:09:06.720711Z","shell.execute_reply.started":"2025-11-24T18:09:06.341536Z","shell.execute_reply":"2025-11-24T18:09:06.719849Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"taxonomy = pd.read_csv(TRAIN_DIR / \"train_taxonomy.tsv\", sep=\"\\t\", names=['EntryID', 'TaxonID'])\n\nprint(f\"Unique species: {taxonomy['TaxonID'].nunique():,}\")\nprint(\"\\nTop 10 most common species (by TaxonID):\")\ntop_species = taxonomy['TaxonID'].value_counts().head(10)\nprint(top_species)\nprint(\"\\nNote: 9606 = Homo sapiens (Human)\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T18:11:04.760369Z","iopub.execute_input":"2025-11-24T18:11:04.76075Z","iopub.status.idle":"2025-11-24T18:11:04.827165Z","shell.execute_reply.started":"2025-11-24T18:11:04.76072Z","shell.execute_reply":"2025-11-24T18:11:04.826171Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ia_weights = pd.read_csv(DATA_DIR / \"IA.tsv\", sep=\"\\t\", names=['term', 'weight'])\nprint(f\"Total terms with weights: {len(ia_weights):,}\")\nprint(f\"\\nWeight statistics:\")\nprint(ia_weights['weight'].describe())\nprint(\"\\nTerms with highest weights (deepest in hierarchy):\")\nprint(ia_weights.nlargest(10, 'weight'))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T18:13:09.900164Z","iopub.execute_input":"2025-11-24T18:13:09.900768Z","iopub.status.idle":"2025-11-24T18:13:09.942875Z","shell.execute_reply.started":"2025-11-24T18:13:09.900738Z","shell.execute_reply":"2025-11-24T18:13:09.941796Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from goatools import obo_parser\ngo_dag = obo_parser.GODag(str(TRAIN_DIR / \"go-basic.obo\"))\n\nprint(f\"\\nLoaded {len(go_dag):,} GO terms\")\nprint(\"\\nRoot terms:\")\nprint(\"  GO:0003674 - Molecular Function (F)\")\nprint(\"  GO:0008150 - Biological Process (P)\")\nprint(\"  GO:0005575 - Cellular Component (C)\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T18:17:08.888101Z","iopub.execute_input":"2025-11-24T18:17:08.888474Z","iopub.status.idle":"2025-11-24T18:17:10.406209Z","shell.execute_reply.started":"2025-11-24T18:17:08.888437Z","shell.execute_reply":"2025-11-24T18:17:10.40512Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def propagate_predictions(predictions_dict, go_dag):\n    propagated = predictions_dict.copy()\n    for go_term, score in predictions_dict.items():\n        if go_term in go_dag:\n            parents = go_dag[go_term].get_all_parents()\n            for parent in parents:\n                propagated[parent] = max(propagated.get(parent, 0.0), score)\n    return propagated","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T18:17:24.310422Z","iopub.execute_input":"2025-11-24T18:17:24.310771Z","iopub.status.idle":"2025-11-24T18:17:24.335397Z","shell.execute_reply.started":"2025-11-24T18:17:24.310743Z","shell.execute_reply":"2025-11-24T18:17:24.334239Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def split_by_ontology(train_terms_df):\n    ontology_map = {\n        'F': 'molecular_function',\n        'P': 'biological_process',\n        'C': 'cellular_component'\n    }\n    splits = {}\n    for aspect, name in ontology_map.items():\n        splits[name] = train_terms_df[train_terms_df['aspect'] == aspect].copy()\n        print(f\"{name:25s}: {len(splits[name]):,} annotations, {splits[name]['EntryID'].nunique():,} proteins, {splits[name]['term'].nunique():,} unique terms\")\n    \n    return splits\n\nprint(\"Splitting training data by ontology:\")\nontology_splits = split_by_ontology(train_terms)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T18:19:05.141843Z","iopub.execute_input":"2025-11-24T18:19:05.142241Z","iopub.status.idle":"2025-11-24T18:19:05.421465Z","shell.execute_reply.started":"2025-11-24T18:19:05.142215Z","shell.execute_reply":"2025-11-24T18:19:05.420608Z"}},"outputs":[],"execution_count":null}]}