Go语言机器学习实战:回归分析与预测模型
·
Go语言机器学习实战:回归分析与预测模型
在机器学习领域,回归分析是一种用于预测连续数值输出的监督学习方法。本文将深入探讨如何使用Go语言实现多种回归算法,并构建实用的预测模型。

一、回归分析概述
回归分析是统计学和机器学习中的核心技术,用于建立自变量和因变量之间的关系模型。常见的回归类型包括:
- 线性回归:最简单的回归模型,假设特征与目标之间存在线性关系
- 多元线性回归:多个特征共同影响目标变量
- 多项式回归:处理非线性关系
- 岭回归:带有L2正则化的线性回归,防止过拟合
- Lasso回归:带有L1正则化的线性回归,可实现特征选择
二、Go语言线性回归实现
2.1 简单线性回归
简单线性回归假设输入特征x和输出y之间存在线性关系:y = wx + b
package main
import (
"fmt"
"math"
)
type LinearRegression struct {
weight float64
bias float64
learningRate float64
}
func NewLinearRegression(lr float64) *LinearRegression {
return &LinearRegression{
weight: 0,
bias: 0,
learningRate: lr,
}
}
func (lr *LinearRegression) Predict(x float64) float64 {
return lr.weight*x + lr.bias
}
func (lr *LinearRegression) Train(x, y []float64, epochs int) {
n := float64(len(x))
for epoch := 0; epoch < epochs; epoch++ {
// 前向传播
var predictions []float64
for _, xi := range x {
predictions = append(predictions, lr.Predict(xi))
}
// 计算梯度
var dw, db float64
for i := 0; i < len(x); i++ {
error := predictions[i] - y[i]
dw += error * x[i]
db += error
}
dw /= n
db /= n
// 更新参数
lr.weight -= lr.learningRate * dw
lr.bias -= lr.learningRate * db
// 计算损失
if epoch%100 == 0 {
loss := lr.MSE(x, y)
fmt.Printf("Epoch %d: MSE = %.4f\n", epoch, loss)
}
}
}
func (lr *LinearRegression) MSE(x, y []float64) float64 {
var sumErr float64
for i := 0; i < len(x); i++ {
pred := lr.Predict(x[i])
sumErr += math.Pow(pred-y[i], 2)
}
return sumErr / float64(len(x))
}
func main() {
// 示例数据:房屋面积与价格
x := []float64{50, 60, 70, 80, 90, 100, 110, 120}
y := []float64{150, 180, 200, 230, 250, 280, 300, 330}
model := NewLinearRegression(0.0001)
model.Train(x, y, 1000)
fmt.Printf("训练完成!权重=%.4f, 偏置=%.4f\n", model.weight, model.bias)
// 预测
testX := 130.0
fmt.Printf("面积%.0f平方米的房屋价格预测:%.2f万元\n", testX, model.Predict(testX))
}
2.2 多元线性回归
当有多个特征影响目标变量时,需要使用多元线性回归:
type MultiLinearRegression struct {
weights []float64
bias float64
learningRate float64
}
func NewMultiLinearRegression(lr float64, featureNum int) *MultiLinearRegression {
return &MultiLinearRegression{
weights: make([]float64, featureNum),
bias: 0,
learningRate: lr,
}
}
func (mlr *MultiLinearRegression) Predict(x []float64) float64 {
var result float64
for i, w := range mlr.weights {
result += w * x[i]
}
return result + mlr.bias
}
func (mlr *MultiLinearRegression) Train(X [][]float64, y []float64, epochs int) {
n := float64(len(X))
for epoch := 0; epoch < epochs; epoch++ {
// 计算梯度
dW := make([]float64, len(mlr.weights))
dB := 0.0
for i := 0; i < len(X); i++ {
pred := mlr.Predict(X[i])
error := pred - y[i]
for j := 0; j < len(mlr.weights); j++ {
dW[j] += error * X[i][j]
}
dB += error
}
// 平均梯度
for j := 0; j < len(mlr.weights); j++ {
dW[j] /= n
}
dB /= n
// 更新参数
for j := 0; j < len(mlr.weights); j++ {
mlr.weights[j] -= mlr.learningRate * dW[j]
}
mlr.bias -= mlr.learningRate * dB
}
}
三、多项式回归实现
多项式回归可以处理非线性关系,通过将特征进行多项式变换:
type PolynomialRegression struct {
weights []float64
degree int
}
func NewPolynomialRegression(degree int) *PolynomialRegression {
return &PolynomialRegression{
weights: make([]float64, degree+1),
degree: degree,
}
}
func (pr *PolynomialRegression) transform(x float64) []float64 {
features := make([]float64, pr.degree+1)
features[0] = 1
for i := 1; i <= pr.degree; i++ {
features[i] = math.Pow(x, float64(i))
}
return features
}
func (pr *PolynomialRegression) Predict(x float64) float64 {
features := pr.transform(x)
var result float64
for i, w := range pr.weights {
result += w * features[i]
}
return result
}
func (pr *PolynomialRegression) Train(x, y []float64, lr float64, epochs int) {
n := float64(len(x))
for epoch := 0; epoch < epochs; epoch++ {
gradients := make([]float64, len(pr.weights))
for i := 0; i < len(x); i++ {
features := pr.transform(x[i])
pred := pr.Predict(x[i])
error := pred - y[i]
for j := 0; j < len(pr.weights); j++ {
gradients[j] += error * features[j]
}
}
for j := 0; j < len(pr.weights); j++ {
gradients[j] /= n
pr.weights[j] -= lr * gradients[j]
}
}
}
四、正则化回归
4.1 岭回归(L2正则化)
type RidgeRegression struct {
weights []float64
bias float64
lambda float64
}
func (rr *RidgeRegression) Train(X [][]float64, y []float64, lr, lambda float64, epochs int) {
rr.lambda = lambda
n := float64(len(X))
for epoch := 0; epoch < epochs; epoch++ {
dW := make([]float64, len(rr.weights))
dB := 0.0
for i := 0; i < len(X); i++ {
pred := rr.Predict(X[i])
error := pred - y[i]
for j := 0; j < len(rr.weights); j++ {
dW[j] += error * X[i][j]
}
dB += error
}
for j := 0; j < len(rr.weights); j++ {
dW[j] = dW[j]/n + lambda*rr.weights[j]
rr.weights[j] -= lr * dW[j]
}
dB /= n
rr.bias -= lr * dB
}
}
4.2 Lasso回归(L1正则化)
type LassoRegression struct {
weights []float64
bias float64
lambda float64
}
func (lr *LassoRegression) Train(X [][]float64, y []float64, lr, lambda float64, epochs int) {
lr.lambda = lambda
n := float64(len(X))
for epoch := 0; epoch < epochs; epoch++ {
dW := make([]float64, len(lr.weights))
dB := 0.0
for i := 0; i < len(X); i++ {
pred := lr.Predict(X[i])
error := pred - y[i]
for j := 0; j < len(lr.weights); j++ {
dW[j] += error * X[i][j]
}
dB += error
}
for j := 0; j < len(lr.weights); j++ {
dW[j] = dW[j]/n + lambda*sign(lr.weights[j])
lr.weights[j] -= lr * dW[j]
}
dB /= n
lr.bias -= lr * dB
}
}
func sign(x float64) float64 {
if x > 0 {
return 1
} else if x < 0 {
return -1
}
return 0
}
五、模型评估指标
回归模型的评估需要使用专门的指标:
func MeanAbsoluteError(yTrue, yPred []float64) float64 {
var sum float64
for i := 0; i < len(yTrue); i++ {
sum += math.Abs(yTrue[i] - yPred[i])
}
return sum / float64(len(yTrue))
}
func MeanSquaredError(yTrue, yPred []float64) float64 {
var sum float64
for i := 0; i < len(yTrue); i++ {
sum += math.Pow(yTrue[i]-yPred[i], 2)
}
return sum / float64(len(yTrue))
}
func RootMeanSquaredError(yTrue, yPred []float64) float64 {
return math.Sqrt(MeanSquaredError(yTrue, yPred))
}
func R2Score(yTrue, yPred []float64) float64 {
var mean, ssTot, ssRes float64
for _, y := range yTrue {
mean += y
}
mean /= float64(len(yTrue))
for i := 0; i < len(yTrue); i++ {
ssTot += math.Pow(yTrue[i]-mean, 2)
ssRes += math.Pow(yTrue[i]-yPred[i], 2)
}
return 1 - ssRes/ssTot
}
六、完整示例:波士顿房价预测
func main() {
// 加载波士顿房价数据集(简化版)
X := [][]float64{
{6.575, 4.98}, // RM(房间数), LSTAT(低收入比例)
{6.421, 9.14},
{7.185, 4.03},
{6.998, 2.94},
{7.147, 5.33},
}
y := []float64{24.0, 21.6, 34.7, 33.4, 36.2}
model := NewMultiLinearRegression(0.0001, 2)
model.Train(X, y, 10000)
fmt.Println("模型权重:", model.weights)
fmt.Println("模型偏置:", model.bias)
// 预测
testX := []float64{7.5, 3.5}
pred := model.Predict(testX)
fmt.Printf("预测房价: %.2f\n", pred)
}
七、总结
通过本文的学习,我们掌握了:
- 线性回归的基本原理和Go语言实现
- 多元线性回归处理多特征场景
- 多项式回归处理非线性关系
- 正则化回归(岭回归和Lasso回归)防止过拟合
- 常用的回归模型评估指标
Go语言的简洁语法和高性能特性使其成为机器学习领域的优秀选择。结合gonum等数值计算库,可以构建更复杂的机器学习系统。下一篇文章将介绍Go语言中的聚类算法实现。
更多推荐




所有评论(0)