{"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":30698,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"We shall start with the installation of necessary tools. <br><br>\n**DuckDB is an open-source, in-memory database system optimized for fast analytical querying and low memory usage. It's lightweight, embeddable, and seamlessly integrates with popular programming languages like Python and R. DuckDB excels in executing rapid SQL queries on large datasets, making it ideal for data exploration and interactive analysis tasks.**","metadata":{"_kg_hide-output":true}},{"cell_type":"code","source":"!pip install duckdb","metadata":{"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"**RDKit is a widely-used open-source toolkit for cheminformatics. It offers various functions for working with chemical structures and data, including molecular representation, substructure searching, and compound library handling. RDKit is popular in pharmaceutical research and drug discovery due to its comprehensive features and easy integration with Python.**","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install rdkit","metadata":{"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **INSTALLATION**","metadata":{}},{"cell_type":"code","source":"import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport numpy as np\nfrom tqdm import tqdm\nimport duckdb\nfrom rdkit import Chem\nfrom rdkit.Chem import AllChem\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import OneHotEncoder\nfrom xgboost import XGBClassifier\nfrom catboost import CatBoostClassifier\nfrom lightgbm import LGBMClassifier\nfrom sklearn.metrics import average_precision_score\n\nfrom sklearn.svm import SVC\nfrom sklearn.ensemble import StackingClassifier, VotingClassifier, BaggingClassifier, RandomForestClassifier\nfrom sklearn.neural_network import MLPClassifier\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.calibration import CalibratedClassifierCV","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# PREPROCESSING AND CLEANING","metadata":{}},{"cell_type":"code","source":"%%time\ntrain_path = '/kaggle/input/leash-BELKA/train.parquet'\ntest_path = '/kaggle/input/leash-BELKA/test.parquet'\n\ncon = duckdb.connect()\n\ndf = 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\ncon.close()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n# Convert SMILES to RDKit molecules\ndf['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\ndf['ecfp'] = df['molecule'].apply(generate_ecfp)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['ecfp'].head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"RANDOM_STATE = 42","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n# One-hot encode the protein_name\nonehot_encoder = OneHotEncoder(sparse_output=False)\nprotein_onehot = onehot_encoder.fit_transform(df['protein_name'].values.reshape(-1, 1))\n\n# Combine ECFPs and one-hot encoded protein_name\nX = [ecfp + protein for ecfp, protein in zip(df['ecfp'].tolist(), protein_onehot.tolist())]\ny = df['binds'].tolist()\n\n# Split the data into train, validation and test sets\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=RANDOM_STATE)\n\nX_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.25, random_state=RANDOM_STATE)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model Definition ","metadata":{}},{"cell_type":"code","source":"NUMBER_OF_MODELS = 3\n# Create and train the ensemble models\ncatboost_model = CatBoostClassifier(iterations=500, random_state=RANDOM_STATE)\nlgbm_model = LGBMClassifier(random_state=RANDOM_STATE)\nxgb_model = XGBClassifier(random_state=RANDOM_STATE, n_jobs=-1,)\n\nmodels = [catboost_model, lgbm_model, xgb_model]\nfor model in models:\n    model.fit(X_train, y_train)","metadata":{"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training of the Ensemble","metadata":{}},{"cell_type":"code","source":"predictions_test = []\n# Calibrate probabilities on validation set\nfor model in models:\n    calibrated_model = CalibratedClassifierCV(model, method='sigmoid', cv='prefit')\n    calibrated_model.fit(X_val, y_val)\n    # Evaluate calibrated model on test set\n    calibrated_probabilities = calibrated_model.predict_proba(X_test)[:, 1]\n    predictions_test.append(calibrated_probabilities)\n    \n# Ensemble predictions for the test set\nensemble_predictions_test = np.mean(predictions_test, axis=0)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Calculate the mean average precision\nmap_score = average_precision_score(y_test, ensemble_predictions_test)\nprint(f\"Mean Average Precision (mAP): {map_score:.8f}\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training","metadata":{}},{"cell_type":"code","source":"import os\n# Process the test.parquet file chunk by chunk sinc the file is huge\ntest_file = '/kaggle/input/leash-BELKA/test.csv'\noutput_file = 'submission.csv'  # Specify the path and filename for the output file\n\n\n\n# Read the test.csv file into a pandas DataFrame\n# Wrap the loop with tqdm to display progress\nfor df_test in tqdm(pd.read_csv(test_file, chunksize=10_000)):\n    \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    \n    predictions_test = []\n    # Calibrate probabilities on validation set\n    for model in models:\n        calibrated_model = CalibratedClassifierCV(model, method='sigmoid', cv='prefit')\n        calibrated_model.fit(X_val, y_val)\n        # Evaluate calibrated model on test set\n        calibrated_probabilities = calibrated_model.predict_proba(X_test)[:, 1]\n        predictions_test.append(calibrated_probabilities)\n\n    # Ensemble predictions for the test set\n    ensemble_predictions_test = np.mean(predictions_test, axis=0)\n\n# Create a DataFrame with 'id' and 'probability' columns\n    output_df = pd.DataFrame({'id': df_test['id'], 'binds': ensemble_predictions_test})\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":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}