Last active
July 24, 2019 11:03
-
-
Save hyyking/1d5bc2c138bee24e584251d97dbb8b67 to your computer and use it in GitHub Desktop.
C linear regression
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<stdio.h> | |
#include<stdlib.h> | |
#define N 10 | |
typedef struct { | |
// Linear Function with form f(x)=a*x+b | |
float a; | |
float b; | |
} LinearFunction; | |
float a_derivative(const LinearFunction *f, const float xi, const float yi) { | |
// Partial Derivative: df/da | |
return (-2) * xi * (yi - (f->a * xi + f->b)); | |
} | |
float b_derivative(const LinearFunction *f, const float xi, const float yi) { | |
// Partial Derivative: df/db | |
return (-2) * (yi - (f->a * xi + f->b)); | |
} | |
void gradient_descent(LinearFunction *f, const float *x, const float *y, const float alpha) { | |
// Gradient descent to minimise: (1/N)*sum((a*x+b - xi)^2) | |
float aa = 0; | |
float bb = 0; | |
for (int i = 0; i < N; i++) { | |
// Update the a & b values of the function | |
aa += a_derivative(f, x[i], y[i]); | |
bb += b_derivative(f, x[i], y[i]); | |
} | |
float progcoeff = (alpha/N); // (1.0/N) * alpha | |
f->a -= progcoeff*aa; | |
f->b -= progcoeff*bb; | |
} | |
void train_function(LinearFunction *f, const float *x, const float *y, const float epochs, const float alpha, const int debug) { | |
// Fit the function looping gradient descent for epochs | |
// The more you add epochs the better the descent will be | |
for (int e = 0; e < epochs; e++) { | |
gradient_descent(f, x, y, alpha); | |
// Debug messages | |
if (e % 100 == 0 && debug) { | |
printf("Epoch: %i\t", e); | |
printf("w: %f, b: %f\n", f->a, f->b); | |
} | |
} | |
} | |
float linear_predict(LinearFunction* f, const float x) { | |
return (f->a * x) + f->b; | |
} | |
int main(int argc, char *argv[]) { | |
// The dataset | |
const float spending[N] = {1, 4, 15, 5, 8, 2, 13, 9, 6, 19}; | |
const float sales[N] = {1, 2, 10, 5, 9, 16, 4, 13, 8, 7}; | |
// Traine the LinearFunction to find (a*) * x + (b*) | |
LinearFunction f = {0, 0}; | |
train_function(&f, spending, sales, 5000, .01, 1); | |
float predicted; | |
if (argc == 2) | |
predicted = linear_predict(&f, atoi(argv[1])); | |
else | |
predicted = linear_predict(&f, 1); | |
printf("Predicted: %f", predicted); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment