Although one can find machine learning examples using scikit-learn, PyTorch, and TensorFlow separately, there aren't really examples where one can see a comparison for these different frameworks on a standard dataset all in one place. But I think it is instructive to see how to use the same variables from the same dataset to accomplish the same prediction task. And that is what we're going to do in this post. We're going to use a very standard diabetes dataset to create basic example classification models based on seven variables to predict if someone is likely to be diabetic. The Github repository is here, the full notebook used to build the models is here, and the deployed Streamlit app can be accessed here.
The seven predictor variables are:
- Number of pregnancies (the data was trained on all female respondents)
- Glucose
- Skin thickness
- Age
- BMI
- Blood Pressure
- Insulin
- scikit-learn (Random Forest)
- scikit-learn (Gradient Boost)
- PyTorch (Neural Network)
- TensorFlow (Neural Network)
rf_model = RandomForestClassifier(n_estimators=100, random_state=78)
rf_model= rf_model.fit(X_train, y_train)
predictions = rf_model.predict(X_test)
filename = 'rf.sav' pickle.dump(rf_model, open(filename, 'wb'))
filename = 'rf.sav' print(classification_report(y_test, predictions))
precision recall f1-score support
0 0.80 0.86 0.83 129
1 0.66 0.56 0.60 63
accuracy 0.76 192
macro avg 0.73 0.71 0.72 192
weighted avg 0.75 0.76 0.75 192
cm = confusion_matrix(y_test, predictions) disp = ConfusionMatrixDisplay(confusion_matrix=cm) disp.plot()
# Create the gradient boost classifier instance gb_model = GradientBoostingClassifier(random_state=78) # Fit the model gb_model = gb_model.fit(X_train, y_train) # Make predictions using the testing data predictions = gb_model.predict(X_test) # Save the model for the Streamlit app filename = 'gb.sav' pickle.dump(gb_model, open(filename, 'wb')) # Create classification report print(classification_report(y_test, predictions))
precision recall f1-score support
0 0.79 0.87 0.83 129
1 0.66 0.52 0.58 63
accuracy 0.76 192
macro avg 0.72 0.70 0.71 192
weighted avg 0.75 0.76 0.75 192
cm = confusion_matrix(y_test, predictions) disp = ConfusionMatrixDisplay(confusion_matrix=cm) disp.plot()
import torch import torch.nn as nn import torch.optim as optim from sklearn.preprocessing import StandardScaler
scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test)
X_train_scaled = torch.tensor(X_train_scaled, dtype=torch.float32) X_test_scaled = torch.tensor(X_test_scaled, dtype=torch.float32) y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32).unsqueeze(1) y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32).unsqueeze(1)
class DiabetesPTModel(nn.Module): def __init__(self): super(DiabetesPTModel, self).__init__() self.fc1 = nn.Linear(7, 16) self.fc2 = nn.Linear(16, 8) self.fc3 = nn.Linear(8, 1) self.sigmoid = nn.Sigmoid() def forward(self, x): x = torch.relu(self.fc1(x)) x = torch.relu(self.fc2(x)) x = self.sigmoid(self.fc3(x)) return x
pt_model = DiabetesPTModel() criterion = nn.BCELoss() optimizer = optim.Adam(model.parameters(), lr=0.001)
num_epochs = 100 for epoch in range(num_epochs): pt_model.train() optimizer.zero_grad() outputs = pt_model(X_train_scaled) loss = criterion(outputs, y_train_tensor) loss.backward() optimizer.step() if (epoch+1) % 10 == 0: print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')
pt_model.eval() with torch.no_grad(): predictions = pt_model(X_test_scaled) predictions = predictions.round() accuracy = (predictions.eq(y_test_tensor).sum() / float(y_test_tensor.shape[0])).item() print(f'Accuracy: {accuracy:.4f}')
torch.save(pt_model.state_dict(), 'diabetes_model_pt.pth') with open('scaler.pkl', 'wb') as f: pickle.dump(scaler, f)
with torch.no_grad(): predictions = model(X_test_scaled) predictions = predictions.round() print(classification_report(y_test_predictions, predictions))
precision recall f1-score support
0 0.79 0.88 0.83 129
1 0.67 0.52 0.59 63
accuracy 0.76 192
macro avg 0.73 0.70 0.71 192
weighted avg 0.75 0.76 0.75 192
cm = confusion_matrix(y_test_tensor, predictions) disp = ConfusionMatrixDisplay(confusion_matrix=cm) disp.plot()
import tensorflow as tf tf_model = tf.keras.Sequential([ tf.keras.layers.Dense(16, activation='relu', input_shape=(7,)), tf.keras.layers.Dense(8, activation='relu'), tf.keras.layers.Dense(1, activation='sigmoid') ])
tf_model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
tf_model.fit(X_train_scaled, y_train, epochs=100, batch_size=32, validation_split=0.2)
loss, accuracy = model.evaluate(X_test_scaled, y_test) print(f'Accuracy: {accuracy:.4f}')
tf_model.save('diabetes_model_tf.h5')
predictions = tf_model.predict(X_test_scaled).round() print(classification_report(y_test, predictions))
precision recall f1-score support
0 0.81 0.83 0.82 129
1 0.63 0.60 0.62 63
accuracy 0.76 192
macro avg 0.72 0.72 0.72 192
weighted avg 0.75 0.76 0.75 192
cm = confusion_matrix(y_test, predictions) disp = ConfusionMatrixDisplay(confusion_matrix=cm) disp.plot()
importances = rf_model.feature_importances_ importances_sorted = sorted(zip(rf_model.feature_importances_, X.columns), reverse=True) # Plot the feature importances features = sorted(zip(X.columns, importances), key = lambda x: x[1]) cols = [f[0] for f in features] width = [f[1] for f in features] fig, ax = plt.subplots() fig.set_size_inches(8,6) plt.margins(y=0.001) ax.barh(y=cols, width=width) plt.show()
No comments:
Post a Comment