Let's Make Robots! | RobotShop

Machine learning by linear regression

Learns
AttachmentSize
Supervised_machine_learning.pdf120.99 KB

For better readability I have attached a pdf, which explains how linear regression is used for supervised machine learning. In this paper I also derived the general equation of linear regression. You do not need to understand the derivation (but you should) to use linear regression. Mathematically a single artificial neuron (perceptron) is just a special case of linear regression.

You can use linear regression to approximate linear or close to linear functions. It can be for example used for color or other pattern recognition. Color recognition is even for an human no easy task. My 3 years old daughter still can't distinguish between all colors. Yellow, orange and pink objects are still just red in her opinion. I might update this entry showing an actual example using a color sensor, if you are interested. Arduino sample code below.

  1 // Linear regression calculator, written by Markus Bindhammer

  2 // Online linear regression calculator:
  3 // http://www.alcula.com/calculators/statistics/linear-regression/
  4
  5 int n = 0
  6 float x_n[100];
  7 float y_n[100];
  8
  9 void setup() {
 10   Serial.begin(9600);
 11 }
 12
 13 void loop() {
 14   Serial.println("Submit x-value or 'ESC'");
 15   char input_x[50];
 16   get_input(input_x, 50);
 17   if (strcmp (input_x, "ESC") == 0 && n > 0) {
 18     // now we ask for x_n+1
 19     Serial.println("");
 20     Serial.println("Submit x_n+1-value");
 21     char input_xnpo[50];
 22     get_input(input_xnpo, 50);
 23     float xnpo_value = atof(input_xnpo);
 24     Serial.print("x_");
 25     Serial.print(n);
 26     Serial.print(" = ");
 27     Serial.println(xnpo_value, 4);
 28     Serial.println("");
 29     // now we compute y_n+1
 30     float SUM_A = 0.0;
 31     float SUM_B = 0.0;
 32     float X = 0.0;
 33     float Y = 0.0;
 34     for (int i = 0; i < n; i ++) {
 35       SUM_A = SUM_A + (x_n[i] * y_n[i]);
 36       SUM_B = SUM_B + pow(x_n[i], 2.0);
 37       X = X + x_n[i];
 38       Y = Y + y_n[i];
 39     }
 40     float floatn = float(n);
 41     X = X / floatn;
 42     Y = Y / floatn;
 43     float ynpo = Y - (((SUM_A - (floatn * X * Y))/(SUM_B - floatn * pow(X, 2.0))) * (X - xnpo_value));
 44     Serial.print("y_n+1 = ");
 45     Serial.println(ynpo, 4);
 46     Serial.println("");
 47     n = 0;
 48   } else {
 49     float x_value = atof(input_x);
 50     x_n[n] = x_value;
 51     Serial.print("x_");
 52     Serial.print(n);
 53     Serial.print(" = ");
 54     Serial.println(x_value, 4);
 55     Serial.println("");
 56     Serial.println("Submit y-value");
 57     char input_y[50];
 58     get_input(input_y, 50);
 59     float y_value = atof(input_y);
 60     y_n[n] = y_value;
 61     Serial.print("y_");
 62     Serial.print(n);
 63     Serial.print(" = ");
 64     Serial.println(y_value, 4);
 65     Serial.println("");
 66     n ++; 
 67   }
 68 }
 69
 70 void get_input(char pd[], int pd_size) {
 71     while (Serial.available() == 0){}
 72   String inputBuffer;
 73   while (Serial.available() > 0) {
 74     char ch = Serial.read();
 75     inputBuffer += ch; 
 76     delay (10);
 77   }
 78   if (inputBuffer.length() > 0) { 
 79     inputBuffer.toCharArray(pd, pd_size); 
 80   }  
 81 }

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Cool stuff.  I think there are a lot of unexplored uses of this.  I tried this out with Anna by getting her to remember named series of numbers in short term memory and then answering various math and stats questions...

Remember 1, 2, 3, 4, 5 as series alpha.

Remember 5, 4, 2, 2, 0 as series beta.

What is the slope of series alpha and series beta?

Correlations, variances, standard deviations, and other mathematical functions that involve data series can also be done.  Thats as far as I got.  I mention all this because of a pet idea I've had for a while...

In high school, one of my instructors used to give us a page or two of data for 4 or 5 variables and say "Derive a formula to match this data".  This was done mostly by picking two variables at a time in the data, graphing them on regular graph paper or log graph paper, and drawing conclusions about the shape of the graph and where a given variable belonged, recording the slope and y-int if the shape was a line, and then choosing another two variables and repeating.  We got fairly good at recognizing shapes and knowing what to try next.  Within 45 minutes or so, we would derive a formula with variables in numerators, denominators, powers, and constants, all from this simple process.

The idea I wanted to try out was getting the robot to be curious about data series, start doing the process I described above, and derive its own formulas / conclusions about data.  Combining this idea with your "stochastic learning algo" to try various combos of variables and graph techniques and derive a conclusion about success/failure from the degree of error in each result could be VERY powerful in my opinion.  Even if it didn't go that far, It seems like simply recognizing how two things are correlated could be a powerful learning tool in a robot.

A simpler option...a lot of financial questions are answered by simple linear regression, where the series are market or stock prices.  A robotic financial advisor that has opinions and answers questions wouldn't be much of a stretch.  

Happy coding,

Martin

 

If the robot is able to continue number series, it will be able to gain some points at every IQ test :)

 

I know basics of neural networks , but i haven't still tried them in a live robot.
Formatted without line numbers

// Linear regression calculator, written by Markus Bindhammer
// Online linear regression calculator:
// http://www.alcula.com/calculators/statistics/linear-regression/
int n = 0;
float x_n[100];
float y_n[100];

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println("Submit x-value or 'ESC'");
  char input_x[50];
  get_input(input_x, 50);

  if (strcmp(input_x, "ESC") == 0 && n > 0) {

    // now we ask for x_n+1
    Serial.println("");
    Serial.println("Submit x_n+1-value");

    char input_xnpo[50];
    get_input(input_xnpo, 50);

    float xnpo_value = atof(input_xnpo);

    Serial.print("x_");
    Serial.print(n);
    Serial.print(" = ");
    Serial.println(xnpo_value, 4);
    Serial.println("");

    // now we compute y_n+1
    float SUM_A = 0.0;
    float SUM_B = 0.0;
    float X = 0.0;
    float Y = 0.0;
 
    for (int i = 0; i < n; i++) {
    
      SUM_A = SUM_A + (x_n[i] * y_n[i]);
      SUM_B = SUM_B + pow(x_n[i], 2.0);
      X = X + x_n[i];
      Y = Y + y_n[i];
 
    }

    float floatn = float(n);
    X= X / floatn;
    Y = Y / floatn;
 
    float ynpo = Y - (((SUM_A - (floatn * X * Y)) / (SUM_B - floatn * pow(X, 2.0))) * (X - xnpo_value));
 
    Serial.print("y_n+1 = ");
    Serial.println(ynpo, 4);
    Serial.println("");
    n = 0;

  } else {

    float x_value = atof(input_x);
    x_n[n] = x_value;
    Serial.print("x_");
    Serial.print(n);
    Serial.print(" = ");
    Serial.println(x_value, 4); 
    Serial.println("");
    Serial.println("Submit y-value");
    char input_y[50];
    get_input(input_y, 50);
    float y_value = atof(input_y);
    y_n[n] = y_value;
    Serial.print("y_");
    Serial.print(n);
    Serial.print(" = ");
    Serial.println(y_value, 4);
    Serial.println("");
    n++;
  }

}

void get_input(char pd[], int pd_size) {

  while (Serial.available() == 0){}

    String inputBuffer;
   
    while (Serial.available() > 0) {

      char ch = Serial.read();
      inputBuffer += ch;
      delay (10);

    }

    if (inputBuffer.length() > 0) {

      inputBuffer.toCharArray(pd, pd_size);

    } 

  }