I looked up a tutorial and created a function based upon its script. It's essentially used so I can select dependent variables that's a subset of a data frame. It runs but it is very very slow.
How would I flatten a nested for-loop such as this?
I tried implementing an enumerate version but it did not work. Ideally I'd like the complexity to be linear, currently, it's at 2^n. I'm not sure, how I can flatten the nested for loop, such that I can append the results of a function to a list.
Algorithm
Let π_{0} denote the null model which contains no predictors. This model simply predicts the sample mean of each observation.
For π=1,2,....,π:
Fit all (π \choose π) models that contain exactly π predictors.
Pick the best among these (π choose π) models, and call it π_π.
Here the best is defined as having the smallest π
ππ or equivalent measure.
Select the single best model among π0,π1,...,ππ using cross validated prediction error, πΆπ, BIC, π
2πππ or any other method.
# This function takes in a subset of a dataframe representing independent
# variables (X) and a column for dependent variable (Y). This function fits
# separate models for each possible combination of the k predictors (which is
# based on the column length of X) and then select the best subset. The
# resulting output is a dataframe.
def BestSubsetSelection(X,Y):
# number of predictors
k = len(X.columns)
# Store the RSS from a linear regression model
RSS_list = []
# Store the R-square from a linear regression model
R_squared_list = []
# Store the features for a given iteration.
feature_list = []
# Store the number of features used for a given iteration. This corresponds with the feature_list.
numb_features = []
# Loop over all possible combinations of k features
for k in range(1, len(X.columns) + 1):
# Looping over all possible combinations: from 11 choose k
for combo in itertools.combinations(X.columns,k):
# Store temporary results
temp_results = fit_linear_reg(X[list(combo)],Y)
# Append RSS to RSS Lists
RSS_list.append(temp_results[0])
# Append R-Squared TO R-Squared list
R_squared_list.append(temp_results[1])
# Append Feature/s to Feature list
feature_list.append(combo)
# Append the number of features to the number of features list
numb_features.append(len(combo))
df = pd.DataFrame({
'No_of_Features': numb_features,
'RSS' : RSS_list,
'R-Squared' : R_squared_list,
'Features' : feature_list
})
# Finding the Best Subsets for each number of features
# The smallest RSS
df_min = df[df.groupby('No_of_Features')['RSS'].transform(min) == df['RSS']]
# The Largest R-Squared Value
df_max = df[df.groupby('No_of_Features')['R-Squared'].transform(min) == df['R-Squared']]
display(df_min)
display(df_max)
# Adding columns to the dataframe with RSS and R-Squared values of the best subset
df['min_RSS'] = df.groupby('No_of_Features')['RSS'].transform(min)
df['max_R_Squared'] = df.groupby('No_of_Features')['R-Squared'].transform(max)
return df
A copy of the full implementation can be found here: https://github.com/melmaniwan/Elections-Analysis/blob/master/Implementing%20Subset%20Selections.ipynb