Optimized Gradient Descent
Putting some turbo boost into our gradient descent code
Series
Series
Putting some turbo boost into our gradient descent code
Bijon Setyawan Raya
July 18, 2022
7 mins
gd_with_df()
is the function that I originally ran to show my experimentations.
However, the time required to run the code is too long whenever the number of iteration increases.
In this post, I will be presenting three means of storing data into dataframes.
def gd_with_df(x, y, epochs, df, alpha = 0.01):
intercept, coefficient = 2.0, -7.5
predictions = predict(intercept, coefficient, x)
sum_error = np.sum((predictions - y) ** 2) / (2 * len(x))
df.loc[0] = [intercept, coefficient, sum_error]
for epoch in range(1, epochs + 1):
predictions = predict(intercept, coefficient, x)
b0_error = (1/len(x)) * np.sum(predictions - y)
b1_error = (1/len(x)) * np.sum((predictions - y) * x)
intercept = intercept - alpha * b0_error
coefficient = coefficient - alpha * b1_error
sum_error = np.sum((predictions - y) ** 2) / (2 * len(x))
df.loc[epoch] = [intercept, coefficient, sum_error]
sum_error = 0
return df
def gd_with_list(x, y, epochs, df, alpha = 0.01):
intercepts = list()
coefficients = list()
sum_errors = list()
intercept, coefficient = 2.0, -7.5
predictions = predict(intercept, coefficient, x)
sum_error = np.sum((predictions - y) ** 2) / (2 * len(x))
intercepts.append(intercept)
coefficients.append(coefficient)
sum_errors.append(sum_error)
for epoch in range(1, epochs+1):
predictions = predict(intercept, coefficient, x)
b0_error = (1/len(x)) * np.sum(predictions - y)
b1_error = (1/len(x)) * np.sum((predictions - y) * x)
intercept = intercept - alpha * b0_error
coefficient = coefficient - alpha * b1_error
sum_error = np.sum((predictions - y) ** 2) / (2 * len(x))
intercepts.append(intercept)
coefficients.append(coefficient)
sum_errors.append(sum_error)
sum_error = 0
df['intercept'] = intercepts
df['coefficient'] = coefficients
df['sum_error'] = sum_errors
return df
def gd_with_dict(x, y, epochs, df, alpha = 0.01):
intercept, coefficient = 2.0, -7.5
predictions = predict(intercept, coefficient, x)
sum_error = np.sum((predictions - y) ** 2) / (2 * len(x))
result = {
'intercept': [intercept],
'coefficient': [coefficient],
'sum_error': [sum_error]
}
for epoch in range(1, epochs+1):
predictions = predict(intercept, coefficient, x)
b0_error = (1/len(x)) * np.sum(predictions - y)
b1_error = (1/len(x)) * np.sum((predictions - y) * x)
intercept = intercept - alpha * b0_error
coefficient = coefficient - alpha * b1_error
sum_error = np.sum((predictions - y) ** 2) / (2 * len(x))
result['intercept'].append(intercept)
result['coefficient'].append(coefficient)
result['sum_error'].append(sum_error)
sum_error = 0
# convert dict to dataframe
df = pd.DataFrame(result)
return df
Iterations | Dataframe (mins) | List (mins) | Dictionary (mins) |
---|---|---|---|
1000 | 0.0303 | 0.0014 | 0.0013 |
10000 | 0.3123 | 0.0114 | 0.0112 |
100000 | 5.7611 | 0.1045 | 0.1064 |
1000000 | I can take a nap | 1.1075 | 1.1141 |
10000000 | $&!^@&#@( | 10.987 | 10.521 |
Summing the numbers up into a single picture, we can see that working with both lists and dictionaries is much faster than working with dataframes.