mlforgex 1.0.2__tar.gz → 1.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mlforgex-1.0.2/mlforgex.egg-info → mlforgex-1.0.3}/PKG-INFO +1 -1
- {mlforgex-1.0.2 → mlforgex-1.0.3}/mlforge/train.py +84 -36
- {mlforgex-1.0.2 → mlforgex-1.0.3/mlforgex.egg-info}/PKG-INFO +1 -1
- {mlforgex-1.0.2 → mlforgex-1.0.3}/setup.py +1 -1
- {mlforgex-1.0.2 → mlforgex-1.0.3}/LICENSE +0 -0
- {mlforgex-1.0.2 → mlforgex-1.0.3}/README.md +0 -0
- {mlforgex-1.0.2 → mlforgex-1.0.3}/mlforge/__init__.py +0 -0
- {mlforgex-1.0.2 → mlforgex-1.0.3}/mlforge/predict.py +0 -0
- {mlforgex-1.0.2 → mlforgex-1.0.3}/mlforgex.egg-info/SOURCES.txt +0 -0
- {mlforgex-1.0.2 → mlforgex-1.0.3}/mlforgex.egg-info/dependency_links.txt +0 -0
- {mlforgex-1.0.2 → mlforgex-1.0.3}/mlforgex.egg-info/entry_points.txt +0 -0
- {mlforgex-1.0.2 → mlforgex-1.0.3}/mlforgex.egg-info/requires.txt +0 -0
- {mlforgex-1.0.2 → mlforgex-1.0.3}/mlforgex.egg-info/top_level.txt +0 -0
- {mlforgex-1.0.2 → mlforgex-1.0.3}/pyproject.toml +0 -0
- {mlforgex-1.0.2 → mlforgex-1.0.3}/setup.cfg +0 -0
- {mlforgex-1.0.2 → mlforgex-1.0.3}/test/test_basic.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mlforgex
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.3
|
|
4
4
|
Summary: Lightweight ML utility for automated training, evaluation, and prediction with CLI and Python API support
|
|
5
5
|
Home-page: https://github.com/yourusername/mlforge
|
|
6
6
|
Author: Priyanshu Mathur
|
|
@@ -38,7 +38,7 @@ def train_model(data_path, dependent_feature,rmse_prob,f1_prob,n_jobs=-1,n_iter=
|
|
|
38
38
|
# os.remove(data_path)
|
|
39
39
|
df.head()
|
|
40
40
|
print("Data loaded successfully")
|
|
41
|
-
|
|
41
|
+
df.replace(["", "NA", "na", "N/A", "n/a", "?", "--"], np.nan, inplace=True)
|
|
42
42
|
for i in df.columns:
|
|
43
43
|
if df[i].dtype=="object":
|
|
44
44
|
df[i] = df[i].fillna(df[i].mode()[0])
|
|
@@ -117,6 +117,8 @@ def train_model(data_path, dependent_feature,rmse_prob,f1_prob,n_jobs=-1,n_iter=
|
|
|
117
117
|
print("Categorical features : ",cat_features)
|
|
118
118
|
print("Numerical features : ",num_features)
|
|
119
119
|
if classification:
|
|
120
|
+
is_multiclass = len(set(y_train)) > 2
|
|
121
|
+
average_type = "weighted" if is_multiclass else "binary"
|
|
120
122
|
print("Balancing the dataset...")
|
|
121
123
|
if mild :
|
|
122
124
|
from imblearn.under_sampling import RandomUnderSampler
|
|
@@ -245,7 +247,7 @@ def train_model(data_path, dependent_feature,rmse_prob,f1_prob,n_jobs=-1,n_iter=
|
|
|
245
247
|
"AdaBoostClassifier":AdaBoostClassifier(),
|
|
246
248
|
"XGBClassifier":XGBClassifier(),
|
|
247
249
|
"KNeighborsClassifier":KNeighborsClassifier(),
|
|
248
|
-
"SVC":SVC()
|
|
250
|
+
"SVC":SVC(probability=True)
|
|
249
251
|
}
|
|
250
252
|
|
|
251
253
|
for i in range(len(list(models))):
|
|
@@ -258,15 +260,26 @@ def train_model(data_path, dependent_feature,rmse_prob,f1_prob,n_jobs=-1,n_iter=
|
|
|
258
260
|
|
|
259
261
|
# Training set performance
|
|
260
262
|
model_train_accuracy = accuracy_score(y_train, y_train_pred) # Calculate Accuracy
|
|
261
|
-
model_train_f1 = f1_score(y_train, y_train_pred, average=
|
|
262
|
-
model_train_precision = precision_score(y_train, y_train_pred) # Calculate Precision
|
|
263
|
-
model_train_recall = recall_score(y_train, y_train_pred) # Calculate Recall
|
|
264
|
-
|
|
263
|
+
model_train_f1 = f1_score(y_train, y_train_pred, average=average_type) # Calculate F1-score
|
|
264
|
+
model_train_precision = precision_score(y_train, y_train_pred, average=average_type) # Calculate Precision
|
|
265
|
+
model_train_recall = recall_score(y_train, y_train_pred, average=average_type) # Calculate Recall
|
|
266
|
+
if average_type == "binary":
|
|
267
|
+
y_train_prob = model.predict_proba(x_train)[:,1]
|
|
268
|
+
model_train_rocauc_score = roc_auc_score(y_train, y_train_prob)
|
|
269
|
+
else:
|
|
270
|
+
y_train_prob=model.predict_proba(x_train)
|
|
271
|
+
model_train_rocauc_score = roc_auc_score(y_train, y_train_prob,multi_class='ovr',average=average_type) #Calculate Roc Auc Score
|
|
265
272
|
# Test set performance
|
|
266
273
|
model_test_accuracy = accuracy_score(y_test, y_test_pred) # Calculate Accuracy
|
|
267
|
-
model_test_f1 = f1_score(y_test, y_test_pred, average=
|
|
268
|
-
model_test_precision = precision_score(y_test, y_test_pred) # Calculate Precision
|
|
269
|
-
model_test_recall = recall_score(y_test, y_test_pred) # Calculate
|
|
274
|
+
model_test_f1 = f1_score(y_test, y_test_pred, average=average_type) # Calculate F1-score
|
|
275
|
+
model_test_precision = precision_score(y_test, y_test_pred, average=average_type) # Calculate Precision
|
|
276
|
+
model_test_recall = recall_score(y_test, y_test_pred, average=average_type) # Calculate Recall
|
|
277
|
+
if average_type == "binary":
|
|
278
|
+
y_test_prob = model.predict_proba(x_test)[:,1]
|
|
279
|
+
model_test_rocauc_score = roc_auc_score(y_test, y_test_prob)
|
|
280
|
+
else:
|
|
281
|
+
y_test_prob=model.predict_proba(x_test)
|
|
282
|
+
model_test_rocauc_score = roc_auc_score(y_test, y_test_prob,multi_class='ovr',average=average_type) #Calculate Roc Auc Score
|
|
270
283
|
|
|
271
284
|
model_dict.append({
|
|
272
285
|
"model":list(models.keys())[i],
|
|
@@ -276,7 +289,6 @@ def train_model(data_path, dependent_feature,rmse_prob,f1_prob,n_jobs=-1,n_iter=
|
|
|
276
289
|
"test_f1": model_test_f1,
|
|
277
290
|
"tuned":False
|
|
278
291
|
})
|
|
279
|
-
model_test_rocauc_score = roc_auc_score(y_test, y_test_pred) #Calculate Roc
|
|
280
292
|
|
|
281
293
|
|
|
282
294
|
# print(list(models.keys())[i])
|
|
@@ -447,7 +459,7 @@ def train_model(data_path, dependent_feature,rmse_prob,f1_prob,n_jobs=-1,n_iter=
|
|
|
447
459
|
["LogisticRegression", {
|
|
448
460
|
'penalty': ['l1', 'l2', 'elasticnet', 'none'],
|
|
449
461
|
'C': np.logspace(-4, 4, 20),
|
|
450
|
-
'solver': ['
|
|
462
|
+
'solver': ['lbfgs', 'liblinear', 'saga'],
|
|
451
463
|
'max_iter': [100, 200, 500, 1000],
|
|
452
464
|
'class_weight': [None, 'balanced'],
|
|
453
465
|
'l1_ratio': [0, 0.25, 0.5, 0.75, 1] # For elasticnet
|
|
@@ -597,7 +609,6 @@ def train_model(data_path, dependent_feature,rmse_prob,f1_prob,n_jobs=-1,n_iter=
|
|
|
597
609
|
for i in range(len(list(models))):
|
|
598
610
|
model = list(models.values())[i]
|
|
599
611
|
model.fit(x_train, y_train) # Train model
|
|
600
|
-
|
|
601
612
|
# Make predictions
|
|
602
613
|
y_train_pred = model.predict(x_train)
|
|
603
614
|
y_test_pred = model.predict(x_test)
|
|
@@ -658,22 +669,38 @@ def train_model(data_path, dependent_feature,rmse_prob,f1_prob,n_jobs=-1,n_iter=
|
|
|
658
669
|
|
|
659
670
|
# Training set performance
|
|
660
671
|
model_train_accuracy = accuracy_score(y_train, y_train_pred) # Calculate Accuracy
|
|
661
|
-
model_train_f1 = f1_score(y_train, y_train_pred, average=
|
|
662
|
-
model_train_precision = precision_score(y_train, y_train_pred) # Calculate Precision
|
|
663
|
-
model_train_recall = recall_score(y_train, y_train_pred) # Calculate Recall
|
|
664
|
-
|
|
672
|
+
model_train_f1 = f1_score(y_train, y_train_pred, average=average_type) # Calculate F1-score
|
|
673
|
+
model_train_precision = precision_score(y_train, y_train_pred,average=average_type) # Calculate Precision
|
|
674
|
+
model_train_recall = recall_score(y_train, y_train_pred,average=average_type) # Calculate Recall
|
|
675
|
+
if average_type == "binary":
|
|
676
|
+
y_train_prob = model.predict_proba(x_train)[:,1]
|
|
677
|
+
model_train_rocauc_score = roc_auc_score(y_train, y_train_prob)
|
|
678
|
+
else:
|
|
679
|
+
y_train_prob=model.predict_proba(x_train)
|
|
680
|
+
model_train_rocauc_score = roc_auc_score(y_train, y_train_prob, multi_class='ovr', average=average_type)
|
|
665
681
|
# Test set performance
|
|
666
682
|
model_test_accuracy = accuracy_score(y_test, y_test_pred) # Calculate Accuracy
|
|
667
|
-
model_test_f1 = f1_score(y_test, y_test_pred, average=
|
|
668
|
-
model_test_precision = precision_score(y_test, y_test_pred) # Calculate Precision
|
|
669
|
-
model_test_recall = recall_score(y_test, y_test_pred) # Calculate
|
|
670
|
-
|
|
683
|
+
model_test_f1 = f1_score(y_test, y_test_pred, average=average_type) # Calculate F1-score
|
|
684
|
+
model_test_precision = precision_score(y_test, y_test_pred,average=average_type) # Calculate Precision
|
|
685
|
+
model_test_recall = recall_score(y_test, y_test_pred,average=average_type) # Calculate Recall
|
|
686
|
+
if average_type == "binary":
|
|
687
|
+
y_test_prob = model.predict_proba(x_test)[:,1]
|
|
688
|
+
model_test_rocauc_score = roc_auc_score(y_test, y_test_prob)
|
|
689
|
+
else:
|
|
690
|
+
y_test_prob=model.predict_proba(x_test)
|
|
691
|
+
model_test_rocauc_score = roc_auc_score(y_test, y_test_prob, multi_class='ovr', average=average_type)
|
|
671
692
|
model_dict={
|
|
672
693
|
"model":list(models.keys())[i],
|
|
673
694
|
"train_accuracy": model_train_accuracy,
|
|
674
695
|
"train_f1": model_train_f1,
|
|
696
|
+
"train_precision": model_train_precision,
|
|
697
|
+
"train_recall": model_train_recall,
|
|
698
|
+
"train_rocauc": model_train_rocauc_score,
|
|
675
699
|
"test_accuracy": model_test_accuracy,
|
|
676
700
|
"test_f1": model_test_f1,
|
|
701
|
+
"test_precision": model_test_precision,
|
|
702
|
+
"test_recall": model_test_recall,
|
|
703
|
+
"test_rocauc": model_test_rocauc_score,
|
|
677
704
|
"tuned":True
|
|
678
705
|
}
|
|
679
706
|
best_models_copy = pd.concat(
|
|
@@ -727,7 +754,7 @@ def train_model(data_path, dependent_feature,rmse_prob,f1_prob,n_jobs=-1,n_iter=
|
|
|
727
754
|
if classification:
|
|
728
755
|
combined_score_ranking=combined_score_ranking[combined_score_ranking["train_f1"]-combined_score_ranking["test_f1"]<0.15]
|
|
729
756
|
# print("====="*35)
|
|
730
|
-
print(combined_score_ranking.iloc[0:1,:])
|
|
757
|
+
# print(combined_score_ranking.iloc[0:1,:])
|
|
731
758
|
best_model_name = combined_score_ranking.iloc[0]["model"]
|
|
732
759
|
best_param_dict = None
|
|
733
760
|
for name, params in best_params:
|
|
@@ -742,7 +769,6 @@ def train_model(data_path, dependent_feature,rmse_prob,f1_prob,n_jobs=-1,n_iter=
|
|
|
742
769
|
print("Saving the model and preprocessor...")
|
|
743
770
|
model_path = os.path.join(artifacts_path, "model.pkl")
|
|
744
771
|
preprocessor_path = os.path.join(artifacts_path, "preprocessor.pkl")
|
|
745
|
-
encoder_path = os.path.join(artifacts_path, "encoder.pkl")
|
|
746
772
|
|
|
747
773
|
with open(model_path, "wb") as f:
|
|
748
774
|
pickle.dump(model, f)
|
|
@@ -751,27 +777,39 @@ def train_model(data_path, dependent_feature,rmse_prob,f1_prob,n_jobs=-1,n_iter=
|
|
|
751
777
|
pickle.dump(preprocessor, f)
|
|
752
778
|
|
|
753
779
|
if classification:
|
|
780
|
+
encoder_path = os.path.join(artifacts_path, "encoder.pkl")
|
|
754
781
|
with open(encoder_path, "wb") as f:
|
|
755
782
|
pickle.dump(le, f)
|
|
756
783
|
response = {
|
|
757
|
-
"
|
|
784
|
+
"Message": "Training completed successfully",
|
|
758
785
|
"Problem_type":"Classification",
|
|
759
|
-
"model_metrics": {
|
|
760
786
|
"Model": combined_score_ranking.iloc[0]["model"],
|
|
761
787
|
"Train_accuracy": float(combined_score_ranking.iloc[0]["train_accuracy"]),
|
|
762
788
|
"Train_f1": float(combined_score_ranking.iloc[0]["train_f1"]),
|
|
789
|
+
"Train_precision": float(combined_score_ranking.iloc[0]["train_precision"]),
|
|
790
|
+
"Train_recall": float(combined_score_ranking.iloc[0]["train_recall"]),
|
|
791
|
+
"Train_rocauc": float(combined_score_ranking.iloc[0]["train_rocauc"]),
|
|
763
792
|
"Test_accuracy": float(combined_score_ranking.iloc[0]["test_accuracy"]),
|
|
764
793
|
"Test_f1": float(combined_score_ranking.iloc[0]["test_f1"]),
|
|
794
|
+
"Test_precision": float(combined_score_ranking.iloc[0]["test_precision"]),
|
|
795
|
+
"Test_recall": float(combined_score_ranking.iloc[0]["test_recall"]),
|
|
796
|
+
"Test_rocauc": float(combined_score_ranking.iloc[0]["test_rocauc"]),
|
|
765
797
|
"Hyper_tuned": bool(combined_score_ranking.iloc[0]["tuned"]),
|
|
766
798
|
"Dropped_Columns":list(dropcorr)
|
|
767
|
-
}
|
|
768
799
|
}
|
|
769
|
-
|
|
800
|
+
if(response["Hyper_tuned"]):
|
|
801
|
+
response["Best_Params"] = best_param_dict
|
|
802
|
+
print("\n")
|
|
803
|
+
print("="*55)
|
|
804
|
+
for key, value in response.items():
|
|
805
|
+
print(f"{key}: {value}")
|
|
806
|
+
print("="*55)
|
|
807
|
+
print("\n")
|
|
808
|
+
plot_classification_metrics(model,x_train, y_train, x_test, y_test,plot_path=plot_path)
|
|
770
809
|
else:
|
|
771
810
|
response={
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
"model_metrics": {
|
|
811
|
+
"Message": "Training completed successfully",
|
|
812
|
+
"Problem_type":"Regression",
|
|
775
813
|
"Model": combined_score_ranking.iloc[0]["model"],
|
|
776
814
|
"Train_R2": float(combined_score_ranking.iloc[0]["train_r2"]),
|
|
777
815
|
"Train_RMSE": float(combined_score_ranking.iloc[0]["train_rmse"]),
|
|
@@ -779,10 +817,17 @@ def train_model(data_path, dependent_feature,rmse_prob,f1_prob,n_jobs=-1,n_iter=
|
|
|
779
817
|
"Test_RMSE": float(combined_score_ranking.iloc[0]["test_rmse"]),
|
|
780
818
|
"Hyper_tuned": bool(combined_score_ranking.iloc[0]["tuned"]),
|
|
781
819
|
"Dropped_Columns":list(dropcorr)
|
|
782
|
-
}
|
|
783
820
|
}
|
|
821
|
+
if(response["Hyper_tuned"]):
|
|
822
|
+
response["Best_Params"] = best_param_dict
|
|
823
|
+
print("\n")
|
|
824
|
+
print("="*55)
|
|
825
|
+
for i in response:
|
|
826
|
+
print(f"{i}: {response[i]}")
|
|
827
|
+
print("="*55)
|
|
828
|
+
print("\n")
|
|
784
829
|
plot_regression_metrics(model, x_train, y_train, x_test, y_test,feature_names,plot_path=plot_path)
|
|
785
|
-
|
|
830
|
+
|
|
786
831
|
print("artifacts_path:", artifacts_path)
|
|
787
832
|
print("model_path:", model_path)
|
|
788
833
|
print("preprocessor_path:", preprocessor_path)
|
|
@@ -794,10 +839,10 @@ def plot_classification_metrics(model, X_train, y_train, X_test, y_test, plot_pa
|
|
|
794
839
|
# Predict
|
|
795
840
|
y_pred = model.predict(X_test)
|
|
796
841
|
y_proba = model.predict_proba(X_test)[:, 1] if hasattr(model, "predict_proba") else None
|
|
797
|
-
|
|
842
|
+
unique_classes = model.classes_
|
|
798
843
|
# Confusion Matrix
|
|
799
844
|
cm = confusion_matrix(y_test, y_pred)
|
|
800
|
-
disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=
|
|
845
|
+
disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=unique_classes)
|
|
801
846
|
disp.plot(cmap="Blues")
|
|
802
847
|
plt.title("Confusion Matrix")
|
|
803
848
|
plt.savefig(os.path.join(plot_path,"confusion_matrix.png"), bbox_inches='tight')
|
|
@@ -810,14 +855,15 @@ def plot_classification_metrics(model, X_train, y_train, X_test, y_test, plot_pa
|
|
|
810
855
|
plt.savefig(os.path.join(plot_path,"roc_curve.png"), bbox_inches='tight')
|
|
811
856
|
plt.close()
|
|
812
857
|
# Precision-Recall Curve
|
|
813
|
-
if y_proba is not None:
|
|
858
|
+
if y_proba is not None and unique_classes.shape[0] == 2:
|
|
814
859
|
precision, recall, _ = precision_recall_curve(y_test, y_proba)
|
|
815
860
|
PrecisionRecallDisplay(precision=precision, recall=recall).plot()
|
|
816
861
|
plt.title("Precision-Recall Curve")
|
|
817
862
|
plt.savefig(os.path.join(plot_path,"precision_recall_curve.png"), bbox_inches='tight')
|
|
818
863
|
plt.close()
|
|
819
864
|
# Learning Curve
|
|
820
|
-
|
|
865
|
+
cv = min(5, np.min(np.bincount(y_train)))
|
|
866
|
+
train_sizes, train_scores, val_scores = learning_curve(model, X_train, y_train, cv=cv, scoring='accuracy')
|
|
821
867
|
plt.plot(train_sizes, np.mean(train_scores, axis=1), label="Train")
|
|
822
868
|
plt.plot(train_sizes, np.mean(val_scores, axis=1), label="Validation")
|
|
823
869
|
plt.title("Learning Curve (Accuracy)")
|
|
@@ -835,6 +881,9 @@ def plot_classification_metrics(model, X_train, y_train, X_test, y_test, plot_pa
|
|
|
835
881
|
ax[1].set_title("Testing Class Distribution")
|
|
836
882
|
plt.savefig(os.path.join(plot_path,"class_distribution.png"), bbox_inches='tight')
|
|
837
883
|
plt.close()
|
|
884
|
+
|
|
885
|
+
|
|
886
|
+
|
|
838
887
|
def plot_regression_metrics(model, X_train, y_train, X_test, y_test,feature_names,plot_path):
|
|
839
888
|
y_pred = model.predict(X_test)
|
|
840
889
|
residuals = y_test - y_pred
|
|
@@ -885,4 +934,3 @@ def main():
|
|
|
885
934
|
parser.add_argument("--cv", default=3, type=int)
|
|
886
935
|
args = parser.parse_args()
|
|
887
936
|
print(train_model(args.data_path, args.dependent_feature, rmse_prob=args.rmse_prob, f1_prob=args.f1_prob, n_jobs=args.n_jobs, n_iter=args.n_iter, cv=args.cv))
|
|
888
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mlforgex
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.3
|
|
4
4
|
Summary: Lightweight ML utility for automated training, evaluation, and prediction with CLI and Python API support
|
|
5
5
|
Home-page: https://github.com/yourusername/mlforge
|
|
6
6
|
Author: Priyanshu Mathur
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|