Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions scripts/DecisionTree.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@




def decision_tree(X_train, y_train, X_test, y_test, test_size=0.3, random_state=42):

# Let's define the model (so our DecisionTreeRegressor) and do a HalvingGridSearchCV to find the best hyperparameters
dt = DecisionTreeRegressor(random_state=random_state)

param_grid = {
"max_depth": [None, 5, 10, 20, 30],
"min_samples_split": [0.001, 0.01, 0.1],
"min_samples_leaf": [0.001, 0.01, 0.1],
}

def decision_tree(X, y, test_size=0.3, random_state=42):

# Split data (aka train_test)
Expand All @@ -31,6 +43,7 @@ def decision_tree(X, y, test_size=0.3, random_state=42):
"min_samples_leaf": [1, 2, 4]
}


halving_search = HalvingGridSearchCV(
dt,
param_grid,
Expand All @@ -42,6 +55,22 @@ def decision_tree(X, y, test_size=0.3, random_state=42):
halving_search.fit(X_train, y_train)
best_dt = halving_search.best_estimator_

#Visualization

train_sizes, train_scores, val_scores = learning_curve(best_dt, X_train, y_train, cv=5, scoring="neg_root_mean_squared_error", train_sizes=np.linspace(0.1,1.0,20))

# Average scores across folds
train_rmse = -train_scores.mean(axis=1)
val_rmse = -val_scores.mean(axis=1)

# Let's visualize the loss curve
plt.figure(figsize=(6, 4))
plt.plot(train_sizes, train_rmse, "o-", label="Training RMSE")
plt.plot(train_sizes, val_rmse, "o-", label="Validation RMSE")
plt.xlabel("Training set size")
plt.ylabel("RMSE")
plt.title("Learning Curve (Decision Tree)")

# Evaluation of the model on the test set
y_pred = best_dt.predict(X_test)
r2 = r2_score(y_test, y_pred)
Expand All @@ -66,10 +95,34 @@ def decision_tree(X, y, test_size=0.3, random_state=42):
plt.title("Learning Curve")
plt.xlabel("Training Set Size")
plt.ylabel("RMSE")

plt.legend()
plt.grid(True)
plt.show()

#predict on the test dataset
y_pred = best_dt.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

metrics = {
"RMSE": rmse,
"MSE": mse,
"MAE": mae,
"R2": r2,
}

print(f"Best parameters: {halving_search.best_params_}")
for k, v in metrics.items():
print(f"{k}: {v:.4f}")

return best_dt, y_pred, metrics

# #How to use this
# results_dt = decision_tree(X_train, y_train, X_test, y_test)

# Let's visualize the loss curve
plt.figure(figsize=(8,6))
plt.plot(train_sizes, train_mean, "o-", label="Training")
Expand Down
88 changes: 59 additions & 29 deletions scripts/Imputing.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,59 @@

import pandas as pd
import numpy as np
from sklearn.impute import KNNImputer
#this function imputes missing values from any df with KNNImputer
def knn_impute_numeric(df, n_neighbors=5):

#select only the numerical variables to do the imputer
numeric_cols = df.select_dtypes(include=['float','int'])
print(f": shape of df with only numeric features={numeric_cols.shape}")

#Impute the numerical variables
imputer = KNNImputer(missing_values=np.nan, n_neighbors=n_neighbors, keep_empty_features=True)
imputed_numeric_data = imputer.fit_transform(numeric_cols)

# Create a new DataFrame with the imputed numeric data
imputed_numeric_df = pd.DataFrame(imputed_numeric_data, columns=numeric_cols.columns, index=df.index)

# Combine the imputed numeric columns with the non-numeric columns to ensure that we keep them
non_numeric_cols = df.select_dtypes(exclude=['float','int'])
imputed_df = pd.concat([imputed_numeric_df, non_numeric_cols], axis=1)

# Ensure the column order is the same as the original dataframe
imputed_df = imputed_df[df.columns]

return imputed_df

#imputed_df = knn_impute_numeric(filtered_df, n_neighbors=5)
#imputed_df.head()
import pandas as pd
import numpy as np
from sklearn.impute import KNNImputer
#this function imputes missing values from any df with KNNImputer
def knn_impute_numeric(df_train, df_test, n_neighbors=5):

#select only the numerical variables to do the imputer
numeric_cols = df_train.select_dtypes(include=['float', 'int']).columns
print(f"Numeric features for imputation: {len(numeric_cols)} columns")

# Fit imputer on training data
imputer = KNNImputer(n_neighbors=n_neighbors, missing_values=np.nan, keep_empty_features=True)
imputed_train = imputer.fit_transform(df_train[numeric_cols])
imputed_train_df = pd.DataFrame(imputed_train, columns=numeric_cols, index=df_train.index)

# Transform test data
imputed_test = imputer.transform(df_test[numeric_cols])
imputed_test_df = pd.DataFrame(imputed_test, columns=numeric_cols, index=df_test.index)

# Keep non-numeric columns unchanged
non_numeric_cols = df_train.select_dtypes(exclude=['float', 'int']).columns
imputed_train_df = pd.concat([imputed_train_df, df_train[non_numeric_cols]], axis=1)[df_train.columns]
imputed_test_df = pd.concat([imputed_test_df, df_test[non_numeric_cols]], axis=1)[df_test.columns]

return imputed_train_df, imputed_test_df, imputer

#How to use
# imputed_train_df, imputed_test_df, imputer = knn_impute_numeric(X_train, X_test, n_neighbors=5)


import pandas as pd
import numpy as np
from sklearn.impute import KNNImputer
#this function imputes missing values from any df with KNNImputer
def knn_impute_numeric(df, n_neighbors=5):

#select only the numerical variables to do the imputer
numeric_cols = df.select_dtypes(include=['float','int'])
print(f": shape of df with only numeric features={numeric_cols.shape}")

#Impute the numerical variables
imputer = KNNImputer(missing_values=np.nan, n_neighbors=n_neighbors, keep_empty_features=True)
imputed_numeric_data = imputer.fit_transform(numeric_cols)

# Create a new DataFrame with the imputed numeric data
imputed_numeric_df = pd.DataFrame(imputed_numeric_data, columns=numeric_cols.columns, index=df.index)

# Combine the imputed numeric columns with the non-numeric columns to ensure that we keep them
non_numeric_cols = df.select_dtypes(exclude=['float','int'])
imputed_df = pd.concat([imputed_numeric_df, non_numeric_cols], axis=1)

# Ensure the column order is the same as the original dataframe
imputed_df = imputed_df[df.columns]

return imputed_df

#imputed_df = knn_impute_numeric(filtered_df, n_neighbors=5)
#imputed_df.head()

101 changes: 70 additions & 31 deletions scripts/Scaling.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,70 @@

#This function scales numerical values
from sklearn.preprocessing import RobustScaler
import pandas as pd
def scaler_numeric(df, target_col=''):

#separate the nutriscore and the rest of the values to do the scaling
X = df.drop([target_col], axis = 1)
y = df[target_col]

#select only the numerical variables to do the scaling
X_numeric = X.select_dtypes(include=['float','int'])
print(f": shape of df with only numeric features={X_numeric.shape}")

#scale the numerical values and put the scaled numerical data into a dataframe
scaler = RobustScaler()
X_scaled = scaler.fit_transform(X_numeric)
X_scaled_df = pd.DataFrame(X_scaled, columns=X_numeric.columns, index=X_numeric.index)

#combine the scaled df with the nutriscore
X_non_numeric = X.select_dtypes(exclude=['float','int'])
X_processed = pd.concat([X_scaled_df, X_non_numeric], axis=1)
scaled_df = pd.concat([X_processed, y], axis=1)

# Ensure the column order is the same as the original dataframe
scaled_df = scaled_df[df.columns]

return scaled_df

#scaled_df = scaler_numeric(imputed_df, target_col='nutriscore_score')
#scaled_df.head()
#This function scales numerical values
from sklearn.preprocessing import RobustScaler
import pandas as pd
def robust_scaler(df_train, df_test, target_col):

#Separate train and test set

X_train = df_train.drop([target_col], axis=1)
X_test = df_test.drop([target_col], axis=1)
y_train = df_train[target_col]
y_test = df_test[target_col]

# Select numeric columns
numeric_cols = X_train.select_dtypes(include=['float','int']).columns

# Fit the scaler on the numeric columns of the train dataset
scaler = RobustScaler()
X_train_scaled = scaler.fit_transform(X_train[numeric_cols])
X_train_scaled_df = pd.DataFrame(X_train_scaled, columns=numeric_cols, index=X_train.index)

# Apply the scaling on the numeric columns of the test datset
X_test_scaled = scaler.transform(X_test[numeric_cols])
X_test_scaled_df = pd.DataFrame(X_test_scaled, columns=numeric_cols, index=X_test.index)

# Combine the numeric with the non-numeric columns for both datasets
non_numeric_cols = X_train.select_dtypes(exclude=['float','int'])
scaled_train_df = pd.concat([X_train_scaled_df, X_train[non_numeric_cols]], axis=1)[X_train.columns]
scaled_test_df = pd.concat([X_test_scaled_df, X_test[non_numeric_cols]], axis=1)[X_test.columns]

scaled_train_df[target_col] = y_train
scaled_test_df[target_col] = y_test
# Ensure original column order
scaled_train_df = scaled_train_df[df_train.columns]
scaled_test_df = scaled_test_df[df_test.columns]

return scaled_train_df, scaled_test_df, scaler

#scaled_train_df, scaled_test_df, scaler = robust_scaler(X_train, X_test, target_col='nutriscore_score')
#scaled_df.head()

#This function scales numerical values
from sklearn.preprocessing import RobustScaler
import pandas as pd
def scaler_numeric(df, target_col=''):

#separate the nutriscore and the rest of the values to do the scaling
X = df.drop([target_col], axis = 1)
y = df[target_col]

#select only the numerical variables to do the scaling
X_numeric = X.select_dtypes(include=['float','int'])
print(f": shape of df with only numeric features={X_numeric.shape}")

#scale the numerical values and put the scaled numerical data into a dataframe
scaler = RobustScaler()
X_scaled = scaler.fit_transform(X_numeric)
X_scaled_df = pd.DataFrame(X_scaled, columns=X_numeric.columns, index=X_numeric.index)

#combine the scaled df with the nutriscore
X_non_numeric = X.select_dtypes(exclude=['float','int'])
X_processed = pd.concat([X_scaled_df, X_non_numeric], axis=1)
scaled_df = pd.concat([X_processed, y], axis=1)

# Ensure the column order is the same as the original dataframe
scaled_df = scaled_df[df.columns]

return scaled_df

#scaled_df = scaler_numeric(imputed_df, target_col='nutriscore_score')
#scaled_df.head()
Loading