JustDataML 0.0.26__py3-none-any.whl
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.
- JDML/JDML.py +153 -0
- JDML/__init__.py +1 -0
- JDML/source/Configuration.py +64 -0
- JDML/source/Exception.py +21 -0
- JDML/source/Logger.py +16 -0
- JDML/source/Pipeline/Predict_Pipeline.py +2249 -0
- JDML/source/Pipeline/Train_Pipeline.py +49 -0
- JDML/source/Pipeline/__init__.py +0 -0
- JDML/source/Utils.py +356 -0
- JDML/source/__init__.py +0 -0
- JDML/source/components/Data_Transformation.py +161 -0
- JDML/source/components/Data_ingestion.py +60 -0
- JDML/source/components/Model_Trainer.py +103 -0
- JDML/source/components/__init__.py +0 -0
- JustDataML-0.0.26.dist-info/METADATA +266 -0
- JustDataML-0.0.26.dist-info/RECORD +19 -0
- JustDataML-0.0.26.dist-info/WHEEL +5 -0
- JustDataML-0.0.26.dist-info/entry_points.txt +2 -0
- JustDataML-0.0.26.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
from ...source.Logger import logging
|
|
6
|
+
from ...source.Exception import CustomException
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
from ...source.components.Data_ingestion import DataIngestion
|
|
10
|
+
from ...source.components.Data_Transformation import Data_Transformation
|
|
11
|
+
from ...source.components.Model_Trainer import ModelTrainer
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TrainingPipeline:
|
|
16
|
+
|
|
17
|
+
"""
|
|
18
|
+
This is a Training Pipeline to Train the Given Model and
|
|
19
|
+
Combining all the Fuctions of this tool and do help us to get the best model for prediction
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, features_cols, data_df, target_col, models, hyperparameter_yes_or_no, problem_objective,normalization_tech):
|
|
24
|
+
self.Features_Cols = features_cols
|
|
25
|
+
self.Data_df = data_df
|
|
26
|
+
self.Target_Col = target_col
|
|
27
|
+
self.Models = models
|
|
28
|
+
self.HyperParamter_Yes_or_No = hyperparameter_yes_or_no
|
|
29
|
+
self.Problem_Objective = problem_objective
|
|
30
|
+
self.Normalization_tech = normalization_tech
|
|
31
|
+
def Train_Model(self):
|
|
32
|
+
try:
|
|
33
|
+
obj = DataIngestion()
|
|
34
|
+
train_data,test_data = obj.initate_data_ingestion(self.Data_df)
|
|
35
|
+
logging.info("Data Splitting is Successful")
|
|
36
|
+
|
|
37
|
+
data_transformation = Data_Transformation(self.Features_Cols,self.Data_df,self.Target_Col,self.Problem_Objective,self.Normalization_tech)
|
|
38
|
+
train_arr,test_arr,_ = data_transformation.initiate_data_tranformation(train_path=train_data,test_path=test_data)
|
|
39
|
+
logging.info("Data Transformation Done Successfully")
|
|
40
|
+
|
|
41
|
+
model_trainer = ModelTrainer(self.Models, self.HyperParamter_Yes_or_No, self.Problem_Objective)
|
|
42
|
+
logging.info("Data Training is Successful")
|
|
43
|
+
logging.info("Model exported Successfully")
|
|
44
|
+
print("Best Model Score is : ",model_trainer.initiate_model_trainer(train_array=train_arr,test_array=test_arr))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
except Exception as e:
|
|
48
|
+
raise CustomException(e,sys)
|
|
49
|
+
|
|
File without changes
|
JDML/source/Utils.py
ADDED
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import csv
|
|
4
|
+
import json
|
|
5
|
+
import pickle
|
|
6
|
+
import pandas as pd
|
|
7
|
+
|
|
8
|
+
from ..source.Exception import CustomException
|
|
9
|
+
#from source.Configuration import Problem_Objective
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score, explained_variance_score, median_absolute_error
|
|
13
|
+
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix
|
|
14
|
+
|
|
15
|
+
from sklearn.model_selection import GridSearchCV
|
|
16
|
+
from sklearn.preprocessing import StandardScaler,MinMaxScaler,RobustScaler,MaxAbsScaler
|
|
17
|
+
|
|
18
|
+
from sklearn.ensemble import (
|
|
19
|
+
AdaBoostRegressor,AdaBoostClassifier,
|
|
20
|
+
GradientBoostingRegressor,GradientBoostingClassifier,
|
|
21
|
+
RandomForestRegressor,RandomForestClassifier
|
|
22
|
+
)
|
|
23
|
+
from sklearn.linear_model import LinearRegression, LogisticRegression, Ridge, RidgeClassifier, Lasso, ElasticNet
|
|
24
|
+
from sklearn.neighbors import KNeighborsRegressor, KNeighborsClassifier
|
|
25
|
+
from sklearn.tree import DecisionTreeRegressor, DecisionTreeClassifier
|
|
26
|
+
from sklearn.svm import SVC, SVR
|
|
27
|
+
from sklearn.naive_bayes import GaussianNB
|
|
28
|
+
from xgboost import XGBRegressor, XGBClassifier
|
|
29
|
+
#from catboost import CatBoostRegressor, CatBoostClassifier
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
regressor_models = {
|
|
33
|
+
"Random Forest": RandomForestRegressor(n_jobs=-1),
|
|
34
|
+
"Decision Tree": DecisionTreeRegressor(),
|
|
35
|
+
"Gradient Boosting": GradientBoostingRegressor(),
|
|
36
|
+
"Linear Regression": LinearRegression(n_jobs=-1),
|
|
37
|
+
"XGBRegressor": XGBRegressor(n_jobs=-1),
|
|
38
|
+
"Support Vector Reg" : SVR(),
|
|
39
|
+
"Linear Ridge" : Ridge(),
|
|
40
|
+
"Linear Lasso" : Lasso(),
|
|
41
|
+
"ElasticNet" : ElasticNet(),
|
|
42
|
+
#"CatBoosting Regressor": CatBoostRegressor(verbose=False),
|
|
43
|
+
"AdaBoost Regressor": AdaBoostRegressor(),
|
|
44
|
+
"KNeighborsRegressor": KNeighborsRegressor(n_jobs=-1)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
classfication_models = {
|
|
49
|
+
"Logistic Regression": LogisticRegression(multi_class='ovr',n_jobs=-1),
|
|
50
|
+
"Ridge Classifcaiton": RidgeClassifier(),
|
|
51
|
+
"GaussianNB": GaussianNB(),
|
|
52
|
+
"KNeighborsClassifier": KNeighborsClassifier(n_jobs=-1),
|
|
53
|
+
"Decision Tree Classifier":DecisionTreeClassifier(),
|
|
54
|
+
"Random Forest Classifier": RandomForestClassifier(n_jobs=-1),
|
|
55
|
+
"Support Vector Classifier": SVC(),
|
|
56
|
+
"AdaBoost Classifier": AdaBoostClassifier(),
|
|
57
|
+
"Gradient Boosting Classifier": GradientBoostingClassifier(),
|
|
58
|
+
"XGBClassifier": XGBClassifier(n_jobs=-1)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
parameters_regressor= {
|
|
64
|
+
"Decision Tree": {
|
|
65
|
+
'criterion':['squared_error', 'friedman_mse', 'absolute_error', 'poisson'],
|
|
66
|
+
# 'splitter':['best','random'],
|
|
67
|
+
# 'max_features':['sqrt','log2'],
|
|
68
|
+
},
|
|
69
|
+
"Random Forest":{
|
|
70
|
+
# 'criterion':['squared_error', 'friedman_mse', 'absolute_error', 'poisson'],
|
|
71
|
+
|
|
72
|
+
# 'max_features':['sqrt','log2',None],
|
|
73
|
+
'n_estimators': [8,16,32,64,128,256]
|
|
74
|
+
},
|
|
75
|
+
"Gradient Boosting":{
|
|
76
|
+
# 'loss':['squared_error', 'huber', 'absolute_error', 'quantile'],
|
|
77
|
+
'learning_rate':[.1,.01,.05,.001],
|
|
78
|
+
'subsample':[0.6,0.7,0.75,0.8,0.85,0.9],
|
|
79
|
+
# 'criterion':['squared_error', 'friedman_mse'],
|
|
80
|
+
# 'max_features':['auto','sqrt','log2'],
|
|
81
|
+
'n_estimators': [8,16,32,64,128,256]
|
|
82
|
+
},
|
|
83
|
+
"Linear Regression":{},
|
|
84
|
+
"XGBRegressor":{
|
|
85
|
+
'learning_rate':[.1,.01,.05,.001],
|
|
86
|
+
'n_estimators': [8,16,32,64,128,256]
|
|
87
|
+
},
|
|
88
|
+
"Support Vector Reg":{
|
|
89
|
+
'C':[0.1,1,10],
|
|
90
|
+
'kernel': ['linear', 'rbf', 'poly']
|
|
91
|
+
},
|
|
92
|
+
"Linear Ridge":{
|
|
93
|
+
'alpha': [0.1, 1, 10]
|
|
94
|
+
},
|
|
95
|
+
"Linear Lasso":{
|
|
96
|
+
'alpha': [0.1, 1, 10]
|
|
97
|
+
},
|
|
98
|
+
"ElasticNet":{
|
|
99
|
+
'alpha': [0.1, 1, 10],
|
|
100
|
+
'l1_ratio': [0.1, 0.5, 0.9]
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
#"CatBoosting Regressor":{
|
|
104
|
+
# 'depth': [6,8,10],
|
|
105
|
+
# 'learning_rate': [0.01, 0.05, 0.1],
|
|
106
|
+
# 'iterations': [30, 50, 100]
|
|
107
|
+
#},
|
|
108
|
+
"AdaBoost Regressor":{
|
|
109
|
+
'learning_rate':[.1,.01,0.5,.001],
|
|
110
|
+
# 'loss':['linear','square','exponential'],
|
|
111
|
+
'n_estimators': [8,16,32,64,128,256]
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
"KNeighborsRegressor": {
|
|
115
|
+
'n_neighbors': [3, 5, 7, 9, 11],
|
|
116
|
+
'weights': ['uniform', 'distance'],
|
|
117
|
+
#'algorithm': ['auto', 'ball_tree', 'kd_tree', 'brute'],
|
|
118
|
+
#'leaf_size': [10, 20, 30, 40, 50],
|
|
119
|
+
'p': [1, 2],
|
|
120
|
+
'metric': ['minkowski']
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
parameters_classifier = {
|
|
127
|
+
"Logistic Regression": {
|
|
128
|
+
'C': [0.001, 0.01, 0.1, 1, 10, 100],
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
"Ridge Classifcaiton": {
|
|
132
|
+
'alpha': [0.1, 1, 10]
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
"GaussianNB": {},
|
|
136
|
+
|
|
137
|
+
"KNeighborsClassifier": {
|
|
138
|
+
'n_neighbors': [3, 5, 7],
|
|
139
|
+
#'weights': ['uniform', 'distance'],
|
|
140
|
+
'algorithm': ['auto', 'ball_tree', 'kd_tree', 'brute']
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
"Decision Tree Classifier":{
|
|
144
|
+
'max_depth': [None, 10, 20, 30],
|
|
145
|
+
#'min_samples_split': [2, 5, 10],
|
|
146
|
+
#'min_samples_leaf': [1, 2, 4]
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
"Random Forest Classifier":{
|
|
150
|
+
'n_estimators': [100, 200, 300],
|
|
151
|
+
#'max_features': ['auto', 'sqrt', 'log2'],
|
|
152
|
+
'max_depth': [None, 10, 20, 30],
|
|
153
|
+
#'min_samples_split': [2, 5, 10],
|
|
154
|
+
#'min_samples_leaf': [1, 2, 4],
|
|
155
|
+
#'bootstrap': [True, False]
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
"Support Vector Classifier":{
|
|
159
|
+
'C': [0.1, 1, 10],
|
|
160
|
+
'kernel': ['linear', 'poly', 'rbf', 'sigmoid'],
|
|
161
|
+
'gamma': ['scale', 'auto']
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
"AdaBoost Classifier":{
|
|
165
|
+
'n_estimators': [50, 100, 200],
|
|
166
|
+
'learning_rate': [0.01, 0.1, 1.0]
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
"Gradient Boosting Classifier": {
|
|
170
|
+
'n_estimators': [50, 100, 200],
|
|
171
|
+
#'learning_rate': [0.01, 0.1, 1.0],
|
|
172
|
+
'max_depth': [3, 5, 7]
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
"XGBClassifier": {
|
|
176
|
+
'n_estimators': [50, 100, 200],
|
|
177
|
+
#'learning_rate': [0.01, 0.1, 1.0],
|
|
178
|
+
'max_depth': [3, 5, 7],
|
|
179
|
+
'gamma': [0, 0.1, 0.2],
|
|
180
|
+
#'subsample': [0.8, 1.0],
|
|
181
|
+
#'colsample_bytree': [0.8, 1.0]
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
Normalization_method = {
|
|
188
|
+
"StandardScaler":StandardScaler(),
|
|
189
|
+
"MinMaxScaler":MinMaxScaler(),
|
|
190
|
+
"RobustScaler":RobustScaler(),
|
|
191
|
+
"MaxAbsScaler":MaxAbsScaler()
|
|
192
|
+
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def save_object(file_path,obj):
|
|
198
|
+
try:
|
|
199
|
+
dir_path = os.path.dirname(file_path)
|
|
200
|
+
os.makedirs(dir_path,exist_ok=True)
|
|
201
|
+
|
|
202
|
+
with open(file_path,"wb") as file_obj:
|
|
203
|
+
pickle.dump(obj,file_obj)
|
|
204
|
+
#logging.info(f"{file_obj} is saved")
|
|
205
|
+
|
|
206
|
+
except Exception as e:
|
|
207
|
+
raise CustomException(e,sys)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def evaluate_model(X_train,y_train,X_test,y_test,models,param,prob):
|
|
211
|
+
try:
|
|
212
|
+
|
|
213
|
+
report = {}
|
|
214
|
+
report_df = pd.DataFrame()
|
|
215
|
+
model_summary = pd.DataFrame()
|
|
216
|
+
for model_name, model in models.items():
|
|
217
|
+
#model = list(models.values())[i]
|
|
218
|
+
#print(model_name)
|
|
219
|
+
if prob == "Regression":
|
|
220
|
+
para = parameters_regressor[model_name]
|
|
221
|
+
elif prob == "Classification":
|
|
222
|
+
para = parameters_classifier[model_name]
|
|
223
|
+
#print(para)
|
|
224
|
+
else:
|
|
225
|
+
print("Problem Objective is not Properly Defined")
|
|
226
|
+
if param == "Yes":
|
|
227
|
+
gs = GridSearchCV(model,para,cv=3,n_jobs=-1)
|
|
228
|
+
gs.fit(X_train,y_train)
|
|
229
|
+
result_out = gs.cv_results_
|
|
230
|
+
result_out_df = pd.DataFrame(result_out)
|
|
231
|
+
result_out_df["Model"] = model_name
|
|
232
|
+
report_df = pd.concat([report_df, result_out_df])
|
|
233
|
+
report_df.to_csv(os.path.join("Output","Hyperparameter_stats.csv"), index=False)
|
|
234
|
+
model.set_params(**gs.best_params_)
|
|
235
|
+
model.fit(X_train,y_train)
|
|
236
|
+
else:
|
|
237
|
+
model.fit(X_train, y_train)
|
|
238
|
+
|
|
239
|
+
y_train_pred = model.predict(X_train)
|
|
240
|
+
y_test_pred = model.predict(X_test)
|
|
241
|
+
|
|
242
|
+
#train_model_score = r2_score(y_train,y_train_pred)
|
|
243
|
+
|
|
244
|
+
# For Evaluation of our Model for reg we will use R-sq value and for clf we will use accuracy. for testing
|
|
245
|
+
|
|
246
|
+
if prob == 'Regression':
|
|
247
|
+
|
|
248
|
+
mae_train = mean_absolute_error(y_train, y_train_pred)
|
|
249
|
+
mse_train = mean_squared_error(y_train, y_train_pred)
|
|
250
|
+
#rmse_train = mean_squared_error(y_train, y_train_pred, squared=False)
|
|
251
|
+
r2_train = r2_score(y_train, y_train_pred)
|
|
252
|
+
explained_var_train = explained_variance_score(y_train, y_train_pred)
|
|
253
|
+
med_abs_error_train = median_absolute_error(y_train, y_train_pred)
|
|
254
|
+
|
|
255
|
+
mae_test = mean_absolute_error(y_test, y_test_pred)
|
|
256
|
+
mse_test = mean_squared_error(y_test, y_test_pred)
|
|
257
|
+
#rmse_test = mean_squared_error(y_test, y_test_pred)
|
|
258
|
+
r2_test = r2_score(y_test, y_test_pred)
|
|
259
|
+
explained_var_test = explained_variance_score(y_test, y_test_pred)
|
|
260
|
+
med_abs_error_test = median_absolute_error(y_test, y_test_pred)
|
|
261
|
+
test_model_score = r2_test
|
|
262
|
+
# Construct DataFrame for metrics
|
|
263
|
+
model_metrics = pd.DataFrame({
|
|
264
|
+
'Model': [model_name],
|
|
265
|
+
'MAE_train': [mae_train],
|
|
266
|
+
'MSE_train': [mse_train],
|
|
267
|
+
#'RMSE_train': [rmse_train],
|
|
268
|
+
'R2_train': [r2_train],
|
|
269
|
+
'Explained_Var_train': [explained_var_train],
|
|
270
|
+
'Med_Abs_Error_train': [med_abs_error_train],
|
|
271
|
+
'MAE_test': [mae_test],
|
|
272
|
+
'MSE_test': [mse_test],
|
|
273
|
+
#'RMSE_test': [rmse_test],
|
|
274
|
+
'R2_test': [r2_test],
|
|
275
|
+
'Explained_Var_test': [explained_var_test],
|
|
276
|
+
'Med_Abs_Error_test': [med_abs_error_test]
|
|
277
|
+
})
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
elif prob == 'Classification':
|
|
281
|
+
# Compute classification metrics
|
|
282
|
+
accuracy_train = accuracy_score(y_train, y_train_pred)
|
|
283
|
+
precision_train = precision_score(y_train, y_train_pred, average='weighted')
|
|
284
|
+
recall_train = recall_score(y_train, y_train_pred, average='weighted')
|
|
285
|
+
f1_train = f1_score(y_train, y_train_pred, average='weighted')
|
|
286
|
+
|
|
287
|
+
accuracy_test = accuracy_score(y_test, y_test_pred)
|
|
288
|
+
precision_test = precision_score(y_test, y_test_pred, average='weighted')
|
|
289
|
+
recall_test = recall_score(y_test, y_test_pred, average='weighted')
|
|
290
|
+
f1_test = f1_score(y_test, y_test_pred, average='weighted')
|
|
291
|
+
test_model_score = accuracy_test
|
|
292
|
+
|
|
293
|
+
# Confusion Matrix
|
|
294
|
+
conf_matrix = confusion_matrix(y_test, y_test_pred)
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
model_metrics = pd.DataFrame({
|
|
298
|
+
'Model': [model_name],
|
|
299
|
+
'Accuracy_train': [accuracy_train],
|
|
300
|
+
'Precision_train': [precision_train],
|
|
301
|
+
'Recall_train': [recall_train],
|
|
302
|
+
'F1_train': [f1_train],
|
|
303
|
+
'Accuracy_test': [accuracy_test],
|
|
304
|
+
'Precision_test': [precision_test],
|
|
305
|
+
'Recall_test': [recall_test],
|
|
306
|
+
'F1_test': [f1_test]
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
else:
|
|
311
|
+
print("Wrong Problem Objective")
|
|
312
|
+
|
|
313
|
+
model_summary = pd.concat([model_summary, model_metrics])
|
|
314
|
+
model_summary.to_csv(os.path.join("Output","Model_Summary.csv"),index=False)
|
|
315
|
+
report[model_name] = test_model_score
|
|
316
|
+
print(f" Model : {model_name} , Test Scores : {test_model_score}")
|
|
317
|
+
|
|
318
|
+
# print(report)
|
|
319
|
+
return report
|
|
320
|
+
|
|
321
|
+
except Exception as e:
|
|
322
|
+
raise CustomException(e,sys)
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def load_object(file_path):
|
|
326
|
+
try:
|
|
327
|
+
with open(file_path,"rb") as file_obj:
|
|
328
|
+
return pickle.load(file_obj)
|
|
329
|
+
except Exception as e:
|
|
330
|
+
raise CustomException(e,sys)
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
def ReadConfig(file_path):
|
|
334
|
+
try:
|
|
335
|
+
if not os.path.exists(file_path):
|
|
336
|
+
os.makedirs("Data",exist_ok=True)
|
|
337
|
+
raise FileNotFoundError("Data_Config.csv file not found. Please make sure it exists in the 'Data' folder.")
|
|
338
|
+
output_json = "".join([file_path.split(".")[0],".json"])
|
|
339
|
+
Config_Dict = {}
|
|
340
|
+
with open(file_path, 'r') as file:
|
|
341
|
+
reader = csv.reader(file)
|
|
342
|
+
for row in reader:
|
|
343
|
+
key = row[0]
|
|
344
|
+
values = [value for value in row[1:] if value] # Exclude empty values
|
|
345
|
+
Config_Dict[key] = values
|
|
346
|
+
with open(output_json,'w') as json_file:
|
|
347
|
+
json.dump(Config_Dict,json_file,indent=4)
|
|
348
|
+
|
|
349
|
+
return Config_Dict
|
|
350
|
+
except Exception as e:
|
|
351
|
+
raise CustomException(e,sys)
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
|
JDML/source/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
import sys
|
|
3
|
+
import os
|
|
4
|
+
import numpy as np
|
|
5
|
+
import pandas as pd
|
|
6
|
+
from sklearn.compose import ColumnTransformer
|
|
7
|
+
from sklearn.impute import SimpleImputer
|
|
8
|
+
from sklearn.pipeline import Pipeline
|
|
9
|
+
from sklearn.preprocessing import OneHotEncoder , LabelEncoder
|
|
10
|
+
|
|
11
|
+
from ...source.Exception import CustomException
|
|
12
|
+
from ...source.Logger import logging
|
|
13
|
+
from ...source.Utils import save_object
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class Data_transformationConfig:
|
|
19
|
+
|
|
20
|
+
"""
|
|
21
|
+
A DataClass Config for Data Tranformation it will save locations to save preprocessor pkl file
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
preprocessor_obj_file_path = os.path.join('artifact','prerocessor.pkl')
|
|
25
|
+
#DataConfig = ReadConfig("Data_Config.csv")
|
|
26
|
+
|
|
27
|
+
class Data_Transformation:
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
This is a very Import Step in our Program to do Data Tranformation
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
# def __init__(self):
|
|
34
|
+
# self.Data_transformationConfig=Data_transformationConfig()
|
|
35
|
+
|
|
36
|
+
def __init__(self, features_cols, data_df, target_col, problem_objective,normalization_tech):
|
|
37
|
+
self.Features_Cols = features_cols
|
|
38
|
+
self.Data_df = data_df
|
|
39
|
+
self.Target_Col = target_col
|
|
40
|
+
self.Problem_Objective = problem_objective
|
|
41
|
+
self.Data_transformationConfig=Data_transformationConfig()
|
|
42
|
+
self.Normalization_tech = normalization_tech
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def get_data_transformer_object(self):
|
|
47
|
+
'''
|
|
48
|
+
This Function is Handling Data Tranformation
|
|
49
|
+
Here it will Identify Categorical Columns and Numerical Columns and do some processing like
|
|
50
|
+
Imputing the missing values if there are any (Using Simple Imputer)
|
|
51
|
+
Standard Scaling for Numberical Cols and OneHot Encoding for Categorical Cols
|
|
52
|
+
If the Problem is Classification Problem then Target Col (Dependent Col) will be label encoded.
|
|
53
|
+
|
|
54
|
+
'''
|
|
55
|
+
try:
|
|
56
|
+
|
|
57
|
+
#All_Features = self.Data_transformationConfig.DataConfig["Features_Cols"]
|
|
58
|
+
All_Features = self.Features_Cols
|
|
59
|
+
numerical_columns = self.Data_df[All_Features].select_dtypes(exclude="object").columns #To get Num Features
|
|
60
|
+
categorical_columns = self.Data_df[All_Features].select_dtypes(include="object").columns #To get Cat Features
|
|
61
|
+
num_pipeline = Pipeline(
|
|
62
|
+
steps=[
|
|
63
|
+
("imputer",SimpleImputer(strategy="median")),
|
|
64
|
+
("scaler",self.Normalization_tech)
|
|
65
|
+
]
|
|
66
|
+
)
|
|
67
|
+
cat_pipeline = Pipeline(
|
|
68
|
+
steps=[
|
|
69
|
+
('imputer',SimpleImputer(strategy="most_frequent")),
|
|
70
|
+
("one hot encoder",OneHotEncoder())
|
|
71
|
+
]
|
|
72
|
+
)
|
|
73
|
+
logging.info("Numerical and Categorical Columns Processed (Scaling and OneHotEncoding Done)")
|
|
74
|
+
logging.info(f"for Numerical Columns we will do scaling with {self.Normalization_tech} )")
|
|
75
|
+
logging.info(f"Categorical columns: {list(categorical_columns)}")
|
|
76
|
+
logging.info(f"Numerical columns: {list(numerical_columns)}")
|
|
77
|
+
|
|
78
|
+
preprocessor = ColumnTransformer(
|
|
79
|
+
[
|
|
80
|
+
("Num_pipeline",num_pipeline,numerical_columns),
|
|
81
|
+
("Cat_pipeline",cat_pipeline,categorical_columns)
|
|
82
|
+
]
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
return preprocessor
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
except Exception as e:
|
|
89
|
+
raise CustomException(e,sys)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def initiate_data_tranformation(self,train_path,test_path):
|
|
93
|
+
|
|
94
|
+
"""
|
|
95
|
+
Here we will do the Data Tranformation using above Pipeline tools.
|
|
96
|
+
Reading DataFrames (train test both)... Spliting it into Features and Targets... and
|
|
97
|
+
doing Preprocessing before goining into model.
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
try:
|
|
101
|
+
train_df = pd.read_csv(train_path)
|
|
102
|
+
test_df = pd.read_csv(test_path)
|
|
103
|
+
|
|
104
|
+
logging.info("The Train and Test Data Imported Sucessfully")
|
|
105
|
+
|
|
106
|
+
logging.info('Obtaining Preprocessor object')
|
|
107
|
+
preprocessor_obj = self.get_data_transformer_object()
|
|
108
|
+
|
|
109
|
+
target_column_name = self.Target_Col[0]
|
|
110
|
+
logging.info(f"Target Col is : {target_column_name}")
|
|
111
|
+
input_feature_train_df=train_df.drop(columns=[target_column_name],axis=1)
|
|
112
|
+
target_feature_train_df=train_df[target_column_name]
|
|
113
|
+
input_feature_test_df=test_df.drop(columns=[target_column_name],axis=1)
|
|
114
|
+
target_feature_test_df=test_df[target_column_name]
|
|
115
|
+
logging.info(
|
|
116
|
+
f"Applying preprocessing object on training dataframe and testing dataframe."
|
|
117
|
+
)
|
|
118
|
+
input_feature_train_arr=preprocessor_obj.fit_transform(input_feature_train_df)
|
|
119
|
+
input_feature_test_arr=preprocessor_obj.transform(input_feature_test_df)
|
|
120
|
+
|
|
121
|
+
# Do Label Encoding for Target Variable (for Classification Only)
|
|
122
|
+
if self.Problem_Objective=='Classification':
|
|
123
|
+
try:
|
|
124
|
+
logging.info("Here Problem Objective is Classification so we have done label encoding for target Variable")
|
|
125
|
+
label_encoder = LabelEncoder()
|
|
126
|
+
target_feature_train_df_encoded = label_encoder.fit_transform(target_feature_train_df)
|
|
127
|
+
target_feature_test_df_encoded = label_encoder.transform(target_feature_test_df)
|
|
128
|
+
train_arr = np.c_[
|
|
129
|
+
input_feature_train_arr, np.array(target_feature_train_df_encoded)
|
|
130
|
+
]
|
|
131
|
+
test_arr = np.c_[input_feature_test_arr, np.array(target_feature_test_df_encoded)]
|
|
132
|
+
label_obj_file_path = os.path.join('artifact','Targetlabel.pkl')
|
|
133
|
+
save_object(label_obj_file_path,label_encoder)
|
|
134
|
+
logging.info("Here Targetlabel.pkl object is saved to artifact folder")
|
|
135
|
+
except Exception as e:
|
|
136
|
+
logging.ERROR(e)
|
|
137
|
+
raise CustomException(e,sys)
|
|
138
|
+
else:
|
|
139
|
+
train_arr = np.c_[
|
|
140
|
+
input_feature_train_arr, np.array(target_feature_train_df)
|
|
141
|
+
]
|
|
142
|
+
test_arr = np.c_[input_feature_test_arr, np.array(target_feature_test_df)]
|
|
143
|
+
|
|
144
|
+
logging.info(f"Saved preprocessing object.")
|
|
145
|
+
|
|
146
|
+
save_object(
|
|
147
|
+
|
|
148
|
+
file_path=self.Data_transformationConfig.preprocessor_obj_file_path,
|
|
149
|
+
obj=preprocessor_obj
|
|
150
|
+
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
return(
|
|
154
|
+
train_arr,
|
|
155
|
+
test_arr,
|
|
156
|
+
self.Data_transformationConfig.preprocessor_obj_file_path
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
except Exception as e:
|
|
160
|
+
raise CustomException(e,sys)
|
|
161
|
+
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from ...source.Exception import CustomException
|
|
5
|
+
from ...source.Logger import logging
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
from sklearn.model_selection import train_test_split
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class DataIngestionConfig:
|
|
15
|
+
"""
|
|
16
|
+
This Class is to save file locations to artifact folder it will save train , test and raw data into it
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
train_data_path: str = os.path.join('artifact','train.csv')
|
|
20
|
+
test_data_path: str = os.path.join('artifact','test.csv')
|
|
21
|
+
raw_data_path: str = os.path.join('artifact','data.csv')
|
|
22
|
+
|
|
23
|
+
class DataIngestion:
|
|
24
|
+
"""
|
|
25
|
+
Here we are starting with Data Ingestion and will read dataset making dir structures doing train test splits
|
|
26
|
+
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(self):
|
|
30
|
+
self.ingestion_config =DataIngestionConfig()
|
|
31
|
+
|
|
32
|
+
def initate_data_ingestion(self,df):
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
To Initate Data Ingestion use this Function.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
logging.info("Entering the Data Ingestion Method or Components")
|
|
39
|
+
|
|
40
|
+
try:
|
|
41
|
+
|
|
42
|
+
#df = Data_df
|
|
43
|
+
logging.info("Read the Data Set as Pandas Dataframe")
|
|
44
|
+
os.makedirs(os.path.dirname(self.ingestion_config.train_data_path),exist_ok=True)
|
|
45
|
+
|
|
46
|
+
df.to_csv(self.ingestion_config.raw_data_path,index=False, header=True)
|
|
47
|
+
logging.info("Train Test Split will Start, Raw Data Exported")
|
|
48
|
+
train_set, test_set = train_test_split(df,test_size=0.2,random_state=14)
|
|
49
|
+
|
|
50
|
+
train_set.to_csv(self.ingestion_config.train_data_path,index=False, header=True)
|
|
51
|
+
test_set.to_csv(self.ingestion_config.test_data_path,index=False, header=True)
|
|
52
|
+
|
|
53
|
+
logging.info("Train Test Split is Done , Data in Artifact Folder")
|
|
54
|
+
return(
|
|
55
|
+
self.ingestion_config.train_data_path,
|
|
56
|
+
self.ingestion_config.test_data_path,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
except Exception as e:
|
|
60
|
+
raise CustomException(e,sys)
|