{"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"}],"dockerImageVersionId":30684,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"Adapted from https://www.kaggle.com/code/beckpro/lightgbm-fold-voting-baseline-lb-0-408","metadata":{}},{"cell_type":"code","source":"!mkdir -p /etc/OpenCL/vendors && echo \"libnvidia-opencl.so.1\" > /etc/OpenCL/vendors/nvidia.icd","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install rdkit-pypi","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install duckdb","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from rdkit import Chem\nfrom rdkit.Chem import AllChem\nimport lightgbm as lgb\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import average_precision_score\nfrom sklearn.preprocessing import OneHotEncoder\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))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import duckdb\nimport pandas as pd\nimport numpy as np\nfrom sklearn.model_selection import StratifiedKFold\nfrom sklearn.base import BaseEstimator, ClassifierMixin\nfrom tqdm.auto import tqdm\ntqdm.pandas()\n# wip\n# import optuna \ntrain_path = '/kaggle/input/leash-BELKA/train.parquet'\ntest_path = '/kaggle/input/leash-BELKA/test.parquet'\n\ntargets = ['BRD4', 'sEH', 'HSA']\ncon = duckdb.connect()\ndata = {}\n\ndef get_data(target):\n    df = con.query(f\"\"\"(SELECT molecule_smiles, binds\n                            FROM parquet_scan('{train_path}')\n                            WHERE binds = 0\n                            and protein_name = '{target}'\n                            ORDER BY random()\n                            LIMIT 30000)\n                            UNION ALL\n                            (SELECT molecule_smiles, binds\n                            FROM parquet_scan('{train_path}')\n                            WHERE binds = 1\n                            and protein_name = '{target}'\n                            ORDER BY random()\n                            LIMIT 30000)\"\"\").df()\n    \n    df['molecule'] = df['molecule_smiles'].progress_apply(Chem.MolFromSmiles)\n    df['ecfp'] = df['molecule'].progress_apply(generate_ecfp)\n    return df[['ecfp', 'binds']]\n\nx = list(map(get_data, targets))\n\ncon.close()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class VotingModel(BaseEstimator, ClassifierMixin):\n    def __init__(self, estimators):\n        super().__init__()\n        self.estimators = estimators\n        \n    def fit(self, X, y=None):\n        return self\n    \n    def predict(self, X):\n        y_preds = [estimator.predict(X) for estimator in self.estimators]\n        return np.mean(y_preds, axis=0)\n    \n    def predict_proba(self, X):\n        y_preds = [estimator.predict_proba(X) for estimator in self.estimators]\n        return np.mean(y_preds, axis=0)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = dict(zip(targets, x))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"assert(list(data.keys()) == targets)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Split the data into train and test sets\nskf = StratifiedKFold(n_splits=5, shuffle=False)\n\nparams = {\n    \"boosting_type\": \"gbdt\",\n    \"objective\": \"binary\",\n    \"metric\": 'average_precision',\n    \"max_depth\": 8,\n    \"learning_rate\": 0.05,\n    \"n_estimators\": 1000,\n    \"colsample_bytree\": 0.8, \n    \"colsample_bynode\": 0.8,\n    \"verbose\": -1,\n    \"random_state\": 42,\n    \"device\": \"gpu\",\n}\n\ndef fit_models(df):\n    X = pd.DataFrame(df['ecfp'].to_list())\n    y = df['binds']\n    \n    fitted_models = []\n    for idx_train, idx_valid in skf.split(X, y):\n        X_train, y_train = X.iloc[idx_train], y.iloc[idx_train]\n        X_valid, y_valid = X.iloc[idx_valid], y.iloc[idx_valid]\n    \n        model = lgb.LGBMClassifier(**params)\n        model.fit(\n            X_train, y_train,\n            eval_set=[(X_valid, y_valid)],\n            callbacks=[lgb.log_evaluation(100), lgb.early_stopping(100)]\n        )\n\n        fitted_models.append(model)\n\n    return VotingModel(fitted_models)\n\nmodels = {k: fit_models(v) for k, v in data.items()}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\n\n\n# Process the test.parquet file chunk by chunk\ntest_file = '/kaggle/input/leash-BELKA/test.csv'\noutput_file = 'submission.csv'  # Specify the path and filename for the output file\n\ndef predict(df_test):\n    # Generate ECFPs for the molecule_smiles\n    df_test['molecule'] = df_test['molecule_smiles'].progress_apply(Chem.MolFromSmiles)\n    df_test['ecfp'] = df_test['molecule'].progress_apply(generate_ecfp)\n    df_final = df_test.drop(columns = ['molecule', 'molecule_smiles'])\n    \n    df_final['binds'] = df_final.progress_apply(lambda x: models[x['protein_name']].predict_proba(np.array(x['ecfp']).reshape(1, -1))[:,1][0], axis = 1)\n    return df_final[['id', 'binds']]\n\ni = 0\n# Read the test.csv file into a pandas DataFrame\nfor df in pd.read_csv(test_file, usecols = ['id', 'molecule_smiles', 'protein_name'], chunksize=100000):\n    print(f'{i}')\n    output_df = predict(df)\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))\n    i += 1","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}