{"metadata":{"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":67356,"databundleVersionId":8006601,"sourceType":"competition"},{"sourceId":8285651,"sourceType":"datasetVersion","datasetId":4921138},{"sourceId":171529473,"sourceType":"kernelVersion"}],"dockerImageVersionId":30673,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true},"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.10.13"},"papermill":{"default_parameters":{},"duration":4746.510917,"end_time":"2024-04-21T18:37:32.954734","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2024-04-21T17:18:26.443817","version":"2.5.0"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"- trained model\n    - https://www.kaggle.com/datasets/motono0223/belka-autogluon-gpu-3m  \n        This model was trained with the following data:\n            binds=1 data : 1.5M records (all positive data in train data)\n            binds=0 data : 1.5M records (random picked)","metadata":{}},{"cell_type":"code","source":"!pip install -q autogluon==1.1.0\n!pip install -q ray==2.6.3\n# tips: https://github.com/autogluon/autogluon/issues/3365\n\nfrom autogluon.tabular import TabularDataset, TabularPredictor\nimport gc","metadata":{"_kg_hide-output":true,"papermill":{"duration":107.638073,"end_time":"2024-04-21T17:20:16.747656","exception":false,"start_time":"2024-04-21T17:18:29.109583","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-05-02T00:40:16.169444Z","iopub.execute_input":"2024-05-02T00:40:16.169802Z","iopub.status.idle":"2024-05-02T00:42:07.447747Z","shell.execute_reply.started":"2024-05-02T00:40:16.169774Z","shell.execute_reply":"2024-05-02T00:42:07.446909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install rdkit","metadata":{"papermill":{"duration":15.615728,"end_time":"2024-04-21T17:20:32.367930","exception":false,"start_time":"2024-04-21T17:20:16.752202","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-05-02T00:42:07.449544Z","iopub.execute_input":"2024-05-02T00:42:07.450000Z","iopub.status.idle":"2024-05-02T00:42:23.372200Z","shell.execute_reply.started":"2024-05-02T00:42:07.449974Z","shell.execute_reply":"2024-05-02T00:42:23.371187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install duckdb","metadata":{"papermill":{"duration":15.005562,"end_time":"2024-04-21T17:20:47.378958","exception":false,"start_time":"2024-04-21T17:20:32.373396","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-05-02T00:42:23.377445Z","iopub.execute_input":"2024-05-02T00:42:23.377741Z","iopub.status.idle":"2024-05-02T00:42:38.276600Z","shell.execute_reply.started":"2024-05-02T00:42:23.377712Z","shell.execute_reply":"2024-05-02T00:42:38.275440Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport rdkit\nfrom rdkit import Chem\nimport duckdb\nimport pickle","metadata":{"papermill":{"duration":0.217529,"end_time":"2024-04-21T17:20:47.602744","exception":false,"start_time":"2024-04-21T17:20:47.385215","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-05-02T00:42:38.278143Z","iopub.execute_input":"2024-05-02T00:42:38.278450Z","iopub.status.idle":"2024-05-02T00:42:38.482389Z","shell.execute_reply.started":"2024-05-02T00:42:38.278423Z","shell.execute_reply":"2024-05-02T00:42:38.481388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_path = '/kaggle/input/leash-predict-chemical-bindings/train.parquet'\ntest_path = '/kaggle/input/leash-predict-chemical-bindings/test.parquet'\n\n#con = duckdb.connect()\n#df = con.query(f\"\"\"(SELECT *\n#                        FROM parquet_scan('{train_path}')\n#                        WHERE binds = 0\n#                        ORDER BY random()\n#                        LIMIT 30000)\n#                        UNION ALL\n#                        (SELECT *\n#                        FROM parquet_scan('{train_path}')\n#                        WHERE binds = 1\n#                        ORDER BY random()\n#                        LIMIT 30000)\"\"\").df()\n#con.close()","metadata":{"papermill":{"duration":0.01328,"end_time":"2024-04-21T17:20:47.622179","exception":false,"start_time":"2024-04-21T17:20:47.608899","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-05-02T00:42:38.483690Z","iopub.execute_input":"2024-05-02T00:42:38.483973Z","iopub.status.idle":"2024-05-02T00:42:38.488705Z","shell.execute_reply.started":"2024-05-02T00:42:38.483948Z","shell.execute_reply":"2024-05-02T00:42:38.487797Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from rdkit import Chem\nfrom rdkit.Chem import AllChem\nfrom sklearn.ensemble import RandomForestClassifier\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import average_precision_score\nfrom sklearn.preprocessing import OneHotEncoder\n\n# Assuming your DataFrame is named 'df' with columns 'molecule_smiles', 'protein_name', and 'binds'\n\n# Convert SMILES to RDKit molecules\n#df['molecule'] = df['molecule_smiles'].apply(Chem.MolFromSmiles)\n\n# Generate ECFPs\ndef generate_ecfp(molecule, radius=2, bits=1024):\n    if molecule is None:\n        return None\n    return list(AllChem.GetMorganFingerprintAsBitVect(molecule, radius, nBits=bits))\n\n#df['ecfp'] = df['molecule'].apply(generate_ecfp)\n\n# One-hot encode the protein_name\nwith open('/kaggle/input/leash-bio-onehot-encoder/protein_name_encoder.pkl', 'rb') as f:\n    onehot_encoder = pickle.load(f)\n\n#onehot_encoder = OneHotEncoder(sparse_output=False)\n#protein_onehot = onehot_encoder.fit_transform(df['protein_name'].values.reshape(-1, 1))\n\n# Combine ECFPs and one-hot encoded protein_name\n#X = [ecfp + protein for ecfp, protein in zip(df['ecfp'].tolist(), protein_onehot.tolist())]\n\n#data = pd.DataFrame(np.array(X), columns=[f\"col{i:04d}\" for i in range(len(X[0]))])\n#data['binds'] = df['binds']\n#train, valid = train_test_split(data, test_size=0.2, random_state=42)\n\n#train = TabularDataset(train)\n#valid = TabularDataset(valid)\n\n#del X, data\n#gc.collect()","metadata":{"papermill":{"duration":0.148412,"end_time":"2024-04-21T17:20:47.776418","exception":false,"start_time":"2024-04-21T17:20:47.628006","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-05-02T00:42:38.489840Z","iopub.execute_input":"2024-05-02T00:42:38.490102Z","iopub.status.idle":"2024-05-02T00:42:38.637735Z","shell.execute_reply.started":"2024-05-02T00:42:38.490080Z","shell.execute_reply":"2024-05-02T00:42:38.636778Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"predictor = TabularPredictor(\n    label=\"binds\",\n    problem_type=\"binary\",\n    eval_metric=\"average_precision\",\n    path=\"predictor\",\n)\"\"\"","metadata":{"papermill":{"duration":0.015946,"end_time":"2024-04-21T17:20:47.798529","exception":false,"start_time":"2024-04-21T17:20:47.782583","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-05-02T00:42:38.639037Z","iopub.execute_input":"2024-05-02T00:42:38.640121Z","iopub.status.idle":"2024-05-02T00:42:38.647174Z","shell.execute_reply.started":"2024-05-02T00:42:38.640092Z","shell.execute_reply":"2024-05-02T00:42:38.646329Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"%%time\npredictor.fit(\n    train,\n    tuning_data=valid,\n    save_space=True,\n    presets=\"optimize_for_deployment\",\n    use_bag_holdout=True,\n)\"\"\"","metadata":{"_kg_hide-output":true,"papermill":{"duration":0.013666,"end_time":"2024-04-21T17:20:47.818061","exception":false,"start_time":"2024-04-21T17:20:47.804395","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-05-02T00:42:38.648261Z","iopub.execute_input":"2024-05-02T00:42:38.648556Z","iopub.status.idle":"2024-05-02T00:42:38.660054Z","shell.execute_reply.started":"2024-05-02T00:42:38.648511Z","shell.execute_reply":"2024-05-02T00:42:38.659149Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"MODEL_PATH = \"/kaggle/input/belka-autogluon-gpu-3m/predictor_3m\"\npredictor = TabularPredictor.load(path=MODEL_PATH, require_version_match=False)","metadata":{"papermill":{"duration":0.567774,"end_time":"2024-04-21T17:20:48.391840","exception":false,"start_time":"2024-04-21T17:20:47.824066","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-05-02T00:42:38.663321Z","iopub.execute_input":"2024-05-02T00:42:38.663766Z","iopub.status.idle":"2024-05-02T00:42:39.230030Z","shell.execute_reply.started":"2024-05-02T00:42:38.663713Z","shell.execute_reply":"2024-05-02T00:42:39.228946Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictor.leaderboard()","metadata":{"papermill":{"duration":0.04759,"end_time":"2024-04-21T17:20:48.445984","exception":false,"start_time":"2024-04-21T17:20:48.398394","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-05-02T00:42:39.231198Z","iopub.execute_input":"2024-05-02T00:42:39.231673Z","iopub.status.idle":"2024-05-02T00:42:39.275431Z","shell.execute_reply.started":"2024-05-02T00:42:39.231647Z","shell.execute_reply":"2024-05-02T00:42:39.274538Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Inference","metadata":{"papermill":{"duration":0.006255,"end_time":"2024-04-21T17:20:48.459822","exception":false,"start_time":"2024-04-21T17:20:48.453567","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import os\nfrom tqdm import tqdm\n\n# Process the test.parquet file chunk by chunk\ntest_file = '/kaggle/input/leash-predict-chemical-bindings/test.csv'\noutput_file = 'submission.csv'  # Specify the path and filename for the output file\n\n# Read the test.parquet file into a pandas DataFrame\nfor seq,df_test in enumerate(tqdm(pd.read_csv(test_file, chunksize=100000))):\n    print(seq)\n    # Generate ECFPs for the molecule_smiles\n    df_test['molecule'] = df_test['molecule_smiles'].apply(Chem.MolFromSmiles)\n    df_test['ecfp'] = df_test['molecule'].apply(generate_ecfp)\n\n    # One-hot encode the protein_name\n    protein_onehot = onehot_encoder.transform(df_test['protein_name'].values.reshape(-1, 1))\n\n    # Combine ECFPs and one-hot encoded protein_name\n    X_test = [ecfp + protein for ecfp, protein in zip(df_test['ecfp'].tolist(), protein_onehot.tolist())]\n    X_test = pd.DataFrame(np.array(X_test), columns=[f\"col{i:04d}\" for i in range(len(X_test[0]))])\n    X_test = TabularDataset(X_test)\n\n    # Predict the probabilities\n    probabilities = predictor.predict_proba(X_test).iloc[:, 1].values\n\n    # Create a DataFrame with 'id' and 'probability' columns\n    output_df = pd.DataFrame({'id': df_test['id'], 'binds': probabilities})\n\n    # Save the output DataFrame to a CSV file\n    output_df.to_csv(output_file, index=False, mode='a', header=not os.path.exists(output_file))","metadata":{"papermill":{"duration":4601.651114,"end_time":"2024-04-21T18:37:30.117302","exception":false,"start_time":"2024-04-21T17:20:48.466188","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-05-02T00:42:39.276686Z","iopub.execute_input":"2024-05-02T00:42:39.277029Z"},"trusted":true},"execution_count":null,"outputs":[]}]}