本章将会使用标准方程法和梯度下降法进行线性回归的实现,使用了手写方法和调用sklearn库的方法。
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]
"""
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]
"""
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_)
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_)
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_)
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_)
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
"""