Skip to content

Instantly share code, notes, and snippets.

@hyyking
Last active July 24, 2019 11:03
Show Gist options
  • Save hyyking/1d5bc2c138bee24e584251d97dbb8b67 to your computer and use it in GitHub Desktop.
Save hyyking/1d5bc2c138bee24e584251d97dbb8b67 to your computer and use it in GitHub Desktop.
C linear regression
#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