{"metadata":{"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":41875,"databundleVersionId":5521661,"sourceType":"competition"},{"sourceId":5499219,"sourceType":"datasetVersion","datasetId":3167603},{"sourceId":7176893,"sourceType":"datasetVersion","datasetId":4147529}],"dockerImageVersionId":30615,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true},"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"![Cover](https://github.com/AniMilina/CAFA-5-Protein-Function-Prediction/raw/main/CAFA%205%20Protein%20Function%20Prediction.jpg)\n","metadata":{}},{"cell_type":"markdown","source":"**From the author:** Hello everyone! My name is Milina, medicine and everything connected with it is my favorite topic of research. I’ll be honest, I didn’t see the result of the model that would suit me. But it was important for me to see that the model was stable, and that the model’s settings could be adjusted to a good result over time.\n\nI created a couple of additional features that expanded the range of research. Proteins in organisms is a very, very broad topic that requires maximum immersion. But I will be glad if my work is useful in your research and discoveries.\n\nI want to say a big thank you to: https://www.kaggle.com/gusthema https://www.kaggle.com/elliot2robot and https://www.kaggle.com/sergeifironov Without you, the submission file would have completely tortured me\n\nI wish you all good luck and new discoveries!","metadata":{}},{"cell_type":"markdown","source":"## Project description","metadata":{}},{"cell_type":"markdown","source":"`Purpose of the competition:`  \n\n>The goal of this competition is to create a model to predict the functions of a set of proteins. The model will be trained on amino acid sequences of proteins and other available data  \nThe work aims to help researchers better understand the functions of proteins, which is important for uncovering how cells, tissues and organs work. It could also help develop new drugs and therapies for various diseases  \n\n`Context:`  \n\n>Proteins play an important role in a variety of activities in tissues, organs and the body as a whole, and also influence the structure and function of cells  \nThey are large molecules consisting of 20 types of amino acids. There are tens of thousands of different proteins in the human body, and each protein consists of tens or hundreds of amino acids linked in series  \nThis amino acid sequence determines the 3D structure and conformational dynamics of the protein, which in turn determines its biological function. Due to genome sequencing projects, we have enormous amounts of genetic sequence data from thousands of species, which provides information about the amino acid sequence of the proteins that are encoded by these genes  \nPrecise assignment of biological function to a protein is key to understanding life at the molecular level. However, the task of assigning a function to a specific protein is complicated by the multiple functions of many proteins, as well as their ability to interact with multiple partners  \nMore knowledge about the functions assigned to proteins could lead to the development of treatments for diseases and improvements in human and animal health in areas such as medicine and agriculture  ","metadata":{}},{"cell_type":"markdown","source":"`Data files:`  \n\n**go-basic.obo:** GO ontology in OBO format  \n**train_sequences.fasta:** Protein sequences for the training dataset  \n**train_terms.tsv:** GO annotations for proteins from the training set  \n**train_taxonomy.tsv:** Taxa for proteins from the training set  \n**IA.txt:** Weights for each term used to calculate weighted precision and recall  \n**testsuperset.fasta:** Protein sequences for predictions  \n**testsuperset-taxon-list.tsv:** Taxa for proteins in the test superset  ","metadata":{}},{"cell_type":"markdown","source":"## Installing and importing libraries","metadata":{}},{"cell_type":"code","source":"!pip install obonet pandas\n# # !pip install biopython","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:56:52.773898Z","iopub.execute_input":"2023-12-12T07:56:52.774268Z","iopub.status.idle":"2023-12-12T07:57:05.447492Z","shell.execute_reply.started":"2023-12-12T07:56:52.774235Z","shell.execute_reply":"2023-12-12T07:57:05.446350Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import obonet\nimport pandas as pd\n\nimport warnings\nimport time\n\nfrom Bio import SeqIO\nfrom Bio.SeqUtils import ProtParam\n\nimport networkx as nx\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import MultiLabelBinarizer\nfrom sklearn.feature_extraction.text import TfidfVectorizer\nfrom sklearn.multiclass import OneVsRestClassifier\nfrom sklearn.svm import SVC\nfrom sklearn.pipeline import make_pipeline\nfrom sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score,classification_report\n\nimport tensorflow as tf\nfrom keras import backend as K\nfrom tensorflow.keras.preprocessing.text import Tokenizer\nfrom tensorflow.keras.preprocessing.sequence import pad_sequences\nfrom tensorflow.keras.models import Sequential\nfrom keras.utils import Sequence\nfrom keras.layers import Input, Embedding, LSTM, Dense, concatenate,Dropout\nfrom keras.models import Model,load_model","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:05.449498Z","iopub.execute_input":"2023-12-12T07:57:05.449812Z","iopub.status.idle":"2023-12-12T07:57:18.401101Z","shell.execute_reply.started":"2023-12-12T07:57:05.449784Z","shell.execute_reply":"2023-12-12T07:57:18.400303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Settings","metadata":{}},{"cell_type":"code","source":"# Disable warnings\n\nwarnings.filterwarnings('ignore')","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:18.402213Z","iopub.execute_input":"2023-12-12T07:57:18.402824Z","iopub.status.idle":"2023-12-12T07:57:18.406894Z","shell.execute_reply.started":"2023-12-12T07:57:18.402797Z","shell.execute_reply":"2023-12-12T07:57:18.406036Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class f:    \n    BOLD = \"\\033[1m\"     # Bold text\n    ITALIC = \"\\033[3m\"   # Italic text\n    END = \"\\033[0m\"      # Reset style","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:18.408827Z","iopub.execute_input":"2023-12-12T07:57:18.409138Z","iopub.status.idle":"2023-12-12T07:57:18.440875Z","shell.execute_reply.started":"2023-12-12T07:57:18.409105Z","shell.execute_reply":"2023-12-12T07:57:18.439920Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Functions","metadata":{}},{"cell_type":"code","source":"def explore_data(dataframes):\n    for name, df in dataframes.items():\n        print(f\"\\n{name} Data:\")\n        print(f\"Shape:\\n{df.shape}\")\n        print(f\"\\nInfo:\")\n        df.info()\n        print(f\"\\nDuplicates:\")\n        duplicates = df[df.duplicated()]\n        print(duplicates)\n        print(f\"\\nMissing Values:\")\n        missing_values = df.isnull().sum()\n        print(missing_values[missing_values > 0])","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:18.441801Z","iopub.execute_input":"2023-12-12T07:57:18.442087Z","iopub.status.idle":"2023-12-12T07:57:18.450849Z","shell.execute_reply.started":"2023-12-12T07:57:18.442063Z","shell.execute_reply":"2023-12-12T07:57:18.449909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def visualize_distribution(data, x, title, xlabel, ylabel, facecolor='lightgray', gridcolor='gray', colors=None, rotation=0):\n    \"\"\"\n    Visualization of data distribution.\n\n    Options:\n    - data: DataFrame, data for visualization.\n    - x: str, column name for the X axis.\n    - title: str, title of the graph.\n    - xlabel: str, X-axis label.\n    - ylabel: str, Y-axis label.\n    - facecolor: str, background color of the chart.\n    - gridcolor: str, color of the chart grid.\n    - colors: list, additional colors for the chart.\n    - rotation: int, the angle of rotation of the labels.\n\n    Returns:\n    None\n    \"\"\"\n    plt.figure(figsize=(10, 6))\n    sns.set_palette(colors) if colors else None\n    sns.countplot(x=x, data=data)\n    sns.set(style=\"whitegrid\")\n    plt.title(title)\n    plt.xlabel(xlabel)\n    plt.ylabel(ylabel)\n    ax = plt.gca()\n    ax.set_facecolor(facecolor)\n    ax.grid(color=gridcolor)\n    plt.xticks(rotation=rotation)\n\n    plt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:18.451788Z","iopub.execute_input":"2023-12-12T07:57:18.452076Z","iopub.status.idle":"2023-12-12T07:57:18.461317Z","shell.execute_reply.started":"2023-12-12T07:57:18.452050Z","shell.execute_reply":"2023-12-12T07:57:18.460516Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Read data","metadata":{}},{"cell_type":"code","source":"obo_path = '/kaggle/input/cafa-5-protein-function-prediction/Train/go-basic.obo'\ngraph = obonet.read_obo(obo_path)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:18.462287Z","iopub.execute_input":"2023-12-12T07:57:18.462602Z","iopub.status.idle":"2023-12-12T07:57:35.516306Z","shell.execute_reply.started":"2023-12-12T07:57:18.462570Z","shell.execute_reply":"2023-12-12T07:57:35.515476Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# graph","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-12-12T07:57:35.517437Z","iopub.execute_input":"2023-12-12T07:57:35.517774Z","iopub.status.idle":"2023-12-12T07:57:35.522215Z","shell.execute_reply.started":"2023-12-12T07:57:35.517743Z","shell.execute_reply":"2023-12-12T07:57:35.521068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fasta_path = \"/kaggle/input/cafa-5-protein-function-prediction/Train/train_sequences.fasta\"\nterms_path = \"/kaggle/input/cafa-5-protein-function-prediction/Train/train_terms.tsv\"\ntaxonomy_path = \"/kaggle/input/cafa-5-protein-function-prediction/Train/train_taxonomy.tsv\"\nia_path = \"/kaggle/input/cafa-5-protein-function-prediction/IA.txt\"","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:35.523314Z","iopub.execute_input":"2023-12-12T07:57:35.523609Z","iopub.status.idle":"2023-12-12T07:57:35.533365Z","shell.execute_reply.started":"2023-12-12T07:57:35.523585Z","shell.execute_reply":"2023-12-12T07:57:35.532533Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fasta_data = pd.DataFrame([(record.id, str(record.seq)) for record in SeqIO.parse(fasta_path, \"fasta\")], columns=['Protein_ID', 'Sequence'])\nterms_data = pd.read_csv(terms_path, sep='\\t', header=None, names=['Protein_ID', 'GO_Term_ID', 'Ontology'])\ntaxonomy_data = pd.read_csv(taxonomy_path, sep='\\t', header=None, names=['Protein_ID', 'Taxon_ID'])\nia_data = pd.read_csv(ia_path, sep='\\t', header=None, names=['GO_Term_ID', 'Weight'])","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:35.536697Z","iopub.execute_input":"2023-12-12T07:57:35.536969Z","iopub.status.idle":"2023-12-12T07:57:42.077280Z","shell.execute_reply.started":"2023-12-12T07:57:35.536946Z","shell.execute_reply":"2023-12-12T07:57:42.076299Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Fasta Data:\")\ndisplay(fasta_data.head())\n\nprint(\"\\nTerms Data:\")\ndisplay(terms_data.head())\n\nprint(\"\\nTaxonomy Data:\")\ndisplay(taxonomy_data.head())\n\nprint(\"\\nIA Data:\")\ndisplay(ia_data.head())","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:42.078562Z","iopub.execute_input":"2023-12-12T07:57:42.078915Z","iopub.status.idle":"2023-12-12T07:57:42.115184Z","shell.execute_reply.started":"2023-12-12T07:57:42.078884Z","shell.execute_reply":"2023-12-12T07:57:42.114306Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Let's check the received data","metadata":{}},{"cell_type":"code","source":"dataframes = {\n    'Fasta': fasta_data,\n    'Terms': terms_data,\n    'Taxonomy': taxonomy_data,\n    'IA': ia_data\n}","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:42.116298Z","iopub.execute_input":"2023-12-12T07:57:42.116555Z","iopub.status.idle":"2023-12-12T07:57:42.120924Z","shell.execute_reply.started":"2023-12-12T07:57:42.116533Z","shell.execute_reply":"2023-12-12T07:57:42.120059Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"explore_data(dataframes)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:42.122137Z","iopub.execute_input":"2023-12-12T07:57:42.122427Z","iopub.status.idle":"2023-12-12T07:57:46.288399Z","shell.execute_reply.started":"2023-12-12T07:57:42.122404Z","shell.execute_reply":"2023-12-12T07:57:46.287408Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"`Fast Data:`   \n\n>Data form: (142246, 2) - 142246 rows and 2 columns  \nData types: Protein_ID and Sequence are represented by string data  \nNo duplicates  \nNo missing values  \n\n**Conclusions: The Fasta dataset contains protein sequences for 142,246 unique protein IDs with no duplicates or missing values**  \n\n`Terms Data:`  \n\n>Data form: (5363864, 3) - 5363864 rows and 3 columns  \nData types: Protein_ID, GO_Term_ID and Ontology are represented by string data  \nNo duplicates  \nNo missing values  \n\n**Conclusions: The Terms dataset contains GO annotations for proteins covering more than 5 million records. No duplicates or missing values**  \n\n`Taxonomy Data:`  \n\n>Data form: (142247, 2) - 142247 rows and 2 columns  \nData types: Protein_ID and Taxon_ID are represented by string data  \nNo duplicates  \nNo missing values  \n\n**Conclusions: The Taxonomy dataset contains taxonomy information for 142,247 unique protein identifiers with no duplicates or missing values**  \n\n`IA Data:`  \n\n>Data form: (43248, 2) - 43248 rows and 2 columns  \nData types: GO_Term_ID is represented by string data, and Weight is represented by numeric data  \nNo duplicates  \nNo missing values  \n\n**Conclusions: The IA dataset contains information about information richness (weights) for GO terms**  \n \n#### General conclusions:  \n\nAll datasets do not contain duplicates or missing values  \nThe Terms dataset is large and contains GO annotations for proteins, and Fasta contains the corresponding sequences  \nIA contains weights for GO terms and Taxonomy provides protein taxonomy information  ","metadata":{}},{"cell_type":"markdown","source":"## Data processing","metadata":{}},{"cell_type":"code","source":"# Transform protein sequences\n\nfasta_data['Sequence'] = fasta_data['Sequence'].str.replace('\\n', '')","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:46.289902Z","iopub.execute_input":"2023-12-12T07:57:46.290368Z","iopub.status.idle":"2023-12-12T07:57:46.435832Z","shell.execute_reply.started":"2023-12-12T07:57:46.290320Z","shell.execute_reply":"2023-12-12T07:57:46.435077Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"merged_data = pd.merge(terms_data, taxonomy_data, on='Protein_ID')","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:46.436911Z","iopub.execute_input":"2023-12-12T07:57:46.437209Z","iopub.status.idle":"2023-12-12T07:57:48.074749Z","shell.execute_reply.started":"2023-12-12T07:57:46.437185Z","shell.execute_reply":"2023-12-12T07:57:48.073876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"merged_data = pd.merge(merged_data, fasta_data[['Protein_ID', 'Sequence']], on='Protein_ID')","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:48.075798Z","iopub.execute_input":"2023-12-12T07:57:48.076097Z","iopub.status.idle":"2023-12-12T07:57:50.625724Z","shell.execute_reply.started":"2023-12-12T07:57:48.076072Z","shell.execute_reply":"2023-12-12T07:57:50.624929Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Let's look at the weights from IA.txt\n\nmerged_data = pd.merge(merged_data, ia_data, on='GO_Term_ID')","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:50.626890Z","iopub.execute_input":"2023-12-12T07:57:50.627244Z","iopub.status.idle":"2023-12-12T07:57:55.566499Z","shell.execute_reply.started":"2023-12-12T07:57:50.627211Z","shell.execute_reply":"2023-12-12T07:57:55.565507Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"merged_data","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:55.567674Z","iopub.execute_input":"2023-12-12T07:57:55.567953Z","iopub.status.idle":"2023-12-12T07:57:55.583195Z","shell.execute_reply.started":"2023-12-12T07:57:55.567929Z","shell.execute_reply":"2023-12-12T07:57:55.582355Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### We received a new, ready-to-use dataset. What can you say about it:  \n\n`Dataset size:` The dataset contains 6 columns and 5363863 rows  \n\n`Data types:` Basically, all columns contain string (object) and numeric (float64) values  \n\n`No duplicates:` According to the data presented, there are no duplicates, since the \"Duplicates\" column in the explore_data output was empty  \n\n`No missing values:` All columns have no missing values, making data analysis easier  \n\n`Weight Values:` Based on the \"Weight\" column, weights are associated with each unique GO term. Weights can be important for assessing model quality, especially when using weighted metrics  \n\n`Distribution of GO terms:` The dataset includes terms from different ontologies (Biological Process, Molecular Function), which allows you to take into account various aspects of gene function  \n\n`Taxon:` Taxon information (Taxon_ID) is present, which can be useful when training a model taking into account taxonomic information  ","metadata":{}},{"cell_type":"markdown","source":"## Let's examine the `go-basic.obo` file, especially in the context of the GO biological ontology. Consider incorporating a hierarchy of terms into training \n","metadata":{}},{"cell_type":"code","source":"# Display information about the graph structure\n\nprint(\"Number of nodes:\", graph.number_of_nodes())\nprint(\"Number of edges:\", graph.number_of_edges())\n\n# Print the first few nodes of the graph\n\nprint(\"\\nFirst few nodes in the graph:\")\nfor i, (node, data) in enumerate(graph.nodes(data=True)):\n     if i < 5:\n        print(f\"{node}: {data}\")\n\n# Print the first few edges of the graph\n\nprint(\"\\nFirst few edges in the graph:\")\nfor i, (source, target, data) in enumerate(graph.edges(data=True)):\n     if i < 5:\n        print(f\"{source} -> {target}: {data}\")","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:55.584350Z","iopub.execute_input":"2023-12-12T07:57:55.584637Z","iopub.status.idle":"2023-12-12T07:57:55.814585Z","shell.execute_reply.started":"2023-12-12T07:57:55.584614Z","shell.execute_reply":"2023-12-12T07:57:55.813572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### The results of the analysis of the `go-basic.obo` file allow us to draw the following conclusions:  \n\n`Number of nodes and edges:`  \n\n>Total nodes: 43,248  \nTotal ribs: 84,805  \n\n`Examples of nodes:`  \n\n>GO:0000001: \"mitochondrion inheritance\" in the space of biological processes  \nGO:0000002: \"mitochondrial genome maintenance\" in the space of biological processes  \nGO:0000003: \"reproduction\" in the space of biological processes  \nGO:0000006: \"high-affinity zinc transmembrane transporter activity\" in molecular function space  \nGO:0000007: \"low-affinity zinc ion transmembrane transporter activity\" in molecular function space  \n\n`Structure of nodes and edges:`  \n\n>Nodes represent terms in the GO ontology that describe biological processes, molecular functions, and cell components  \nEdges represent relationships between terms, such as the \"is_a\" relationship (which is a subtype)  \n\n`Information in nodes:`  \n\n>Nodes contain information about the term, its description, namespace membership, synonyms, alternative identifiers and other properties  \n\n`Hierarchy:`  \n\n>The GO ontology has a hierarchical structure, where some terms are subtypes of others\nThese findings highlight the importance of term hierarchy structure in a GO ontology, which can be useful when training a model to predict protein functions  ","metadata":{}},{"cell_type":"markdown","source":"## Exploratory Data Analysis","metadata":{}},{"cell_type":"code","source":"# Get a random subsample of 50% of the data  \n\nmerged_data_sample = merged_data.sample(frac=0.5, random_state=12345)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:55.815928Z","iopub.execute_input":"2023-12-12T07:57:55.816725Z","iopub.status.idle":"2023-12-12T07:57:57.429165Z","shell.execute_reply.started":"2023-12-12T07:57:55.816689Z","shell.execute_reply":"2023-12-12T07:57:57.428350Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"merged_data_sample ","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:57.430290Z","iopub.execute_input":"2023-12-12T07:57:57.430586Z","iopub.status.idle":"2023-12-12T07:57:57.445565Z","shell.execute_reply.started":"2023-12-12T07:57:57.430561Z","shell.execute_reply":"2023-12-12T07:57:57.444620Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Search for anomalies:  \n\nTo find anomalies in the data, we can look at several aspects such as:  \n\n`Length of protein sequences`  \n\nLet's build a histogram of the length distribution of protein sequences  \nWe investigate the presence of incorrect values or outliers in the length distribution  \n\n`GO Terms`  \n\nLet's check if there are protein sequences with unusual or incorrect GO terms  \nLet's look at the distribution of frequency of use of various terms   ","metadata":{}},{"cell_type":"code","source":"facecolor='white'\ngridcolor='gray'\n\nplt.figure(figsize=(12, 6))\nsns.histplot(merged_data_sample['Sequence'].apply(len), bins=50, kde=True, color='skyblue')\nsns.set(style=\"whitegrid\")\nplt.title('Protein sequence length distribution')\nplt.xlabel('Sequence length')\nplt.ylabel('Frequency')\nax = plt.gca()\nax.set_facecolor(facecolor)\nax.grid(color=gridcolor)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:57:57.446776Z","iopub.execute_input":"2023-12-12T07:57:57.447123Z","iopub.status.idle":"2023-12-12T07:58:10.859703Z","shell.execute_reply.started":"2023-12-12T07:57:57.447093Z","shell.execute_reply":"2023-12-12T07:58:10.858828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Comparison between training and test set:","metadata":{}},{"cell_type":"code","source":"test_sequences = [str(record.seq) for record in SeqIO.parse('/kaggle/input/cafa-5-protein-function-prediction/Test (Targets)/testsuperset.fasta', 'fasta')]\ntest_taxonomy = pd.read_csv('/kaggle/input/cafa-5-protein-function-prediction/Test (Targets)/testsuperset-taxon-list.tsv', sep='\\t', encoding='ISO-8859-1')","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:58:10.861068Z","iopub.execute_input":"2023-12-12T07:58:10.861428Z","iopub.status.idle":"2023-12-12T07:58:12.973104Z","shell.execute_reply.started":"2023-12-12T07:58:10.861395Z","shell.execute_reply":"2023-12-12T07:58:12.972303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_taxonomy.head(3)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:58:12.974510Z","iopub.execute_input":"2023-12-12T07:58:12.974878Z","iopub.status.idle":"2023-12-12T07:58:12.983801Z","shell.execute_reply.started":"2023-12-12T07:58:12.974844Z","shell.execute_reply":"2023-12-12T07:58:12.982859Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# test_sequences","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:58:12.984989Z","iopub.execute_input":"2023-12-12T07:58:12.985298Z","iopub.status.idle":"2023-12-12T07:58:12.992223Z","shell.execute_reply.started":"2023-12-12T07:58:12.985258Z","shell.execute_reply":"2023-12-12T07:58:12.991342Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Again we make a random sample that will equalize the number of lines in the train and test, \n# of course this reduces the accuracy, but as an experiment you can try\n\nmerged_data_for_test = merged_data.sample(frac=0.0000168, random_state=12345)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:58:12.993245Z","iopub.execute_input":"2023-12-12T07:58:12.993566Z","iopub.status.idle":"2023-12-12T07:58:13.170055Z","shell.execute_reply.started":"2023-12-12T07:58:12.993534Z","shell.execute_reply":"2023-12-12T07:58:13.169266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# merged_data_for_test","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:58:13.171144Z","iopub.execute_input":"2023-12-12T07:58:13.171491Z","iopub.status.idle":"2023-12-12T07:58:13.175615Z","shell.execute_reply.started":"2023-12-12T07:58:13.171459Z","shell.execute_reply":"2023-12-12T07:58:13.174665Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Comparison of class distribution\n\nplt.figure(figsize=(14, 13))\nsns.countplot(y='Taxon_ID', data=merged_data_for_test,\n               order=merged_data_for_test['Taxon_ID'].value_counts().index, color='skyblue',label='Train Set')\nsns.countplot(y='ID', data=test_taxonomy,\n               order=test_taxonomy['ID'].value_counts().index, color='hotpink', label='Test Set')\nplt.title('Comparison of class distribution between training and test datasets')\nplt.xlabel('Use frequency')\nplt.ylabel('Species ID')\nax = plt.gca()\nax.set_facecolor(facecolor)\nax.grid(color=gridcolor)\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:58:13.182487Z","iopub.execute_input":"2023-12-12T07:58:13.182759Z","iopub.status.idle":"2023-12-12T07:58:14.812440Z","shell.execute_reply.started":"2023-12-12T07:58:13.182735Z","shell.execute_reply":"2023-12-12T07:58:14.811487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The comparison is meaningless, since in the test each protein is presented in one copy, but it is interesting now to look at the distribution of species in the train ","metadata":{}},{"cell_type":"markdown","source":"Since there are 90 types of proteins, and the maximum number of one type is 1,064,498, I will make the threshold 1% of this number","metadata":{}},{"cell_type":"code","source":"threshold = 10645\n\ntaxon_counts = merged_data['Taxon_ID'].value_counts()\n\nfiltered_taxon_counts = taxon_counts[(taxon_counts >= threshold) & (taxon_counts <= taxon_counts.max())]","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:58:14.813457Z","iopub.execute_input":"2023-12-12T07:58:14.813719Z","iopub.status.idle":"2023-12-12T07:58:15.384363Z","shell.execute_reply.started":"2023-12-12T07:58:14.813696Z","shell.execute_reply":"2023-12-12T07:58:15.383169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"colors = ['gray', 'salmon', 'pink', 'steelblue', 'hotpink', 'lightgray', 'lightgreen', 'gold', 'seagreen', 'skyblue', 'orchid']\n\nplt.figure(figsize=(10, 6))\nsns.barplot(x=filtered_taxon_counts.values, y=filtered_taxon_counts.index, palette=colors)\nplt.title('Distribution of protein species in training dataset (constrained above threshold)')\nplt.xlabel('Use frequency')\nplt.ylabel('Taxon_ID')\nax = plt.gca()\nax.set_facecolor(facecolor)\nax.grid(color=gridcolor)\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:58:15.385600Z","iopub.execute_input":"2023-12-12T07:58:15.385970Z","iopub.status.idle":"2023-12-12T07:58:15.893939Z","shell.execute_reply.started":"2023-12-12T07:58:15.385936Z","shell.execute_reply":"2023-12-12T07:58:15.892744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Obviously - a huge part of the protein protein species belongs to the minority","metadata":{}},{"cell_type":"markdown","source":"## Research part. Creating New Features","metadata":{}},{"cell_type":"markdown","source":"Let's create additional features based on protein sequences. The choice of letters to represent amino acids is based on abbreviations used in bioinformatics and molecular biology. Each letter represents an abbreviation for a specific amino acid. Here's what these abbreviations mean:  \n\nA: Alanine  \nC: Cysteine  \nD: Aspartic acid  \nE: Glutamic acid  \nF: Phenylalanine  \nG: Glycine  \nH: Histidine  \nI: Isoleucine  \nK: Lysine  \nL: Leucine  \nM: Methionine  \nN: Asparagine  \nP: Proline  \nQ: Glutamine  \nR: Arginine  \nS: Serine  \nT: Threonine  \nV: Valine  \nW: Tryptophan  \nY: Tyrosine  \n\nThese letters represent the basic 20 standard amino acids that make up proteins. In bioinformatics they are widely used to represent sequences of proteins and nucleotides (in the case of nucleic acids)","metadata":{}},{"cell_type":"markdown","source":"## NB!","metadata":{}},{"cell_type":"markdown","source":"I had to create an experimental dataset `merged_data_sample` since both locally and on Kaggle the kernel crashed on the next part. Then you can change the frac parameter and increase the random sample accordingly","metadata":{}},{"cell_type":"code","source":"# Receive a random subsample of 10% of the data\n\nmerged_data_sample = merged_data.sample(frac=0.1, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:58:15.895342Z","iopub.execute_input":"2023-12-12T07:58:15.895973Z","iopub.status.idle":"2023-12-12T07:58:16.362825Z","shell.execute_reply.started":"2023-12-12T07:58:15.895936Z","shell.execute_reply":"2023-12-12T07:58:16.361827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def calculate_amino_acid_statistics(sequence):\n    valid_amino_acids = set(\"ACDEFGHIKLMNPQRSTVWY\")  # Allowed amino acids\n    \n    filtered_sequence = \"\".join(aa for aa in sequence if aa.upper() in valid_amino_acids)\n    \n    if not filtered_sequence:\n        return pd.Series([np.nan, np.nan, np.nan, np.nan], index=['MolecularWeight', 'Aromaticity', 'InstabilityIndex', 'IsoelectricPoint'])\n    \n    protein_analyzer = ProtParam.ProteinAnalysis(str(filtered_sequence))\n    \n    mol_weight = protein_analyzer.molecular_weight()\n    aromaticity = protein_analyzer.aromaticity()\n    instability_index = protein_analyzer.instability_index()\n    isoelectric_point = protein_analyzer.isoelectric_point()\n    \n    return pd.Series([mol_weight, aromaticity, instability_index, isoelectric_point], index=['MolecularWeight', 'Aromaticity', 'InstabilityIndex', 'IsoelectricPoint'])\n","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:58:16.364123Z","iopub.execute_input":"2023-12-12T07:58:16.364474Z","iopub.status.idle":"2023-12-12T07:58:16.372505Z","shell.execute_reply.started":"2023-12-12T07:58:16.364443Z","shell.execute_reply":"2023-12-12T07:58:16.371563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"merged_data_sample[['MolecularWeight', 'Aromaticity', 'InstabilityIndex', 'IsoelectricPoint']] = merged_data_sample['Sequence'].apply(calculate_amino_acid_statistics)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T07:58:16.373673Z","iopub.execute_input":"2023-12-12T07:58:16.373981Z","iopub.status.idle":"2023-12-12T08:06:11.160797Z","shell.execute_reply.started":"2023-12-12T07:58:16.373951Z","shell.execute_reply":"2023-12-12T08:06:11.160037Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"merged_data_sample.info()","metadata":{"execution":{"iopub.status.busy":"2023-12-12T08:06:11.161866Z","iopub.execute_input":"2023-12-12T08:06:11.162157Z","iopub.status.idle":"2023-12-12T08:06:11.459156Z","shell.execute_reply.started":"2023-12-12T08:06:11.162133Z","shell.execute_reply":"2023-12-12T08:06:11.458032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(16, 8))\n\nplt.subplot(2, 2, 1)\nsns.histplot(merged_data_sample['MolecularWeight'], bins=50, color='skyblue')\nplt.title('Distribution of protein molecular weights')\n\n\nplt.subplot(2, 2, 2)\nsns.histplot(merged_data_sample['Aromaticity'], bins=50, color='salmon')\nplt.title('Distribution of protein aromaticity')\n\n\nplt.subplot(2, 2, 3)\nsns.histplot(merged_data_sample['InstabilityIndex'], bins=50, color='gray')\nplt.title('Distribution of the protein instability index')\n\n\nplt.subplot(2, 2, 4)\nsns.histplot(merged_data_sample['IsoelectricPoint'], bins=50, color = 'pink')\nplt.title('Distribution of protein isoelectric points')\n\nplt.subplots_adjust(hspace=0.5, wspace=0.3)\n\nplt.show()\n'x'","metadata":{"execution":{"iopub.status.busy":"2023-12-12T08:06:11.460405Z","iopub.execute_input":"2023-12-12T08:06:11.460660Z","iopub.status.idle":"2023-12-12T08:06:14.960073Z","shell.execute_reply.started":"2023-12-12T08:06:11.460638Z","shell.execute_reply":"2023-12-12T08:06:14.959143Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model training","metadata":{}},{"cell_type":"code","source":"# Dividing data into training and test sets\n\ntrain_data, test_data = train_test_split(merged_data_sample, test_size=0.2, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T08:06:14.961371Z","iopub.execute_input":"2023-12-12T08:06:14.961667Z","iopub.status.idle":"2023-12-12T08:06:15.149704Z","shell.execute_reply.started":"2023-12-12T08:06:14.961640Z","shell.execute_reply":"2023-12-12T08:06:15.148920Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data.shape, test_data.shape","metadata":{"execution":{"iopub.status.busy":"2023-12-12T08:06:15.150812Z","iopub.execute_input":"2023-12-12T08:06:15.151114Z","iopub.status.idle":"2023-12-12T08:06:15.157204Z","shell.execute_reply.started":"2023-12-12T08:06:15.151088Z","shell.execute_reply":"2023-12-12T08:06:15.156192Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Creating a vectorizer for amino acid sequences\n\ntokenizer = Tokenizer(char_level=True)\ntokenizer.fit_on_texts(train_data['Sequence'])\nX_train_sequence = tokenizer.texts_to_sequences(train_data['Sequence'])\nX_test_sequence = tokenizer.texts_to_sequences(test_data['Sequence'])","metadata":{"execution":{"iopub.status.busy":"2023-12-12T08:06:15.158237Z","iopub.execute_input":"2023-12-12T08:06:15.158547Z","iopub.status.idle":"2023-12-12T08:09:12.669621Z","shell.execute_reply.started":"2023-12-12T08:06:15.158522Z","shell.execute_reply":"2023-12-12T08:09:12.668616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Padding sequences to the same length\n\naverage_length = int(sum(map(len, X_train_sequence)) / len(X_train_sequence))\nmax_sequence_length = average_length\n\nX_train_sequence = pad_sequences(X_train_sequence, maxlen=max_sequence_length)\nX_test_sequence = pad_sequences(X_test_sequence, maxlen=max_sequence_length)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T08:09:12.670756Z","iopub.execute_input":"2023-12-12T08:09:12.671057Z","iopub.status.idle":"2023-12-12T08:09:32.156587Z","shell.execute_reply.started":"2023-12-12T08:09:12.671031Z","shell.execute_reply":"2023-12-12T08:09:32.155798Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create a vectorizer for the taxonomy\n\nmlb = MultiLabelBinarizer()\ny_train_taxonomy = mlb.fit_transform(train_data['Taxon_ID'])\ny_test_taxonomy = mlb.transform(test_data['Taxon_ID'])","metadata":{"execution":{"iopub.status.busy":"2023-12-12T08:09:32.157605Z","iopub.execute_input":"2023-12-12T08:09:32.157857Z","iopub.status.idle":"2023-12-12T08:09:33.209762Z","shell.execute_reply.started":"2023-12-12T08:09:32.157836Z","shell.execute_reply":"2023-12-12T08:09:33.208986Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The model requires additional tuning, I tried different options for the `output_dim`, `Dropout`, `LSTM` parameters, but the result was either worse or almost the same. Haven't tried adding activation functions for hidden layers of ReLU or its variations such as Leaky ReLU, ELU or SELU","metadata":{}},{"cell_type":"code","source":"# # Try this\n\n# model = Sequential()\n# model.add(Embedding(input_dim=len(tokenizer.word_index) + 1, output_dim=500, input_length=max_sequence_length))\n# model.add(Dropout(0.2))\n# model.add(LSTM(100, activation='relu')) # Changing the activation function ## bad idea\n# model.add(Dropout(0.2))\n# model.add(Dense(len(mlb.classes_), activation='sigmoid'))\n# model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-12-12T08:09:33.210905Z","iopub.execute_input":"2023-12-12T08:09:33.211203Z","iopub.status.idle":"2023-12-12T08:09:33.215597Z","shell.execute_reply.started":"2023-12-12T08:09:33.211179Z","shell.execute_reply":"2023-12-12T08:09:33.214643Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = Sequential()\nmodel.add(Embedding(input_dim=len(tokenizer.word_index) + 1, output_dim=500, input_length=max_sequence_length)) \nmodel.add(Dropout(0.2))\nmodel.add(LSTM(100)) \nmodel.add(Dropout(0.2))\nmodel.add(Dense(len(mlb.classes_), activation='sigmoid')) \nmodel.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])\n\nmodel.fit(X_train_sequence, y_train_taxonomy, epochs=13, batch_size=32, validation_split=0.2)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T08:09:33.216907Z","iopub.execute_input":"2023-12-12T08:09:33.217523Z","iopub.status.idle":"2023-12-12T09:46:11.562591Z","shell.execute_reply.started":"2023-12-12T08:09:33.217490Z","shell.execute_reply":"2023-12-12T09:46:11.561631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Model evaluation on test set\n\ny_pred = model.predict(X_test_sequence)\n\ny_pred_binary = (y_pred > 0.5).astype(int)\n\naccuracy = accuracy_score(y_test_taxonomy, y_pred_binary)\nf1 = f1_score(y_test_taxonomy, y_pred_binary, average='weighted')\nprecision = precision_score(y_test_taxonomy, y_pred_binary, average='weighted')\nrecall = recall_score(y_test_taxonomy, y_pred_binary, average='weighted')\n\nprint(f'Test Accuracy: {accuracy}, Test F1: {f1}, Test Precision: {precision}, Test Recall: {recall}')","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:46:11.564037Z","iopub.execute_input":"2023-12-12T09:46:11.564691Z","iopub.status.idle":"2023-12-12T09:47:08.847832Z","shell.execute_reply.started":"2023-12-12T09:46:11.564655Z","shell.execute_reply":"2023-12-12T09:47:08.846725Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save('/kaggle/working/model_PFP.keras')","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:47:08.849241Z","iopub.execute_input":"2023-12-12T09:47:08.849623Z","iopub.status.idle":"2023-12-12T09:47:08.908846Z","shell.execute_reply.started":"2023-12-12T09:47:08.849588Z","shell.execute_reply":"2023-12-12T09:47:08.908134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Prediction on a test superset","metadata":{}},{"cell_type":"code","source":"# Download test protein sequences\n\n# test_sequences = [str(record.seq) for record in SeqIO.parse('/kaggle/input/cafa-5-protein-function-prediction/Test (Targets)/testsuperset.fasta', 'fasta')]","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:47:08.909909Z","iopub.execute_input":"2023-12-12T09:47:08.910197Z","iopub.status.idle":"2023-12-12T09:47:08.913815Z","shell.execute_reply.started":"2023-12-12T09:47:08.910172Z","shell.execute_reply":"2023-12-12T09:47:08.913047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create a DataFrame with protein sequences\n\ntest_data = pd.DataFrame({'Sequence': test_sequences})","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:47:08.914998Z","iopub.execute_input":"2023-12-12T09:47:08.915312Z","iopub.status.idle":"2023-12-12T09:47:08.947528Z","shell.execute_reply.started":"2023-12-12T09:47:08.915287Z","shell.execute_reply":"2023-12-12T09:47:08.946599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"average_length_test = int(sum(map(len, X_test_sequence)) / len(X_test_sequence))\n\nmax_sequence_length = average_length_test","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:47:08.948541Z","iopub.execute_input":"2023-12-12T09:47:08.948811Z","iopub.status.idle":"2023-12-12T09:47:08.974587Z","shell.execute_reply.started":"2023-12-12T09:47:08.948786Z","shell.execute_reply":"2023-12-12T09:47:08.973718Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_test_sequence = pad_sequences(X_test_sequence, maxlen=max_sequence_length)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:47:08.975768Z","iopub.execute_input":"2023-12-12T09:47:08.976116Z","iopub.status.idle":"2023-12-12T09:47:09.378158Z","shell.execute_reply.started":"2023-12-12T09:47:08.976080Z","shell.execute_reply":"2023-12-12T09:47:09.377253Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load taxonomy for test superset\n\n# test_taxonomy = pd.read_csv('/kaggle/input/cafa-5-protein-function-prediction/Test (Targets)/testsuperset-taxon-list.tsv', sep='\\t', encoding='ISO-8859-1')","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:47:09.379698Z","iopub.execute_input":"2023-12-12T09:47:09.379980Z","iopub.status.idle":"2023-12-12T09:47:09.383874Z","shell.execute_reply.started":"2023-12-12T09:47:09.379956Z","shell.execute_reply":"2023-12-12T09:47:09.382856Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_submission = pd.read_csv('/kaggle/input/cafa-5-protein-function-prediction/sample_submission.tsv', sep='\\t')","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:47:09.384845Z","iopub.execute_input":"2023-12-12T09:47:09.385153Z","iopub.status.idle":"2023-12-12T09:47:09.609646Z","shell.execute_reply.started":"2023-12-12T09:47:09.385128Z","shell.execute_reply":"2023-12-12T09:47:09.608823Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sample_submission","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:47:09.610708Z","iopub.execute_input":"2023-12-12T09:47:09.610992Z","iopub.status.idle":"2023-12-12T09:47:09.615292Z","shell.execute_reply.started":"2023-12-12T09:47:09.610967Z","shell.execute_reply":"2023-12-12T09:47:09.614345Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Prediction\n\n# predictions = model.predict(X_test_sequence)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:47:09.616402Z","iopub.execute_input":"2023-12-12T09:47:09.616666Z","iopub.status.idle":"2023-12-12T09:47:09.625817Z","shell.execute_reply.started":"2023-12-12T09:47:09.616643Z","shell.execute_reply":"2023-12-12T09:47:09.625060Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# predictions.shape","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:47:09.626859Z","iopub.execute_input":"2023-12-12T09:47:09.627469Z","iopub.status.idle":"2023-12-12T09:47:09.635485Z","shell.execute_reply.started":"2023-12-12T09:47:09.627441Z","shell.execute_reply":"2023-12-12T09:47:09.634707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# test_taxonomy","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:47:09.636413Z","iopub.execute_input":"2023-12-12T09:47:09.636644Z","iopub.status.idle":"2023-12-12T09:47:09.645261Z","shell.execute_reply.started":"2023-12-12T09:47:09.636623Z","shell.execute_reply":"2023-12-12T09:47:09.644419Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from itertools import product\nimport numpy as np","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:47:09.646258Z","iopub.execute_input":"2023-12-12T09:47:09.646513Z","iopub.status.idle":"2023-12-12T09:47:09.654619Z","shell.execute_reply.started":"2023-12-12T09:47:09.646490Z","shell.execute_reply":"2023-12-12T09:47:09.653809Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_embeddings = np.load('/kaggle/input/t5embeds/test_embeds.npy')\n\n# Convert test_embeddings to dataframe\ncolumn_num = test_embeddings.shape[1]\ntest_df = pd.DataFrame(test_embeddings, columns = [\"Column_\" + str(i) for i in range(1, column_num+1)])\nprint(test_df.shape)\n","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:47:09.655588Z","iopub.execute_input":"2023-12-12T09:47:09.655830Z","iopub.status.idle":"2023-12-12T09:47:27.103751Z","shell.execute_reply.started":"2023-12-12T09:47:09.655808Z","shell.execute_reply":"2023-12-12T09:47:27.102834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"selected_columns = test_df.columns[:636]\ntest_df_subset = test_df[selected_columns]\n\npredictions = model.predict(test_df_subset)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:47:27.105686Z","iopub.execute_input":"2023-12-12T09:47:27.105979Z","iopub.status.idle":"2023-12-12T09:48:43.206408Z","shell.execute_reply.started":"2023-12-12T09:47:27.105953Z","shell.execute_reply":"2023-12-12T09:48:43.205562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Set the limit for label\nnum_of_labels = 1500\n\n# Take value counts in descending order and fetch first 1500 `GO term ID` as labels\nlabels = terms_data['GO_Term_ID'].value_counts().index[:num_of_labels].tolist()","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:48:43.207978Z","iopub.execute_input":"2023-12-12T09:48:43.208360Z","iopub.status.idle":"2023-12-12T09:48:44.012443Z","shell.execute_reply.started":"2023-12-12T09:48:43.208329Z","shell.execute_reply":"2023-12-12T09:48:44.011535Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if len(labels) > predictions.shape[1]:\n    labels = labels[:predictions.shape[1]]\nelif len(labels) < predictions.shape[1]:\n    additional_labels = list(set(predictions.columns) - set(labels))\n    labels.extend(additional_labels)\n","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:48:44.013647Z","iopub.execute_input":"2023-12-12T09:48:44.014046Z","iopub.status.idle":"2023-12-12T09:48:44.022169Z","shell.execute_reply.started":"2023-12-12T09:48:44.013997Z","shell.execute_reply":"2023-12-12T09:48:44.021283Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Reference: https://www.kaggle.com/code/alexandervc/baseline-multilabel-to-multitarget-binary\n\ndf_submission = pd.DataFrame(columns=['Protein Id', 'GO Term Id', 'Prediction'])\ntest_protein_ids = np.load('/kaggle/input/t5embeds/test_ids.npy')\n\ndata = []\n\nfor i, protein_id in enumerate(test_protein_ids):\n    for j, go_term_id in enumerate(labels):\n        prediction_value = predictions[i, j]\n        data.append({\n            'Protein Id': protein_id,\n            'GO Term Id': go_term_id,\n            'Prediction': prediction_value\n        })\n\ndf_submission = pd.DataFrame(data, columns=['Protein Id', 'GO Term Id', 'Prediction'])\ndf_submission.to_csv(\"submission.tsv\", header=False, index=False, sep=\"\\t\")","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:48:44.023296Z","iopub.execute_input":"2023-12-12T09:48:44.023976Z","iopub.status.idle":"2023-12-12T09:48:51.004486Z","shell.execute_reply.started":"2023-12-12T09:48:44.023941Z","shell.execute_reply":"2023-12-12T09:48:51.003463Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submission","metadata":{"execution":{"iopub.status.busy":"2023-12-12T09:48:51.005773Z","iopub.execute_input":"2023-12-12T09:48:51.007606Z","iopub.status.idle":"2023-12-12T09:48:51.023144Z","shell.execute_reply.started":"2023-12-12T09:48:51.007568Z","shell.execute_reply":"2023-12-12T09:48:51.022146Z"},"trusted":true},"execution_count":null,"outputs":[]}]}