Введение
Простая линейная регрессия — это простейший метод машинного обучения с учителем. В этом цель модели ML состоит в том, чтобы найти наилучшую линейную связь между двумя переменными: x (независимая переменная) и y (целевая/зависимая переменная) и выразить ее в форме y_predicted = b0 + b1 * x_input. Мы реализуем этот алгоритм с нуля, используя GoLang.
Область статьи:
- В этой статье обсуждается, как найти b0, b1 в строке наилучшего соответствия y_predicted = b0 + b1*x_input.
- В этой статье реализовано несколько функций в GoLang, таких как «обучение тестового разделения» для разделения данных, rmseValue для поиска значений RMSE для оценки модели и т. д.
- В эту статью включены все коды в GoLang.
Простая линейная регрессия
Он изображает взаимосвязь между двумя переменными. Он представлен визуально в виде прямой линии (y=mx+c), наклон которой указывает, как изменение одной переменной влияет на другую. В линейной регрессии уравнение линии задается как y(x)=b₀+b₁*x, где b₀ и b₁ — коэффициенты регрессии.
Нахождение b₀ и b₁ и RMSE
b1 = sum((xi-mean(x)) * (yi-mean(y))) / sum((xi - mean(x))*(xi - mean(x))) где xi и yi - i -th входные атрибуты, а mean() — это среднее значение переменной в нашем наборе данных.
b0 = среднее (y) — b1 * среднее (x)
Ошибка рассчитывается с использованием среднеквадратичного значения или RMSE: RMSE = sqrt(sum((pi — yi)²)/n), где pi i-е — прогнозируемое целевое значение (прогнозируемый результат) из набора тестовых данных, а yi — i-е фактическое целевое значение (фактический результат) из набора данных.
Блок-схема различных функций в коде Golang ниже
Код на GoLang
package main import ( "fmt" "math" "gonum.org/v1/gonum/stat" ) // resultXY --> sum((x-meanX)*(y-meanY)) // resultXX --> sum((x-meanX)^2) func sumXYandXX(arrayX []float64, arrayY []float64, meanX float64, meanY float64) (float64, float64) { resultXX := 0.0 resultXY := 0.0 for x := 0; x < len(arrayX); x++ { for y := 0; y < len(arrayY); y++ { if x == y { resultXY += (arrayX[x] - meanX) * (arrayY[y] - meanY) } } resultXX += (arrayX[x] - meanX) * (arrayX[x] - meanX) } return resultXY, resultXX } // estimateBoB1 --> Function that calculates the regression coefficients b0 and b1 // y_predicted = b0 + b1*x_input func estimateB0B1(x []float64, y []float64) (float64, float64) { var meanX float64 var meanY float64 var sumXY float64 var sumXX float64 meanX = stat.Mean(x, nil) //mean of x meanY = stat.Mean(y, nil) //mean pf y sumXY, sumXX = sumXYandXX(x, y, meanX, meanY) // regression coefficients b1 := sumXY / sumXX // b1 or slope b0 := meanY - b1*meanX // b0 or intercept return b0, b1 } func rmseCost(y_predicted []float64, y_test []float64) float64 { sz := len(y_test) var rmse float64 = 0.0 for i := 0; i < len(y_test); i++ { rmse = rmse + math.Abs(y_test[i]-y_predicted[i])*math.Abs(y_test[i]-y_predicted[i]) } rmse = rmse / float64(sz) rmse = math.Sqrt(rmse) return rmse } func testing(x_test []float64, b0 float64, b1 float64) []float64 { sz := len(x_test) res := make([]float64, sz) for i := 0; i < len(x_test); i++ { res[i] = b0 + b1*x_test[i] fmt.Println("for input value : ", x_test[i], ", prediction is : ", res[i]) } return res } func train_test_split(x_ []float64, y_ []float64, train_ratio float64) ([]float64, []float64, []float64, []float64) { if len(x_) != len(y_) { fmt.Printf("Size of X and Y are different :", len(x_), " and ", len(y_)) } var length float64 = float64(len(x_)) pos := int(length * train_ratio) var test_x = x_[pos-1:] var test_y = y_[pos-1:] var train_x = x_[:pos-1] var train_y = y_[:pos-1] return test_x, test_y, train_x, train_y } func main() { var X_data = []float64{-5.1, -4, -3, 2.1, -1, 0, 0.9, 2, 3.02, 4, 5, 6, 7.09, 8, 8.98, 10, 11, 12, 1, 3, 14, 15, -11, -12, 29, 30, 1, 50, 455, 500} var y_data = []float64{-9, -7.1, -5, 5, -1, 1, 3.1, 5, 7, 9, 11, 13, 15, 17, 18.95, 21, 23, 25, 3, 7, 29, 31, -21, -23, 59.1, 60.95, 3, 101, 909.9, 999.78} test_x, test_y, train_x, train_y := train_test_split(X_data, y_data, 0.80) //coefficients b0, b1 := estimateB0B1(train_x, train_y) //preliminary output with calculated coefficients fmt.Printf("Los valores de b0=%v , b1=%v\n", b0, b1) var prediction = testing(test_x, b0, b1) var rmseValue float64 = 0.0 rmseValue = rmseCost(prediction, test_y) fmt.Println("RMSE : ", rmseValue) }
Будущие работы
Точно так же логистическая регрессия может быть закодирована с нуля, поскольку она похожа на линейную регрессию.