diff --git a/api/app.py b/api/app.py index 0a35458..561d417 100644 --- a/api/app.py +++ b/api/app.py @@ -20,18 +20,56 @@ def hello_world(): return 'Digit Classification Model Deployment' -@app.route("/predict",methods =['POST']) -def predict(): - model_path = "./models/svm_C : 0.1_gamma : 0.0001.joblib" - model = load(model_path) +# @app.route("/predict",methods =['POST']) +# def predict(): +# model_path = "./models/svm_C : 0.1_gamma : 0.0001.joblib" +# model = load(model_path) +# data = request.get_json() +# data['image'] = np.array(data['image']).astype(float) + +# image_data = data['image'].reshape(1, -1) + +# _,prediction,_ = predict_and_eval(model , image_data,np.array([0])) +# return ({"Prediction": str(prediction[0])}) + +# Global variables +svm_model = None +lr_model = None +tree_model = None + +def load_model(): + global svm_model, lr_model, tree_model + + # Load SVM model + svm_model = load("./models/svm_C : 0.1_gamma : 0.0001.joblib") + + # Load Logistic Regression model + lr_model = load("./models/M22AIE212_lr_lbfgs.joblib") + + # Load Decision Tree model + tree_model = load("./models/decision_tree_criterion : entropy_max_depth : 20.joblib") + +# Call load_model() when the application starts +load_model() + +@app.route('/predict/', methods=['POST']) +def predict(model_type): + + if model_type == "svm" : + model = svm_model + elif model_type == "decision_tree": + model = tree_model + elif model_type == "lr" : + model = lr_model + data = request.get_json() data['image'] = np.array(data['image']).astype(float) image_data = data['image'].reshape(1, -1) _,prediction,_ = predict_and_eval(model , image_data,np.array([0])) - return ({"Prediction": str(prediction[0])}) + return ({f"{model_type.upper()} Prediction": str(prediction[0])}) -if __name__ =="__main__" : - app.run(host = "0.0.0.0",port = 80) +# if __name__ =="__main__" : +# app.run(host = "0.0.0.0",port = 80) diff --git a/config.json b/config.json index c08f11b..f908bd7 100644 --- a/config.json +++ b/config.json @@ -9,5 +9,10 @@ "criterion" : ["gini","entropy"], "max_depth" : [10,15,20,30,40,50,60,70,80,90,100] + }, + + "lr" : { + + "solver" : ["lbfgs", "liblinear","newton-cg", "newton-cholesky", "sag", "saga"] } } \ No newline at end of file diff --git a/docker/DependencyDockerfile b/docker/DependencyDockerfile new file mode 100644 index 0000000..4e2e97a --- /dev/null +++ b/docker/DependencyDockerfile @@ -0,0 +1,4 @@ +FROM python:3.9.17 +WORKDIR /digits +COPY . /digits/ +RUN pip3 install --no-cache-dir -r /digits/requirements.txt diff --git a/docker/FinalDockerfile b/docker/FinalDockerfile new file mode 100644 index 0000000..131209d --- /dev/null +++ b/docker/FinalDockerfile @@ -0,0 +1,3 @@ +FROM base:latest +RUN mkdir -p models +CMD ["pytest"] \ No newline at end of file diff --git a/docker_push_helper.sh b/docker_push_helper.sh new file mode 100644 index 0000000..863213e --- /dev/null +++ b/docker_push_helper.sh @@ -0,0 +1,2 @@ +az acr build --file docker/DependencyDockerfile --registry sagarmlops23 --image base . +az acr build --file docker/FinalDockerfile --registry sagarmlops23 --image digits . \ No newline at end of file diff --git a/exp.py b/exp.py index 2b8a374..85ab4c2 100644 --- a/exp.py +++ b/exp.py @@ -55,7 +55,7 @@ parser.add_argument('-model', '--model_type', type = str, - default = 'decision_tree svm', + default = 'decision_tree svm lr', help = 'name of model') parser.add_argument('-config', '--config_path', @@ -96,8 +96,15 @@ param_grid = params_dict['decision_tree'] list_of_all_param_combination_dt = ParameterGrid(param_grid) + +# Model 3 : Logistic Regression +param_grid = params_dict['lr'] +list_of_all_param_combination_lr = ParameterGrid(param_grid) + + hparam_dict = {'svm' : list_of_all_param_combination_svm , - 'decision_tree' : list_of_all_param_combination_dt } + 'decision_tree' : list_of_all_param_combination_dt, + 'lr' : list_of_all_param_combination_lr } print("Iterating for different test and dev size : ") @@ -147,22 +154,22 @@ print(f"Average Dev Accuracy of {model_type}: ",sum(all_dev_accuracy)/max_run) -print("Confusion Matrix Between SVM Decision Tree predictions for Test Data : ") -y_svm_pred = pd.Series(predictions['svm'], name='Production(SVM)') -y_dt_pred= pd.Series(predictions['decision_tree'], name='Candidate(DT)') -df_confusion = pd.crosstab(y_svm_pred, y_dt_pred) -print(df_confusion) +# print("Confusion Matrix Between SVM Decision Tree predictions for Test Data : ") +# y_svm_pred = pd.Series(predictions['svm'], name='Production(SVM)') +# y_dt_pred= pd.Series(predictions['decision_tree'], name='Candidate(DT)') +# df_confusion = pd.crosstab(y_svm_pred, y_dt_pred) +# print(df_confusion) -# SVM test predictions Comparison with actuals -y_check_svm = y_svm_pred == actuals['svm'] +# # SVM test predictions Comparison with actuals +# y_check_svm = y_svm_pred == actuals['svm'] -# Decision tree test Comparison with actuals -y_check_dt = y_dt_pred == actuals['decision_tree'] +# # Decision tree test Comparison with actuals +# y_check_dt = y_dt_pred == actuals['decision_tree'] -y_svm = pd.Series(y_check_svm, name='Production(SVM)') -y_dt = pd.Series(y_check_dt, name='Candidate(DT)') -df_confusion = pd.crosstab(y_svm, y_dt) -print(df_confusion) +# y_svm = pd.Series(y_check_svm, name='Production(SVM)') +# y_dt = pd.Series(y_check_dt, name='Candidate(DT)') +# df_confusion = pd.crosstab(y_svm, y_dt) +# print(df_confusion) -print("F1 Score Production (SVM)" , f1_score(actuals['svm'], y_svm_pred, average='macro')) -print("F1 Score Candidate (DT)" , f1_score(actuals['decision_tree'], y_dt_pred, average='macro')) \ No newline at end of file +# print("F1 Score Production (SVM)" , f1_score(actuals['svm'], y_svm_pred, average='macro')) +# print("F1 Score Candidate (DT)" , f1_score(actuals['decision_tree'], y_dt_pred, average='macro')) \ No newline at end of file diff --git a/models/M22AIE212_lr_lbfgs.joblib b/models/M22AIE212_lr_lbfgs.joblib new file mode 100644 index 0000000..a87391f Binary files /dev/null and b/models/M22AIE212_lr_lbfgs.joblib differ diff --git a/models/M22AIE212_lr_liblinear.joblib b/models/M22AIE212_lr_liblinear.joblib new file mode 100644 index 0000000..fa96f3a Binary files /dev/null and b/models/M22AIE212_lr_liblinear.joblib differ diff --git a/models/M22AIE212_lr_newton-cg.joblib b/models/M22AIE212_lr_newton-cg.joblib new file mode 100644 index 0000000..b58f375 Binary files /dev/null and b/models/M22AIE212_lr_newton-cg.joblib differ diff --git a/models/M22AIE212_lr_newton-cholesky.joblib b/models/M22AIE212_lr_newton-cholesky.joblib new file mode 100644 index 0000000..4302ce7 Binary files /dev/null and b/models/M22AIE212_lr_newton-cholesky.joblib differ diff --git a/models/M22AIE212_lr_sag.joblib b/models/M22AIE212_lr_sag.joblib new file mode 100644 index 0000000..bb991c0 Binary files /dev/null and b/models/M22AIE212_lr_sag.joblib differ diff --git a/models/M22AIE212_lr_saga.joblib b/models/M22AIE212_lr_saga.joblib new file mode 100644 index 0000000..db0bc7a Binary files /dev/null and b/models/M22AIE212_lr_saga.joblib differ diff --git a/models/cat.dog b/models/cat.dog new file mode 100644 index 0000000..e69de29 diff --git a/models/decision_tree_criterion : entropy_max_depth : 20.joblib b/models/decision_tree_criterion : entropy_max_depth : 20.joblib new file mode 100644 index 0000000..47213f6 Binary files /dev/null and b/models/decision_tree_criterion : entropy_max_depth : 20.joblib differ diff --git a/models/decision_tree_criterion : entropy_max_depth : 40.joblib b/models/decision_tree_criterion : entropy_max_depth : 40.joblib new file mode 100644 index 0000000..d990041 Binary files /dev/null and b/models/decision_tree_criterion : entropy_max_depth : 40.joblib differ diff --git a/models/decision_tree_criterion : entropy_max_depth : 90.joblib b/models/decision_tree_criterion : entropy_max_depth : 90.joblib new file mode 100644 index 0000000..32580fd Binary files /dev/null and b/models/decision_tree_criterion : entropy_max_depth : 90.joblib differ diff --git a/models/decision_tree_criterion : gini_max_depth : 10.joblib b/models/decision_tree_criterion : gini_max_depth : 10.joblib index 48d5435..868aa7d 100644 Binary files a/models/decision_tree_criterion : gini_max_depth : 10.joblib and b/models/decision_tree_criterion : gini_max_depth : 10.joblib differ diff --git a/models/decision_tree_criterion : gini_max_depth : 15.joblib b/models/decision_tree_criterion : gini_max_depth : 15.joblib new file mode 100644 index 0000000..5a3ce98 Binary files /dev/null and b/models/decision_tree_criterion : gini_max_depth : 15.joblib differ diff --git a/models/decision_tree_criterion : gini_max_depth : 20.joblib b/models/decision_tree_criterion : gini_max_depth : 20.joblib index 7f8bfb3..e83ac11 100644 Binary files a/models/decision_tree_criterion : gini_max_depth : 20.joblib and b/models/decision_tree_criterion : gini_max_depth : 20.joblib differ diff --git a/models/decision_tree_criterion : gini_max_depth : 30.joblib b/models/decision_tree_criterion : gini_max_depth : 30.joblib new file mode 100644 index 0000000..9754db7 Binary files /dev/null and b/models/decision_tree_criterion : gini_max_depth : 30.joblib differ diff --git a/models/decision_tree_criterion : gini_max_depth : 60.joblib b/models/decision_tree_criterion : gini_max_depth : 60.joblib new file mode 100644 index 0000000..ef24112 Binary files /dev/null and b/models/decision_tree_criterion : gini_max_depth : 60.joblib differ diff --git a/models/decision_tree_criterion : gini_max_depth : 80.joblib b/models/decision_tree_criterion : gini_max_depth : 80.joblib index 987108d..4c4715f 100644 Binary files a/models/decision_tree_criterion : gini_max_depth : 80.joblib and b/models/decision_tree_criterion : gini_max_depth : 80.joblib differ diff --git a/models/decision_tree_criterion : gini_max_depth : 90.joblib b/models/decision_tree_criterion : gini_max_depth : 90.joblib new file mode 100644 index 0000000..6cf4750 Binary files /dev/null and b/models/decision_tree_criterion : gini_max_depth : 90.joblib differ diff --git a/models/lr_solver : lbfgs.joblib b/models/lr_solver : lbfgs.joblib new file mode 100644 index 0000000..a87391f Binary files /dev/null and b/models/lr_solver : lbfgs.joblib differ diff --git a/models/svm_C : 0.1_gamma : 0.0001.joblib b/models/svm_C : 0.1_gamma : 0.0001.joblib index 2ba2b8f..51e8a15 100644 Binary files a/models/svm_C : 0.1_gamma : 0.0001.joblib and b/models/svm_C : 0.1_gamma : 0.0001.joblib differ diff --git a/models/svm_C : 0.1_gamma : 0.001.joblib b/models/svm_C : 0.1_gamma : 0.001.joblib index 4249186..ecf3b02 100644 Binary files a/models/svm_C : 0.1_gamma : 0.001.joblib and b/models/svm_C : 0.1_gamma : 0.001.joblib differ diff --git a/models/svm_C : 0.1_gamma : 0.1.joblib b/models/svm_C : 0.1_gamma : 0.1.joblib new file mode 100644 index 0000000..7609c5d Binary files /dev/null and b/models/svm_C : 0.1_gamma : 0.1.joblib differ diff --git a/models/svm_C : 0.1_gamma : 1.joblib b/models/svm_C : 0.1_gamma : 1.joblib new file mode 100644 index 0000000..ecfe6f4 Binary files /dev/null and b/models/svm_C : 0.1_gamma : 1.joblib differ diff --git a/models/svm_C : 1_gamma : 0.001.joblib b/models/svm_C : 1_gamma : 0.001.joblib index 51e118e..0e4eeb4 100644 Binary files a/models/svm_C : 1_gamma : 0.001.joblib and b/models/svm_C : 1_gamma : 0.001.joblib differ diff --git a/models/svm_C : 1_gamma : 0.1.joblib b/models/svm_C : 1_gamma : 0.1.joblib new file mode 100644 index 0000000..af4c90a Binary files /dev/null and b/models/svm_C : 1_gamma : 0.1.joblib differ diff --git a/models/svm_C : 1_gamma : 1.joblib b/models/svm_C : 1_gamma : 1.joblib new file mode 100644 index 0000000..5ac4b39 Binary files /dev/null and b/models/svm_C : 1_gamma : 1.joblib differ diff --git a/models/svm_C : 1_gamma : 10.joblib b/models/svm_C : 1_gamma : 10.joblib new file mode 100644 index 0000000..20a1692 Binary files /dev/null and b/models/svm_C : 1_gamma : 10.joblib differ diff --git a/models/svm_C : 2_gamma : 1.joblib b/models/svm_C : 2_gamma : 1.joblib new file mode 100644 index 0000000..2d3f1d6 Binary files /dev/null and b/models/svm_C : 2_gamma : 1.joblib differ diff --git a/test_utils.py b/test_utils.py index 0f173fb..a483224 100644 --- a/test_utils.py +++ b/test_utils.py @@ -2,6 +2,7 @@ import os from sklearn.model_selection import ParameterGrid import numpy as np +from sklearn.linear_model import LogisticRegression np.random.seed(42) # Creating models directory if os.path.exists("models"): @@ -26,6 +27,14 @@ def dummy_hyper_parameters(): return gamma_list , C_ranges,h_params_combinations +def dummy_hyper_lr_parameters(): + + solver = ["lbfgs", "liblinear","newton-cg", "newton-cholesky", "sag", "saga"] + param_grid = {'solver': solver} + h_params_combinations =ParameterGrid(param_grid) + + return h_params_combinations + def create_dummy_data() : X , y = read_digits() @@ -78,7 +87,105 @@ def test_get_root() : assert response.get_data() == b'Digit Classification Model Deployment' -def test_post_predict(): +# def test_post_predict(): + +# X,y = read_digits() +# X_reshape = preprocess_data(X) + +# ## Digit 0 test +# indices_digit_0 = np.where(y == 0)[0] +# index_digit_0 = np.random.choice(indices_digit_0) +# image_data_0 = list(X_reshape[index_digit_0].astype(str)) + +# response = app.test_client().post("/predict", json={"image":image_data_0}) + +# ## Status Code Check +# assert response.status_code == 200 +# assert response.get_json()['Prediction'] == '0' + +# ## Digit 1 test +# indices_digit_1 = np.where(y == 1)[0] +# index_digit_1 = np.random.choice(indices_digit_1) +# image_data_1 = list(X_reshape[index_digit_1].astype(str)) +# response = app.test_client().post("/predict", json={"image":image_data_1}) +# assert response.get_json()['Prediction'] == '1' + +# ## Digit 2 test +# indices_digit_2 = np.where(y == 2)[0] +# index_digit_2 = np.random.choice(indices_digit_2) +# image_data_2 = list(X_reshape[index_digit_2].astype(str)) +# response = app.test_client().post("/predict", json={"image":image_data_2}) +# assert response.get_json()['Prediction'] == '2' + +# ## Digit 3 test +# indices_digit_3 = np.where(y == 3)[0] +# index_digit_3 = np.random.choice(indices_digit_3) +# image_data_3 = list(X_reshape[index_digit_3].astype(str)) +# response = app.test_client().post("/predict", json={"image":image_data_3}) +# assert response.get_json()['Prediction'] == '3' + +# ## Digit 4 test +# indices_digit_4 = np.where(y == 4)[0] +# index_digit_4 = np.random.choice(indices_digit_4) +# image_data_4 = list(X_reshape[index_digit_4].astype(str)) +# response = app.test_client().post("/predict", json={"image":image_data_4}) +# assert response.get_json()['Prediction'] == '4' + +# ## Digit 5 test +# indices_digit_5 = np.where(y == 5)[0] +# index_digit_5 = np.random.choice(indices_digit_5) +# image_data_5 = list(X_reshape[index_digit_5].astype(str)) +# response = app.test_client().post("/predict", json={"image":image_data_5}) +# assert response.get_json()['Prediction'] == '5' + +# ## Digit 6 test +# indices_digit_6 = np.where(y == 6)[0] +# index_digit_6 = np.random.choice(indices_digit_6) +# image_data_6 = list(X_reshape[index_digit_6].astype(str)) +# response = app.test_client().post("/predict", json={"image":image_data_6}) +# assert response.get_json()['Prediction'] == '6' + +# ## Digit 7 test +# indices_digit_7 = np.where(y == 7)[0] +# index_digit_7 = np.random.choice(indices_digit_7) +# image_data_7 = list(X_reshape[index_digit_7].astype(str)) +# response = app.test_client().post("/predict", json={"image":image_data_7}) +# assert response.get_json()['Prediction'] == '7' + +# ## Digit 8 test +# indices_digit_8 = np.where(y == 8)[0] +# index_digit_8 = np.random.choice(indices_digit_8) +# image_data_8 = list(X_reshape[index_digit_8].astype(str)) +# response = app.test_client().post("/predict", json={"image":image_data_8}) +# assert response.get_json()['Prediction'] == '8' + +# ## Digit 9 test +# indices_digit_9 = np.where(y == 9)[0] +# index_digit_9 = np.random.choice(indices_digit_9) +# image_data_9 = list(X_reshape[index_digit_9].astype(str)) +# response = app.test_client().post("/predict", json={"image":image_data_9}) +# assert response.get_json()['Prediction'] == '9' + +def test_model_lr_loading() : + X_train,y_train,X_dev,y_dev = create_dummy_data() + list_of_all_param_combination = dummy_hyper_lr_parameters() + _ ,best_model_path , _ = tune_hparams(X_train,y_train,X_dev,y_dev,list_of_all_param_combination,model_type = 'lr') + + loaded_model = load(best_model_path) + assert isinstance(loaded_model, LogisticRegression), f"Model loaded from {best_model_path} is not a Logistic Regression model" + + + +def test_model_lr_loading_solver() : + X_train,y_train,X_dev,y_dev = create_dummy_data() + list_of_all_param_combination = dummy_hyper_lr_parameters() + _ ,best_model_path , _ = tune_hparams(X_train,y_train,X_dev,y_dev,list_of_all_param_combination,model_type = 'lr') + + loaded_model = load(best_model_path) + + assert loaded_model.solver == best_model_path.split("_")[-1].split(".")[0].split(":")[-1].strip(), f"Solver name in the model file name does not match the solver used in the loaded model ({loaded_model.solver})" + +def test_post_predict_svm(): X,y = read_digits() X_reshape = preprocess_data(X) @@ -88,71 +195,37 @@ def test_post_predict(): index_digit_0 = np.random.choice(indices_digit_0) image_data_0 = list(X_reshape[index_digit_0].astype(str)) - response = app.test_client().post("/predict", json={"image":image_data_0}) + response = app.test_client().post("/predict/svm", json={"image":image_data_0}) ## Status Code Check assert response.status_code == 200 - assert response.get_json()['Prediction'] == '0' - - ## Digit 1 test - indices_digit_1 = np.where(y == 1)[0] - index_digit_1 = np.random.choice(indices_digit_1) - image_data_1 = list(X_reshape[index_digit_1].astype(str)) - response = app.test_client().post("/predict", json={"image":image_data_1}) - assert response.get_json()['Prediction'] == '1' - - ## Digit 2 test - indices_digit_2 = np.where(y == 2)[0] - index_digit_2 = np.random.choice(indices_digit_2) - image_data_2 = list(X_reshape[index_digit_2].astype(str)) - response = app.test_client().post("/predict", json={"image":image_data_2}) - assert response.get_json()['Prediction'] == '2' - - ## Digit 3 test - indices_digit_3 = np.where(y == 3)[0] - index_digit_3 = np.random.choice(indices_digit_3) - image_data_3 = list(X_reshape[index_digit_3].astype(str)) - response = app.test_client().post("/predict", json={"image":image_data_3}) - assert response.get_json()['Prediction'] == '3' - - ## Digit 4 test - indices_digit_4 = np.where(y == 4)[0] - index_digit_4 = np.random.choice(indices_digit_4) - image_data_4 = list(X_reshape[index_digit_4].astype(str)) - response = app.test_client().post("/predict", json={"image":image_data_4}) - assert response.get_json()['Prediction'] == '4' - - ## Digit 5 test - indices_digit_5 = np.where(y == 5)[0] - index_digit_5 = np.random.choice(indices_digit_5) - image_data_5 = list(X_reshape[index_digit_5].astype(str)) - response = app.test_client().post("/predict", json={"image":image_data_5}) - assert response.get_json()['Prediction'] == '5' - - ## Digit 6 test - indices_digit_6 = np.where(y == 6)[0] - index_digit_6 = np.random.choice(indices_digit_6) - image_data_6 = list(X_reshape[index_digit_6].astype(str)) - response = app.test_client().post("/predict", json={"image":image_data_6}) - assert response.get_json()['Prediction'] == '6' - - ## Digit 7 test - indices_digit_7 = np.where(y == 7)[0] - index_digit_7 = np.random.choice(indices_digit_7) - image_data_7 = list(X_reshape[index_digit_7].astype(str)) - response = app.test_client().post("/predict", json={"image":image_data_7}) - assert response.get_json()['Prediction'] == '7' - - ## Digit 8 test - indices_digit_8 = np.where(y == 8)[0] - index_digit_8 = np.random.choice(indices_digit_8) - image_data_8 = list(X_reshape[index_digit_8].astype(str)) - response = app.test_client().post("/predict", json={"image":image_data_8}) - assert response.get_json()['Prediction'] == '8' - - ## Digit 9 test - indices_digit_9 = np.where(y == 9)[0] - index_digit_9 = np.random.choice(indices_digit_9) - image_data_9 = list(X_reshape[index_digit_9].astype(str)) - response = app.test_client().post("/predict", json={"image":image_data_9}) - assert response.get_json()['Prediction'] == '9' + +def test_post_predict_lr(): + + X,y = read_digits() + X_reshape = preprocess_data(X) + + ## Digit 0 test + indices_digit_0 = np.where(y == 0)[0] + index_digit_0 = np.random.choice(indices_digit_0) + image_data_0 = list(X_reshape[index_digit_0].astype(str)) + + response = app.test_client().post("/predict/lr", json={"image":image_data_0}) + + ## Status Code Check + assert response.status_code == 200 + +def test_post_predict_decision_tree(): + + X,y = read_digits() + X_reshape = preprocess_data(X) + + ## Digit 0 test + indices_digit_0 = np.where(y == 0)[0] + index_digit_0 = np.random.choice(indices_digit_0) + image_data_0 = list(X_reshape[index_digit_0].astype(str)) + + response = app.test_client().post("/predict/decision_tree", json={"image":image_data_0}) + + ## Status Code Check + assert response.status_code == 200 \ No newline at end of file diff --git a/utils.py b/utils.py index 6b88099..d90331d 100644 --- a/utils.py +++ b/utils.py @@ -2,6 +2,8 @@ from sklearn.model_selection import train_test_split import matplotlib.pyplot as plt from sklearn import tree +from sklearn.linear_model import LogisticRegression +from sklearn.preprocessing import normalize from joblib import dump,load @@ -16,6 +18,9 @@ def preprocess_data(digit_image) : n_samples = len(digit_image) data = digit_image.reshape((n_samples, -1)) + ## unit normalization + data = normalize(data) + return data def split_data(X, y , test_size ,dev_size , random_state = 1) : @@ -54,6 +59,8 @@ def train_model(X , y, model_params ,model_type = "svm" ) : clf = svm.SVC elif model_type == "decision_tree": clf = tree.DecisionTreeClassifier + elif model_type == "lr": + clf = LogisticRegression model = clf(**model_params) @@ -145,12 +152,17 @@ def tune_hparams(X_train,y_train,X_dev,y_dev,list_of_all_param_combination,model best_acc_so_far = -1 best_model = None - + for param_combination in list_of_all_param_combination : cur_model = train_model(X_train,y_train, param_combination,model_type = model_type) cur_accuracy,_,_ = predict_and_eval(cur_model,X_dev,y_dev) + if model_type == "lr" : + print(f"Accuracy of logistic regression with Solver {param_combination['solver']} is {cur_accuracy}") + lr_model_path = "./models/M22AIE212_" + model_type + "_" + param_combination['solver'] + ".joblib" + dump(cur_model,lr_model_path) + if cur_accuracy > best_acc_so_far : print("New best accuracy : ",cur_accuracy) best_acc_so_far = cur_accuracy @@ -159,5 +171,7 @@ def tune_hparams(X_train,y_train,X_dev,y_dev,list_of_all_param_combination,model best_model_path = "./models/" + model_type + "_" + "_".join([f'{k} : {v}' for k,v in optimal_params.items()]) + ".joblib" print(best_model_path) dump(best_model,best_model_path) + + return optimal_params , best_model_path , best_acc_so_far