nexadrug / model.py
SHREE-03's picture
Update model.py
5f57738 verified
Raw
History Blame Contribute Delete
4.59 kB
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
# 1. Load and preprocess data
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")
# 2. PyTorch Dataset
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)
# 3. Model
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)
# 4. Train
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}")
# 5. Evaluate
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}")
# 6. Save Model
torch.save(model.state_dict(), "drug_prediction_model.pth")
print("Model saved as drug_prediction_model.pth")
# 7. Predict New Sample
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}")