{"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"}],"dockerImageVersionId":31239,"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-12-26T13:28:39.94363Z","iopub.execute_input":"2025-12-26T13:28:39.943862Z","iopub.status.idle":"2025-12-26T13:28:42.322709Z","shell.execute_reply.started":"2025-12-26T13:28:39.943841Z","shell.execute_reply":"2025-12-26T13:28:42.321719Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install biopython obonet\n\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.multioutput import MultiOutputClassifier\nfrom sklearn.ensemble import RandomForestClassifier\nfrom sklearn.metrics import f1_score, precision_recall_fscore_support\nimport ast  # For safe eval if needed\nfrom Bio import SeqIO  # For FASTA parsing\nimport networkx as nx  # For GO graph\nimport obonet  # For OBO parsing\n\n# Step 1: Load the data\ntrain_terms_path = '/kaggle/input/cafa-6-protein-function-prediction/Train/train_terms.tsv'\ntrain_seq_path = '/kaggle/input/cafa-6-protein-function-prediction/Train/train_sequences.fasta'\ntrain_tax_path = '/kaggle/input/cafa-6-protein-function-prediction/Train/train_taxonomy.tsv'\ngo_obo_path = '/kaggle/input/cafa-6-protein-function-prediction/Train/go-basic.obo'\ntest_seq_path = '/kaggle/input/cafa-6-protein-function-prediction/Test/testsuperset.fasta'\nia_path = '/kaggle/input/cafa-6-protein-function-prediction/IA.tsv'\nsample_sub_path = '/kaggle/input/cafa-6-protein-function-prediction/sample_submission.tsv'\n\n# Load training terms\ntrain_terms = pd.read_csv(train_terms_path, sep='\\t', header=None, names=['EntryID', 'term', 'aspect'])\nprint(f\"Loaded {len(train_terms)} training annotations.\")\n\n# Load training taxonomy\ntrain_tax = pd.read_csv(train_tax_path, sep='\\t', header=None, names=['EntryID', 'taxon'])\nprint(f\"Loaded {len(train_tax)} training proteins with taxonomy.\")\n\n# Load IA weights\nia_df = pd.read_csv(ia_path, sep='\\t', header=None, names=['GO_term', 'ia_weight'])\nia_dict = dict(zip(ia_df['GO_term'], ia_df['ia_weight']))\nprint(f\"Loaded IA weights for {len(ia_dict)} GO terms.\")\n\n# Parse GO ontology\ngo_graph = obonet.read_obo(go_obo_path)\ngo_dag = nx.DiGraph(go_graph)  # Convert to directed graph for hierarchy\nprint(f\"Loaded GO graph with {len(go_graph)} terms.\")\n\n# Step 2: Process protein sequences\n\ndef extract_simple_features(seq):\n    \"\"\"Simple feature extractor: amino acid composition + length.\"\"\"\n    length = len(seq)\n    aa_comp = np.array([seq.count(aa) / length for aa in 'ACDEFGHIKLMNPQRSTVWY'])\n    return np.concatenate([[length], aa_comp])\n\n# Load training sequences\ntrain_sequences = {}\nfor record in SeqIO.parse(train_seq_path, \"fasta\"):\n    uniprot_id = str(record.id).split('|')[1]  # Extract UniProt ID\n    train_sequences[uniprot_id] = str(record.seq)\n\nprint(f\"Loaded {len(train_sequences)} training sequences.\")\n\n# Create feature matrix for training\ntrain_proteins = list(train_sequences.keys())\nX_train = np.array([extract_simple_features(train_sequences[prot]) for prot in train_proteins])\nprint(f\"Feature matrix shape: {X_train.shape}\")\n\n# Step 3: Prepare labels\nterm_freq = train_terms['term'].value_counts()\ntop_terms = term_freq.head(100).index.tolist()  # Limit to top 100 terms\nprint(f\"Using top {len(top_terms)} GO terms.\")\n\n# Create label matrix\ny_train = np.zeros((len(train_proteins), len(top_terms)))\nprotein_to_idx = {prot: i for i, prot in enumerate(train_proteins)}\nfor _, row in train_terms.iterrows():\n    if row['term'] in top_terms and row['EntryID'] in protein_to_idx:\n        term_idx = top_terms.index(row['term'])\n        prot_idx = protein_to_idx[row['EntryID']]\n        y_train[prot_idx, term_idx] = 1\n\nprint(f\"Label matrix shape: {y_train.shape}\")\n\n# Step 4: Train a simple multi-label classifier\nX_tr, X_val, y_tr, y_val = train_test_split(X_train, y_train, test_size=0.2, random_state=42)\n\nclf = MultiOutputClassifier(RandomForestClassifier(n_estimators=100, random_state=42))\nclf.fit(X_tr, y_tr)\n\n# Validate (simple F1)\ny_pred_val = clf.predict(X_val)\nf1 = f1_score(y_val, y_pred_val, average='weighted')\nprint(f\"Validation weighted F1: {f1:.4f}\")\n\n\n# Step 5: Load test sequences\ntest_sequences = {}\nfor record in SeqIO.parse(test_seq_path, \"fasta\"):\n    uniprot_id = str(record.id).split('|')[1]  # Extract UniProt ID\n    test_sequences[uniprot_id] = str(record.seq)\n\nprint(f\"Loaded {len(test_sequences)} test sequences.\")\n\n# Extract features for test\ntest_proteins = list(test_sequences.keys())\nX_test = np.array([extract_simple_features(test_sequences[prot]) for prot in test_proteins])\n\n# Predict probabilities\ny_pred_test = clf.predict_proba(X_test)\n# For submission, use max probability per class\nprobs = np.array([pred[:, 1] for pred in y_pred_test]).T  # Shape: (n_test, n_terms)\n\n# Step 6: Generate submission\nsubmission_lines = []\nfor i, prot in enumerate(test_proteins):\n    for j, term in enumerate(top_terms):\n        if probs[i, j] > 0.01:  # Threshold to limit predictions\n            submission_lines.append(f\"{prot}\\t{term}\\t{probs[i, j]:.3f}\")\n\n\n# Write to file\nwith open('submission.tsv', 'w') as f:\n    for line in submission_lines:\n        f.write(line + '\\n')\n\nprint(f\"Generated {len(submission_lines)} prediction lines.\")\nprint(\"Submission file 'submission.tsv' ready for upload.\")\n\n# Optional: Plot term frequencies\nplt.figure(figsize=(10, 6))\nsns.barplot(x=term_freq.head(20).values, y=term_freq.head(20).index)\nplt.title(\"Top 20 Most Frequent GO Terms\")\nplt.xlabel(\"Frequency\")\nplt.show()\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-26T13:30:46.394626Z","iopub.execute_input":"2025-12-26T13:30:46.395026Z"}},"outputs":[],"execution_count":null}]}