Previously, we examined various functions that are used across a variety of artificial intelligence applications. Today, we’re looking at a specific algorithm. While not typically considered artificial intelligence, linear regression is the most basic means of allowing a computer to learn how to solve a problem. For linear regression, the user provides an array of input values as well as an array of expected output values. In algebra, these would be the x and y values of the equation respectively. Additionally, the user will need to provide a degree for the polynomial. This is the highest exponent for the x value in the equation. For example, a third degree polynomial would be ax^3 + bc^2 + cx + d.
Our first class will be the generic base class shared across all linear regression implementations. In this class, we define a method to calculate the score of a set of values as well as an abstract method to calculate the coefficients. NOTE: Referenced code is available for download from BitBucket.
import com.talixa.techlib.ai.general.Errors;
import com.talixa.techlib.math.Polynomial;
public abstract class PolyFinder {
protected float[] input;
protected float[] idealOutput;
protected float[] actualOutput;
protected float[] bestCoefficients;
protected int degree;
public PolyFinder(float[] input, float[] idealOutput, int degree) {
this.input = input;
this.idealOutput = idealOutput;
this.actualOutput = new float[idealOutput.length];
this.bestCoefficients = new float[degree+1];
this.degree = degree;
}
public abstract float[] getCoefficients(int maxIterations);
protected float calculateScore(float[] coefficients) {
// iterate through all input values and calculate the output
// based on the generated polynomials
for(int i = 0; i < input.length; ++i) {
actualOutput[i] = Polynomial.calculate(input[i], coefficients);
}
// return the error of this set of coefficients
return Errors.sumOfSquares(idealOutput, actualOutput);
}
}
Our next step is to create an actual implementation of code to get the coefficients. Multiple method are available, but we will look at the simplest – greedy random training. In greedy random training, the system will generate random values and keep the values with the lowest error score. It’s a trivial implementation and works well for low-order polynomials.
import java.util.Arrays;
import com.talixa.techlib.ai.prng.RandomLCG;
public class PolyGreedy extends PolyFinder {
private float minX;
private float maxX;
public PolyGreedy(float[] trainingInput, float[] idealOutput, int degree, float minX, float maxX) {
super(trainingInput, idealOutput, degree);
this.minX = minX;
this.maxX = maxX;
}
public float[] getCoefficients(int maxIterations) {
// iterate through the coefficient generator maxIterations times
for(int i = 0; i < maxIterations; ++i) {
iterate();
}
// return a copy of the best coefficients found
return Arrays.copyOf(bestCoefficients, bestCoefficients.length);
}
private void iterate() {
// get score with current values
float oldScore = calculateScore(bestCoefficients);
// randomly determine new values
float[] newCoefficients = new float[degree+1];
for(int i = 0; i < (degree+1); ++i) {
newCoefficients[i] = RandomLCG.getNextInt() % (maxX - minX) + minX;
}
// test score with new values
float newScore = calculateScore(newCoefficients);
// determine if better match
if (newScore < oldScore) {
bestCoefficients = newCoefficients;
}
}
}
With the greedy random training, we define the min and max values for the parameters and then iterate over and over selecting random values for the equation. Each time a new value is created, it is compared with the current best score. If this score is better, it becomes the new winner. This algorithm can be run thousands of times to quickly create a set of coefficients to solve the equation.
For many datasets, this can create a workable answer within a short time. However, linear regression works best less complicated datasets were some relationship between the x and y values is known to exist. In cases of multiple input values where the relationship between variables is less clear, other algorithms may provide a better answer.