线性回归代码

本章将会使用标准方程法和梯度下降法进行线性回归的实现,使用了手写方法和调用sklearn库的方法。

目录

  • 标准方程法
  • 梯度下降法
  • sklearn中的标准方程法
  • sklearn中的梯度下降法
  • sklearn中的Ridge
  • sklearn中的Lasso
  • sklearn中的弹性网
  • sklearn中线性回归API介绍

标准方程法

import numpy as np
import matplotlib.pyplot as plt
import random

# 生成原始数据
x_data = np.linspace(1, 10, 100)# 生成(1,10)之间100个数,包含10
y_data = np.array([j * 1.5 + random.gauss(0, 0.9) for j in x_data])

# 数据预处理
x_data = x_data[:, np.newaxis]# 添加一维度,变成二维
y_data = y_data[:, np.newaxis]
# 添加偏置
X_data = np.concatenate((np.ones((100, 1)), x_data), axis=1)
print(X_data.shape)

# 定义利用标准方程法求weights的方法
def calc_weights(X_data, y_data):
    """
    标准方程法求weights,矩阵必须是可逆矩阵
    算法: weights = (X的转置矩阵 * X矩阵)的逆矩阵 * X的转置矩阵 * Y矩阵
    :param x_data: 特征数据
    :param y_data: 标签数据
    """
    x_mat = np.mat(X_data)
    y_mat = np.mat(y_data)
    xT_x = x_mat.T * x_mat
    if np.linalg.det(xT_x) == 0:
        print("x_mat为不可逆矩阵,不能使用标准方程法求解")
        return
    weights = xT_x.I * x_mat.T * y_mat
    return weights
weights = calc_weights(X_data, y_data)
print(weights)
x_test = np.array([2, 5, 8, 9])[:, np.newaxis]
predict_result = weights[0] + x_test * weights[1]
# 原始数据
plt.plot(x_data, y_data, "b.")
# 预测数据
plt.plot(x_test, predict_result, "r")
plt.show()

"""
计算出来的偏执、权重分别是[0.25152067], [1.44650503]
"""

梯度下降法

import numpy as np
import random

# 生成原始数据
x_data = np.linspace(1, 10, 100)  # 生成(1,10)之间100个数,包含10
y_data = np.array([j * 1.5 + random.gauss(0, 0.9) for j in x_data])
x_data = x_data[:, np.newaxis]  # 添加一维度,变成二维
y_data = y_data[:, np.newaxis]
X_data = np.concatenate((np.ones((100, 1)), x_data), axis=1)


class GradientDescent(object):
    def __init__(self, epochs=2000, lr=0.01, b=0, w=0):
        """
        :param epochs: 迭代次数
        :param lr: 学习率
        :param b: 初始偏置
        :param w: 初始权重
        """
        self.epochs = epochs
        self.lr = lr
        self.b = b
        self.w = w

    # 最小二乘法计算开始的误差
    def compute_error(self, x_data, y_data):
        total_error = 0
        for i in range(0, len(x_data)):
            total_error += (y_data[i] - (self.w * x_data[i] + self.b)) ** 2
        return total_error / float(len(x_data))

    def gradient_descent(self, x_data, y_data):
        """
        梯度下降,计算w权值和b偏置
        :return:
        """
        # 计算总数据量
        m = float(len(x_data))

        for i in range(self.epochs):
            b_grad = 0
            k_grad = 0

            # 计算梯度的总和再求平均
            for j in range(len(x_data)):
                b_grad += -(1 / m * (y_data[j] - self.b - self.w * x_data[j]))
                k_grad += -(1 / m * (y_data[j] - self.b - self.w * x_data[j])) * x_data[j]
            # 更新 b 和 k
            self.b = self.b - (self.lr * b_grad)
            self.w = self.w - (self.lr * k_grad)
        return self.b, self.w


grd = GradientDescent()
b,w = grd.gradient_descent(x_data,y_data)
print(b,w)
"""
计算出来的偏执、权重分别是[-0.20246876], [1.55851412]
"""

sklearn中的标准方程法

mport numpy as np
import random
from sklearn.linear_model import LinearRegression # 导入线性回归类模块
# 生成原始数据
x_data = np.linspace(1, 10, 100)
y_data = np.array([j * 1.5 + random.gauss(0, 0.9) for j in x_data])
x_data = x_data[:, np.newaxis]
y_data = y_data[:, np.newaxis]
X_data = np.concatenate((np.ones((100, 1)), x_data), axis=1)

linear_model = LinearRegression() # 初始化类
linear_model.fit(x_data,y_data)# sklearn都使用fit方法训练
print(linear_model.coef_) # 权重
print(linear_model.intercept_) # 偏执
"""
计算出来的偏执、权重分别是[0.21410195], [1.47514017]
"""

sklearn中的梯度下降法

import numpy as np
import random
from sklearn.linear_model import SGDRegressor
# 生成原始数据
x_data = np.linspace(1, 10, 100)  # 生成(1,10)之间100个数,包含10
y_data = np.array([j * 1.5 + random.gauss(0, 0.9) for j in x_data])
x_data = x_data[:, np.newaxis]  # 添加一维度,变成二维
y_data = y_data[:, np.newaxis]
X_data = np.concatenate((np.ones((100, 1)), x_data), axis=1)

sgd_line = SGDRegressor(max_iter=1000, tol=1e-3)
sgd_line.fit(x_data, y_data)
print(sgd_line.intercept_)
print(sgd_line.coef_)

加入L2正则 (岭回归,Ridge)

import numpy as np
import random
from sklearn.linear_model import Ridge
# 生成原始数据
x_data = np.linspace(1, 10, 100)  # 生成(1,10)之间100个数,包含10
y_data = np.array([j * 1.5 + random.gauss(0, 0.9) for j in x_data])
x_data = x_data[:, np.newaxis]  # 添加一维度,变成二维
y_data = y_data[:, np.newaxis]
X_data = np.concatenate((np.ones((100, 1)), x_data), axis=1)

line_ridge = Ridge()
line_ridge.fit(x_data, y_data)
print(line_ridge.intercept_)
print(line_ridge.coef_)

加入L1正则(Lasso)

mport numpy as np
import random
from sklearn.linear_model import Lasso
# 生成原始数据
x_data = np.linspace(1, 10, 100)  # 生成(1,10)之间100个数,包含10
y_data = np.array([j * 1.5 + random.gauss(0, 0.9) for j in x_data])
x_data = x_data[:, np.newaxis]  # 添加一维度,变成二维
y_data = y_data[:, np.newaxis]
X_data = np.concatenate((np.ones((100, 1)), x_data), axis=1)

line_lasso = Lasso()
line_lasso.fit(x_data, y_data)
print(line_lasso.intercept_)
print(line_lasso.coef_)


弹性网(L1和L2一起使用)

import numpy as np
import random
from sklearn.linear_model import ElasticNet
# 生成原始数据
x_data = np.linspace(1, 10, 100)  # 生成(1,10)之间100个数,包含10
y_data = np.array([j * 1.5 + random.gauss(0, 0.9) for j in x_data])
x_data = x_data[:, np.newaxis]  # 添加一维度,变成二维
y_data = y_data[:, np.newaxis]
X_data = np.concatenate((np.ones((100, 1)), x_data), axis=1)

line_elastic= ElasticNet()
line_elastic.fit(x_data, y_data)
print(line_elastic.intercept_)
print(line_elastic.coef_)


参数的讲解

sklearn中线性回归API介绍

1.标准方程法
from sklearn.linear_model import LinearRegression 
"""
def __init__(self, fit_intercept=True, normalize=False, copy_X=True,
                 n_jobs=None):
类中参数:
	fit_intercept:是否使用截距,不使用过0点,默认为True
	normalize:数据归一化,默认False, 方法是(减去均值除以方差)
	copy_X:是否复制一份,
	n_jobs:使用计算的核数,不设置使用1核


属性:
	coef_ :权重
	rank_ : 输入X_data的秩,只有是稠密矩阵才可以使用
	singular_ :
	intercept_ : 偏执

方法:
	fit:训练,输入是2维
		fit里面的参数:
			sample_weight:每个样本的权重,有多少样本就要多少个值
	get_params:得到实例化类的参数
	score:使用R^2进行评判模型好坏
	predict:预测
"""

2.梯度下降法

from sklearn.linear_model import SGDRegressor
"""
类中参数
	loss="squared_loss", 损失值有4种(squared_loss,huber,epsilon_insensitive,squared_epsilon_insensitive)
	penalty="l2", 使用l2惩罚,也可使用l1
	alpha=0.0001,
    l1_ratio=0.15, 
    fit_intercept=True, 
    max_iter=1000, 最大迭代次数
    tol=1e-3,
    shuffle=True, 是否打乱顺序,对输入数据
    verbose=0, 
    epsilon=DEFAULT_EPSILON,
    random_state=None, 
    learning_rate="invscaling", # 学习率变换的方法,有4种。
    eta0=0.01,
    power_t=0.25, 
    early_stopping=False, 
    validation_fraction=0.1,
    n_iter_no_change=5, 
    warm_start=False, 
    average=False
"""

你可能感兴趣的:(机器学习)