| Name | Size | Uploaded | Xet hash |
|---|---|---|---|
| README.md | 6.15 kB xet | 86226080 | |
| label_encoder.pkl | 275 Bytes xet | 639f3736 | |
| preprocessor.pkl | 3.22 kB xet | 09a0457f | |
| random_forest_final_model.joblib | 60.8 kB xet | 98aa2bd6 | |
| resnet-18.pth | 134 MB xet | c34f68c9 |
Model Card for DSI TB DRUG RESISTANCE PREDICTION
DSI model is a classification model that predicts drug resistance in TB patients 2 months after they start treatment.
Model Details
Model Description
Month 2 Sputum Conversion Prediction (Tabular + CXR images)
The Drug Resistance Prediction model is RandomForest based predictive model designed to identify tuberculosis (TB) patients who are likely to exhibit drug resistance two months after initiating treatment. Drug-resistant TB patients do not respond to the standard first-line medications, and their TB status remains MTBc-positive rather than converting to MTBc-negative as expected. The DSI model aims to predict this resistance early, using demographic and clinical information collected at baseline (month 0). By identifying patients at high risk of drug resistance, the model supports clinicians in making timely decisions—such as initiating a more aggressive treatment regimen—potentially improving patient outcomes and preventing prolonged infectiousness.
- Developed by: Marconi Lab
- Funded by:
- Shared by: Marconi Lab
- Model type: LightGBM classifier
- License: MIT
Model Sources
- Repository: https://github.com/Marconi-Lab/DSI.git
Intended Use
- Primary use case: Early prediction of sputum conversion to guide treatment monitoring.
- Intended users: Healthcare researchers, clinicians
- Input:
- 21 structured tabular features (demographics, vitals, symptoms)
- 512-dimensional feature vector from CXR image
- Output: Binary prediction
1 = MTBC Negative0 = MTBC Positive
Training Data
- Features:
- Numerical:
AGE_YEARS,BMI,TEMPERATURE_CELICIUS,HOUSEHOLD_DENSITY - Binary categorical:
SEX,HIV_STATUS, etc. - Multiclass categorical:
EDUCATION_LEVEL,OWNERSHIP,SIGHT_OF_TB_DISEASE - Image feature: 512-dim vector from pretrained ResNet-18
- Numerical:
- Preprocessing:
- StandardScaler for numerical features
- OneHotEncoder for categorical features
- ResNet-18 for image embeddings
Training & Evaluation
- Tabular Preprocessing:
ColumnTransformer - Image Features: Extracted using pretrained
timm.create_model('resnet18') - Fusion:
np.hstackof tabular and image feature vectors - Label Encoding:
LabelEncoderon2_MONTHS - Models Evaluated: Random Forest, AdaBoost, Gradient Boosting, XGBoost
- Best model:
RandomForestClassifier(class_weight='balanced')
Results (Test Set)
| Metric | Value |
|---|---|
| Accuracy | 0.9091 |
| Recall (MTBc Negative) | 1.00 |
| Recall (MTBc Positive) | 0.00 |
| F1 Score (MTBc Negative) | 0.95 |
| F1 Score (MTBc Positive) | 0.00 |
| Weighted F1 Score | 0.87 |
Confusion Matrix:
| Predicted MTBc Negative | Predicted MTBc Positive | |
|---|---|---|
| Actual MTBc Positive | 10 | 0 |
| Actual MTBc Negative | 1 | 0 |
Limitations
- Severe class imbalance (only 1 MTBC+ case in train/test)
- Poor generalization to positive cases
- Small dataset (35 total samples: 24 train, 11 test)
Inference Example
import torch
import timm
import joblib
import pickle
import numpy as np
import pandas as pd
from PIL import Image
from torchvision import transforms
# Load Saved Artifacts
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# Load image feature extractor
image_model = timm.create_model("resnet18", pretrained=False, num_classes=3)
image_model.load_state_dict(torch.load("resnet-18.pth", map_location=device)["model_state_dict"])
image_model.fc = torch.nn.Identity()
image_model = image_model.to(device)
image_model.eval()
# Load Random Forest model and preprocessing tools
rf_model = joblib.load("random_forest_final_model.joblib")
with open("preprocessor.pkl", "rb") as f:
preprocessor = pickle.load(f)
with open("label_encoder.pkl", "rb") as f:
label_encoder = pickle.load(f)
# Preprocessing Function
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
])
def extract_image_features(image_path):
img = Image.open(image_path).convert("RGB")
img_tensor = transform(img).unsqueeze(0).to(device)
with torch.no_grad():
features = image_model(img_tensor).squeeze().cpu().numpy()
return features
# Inference Function
def predict(image_path, tabular_input_dict):
# Extract image features
image_features = extract_image_features(image_path)
# Process tabular input
tabular_df = pd.DataFrame([tabular_input_dict])
tabular_processed = preprocessor.transform(tabular_df)
# Concatenate tabular and image features
combined_input = np.hstack([tabular_processed, image_features.reshape(1, -1)])
# Predict and decode label
y_pred = rf_model.predict(combined_input)
predicted_label = label_encoder.inverse_transform(y_pred)[0]
return predicted_label
# Example Usage
tabular_input = {
"SEX": "M",
"AGE_YEARS": 35,
"BMI": 16.5,
"HIV_STATUS": "NEGATIVE",
"HAS_DIABETES_YES/NO": "NO",
"SMOKES_CIGARETTES_YES/NO": "YES",
"CONSUMES_ALCOHOL_YES/NO": "NO",
"SIGHT_OF_TB_DISEASE": "LUNGS",
"TEMPERATURE_CELICIUS": 39.0,
"COUGH": "YES",
"FEVER": "YES",
"WEIGHT_LOSS": "YES",
"NIGHT_SWEATS": "YES",
"DYSPENA": "NO",
"CHEST_PAIN": "YES",
"HEMOPTYSIS": "NO",
"CONSUMED_ANTIBIOTICS_IN_THE_PAST_6_MONTHS__YES/NO": "NO",
"OWNERSHIP": "RENTED",
"EDUCATION_LEVEL": "TERTIARY EDUCATION",
"HOUSEHOLD_DENSITY": 6.0
}
prediction = predict("example_cxr.jpg", tabular_input)
print("Predicted TB Conversion at Month 2:", prediction)
Model Card Authors
Marconi Lab
Model Card Contact
- Total size
- 134 MB
- Files
- 5
- Last updated
- Jun 16
- Pre-warmed CDN
- US EU US EU