/// <summary> /// Performs linear regression on the input data. /// </summary> /// <param name="data">Training data</param> /// <param name="alpha">The learning rate for the algorithm</param> /// <param name="lambda">The regularization weight for the algorithm</param> /// <param name="iters">The number of training iterations to run</param> /// <returns>Tuple containing the parameter and error vectors</returns> private Tuple<InsightVector, InsightVector> PerformLinearRegression(InsightMatrix data, double alpha, double lambda, int iters) { // First add a ones column for the intercept term data = data.InsertColumn(0, 1); // Split the data into training data and the target variable var X = data.RemoveColumn(data.ColumnCount - 1); var y = data.Column(data.ColumnCount - 1); // Initialize several variables needed for the computation var theta = new InsightVector(X.ColumnCount); var temp = new InsightVector(X.ColumnCount); var error = new InsightVector(iters); // Perform gradient descent on the parameters theta for (int i = 0; i < iters; i++) { var delta = (X * theta.ToColumnMatrix()) - y.ToColumnMatrix(); for (int j = 0; j < theta.Count; j++) { var inner = delta.Multiply(X.SubMatrix(0, X.RowCount, j, 1)); if (j == 0) { temp[j] = theta[j] - ((alpha / X.RowCount) * inner.Column(0).Sum()); } else { var reg = (2 * lambda) * theta[j]; temp[j] = theta[j] - ((alpha / X.RowCount) * inner.Column(0).Sum()) + reg; } } theta = temp.Clone(); error[i] = ComputeError(X, y, theta, lambda); } return new Tuple<InsightVector, InsightVector>(theta, error); }