{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.12.12"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":116062,"databundleVersionId":14875579,"sourceType":"competition"},{"sourceId":14651422,"sourceType":"datasetVersion","datasetId":9359575}],"dockerImageVersionId":31234,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false},"papermill":{"default_parameters":{},"duration":34.967031,"end_time":"2026-01-29T11:42:27.180074","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2026-01-29T11:41:52.213043","version":"2.6.0"}},"nbformat_minor":4,"nbformat":4,"cells":[{"id":"bd157543-3799-4859-8970-02a8c4155f96","cell_type":"markdown","source":"## Local Submission Loader + Analysis","metadata":{}},{"id":"27bd3b10","cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport shutil\nimport warnings\nwarnings.filterwarnings('ignore')\n\nprint(\"✅ All libraries imported successfully\")","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.execute_input":"2026-01-29T11:41:55.841780Z","iopub.status.busy":"2026-01-29T11:41:55.841334Z","iopub.status.idle":"2026-01-29T11:41:59.756916Z","shell.execute_reply":"2026-01-29T11:41:59.755681Z"},"papermill":{"duration":3.921737,"end_time":"2026-01-29T11:41:59.759113","exception":false,"start_time":"2026-01-29T11:41:55.837376","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"0d2dcffa","cell_type":"code","source":"# File paths\nINPUT_FILE = '/kaggle/input/cafa-submission/submission.tsv'\nOUTPUT_FILE = 'submission.tsv'\n\nprint(\"=\"*60)\nprint(\"CAFA-6 SUBMISSION PROCESSING\")\nprint(\"=\"*60)\n\nprint(\"\\n[1/3] Copying submission file...\")\nshutil.copy(INPUT_FILE, OUTPUT_FILE)\nprint(\"✅ Full submission copied to output directory\")\nprint(f\"   Output file: {OUTPUT_FILE}\")","metadata":{"execution":{"iopub.execute_input":"2026-01-29T11:41:59.764972Z","iopub.status.busy":"2026-01-29T11:41:59.764498Z","iopub.status.idle":"2026-01-29T11:42:17.631618Z","shell.execute_reply":"2026-01-29T11:42:17.630516Z"},"papermill":{"duration":17.872328,"end_time":"2026-01-29T11:42:17.633715","exception":false,"start_time":"2026-01-29T11:41:59.761387","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"9eb3394c","cell_type":"code","source":"print(\"\\n[2/3] Loading sample data for visualization...\")\n\n# Parameters\nSAMPLE_SIZE = 1_000_000  # 1 million rows\nCHUNK_SIZE = 500_000\nMAX_ROWS_TO_READ = 5_000_000  # Read max 5M rows\n\n# Read in chunks\nchunks = []\ntotal_rows = 0\n\nfor chunk in pd.read_csv(\n    INPUT_FILE, \n    sep='\\t', \n    header=None, \n    names=['protein_id', 'go_term', 'score'],\n    dtype={'protein_id': str, 'go_term': str, 'score': np.float32},\n    chunksize=CHUNK_SIZE, \n    nrows=MAX_ROWS_TO_READ\n):\n    chunks.append(chunk)\n    total_rows += len(chunk)\n    if total_rows >= SAMPLE_SIZE:\n        break\n\n# Combine and sample\nsample_df = pd.concat(chunks, ignore_index=True)\nif len(sample_df) > SAMPLE_SIZE:\n    sample_df = sample_df.sample(SAMPLE_SIZE, random_state=42)\n\ndel chunks  # Free memory\n\nprint(f\"✅ Loaded {len(sample_df):,} rows for analysis\")\nprint(f\"   Unique proteins: {sample_df['protein_id'].nunique():,}\")\nprint(f\"   Unique GO terms: {sample_df['go_term'].nunique():,}\")\nprint(f\"\\nSample preview:\")\nprint(sample_df.head())","metadata":{"execution":{"iopub.execute_input":"2026-01-29T11:42:17.639938Z","iopub.status.busy":"2026-01-29T11:42:17.639562Z","iopub.status.idle":"2026-01-29T11:42:18.424055Z","shell.execute_reply":"2026-01-29T11:42:18.422942Z"},"papermill":{"duration":0.790111,"end_time":"2026-01-29T11:42:18.426159","exception":false,"start_time":"2026-01-29T11:42:17.636048","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"fed5da93","cell_type":"code","source":"print(\"\\n[3/3] Generating visualizations...\")\n\n# Set style\nplt.style.use('default')\nsns.set_palette(\"husl\")\n\n# Create figure\nfig = plt.figure(figsize=(16, 12))\ngs = fig.add_gridspec(3, 3, hspace=0.3, wspace=0.3)\n\n# 1. Score Distribution - Histogram\nax1 = fig.add_subplot(gs[0, 0])\nax1.hist(sample_df['score'], bins=60, color='steelblue', edgecolor='black', alpha=0.8)\nax1.set_xlabel('Prediction Score', fontsize=10)\nax1.set_ylabel('Frequency', fontsize=10)\nax1.set_title('Score Distribution', fontsize=12, fontweight='bold')\nmean_score = sample_df['score'].mean()\nmedian_score = sample_df['score'].median()\nax1.axvline(mean_score, color='red', linestyle='--', linewidth=2, label=f'Mean: {mean_score:.4f}')\nax1.axvline(median_score, color='orange', linestyle='--', linewidth=2, label=f'Median: {median_score:.4f}')\nax1.legend(fontsize=9)\nax1.grid(alpha=0.3)\n\n# 2. Score Distribution - Log Scale\nax2 = fig.add_subplot(gs[0, 1])\nax2.hist(sample_df['score'], bins=60, color='coral', edgecolor='black', alpha=0.8)\nax2.set_xlabel('Prediction Score', fontsize=10)\nax2.set_ylabel('Frequency (log scale)', fontsize=10)\nax2.set_title('Score Distribution (Log Scale)', fontsize=12, fontweight='bold')\nax2.set_yscale('log')\nax2.grid(alpha=0.3)\n\n# 3. Score Box Plot\nax3 = fig.add_subplot(gs[0, 2])\nbp = ax3.boxplot(sample_df['score'], vert=True, patch_artist=True)\nbp['boxes'][0].set_facecolor('lightgreen')\nbp['boxes'][0].set_alpha(0.8)\nax3.set_ylabel('Score', fontsize=10)\nax3.set_title('Score Box Plot', fontsize=12, fontweight='bold')\nax3.grid(alpha=0.3, axis='y')\n\n# 4. Predictions per Protein\nax4 = fig.add_subplot(gs[1, 0])\npreds_per_protein = sample_df.groupby('protein_id').size()\nax4.hist(preds_per_protein, bins=40, color='mediumseagreen', edgecolor='black', alpha=0.8)\nax4.set_xlabel('GO Terms per Protein', fontsize=10)\nax4.set_ylabel('Number of Proteins', fontsize=10)\nax4.set_title('Predictions per Protein', fontsize=12, fontweight='bold')\nmean_preds = preds_per_protein.mean()\nax4.axvline(mean_preds, color='red', linestyle='--', linewidth=2, label=f'Mean: {mean_preds:.1f}')\nax4.legend(fontsize=9)\nax4.grid(alpha=0.3)\n\n# 5. Top 25 Most Frequent GO Terms\nax5 = fig.add_subplot(gs[1, 1:])\ntop_go_terms = sample_df['go_term'].value_counts().head(25)\nbars = ax5.barh(range(len(top_go_terms)), top_go_terms.values, color='mediumpurple', alpha=0.8)\nax5.set_yticks(range(len(top_go_terms)))\nax5.set_yticklabels(top_go_terms.index, fontsize=8)\nax5.set_xlabel('Frequency', fontsize=10)\nax5.set_title('Top 25 Most Predicted GO Terms', fontsize=12, fontweight='bold')\nax5.invert_yaxis()\nax5.grid(alpha=0.3, axis='x')\nfor i, (bar, value) in enumerate(zip(bars, top_go_terms.values)):\n    ax5.text(value, i, f' {value:,}', va='center', fontsize=7)\n\n# 6. Score Range Breakdown (Pie Chart)\nax6 = fig.add_subplot(gs[2, 0])\nscore_ranges = [\n    ('< 0.01', (sample_df['score'] < 0.01).sum()),\n    ('0.01-0.1', ((sample_df['score'] >= 0.01) & (sample_df['score'] < 0.1)).sum()),\n    ('0.1-0.5', ((sample_df['score'] >= 0.1) & (sample_df['score'] < 0.5)).sum()),\n    ('0.5-1.0', ((sample_df['score'] >= 0.5) & (sample_df['score'] < 1.0)).sum()),\n    ('>= 1.0', (sample_df['score'] >= 1.0).sum())\n]\nlabels, values = zip(*score_ranges)\ncolors = ['#ff9999', '#ffcc99', '#ffff99', '#99ff99', '#99ccff']\nwedges, texts, autotexts = ax6.pie(values, labels=labels, autopct='%1.1f%%', \n                                     colors=colors, startangle=90)\nax6.set_title('Score Range Distribution', fontsize=12, fontweight='bold')\nfor autotext in autotexts:\n    autotext.set_color('black')\n    autotext.set_fontsize(9)\n    autotext.set_fontweight('bold')\n\n# 7. Cumulative Score Distribution\nax7 = fig.add_subplot(gs[2, 1])\nsorted_scores = np.sort(sample_df['score'])\ncumulative = np.arange(1, len(sorted_scores) + 1) / len(sorted_scores) * 100\nax7.plot(sorted_scores, cumulative, color='darkblue', linewidth=2)\nax7.set_xlabel('Score', fontsize=10)\nax7.set_ylabel('Cumulative %', fontsize=10)\nax7.set_title('Cumulative Distribution', fontsize=12, fontweight='bold')\nax7.grid(alpha=0.3)\nax7.axhline(50, color='red', linestyle='--', alpha=0.5, label='50%')\nax7.axhline(90, color='orange', linestyle='--', alpha=0.5, label='90%')\nax7.legend(fontsize=8)\n\n# 8. Top 15 Proteins by Prediction Count\nax8 = fig.add_subplot(gs[2, 2])\ntop_proteins = sample_df['protein_id'].value_counts().head(15)\nax8.barh(range(len(top_proteins)), top_proteins.values, color='teal', alpha=0.8)\nax8.set_yticks(range(len(top_proteins)))\nax8.set_yticklabels([p[:12] + '...' if len(p) > 12 else p for p in top_proteins.index], fontsize=7)\nax8.set_xlabel('Predictions', fontsize=10)\nax8.set_title('Top 15 Proteins', fontsize=12, fontweight='bold')\nax8.invert_yaxis()\nax8.grid(alpha=0.3, axis='x')\n\n# Main title\nplt.suptitle('CAFA-6 Submission Analysis Dashboard', fontsize=16, fontweight='bold', y=0.995)\n\n# Save\nplt.savefig('submission_analysis.png', dpi=200, bbox_inches='tight')\nprint(\"✅ Visualization saved as 'submission_analysis.png'\")\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.execute_input":"2026-01-29T11:42:18.432425Z","iopub.status.busy":"2026-01-29T11:42:18.432118Z","iopub.status.idle":"2026-01-29T11:42:26.448502Z","shell.execute_reply":"2026-01-29T11:42:26.447424Z"},"papermill":{"duration":8.024879,"end_time":"2026-01-29T11:42:26.453191","exception":false,"start_time":"2026-01-29T11:42:18.428312","status":"completed"},"tags":[]},"outputs":[],"execution_count":null}]}