| import pandas as pd |
| import numpy as np |
| import torch |
| import torch.nn as nn |
| from torch.utils.data import Dataset, DataLoader |
| from sklearn.model_selection import train_test_split |
| from sklearn.preprocessing import StandardScaler |
| from sklearn.metrics import mean_squared_error |
| import joblib |
|
|
| |
| dfs = [] |
| for i in range(1, 12): |
| try: |
| df = pd.read_csv(f'SAMPLE{i}.csv') |
| df.columns = df.columns.str.strip() |
| dfs.append(df) |
| except FileNotFoundError: |
| print(f"SAMPLE{i}.csv not found") |
|
|
| df = pd.concat(dfs, ignore_index=True) |
|
|
| columns_to_drop = ['cid', 'cmpdname', 'cmpdsynonym', 'inchi', 'smiles', 'inchikey', 'iupacname', |
| 'meshheadings', 'annothits', 'annotation', 'mf', 'aids', 'cidcdate', 'sidsrcname', 'depcatg'] |
| X = df.drop(columns=columns_to_drop, axis=1, errors='ignore') |
| target_columns = ['mw', 'polararea'] |
| target_columns = [col for col in target_columns if col in df.columns] |
| y = df[target_columns].apply(pd.to_numeric, errors='coerce') |
|
|
| numeric_cols = X.select_dtypes(include=['number']).columns |
| for col in numeric_cols: |
| X[col] = pd.to_numeric(X[col], errors='coerce') |
| X[col] = X[col].fillna(X[col].mean()) |
| X = X.select_dtypes(include=['number']) |
|
|
| X = X[y.notna().all(axis=1)] |
| y = y[y.notna().all(axis=1)] |
|
|
| X_train, X_test, y_train, y_test = train_test_split(X.values, y.values, test_size=0.2, random_state=42) |
|
|
| scaler = StandardScaler() |
| X_train_scaled = scaler.fit_transform(X_train) |
| X_test_scaled = scaler.transform(X_test) |
|
|
| joblib.dump(scaler, "scaler.h5") |
|
|
| |
| class DrugDataset(Dataset): |
| def __init__(self, X, y): |
| self.X = torch.tensor(X, dtype=torch.float32) |
| self.y = torch.tensor(y, dtype=torch.float32) |
|
|
| def __len__(self): |
| return len(self.X) |
|
|
| def __getitem__(self, idx): |
| return self.X[idx], self.y[idx] |
|
|
| train_dataset = DrugDataset(X_train_scaled, y_train) |
| test_dataset = DrugDataset(X_test_scaled, y_test) |
|
|
| train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) |
| test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False) |
|
|
| |
| class MultiOutputRegressorNN(nn.Module): |
| def __init__(self, input_dim, output_dim): |
| super().__init__() |
| self.network = nn.Sequential( |
| nn.Linear(input_dim, 64), |
| nn.ReLU(), |
| nn.Linear(64, 64), |
| nn.ReLU(), |
| nn.Linear(64, output_dim) |
| ) |
|
|
| def forward(self, x): |
| return self.network(x) |
|
|
| device = torch.device("cuda" if torch.cuda.is_available() else "cpu") |
| model = MultiOutputRegressorNN(input_dim=X.shape[1], output_dim=len(target_columns)).to(device) |
|
|
| |
| criterion = nn.MSELoss() |
| optimizer = torch.optim.Adam(model.parameters(), lr=0.001) |
|
|
| for epoch in range(100): |
| model.train() |
| total_loss = 0 |
| for X_batch, y_batch in train_loader: |
| X_batch, y_batch = X_batch.to(device), y_batch.to(device) |
| optimizer.zero_grad() |
| output = model(X_batch) |
| loss = criterion(output, y_batch) |
| loss.backward() |
| optimizer.step() |
| total_loss += loss.item() |
| if (epoch + 1) % 10 == 0: |
| print(f"Epoch {epoch+1}, Loss: {total_loss / len(train_loader):.4f}") |
|
|
| |
| model.eval() |
| all_preds, all_targets = [], [] |
| with torch.no_grad(): |
| for X_batch, y_batch in test_loader: |
| X_batch = X_batch.to(device) |
| preds = model(X_batch).cpu().numpy() |
| all_preds.append(preds) |
| all_targets.append(y_batch.numpy()) |
|
|
| y_pred = np.vstack(all_preds) |
| y_true = np.vstack(all_targets) |
|
|
| for i, col in enumerate(target_columns): |
| rmse = mean_squared_error(y_true[:, i], y_pred[:, i], squared=False) |
| print(f"RMSE for {col}: {rmse:.2f}") |
|
|
| |
| torch.save(model.state_dict(), "drug_prediction_model.pth") |
| print("Model saved as drug_prediction_model.pth") |
|
|
| |
| new_data = pd.DataFrame({ |
| 'polararea': [17.1], |
| 'complexity': [0.0], |
| 'xlogp': [-0.32], |
| 'heavycnt': [2], |
| 'hbonddonor': [1], |
| 'hbondacc': [1], |
| 'rotbonds': [0], |
| 'exactmass': [46.0689], |
| 'monoisotopicmass': [46.0689], |
| 'charge': [0], |
| 'covalentunitcnt': [1] |
| }) |
|
|
| for col in X.columns: |
| if col not in new_data.columns: |
| new_data[col] = 0 |
| new_data = new_data[X.columns] |
| new_data_scaled = scaler.transform(new_data) |
| new_tensor = torch.tensor(new_data_scaled, dtype=torch.float32).to(device) |
|
|
| model.eval() |
| with torch.no_grad(): |
| prediction = model(new_tensor).cpu().numpy()[0] |
|
|
| for i, col in enumerate(target_columns): |
| print(f"Predicted {col}: {prediction[i]:.2f}") |
|
|