{"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":30732,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install duckdb\n!pip install rdkit","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-07-01T11:38:56.806082Z","iopub.execute_input":"2024-07-01T11:38:56.806682Z","iopub.status.idle":"2024-07-01T11:39:30.631261Z","shell.execute_reply.started":"2024-07-01T11:38:56.806633Z","shell.execute_reply":"2024-07-01T11:39:30.629667Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install torch-geometric","metadata":{"execution":{"iopub.status.busy":"2024-07-01T11:40:22.237882Z","iopub.execute_input":"2024-07-01T11:40:22.238351Z","iopub.status.idle":"2024-07-01T11:40:39.587079Z","shell.execute_reply.started":"2024-07-01T11:40:22.238314Z","shell.execute_reply":"2024-07-01T11:40:39.585595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Import necessary libraries\nfrom sklearn.metrics import average_precision_score\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch_geometric.data import Data, DataLoader\nfrom torch_geometric.nn import GCNConv\nimport pandas as pd\nfrom rdkit import Chem\nfrom rdkit.Chem import Descriptors\nimport duckdb\n","metadata":{"execution":{"iopub.status.busy":"2024-07-01T11:40:56.634730Z","iopub.execute_input":"2024-07-01T11:40:56.635194Z","iopub.status.idle":"2024-07-01T11:41:01.778539Z","shell.execute_reply.started":"2024-07-01T11:40:56.635156Z","shell.execute_reply":"2024-07-01T11:41:01.776702Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# File paths\ntrain_parquet_path = '/kaggle/input/leash-BELKA/train.parquet'\ntest_parquet_path = '/kaggle/input/leash-BELKA/test.parquet'\ntrain_csv_path = '/kaggle/input/leash-BELKA/train.csv'\ntest_csv_path = '/kaggle/input/leash-BELKA/test.csv'\n\n# Connect to DuckDB\ncon = duckdb.connect()\n\n# Sample 30,000 rows each for binds = 0 and binds = 1 from train.parquet\nquery_train = f\"\"\"\n    (SELECT *\n    FROM parquet_scan('{train_parquet_path}')\n    WHERE binds = 0\n    ORDER BY random()\n    LIMIT 30000)\n    UNION ALL\n    (SELECT *\n    FROM parquet_scan('{train_parquet_path}')\n    WHERE binds = 1\n    ORDER BY random()\n    LIMIT 30000)\n\"\"\"\n\n# Load data into DataFrame\ntrain_df = con.from_query(query_train).df()\n\n# Load test data without sampling\nquery_test = f\"\"\"\n    SELECT *\n    FROM parquet_scan('{test_parquet_path}')\n\"\"\"\n\ntest_df = con.from_query(query_test).df()\n\n# Close DuckDB connection\ncon.close()","metadata":{"execution":{"iopub.status.busy":"2024-07-01T11:41:03.479385Z","iopub.execute_input":"2024-07-01T11:41:03.480611Z","iopub.status.idle":"2024-07-01T11:42:04.381548Z","shell.execute_reply.started":"2024-07-01T11:41:03.480540Z","shell.execute_reply":"2024-07-01T11:42:04.380088Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Perform feature engineering\ndef calculate_descriptors(smiles):\n    mol = Chem.MolFromSmiles(smiles)\n    if mol is None:\n        return None, None\n    num_atoms = mol.GetNumAtoms()\n    mol_weight = Descriptors.MolWt(mol)\n    return num_atoms, mol_weight\n\n# Calculate descriptors for train and test data\ntrain_df['num_atoms'], train_df['mol_weight'] = zip(*train_df['molecule_smiles'].apply(calculate_descriptors))\ntest_df['num_atoms'], test_df['mol_weight'] = zip(*test_df['molecule_smiles'].apply(calculate_descriptors))\n","metadata":{"execution":{"iopub.status.busy":"2024-07-01T11:42:08.138101Z","iopub.execute_input":"2024-07-01T11:42:08.138536Z","iopub.status.idle":"2024-07-01T11:52:06.405614Z","shell.execute_reply.started":"2024-07-01T11:42:08.138503Z","shell.execute_reply":"2024-07-01T11:52:06.404009Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define features and target\nfeatures = ['num_atoms', 'mol_weight']\ntarget = 'binds'\n\nX_train = train_df[features]\ny_train = train_df[target]\nX_test = test_df[features]\n","metadata":{"execution":{"iopub.status.busy":"2024-07-01T11:52:57.664330Z","iopub.execute_input":"2024-07-01T11:52:57.664823Z","iopub.status.idle":"2024-07-01T11:52:57.695204Z","shell.execute_reply.started":"2024-07-01T11:52:57.664775Z","shell.execute_reply":"2024-07-01T11:52:57.693780Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define the GNN model\nclass GNNModel(nn.Module):\n    def __init__(self, num_features, hidden_dim, num_classes):\n        super(GNNModel, self).__init__()\n        self.conv1 = GCNConv(num_features, hidden_dim)\n        self.conv2 = GCNConv(hidden_dim, num_classes)\n\n    def forward(self, x, edge_index):\n        x = self.conv1(x, edge_index)\n        x = torch.relu(x)\n        x = self.conv2(x, edge_index)\n        return torch.sigmoid(x)","metadata":{"execution":{"iopub.status.busy":"2024-07-01T11:53:34.740514Z","iopub.execute_input":"2024-07-01T11:53:34.741045Z","iopub.status.idle":"2024-07-01T11:53:34.750721Z","shell.execute_reply.started":"2024-07-01T11:53:34.741005Z","shell.execute_reply":"2024-07-01T11:53:34.749309Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Initialize a basic GNN model\nnum_features = len(features)\nhidden_dim = 64\nnum_classes = 1  # Binary classification\n\nmodel = GNNModel(num_features, hidden_dim, num_classes)\n\n# Dummy edge index (assumed fully connected graph for simplicity)\nedge_index = torch.tensor([[0, 1, 2], [1, 0, 2]], dtype=torch.long)\n\n# Define loss function and optimizer\ncriterion = nn.BCELoss()\noptimizer = optim.Adam(model.parameters(), lr=0.001)\n\n# Convert data to tensors\nX_train_tensor = torch.tensor(X_train.values, dtype=torch.float32)\ny_train_tensor = torch.tensor(y_train.values.reshape(-1, 1), dtype=torch.float32)\n","metadata":{"execution":{"iopub.status.busy":"2024-07-01T11:53:36.114194Z","iopub.execute_input":"2024-07-01T11:53:36.115049Z","iopub.status.idle":"2024-07-01T11:53:36.262237Z","shell.execute_reply.started":"2024-07-01T11:53:36.115007Z","shell.execute_reply":"2024-07-01T11:53:36.260918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train the model\nmodel.train()\nfor epoch in range(10):  # Adjust epochs as needed\n    optimizer.zero_grad()\n    output = model(X_train_tensor, edge_index)\n    loss = criterion(output, y_train_tensor)\n    loss.backward()\n    optimizer.step()\n\n# Set model to evaluation mode\nmodel.eval()","metadata":{"execution":{"iopub.status.busy":"2024-07-01T11:53:40.443633Z","iopub.execute_input":"2024-07-01T11:53:40.444856Z","iopub.status.idle":"2024-07-01T11:53:41.077395Z","shell.execute_reply.started":"2024-07-01T11:53:40.444800Z","shell.execute_reply":"2024-07-01T11:53:41.076117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Convert test data to tensor\nX_test_tensor = torch.tensor(X_test.values, dtype=torch.float32)\n","metadata":{"execution":{"iopub.status.busy":"2024-07-01T11:54:01.102988Z","iopub.execute_input":"2024-07-01T11:54:01.103462Z","iopub.status.idle":"2024-07-01T11:54:01.116489Z","shell.execute_reply.started":"2024-07-01T11:54:01.103425Z","shell.execute_reply":"2024-07-01T11:54:01.115317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Make predictions on the test set\nwith torch.no_grad():\n    y_pred = model(X_test_tensor, edge_index).numpy().flatten()  # Flatten y_pred\n\n","metadata":{"execution":{"iopub.status.busy":"2024-07-01T11:55:26.567598Z","iopub.execute_input":"2024-07-01T11:55:26.568157Z","iopub.status.idle":"2024-07-01T11:55:28.269385Z","shell.execute_reply.started":"2024-07-01T11:55:26.568115Z","shell.execute_reply":"2024-07-01T11:55:28.267949Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create submission DataFrame\nsubmission_df = pd.DataFrame({'id': test_df['id'], 'binds': y_pred})\n\n# Save submission file\nsubmission_df.to_csv('submission_gnn.csv', index=False)\nsubmission_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-07-01T11:55:39.841735Z","iopub.execute_input":"2024-07-01T11:55:39.842296Z","iopub.status.idle":"2024-07-01T11:55:43.338665Z","shell.execute_reply.started":"2024-07-01T11:55:39.842256Z","shell.execute_reply":"2024-07-01T11:55:43.337396Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}