{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.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":67356,"databundleVersionId":8006601,"sourceType":"competition"},{"sourceId":8042988,"sourceType":"datasetVersion","datasetId":4740586}],"dockerImageVersionId":30684,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# What is about ?\n\nNotebook gives an introductory example how to use  \"siamese-smole-bert\"  by LSV @ Saarland University  to get embeddings for SMILES.\nBased on SESHURAJUP https://www.kaggle.com/code/seshurajup/buildingblock-analysis-smiles-transformer (please upvote his work).\nAnd using \"shrunken dataset\" by GreaSnow    https://www.kaggle.com/datasets/shlomoron/belka-shrunken-train-set (please upvote his work)\n\nTiming:\n\n10000 smiles encoded in 3min 12sec. CPU. It is about 2 times slower than ChemBerta: https://www.kaggle.com/code/alexandervc/chembert2a-smiles-embeddings-for-beginners\n\nSome quick look on embeddings is performed - clustermap, umap.     \n","metadata":{}},{"cell_type":"markdown","source":"# Preliminaries","metadata":{}},{"cell_type":"code","source":"# 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)\nimport time\nt0start = time.time() \n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\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":{"execution":{"iopub.status.busy":"2024-04-13T20:51:30.358119Z","iopub.execute_input":"2024-04-13T20:51:30.358689Z","iopub.status.idle":"2024-04-13T20:51:32.001212Z","shell.execute_reply.started":"2024-04-13T20:51:30.358647Z","shell.execute_reply":"2024-04-13T20:51:31.999801Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Via duckDB - access to huge data file \n\nwill not use in the present version ","metadata":{}},{"cell_type":"code","source":"# %%time\n\n# ! pip install -qq duckdb\n# import duckdb\n# import pandas as pd\n\n# train_path = '/kaggle/input/leash-BELKA/train.parquet'\n# test_path = '/kaggle/input/leash-BELKA/test.parquet'\n\n# con = duckdb.connect()\n\n# all_building_blocks_df = con.query(f\"\"\"(SELECT * FROM (\n#     SELECT distinct buildingblock1_smiles as smile, 'buildingblock1' as group, 'test' as split, protein_name, 2 as binds  FROM parquet_scan('{test_path}')\n#     UNION\n#     SELECT distinct buildingblock1_smiles as smile, 'buildingblock1' as group, 'train' as split, protein_name, binds FROM parquet_scan('{train_path}')\n#     UNION\n#     SELECT distinct buildingblock2_smiles as smile, 'buildingblock2' as group, 'test' as split, protein_name, 2 as binds  FROM parquet_scan('{test_path}')\n#     UNION\n#     SELECT distinct buildingblock2_smiles as smile, 'buildingblock2' as group, 'train' as split, protein_name, binds FROM parquet_scan('{train_path}')\n#     UNION\n#     SELECT distinct buildingblock3_smiles as smile, 'buildingblock3' as group, 'test' as split, protein_name, 2 as binds  FROM parquet_scan('{test_path}')\n#     UNION\n#     SELECT distinct buildingblock3_smiles as smile, 'buildingblock3' as group, 'train' as split, protein_name, binds FROM parquet_scan('{train_path}')\n#     ) as t)\"\"\").df()\n\n# all_building_blocks_df","metadata":{"_uuid":"3ca28711-7d13-45ae-8654-3bfab478fe68","_cell_guid":"01578101-a283-4ac3-ae7e-829006ce2a07","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-13T20:51:32.003632Z","iopub.execute_input":"2024-04-13T20:51:32.004638Z","iopub.status.idle":"2024-04-13T20:51:32.011674Z","shell.execute_reply.started":"2024-04-13T20:51:32.004591Z","shell.execute_reply":"2024-04-13T20:51:32.010147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# smiles = list(set(all_building_blocks_df['smile']))\n# len(smiles)","metadata":{"_uuid":"5388d62f-33ca-40bd-901e-13718a976be6","_cell_guid":"b45809c4-929a-4251-952f-a52914f03f1c","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-13T20:51:32.013799Z","iopub.execute_input":"2024-04-13T20:51:32.014578Z","iopub.status.idle":"2024-04-13T20:51:32.029135Z","shell.execute_reply.started":"2024-04-13T20:51:32.014537Z","shell.execute_reply":"2024-04-13T20:51:32.028131Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load data\n\nThanks to GreySnow:\n\nhttps://www.kaggle.com/datasets/shlomoron/belka-shrunken-train-set","metadata":{}},{"cell_type":"code","source":"%%time\nnrows_to_load = int(1e6)\n\ndtypes = {'buildingblock1_smiles': np.int16, 'buildingblock2_smiles': np.int16, 'buildingblock3_smiles': np.int16,\n          'binds_BRD4':np.byte, 'binds_HSA':np.byte, 'binds_sEH':np.byte}\n\ntrain = pd.read_csv('/kaggle/input/belka-shrunken-train-set/train.csv', dtype = dtypes,  nrows = 10000 )\nprint(len(train))\ndisplay(train.head())","metadata":{"execution":{"iopub.status.busy":"2024-04-13T20:51:50.396210Z","iopub.execute_input":"2024-04-13T20:51:50.396813Z","iopub.status.idle":"2024-04-13T20:51:50.440578Z","shell.execute_reply.started":"2024-04-13T20:51:50.396771Z","shell.execute_reply":"2024-04-13T20:51:50.439130Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Install Bert for SMILES:  siamese-smole-bert\n\nhttps://huggingface.co/UdS-LSV/siamese-smole-bert-muv-1x\n\nby LSV @ Saarland University. That seems to be even more new than ChemBERTa-2 (since their repository links/thanks to ChemBERTa-2).\n ","metadata":{}},{"cell_type":"code","source":"%%time\n! pip3 install -qq sentence_transformers","metadata":{"_uuid":"ffa2a47b-fb80-4c84-888d-65bd050c9c0b","_cell_guid":"df455593-8c20-407e-9330-91cb2c150f5c","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-13T20:51:51.828227Z","iopub.execute_input":"2024-04-13T20:51:51.828614Z","iopub.status.idle":"2024-04-13T20:52:07.316819Z","shell.execute_reply.started":"2024-04-13T20:51:51.828586Z","shell.execute_reply":"2024-04-13T20:52:07.315125Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nfrom sentence_transformers import SentenceTransformer\nmodel = SentenceTransformer('UdS-LSV/siamese-smole-bert-muv-1x')","metadata":{"_uuid":"bf0af87f-c144-4a3c-8f5f-35775b4b80f8","_cell_guid":"0c79a724-0e79-44f1-a379-8c65e5b26baf","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-13T20:52:07.320251Z","iopub.execute_input":"2024-04-13T20:52:07.320818Z","iopub.status.idle":"2024-04-13T20:52:08.669467Z","shell.execute_reply.started":"2024-04-13T20:52:07.320767Z","shell.execute_reply":"2024-04-13T20:52:08.668131Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Smiles encoding","metadata":{}},{"cell_type":"code","source":"model.encode??","metadata":{"execution":{"iopub.status.busy":"2024-04-13T21:00:21.851738Z","iopub.execute_input":"2024-04-13T21:00:21.852589Z","iopub.status.idle":"2024-04-13T21:00:21.917349Z","shell.execute_reply.started":"2024-04-13T21:00:21.852541Z","shell.execute_reply":"2024-04-13T21:00:21.915831Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nsmile = train['molecule_smiles'].iat[0]\nlen(smile), smile\nemb = model.encode(smile)\nprint( ' type(emb):',  type(emb), 'emb.shape', emb.shape ) \nprint(emb[:10])\nplt.figure(figsize = (20,3))\nplt.plot(emb)\nplt.title('Emb coordinates', fontsize = 20 )\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-04-13T20:55:33.632500Z","iopub.execute_input":"2024-04-13T20:55:33.632944Z","iopub.status.idle":"2024-04-13T20:55:34.027040Z","shell.execute_reply.started":"2024-04-13T20:55:33.632910Z","shell.execute_reply":"2024-04-13T20:55:34.026112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Compute multiple embeddings","metadata":{}},{"cell_type":"code","source":"%%time\nprint('Naive way')\nlist_emb = [model.encode(smile, show_progress_bar= False) for smile in train['molecule_smiles'].iloc[:1000] ]","metadata":{"execution":{"iopub.status.busy":"2024-04-13T20:59:04.754559Z","iopub.execute_input":"2024-04-13T20:59:04.755226Z","iopub.status.idle":"2024-04-13T20:59:41.418668Z","shell.execute_reply.started":"2024-04-13T20:59:04.755193Z","shell.execute_reply":"2024-04-13T20:59:41.417363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nprint('Intrinsic way')\nemb = model.encode(train['molecule_smiles'].to_list()[:10000])","metadata":{"execution":{"iopub.status.busy":"2024-04-13T21:10:21.720718Z","iopub.execute_input":"2024-04-13T21:10:21.721235Z","iopub.status.idle":"2024-04-13T21:13:34.365451Z","shell.execute_reply.started":"2024-04-13T21:10:21.721199Z","shell.execute_reply":"2024-04-13T21:13:34.364198Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"type(emb), emb.shape","metadata":{"execution":{"iopub.status.busy":"2024-04-13T21:13:34.367692Z","iopub.execute_input":"2024-04-13T21:13:34.368557Z","iopub.status.idle":"2024-04-13T21:13:34.375652Z","shell.execute_reply.started":"2024-04-13T21:13:34.368522Z","shell.execute_reply":"2024-04-13T21:13:34.374591Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nnp.save('train_embs_UdS-LSV_siamese-smole-bert.npy', emb)\n","metadata":{"execution":{"iopub.status.busy":"2024-04-13T21:13:34.377060Z","iopub.execute_input":"2024-04-13T21:13:34.378241Z","iopub.status.idle":"2024-04-13T21:13:34.414286Z","shell.execute_reply.started":"2024-04-13T21:13:34.378167Z","shell.execute_reply":"2024-04-13T21:13:34.412889Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Clustermaps ","metadata":{}},{"cell_type":"code","source":"%%time\n\ncm = np.corrcoef(emb[:100,:].T)\nprint(cm.shape)\nsns.clustermap(cm, cmap='coolwarm')\nplt.title('Correlation of emb coordinates',fontsize = 20)\nplt.show()\n\n\ncm = np.corrcoef(emb[:700,:])\nprint(cm.shape)\nsns.clustermap(cm, cmap='coolwarm')\nplt.title('Correlations of smiles',fontsize = 20)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-04-13T21:09:07.742472Z","iopub.execute_input":"2024-04-13T21:09:07.742888Z","iopub.status.idle":"2024-04-13T21:09:12.390285Z","shell.execute_reply.started":"2024-04-13T21:09:07.742857Z","shell.execute_reply":"2024-04-13T21:09:12.389106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# UMAP","metadata":{}},{"cell_type":"code","source":"%%time\nimport umap\n\nreducer = umap.UMAP()\nr = reducer.fit_transform(emb)\nsns.scatterplot(x = r[:,0],y = r[:,1], hue = range(len(r)))\nplt.show()\n\nd = pd.DataFrame(r)\nd=d.reset_index()\nd.corr()","metadata":{"execution":{"iopub.status.busy":"2024-04-13T21:34:36.064574Z","iopub.execute_input":"2024-04-13T21:34:36.065013Z","iopub.status.idle":"2024-04-13T21:34:50.344371Z","shell.execute_reply.started":"2024-04-13T21:34:36.064981Z","shell.execute_reply":"2024-04-13T21:34:50.343013Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.columns","metadata":{"execution":{"iopub.status.busy":"2024-04-13T21:35:21.349434Z","iopub.execute_input":"2024-04-13T21:35:21.350821Z","iopub.status.idle":"2024-04-13T21:35:21.359135Z","shell.execute_reply.started":"2024-04-13T21:35:21.350783Z","shell.execute_reply":"2024-04-13T21:35:21.357675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for col in [ 'binds_BRD4', 'binds_HSA', 'binds_sEH']:\n    sns.scatterplot(x = r[:,0],y = r[:,1], hue = train[col])\n    plt.title(col,fontsize = 20 )\n    plt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-04-13T21:36:39.718547Z","iopub.execute_input":"2024-04-13T21:36:39.718997Z","iopub.status.idle":"2024-04-13T21:36:41.895846Z","shell.execute_reply.started":"2024-04-13T21:36:39.718965Z","shell.execute_reply":"2024-04-13T21:36:41.894557Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Final timing","metadata":{}},{"cell_type":"code","source":"print('%.1f seconds passed total '%(time.time()-t0start) )\nprint('%.1f minutes passed total '%( (time.time()-t0start)/60)  )\nprint('%.2f hours passed total '%( (time.time()-t0start)/3600)  )","metadata":{},"execution_count":null,"outputs":[]}]}