CoolFace
Apppublic

Rimsha-Bashir/Crop-Yield-Prediction-App

sourceHugging Faceupdated 11mo agoView on Hugging Face
0likes
train.py266 linesDownload Raw Back to scripts
1import pandas as pd 
2import numpy as np 
3import matplotlib.pyplot as plt
4import pickle
5import seaborn as sns
6import xgboost as xgb
7
8from sklearn.preprocessing import StandardScaler
9from sklearn.model_selection import train_test_split
10from sklearn.feature_extraction import DictVectorizer
11
12from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
13
14
15df = pd.read_csv('../data/yield_final.csv')
16
17
18
19categorical = ['country','crop', 'year']
20
21numerical = ['average_rain_fall_mm_per_year',
22 'pesticide_tonnes',
23 'avg_temp']
24
25eta = 0.1
26max_depth = 7
27min_child_weight = 5 
28
29
30## Splitting dataset into train, test and validation
31
32print("Splitting Dataset... \n\n")
33
34df_full_train, df_test = train_test_split(df, test_size=0.2, random_state=1)
35df_train, df_val = train_test_split(df_full_train, test_size=0.25, random_state=1)
36
37df_full_train = df_full_train.reset_index(drop=True)
38df_train=df_train.reset_index(drop=True)
39df_test=df_test.reset_index(drop=True)
40df_val=df_val.reset_index(drop=True)
41
42y_full_train = df_full_train['yield_hg_ha'].values
43y_train = df_train.yield_hg_ha.values
44y_test = df_test.yield_hg_ha.values
45y_val = df_val.yield_hg_ha.values
46
47y_train_log = np.log1p(y_train)
48y_val_log = np.log1p(y_val)
49y_full_train_log = np.log1p(y_full_train)
50
51
52del df_full_train['yield_hg_ha']
53del df_train['yield_hg_ha']
54del df_test['yield_hg_ha']
55del df_val['yield_hg_ha']
56
57
58## Feature Engineering
59
60print("Performing Feature Engineering... \n\n")
61
62# Log-transform highly skewed numerical features
63skewed_features = ['pesticide_tonnes', 'average_rain_fall_mm_per_year']
64for col in skewed_features:
65    df_full_train[col] = np.log1p(df_full_train[col])
66    df_train[col] = np.log1p(df_train[col])
67    df_val[col] = np.log1p(df_val[col])
68    df_test[col] = np.log1p(df_test[col])
69
70
71scaler = StandardScaler()
72df_full_train[numerical] = scaler.fit_transform(df_full_train[numerical])
73df_train[numerical] = scaler.fit_transform(df_train[numerical])
74df_val[numerical] = scaler.transform(df_val[numerical])
75df_test[numerical] = scaler.transform(df_test[numerical])
76
77
78# XGBoost:
79
80
81# Train XGBoost
82
83print("Training XGBoost Model... \n\n")
84
85
86def xgb_train(df_train, df_val, y_train_log, y_val_log, eta, 
87              num_boost_round, max_depth, min_child_weight):
88
89    dicts_train = df_train.to_dict(orient='records')
90    dicts_val = df_val.to_dict(orient='records')
91
92    dv = DictVectorizer(sparse=False)
93    X_train = dv.fit_transform(dicts_train)
94    X_val = dv.transform(dicts_val)
95
96    features = dv.get_feature_names_out().tolist()
97
98    dtrain = xgb.DMatrix(X_train, label=y_train_log, feature_names=features)
99    dval = xgb.DMatrix(X_val, label=y_val_log, feature_names=features)
100
101    watchlist = [(dtrain, 'train'), (dval, 'val')]
102
103    xgb_params = {
104        'eta': eta,                     
105        'max_depth': max_depth,                
106        'min_child_weight': min_child_weight,         
107        'objective': 'reg:squarederror',                        
108        'eval_metric':['rmse', 'mae'],
109        'nthreads':8,         
110        'seed':1,            
111        'verbosity':0  
112    }
113
114
115    evals_result = {}
116
117    model = xgb.train(
118        params=xgb_params,
119        dtrain=dtrain,
120        num_boost_round=num_boost_round,
121        evals=watchlist,
122        evals_result=evals_result,
123        verbose_eval=False
124    )
125
126    # Predictions in log scale
127    y_train_pred_log = model.predict(dtrain)
128    y_val_pred_log = model.predict(dval)
129
130    # Convert back to original scale
131    y_train_pred = np.expm1(y_train_pred_log)
132    y_val_pred = np.expm1(y_val_pred_log)
133
134    # Compute metrics in original scale
135    df_metrics = pd.DataFrame({
136    'boost_round': range(num_boost_round),
137    'train_rmse': evals_result['train']['rmse'],
138    'val_rmse': evals_result['val']['rmse'],
139    'train_mae': evals_result['train']['mae'],
140    'val_mae': evals_result['val']['mae']
141    })
142
143
144    return dv, model, df_metrics
145
146
147
148# Predict function
149def xgb_predict(df, dv, model):
150    dicts = df.to_dict(orient='records')
151    X = dv.transform(dicts)
152
153    features = dv.get_feature_names_out().tolist()
154
155    d = xgb.DMatrix(X, feature_names=features)
156
157    y_pred = model.predict(d)
158
159    return y_pred
160
161
162
163def regression_metrics(y_actual, y_pred):
164    mse = mean_squared_error(y_actual, y_pred)  # compare with y_val in original units
165    rmse = np.sqrt(mse)
166    mae = mean_absolute_error(y_actual, y_pred)
167    r2 = r2_score(y_actual, y_pred)
168
169    return rmse, mae, r2
170
171print("Evaluation Metrtics on Validation Dataset... \n\n")
172
173dv, model, df_metrics = xgb_train(
174        df_train, df_val, y_train_log, y_val_log,
175        eta=eta, num_boost_round=200, max_depth=max_depth, min_child_weight=min_child_weight
176    )
177
178
179y_pred_val_log = xgb_predict(df_val, dv, model)
180y_pred_val = np.expm1(y_pred_val_log) 
181
182
183rmse, mae, r2_val = regression_metrics(y_val, y_pred_val)
184
185print(f"Validation RMSE:{rmse}")
186print(f"Validation MAE:{mae}")
187print(f"Validation R2:{r2_val}")
188
189
190
191def xgb_train_full(df_train, y_train_log, eta, 
192              num_boost_round, max_depth, min_child_weight):
193
194    dicts_train = df_train.to_dict(orient='records')
195    dv = DictVectorizer(sparse=False)
196    X_train = dv.fit_transform(dicts_train)
197
198    features = dv.get_feature_names_out().tolist()
199
200    dtrain = xgb.DMatrix(X_train, label=y_train_log, feature_names=features)
201
202    xgb_params = {
203        'eta': eta,                     
204        'max_depth': max_depth,                
205        'min_child_weight': min_child_weight,         
206        'objective': 'reg:squarederror',                        
207        'eval_metric': ['rmse', 'mae'],
208        'nthreads': 8,         
209        'seed': 1,            
210        'verbosity': 0  
211    }
212
213    evals_result = {}
214    watchlist = [(dtrain, 'train')]  
215
216    model = xgb.train(
217        params=xgb_params,
218        dtrain=dtrain,
219        num_boost_round=num_boost_round,
220        evals=watchlist,
221        evals_result=evals_result,
222        verbose_eval=False
223    )
224
225    # Gather metrics
226    df_metrics = pd.DataFrame({
227        'boost_round': range(num_boost_round),
228        'train_rmse': evals_result['train']['rmse'],
229        'train_mae': evals_result['train']['mae']
230    })
231
232    return dv, model, df_metrics
233
234print("Training the full train dataframe... \n\n")
235
236dv, model, df_metrics = xgb_train_full(
237        df_full_train, y_full_train_log, eta=eta, num_boost_round=200,
238        max_depth=max_depth, min_child_weight=min_child_weight
239    )
240
241# Predict on test set
242y_pred_test_log = xgb_predict(df_test, dv, model)
243y_pred_test = np.expm1(y_pred_test_log)  # convert back to original units
244
245print("Evaluation Metrics on Test... \n\n")
246
247# Evaluate metrics on test
248rmse, mae, r2 = regression_metrics(y_test, y_pred_test)
249
250print(f"Test RMSE:{rmse}")
251print(f"Test MAE:{mae}")
252print(f"Test R2:{r2}")
253
254print("Saving the final model in local folder... \n\n")
255
256output_file='../model/xgboost_eta=%s_depth=%s_minchild=%s_round=200.bin'%(eta, max_depth, min_child_weight)
257with open(output_file, 'wb') as f_out:
258    pickle.dump((model,dv), f_out)
259    
260
261
262
263
264
265
266