我们有一个数据集,其中包含有关“学习小时数”与“获得的分数”之间关系的信息。已经观察到许多学生,并记录他们的学习时间和成绩。这将是我们的训练数据。目标是设计一个模型,给定学习时间,可以预测成绩。使用训练数据,获得将会给出最小误差的回归线。然后这个线性方程可以用于任何新的数据。也就是说,如果我们将学习时间作为输入,我们的模型应该以最小误差预测它们的分数。
Y(pred)= alpha + beta * x
为了使误差最小化,必须确定alpha和beta。如果平方误差和被用作评估模型的度量,目标是获得最小化这个误差的直线。
如果我们不对这个错误进行平方,那么正面和负面的样本误差就会相互抵消。
为了估计模型的参数alpha和beta,我们已知一组样本(yi, xi)(其中i=1,2,…,n),其计算的目标为最小化残差平方和:
使用微分法求极值:将上式分别对alpha 和 beta 做一阶偏微分,并令其等于0:
此二元一次线性方程组可用克莱姆法则求解,得解和:
探索:
• 如果> 0,则x(预测变量)和y(目标)具有正相关关系,y随x的增加而增加。
• 如果 <0,则x(自变量)和y(目标)具有负相关关系,y随x的增加而减少。
探索:
• 如果没有这个项,那么拟合线将超过原点。 回归系数和预测都会有偏差。偏置补偿了目标值y的平均值(在训练集)与自变量x平均值和的乘积之间的偏差。
标准方程系数(Co-efficient from Normal equations)
除了上述方程外,模型的系数也可以用标准方程计算。
Theta包含所有预测因子的系数,包括常数项。 标准方程通过对输入矩阵取逆来执行计算。 随着函数数量的增加,计算的复杂性将会增加。 当样本特征维数变大时,求逆会比较耗时。
import numpy as np from sklearn.utils import shuffle from sklearn.datasets import load_diabetes class lr_model(): def __init__(self): pass def prepare_data(self): data = load_diabetes().data target = load_diabetes().target X, y = shuffle(data, target, random_state=42) X = X.astype(np.float32) y = y.reshape((-1, 1)) data = np.concatenate((X, y), axis=1) return data def initialize_params(self, dims): w = np.zeros((dims, 1)) b = 0 return w, b def linear_loss(self, X, y, w, b): num_train = X.shape[0] num_feature = X.shape[1] y_hat = np.dot(X, w) + b loss = np.sum((y_hat-y)**2) / num_train dw = np.dot(X.T, (y_hat - y)) / num_train db = np.sum((y_hat - y)) / num_train return y_hat, loss, dw, db def linear_train(self, X, y, learning_rate, epochs): w, b = self.initialize_params(X.shape[1]) for i in range(1, epochs): y_hat, loss, dw, db = self.linear_loss(X, y, w, b) w += -learning_rate * dw b += -learning_rate * db if i % 10000 == 0: print('epoch %d loss %f' % (i, loss)) params = { 'w': w, 'b': b } grads = { 'dw': dw, 'db': db } return loss, params, grads def predict(self, X, params): w = params['w'] b = params['b'] y_pred = np.dot(X, w) + b return y_pred def linear_cross_validation(self, data, k, randomize=True): if randomize: data = list(data) shuffle(data) slices = [data[i::k] for i in range(k)] for i in range(k): validation = slices[i] train = [data for s in slices if s is not validation for data in s] train = np.array(train) validation = np.array(validation) yield train, validation if __name__ == '__main__': lr = lr_model() data = lr.prepare_data() for train, validation in lr.linear_cross_validation(data, 5): X_train = train[:, :10] y_train = train[:, -1].reshape((-1, 1)) X_valid = validation[:, :10] y_valid = validation[:, -1].reshape((-1, 1)) loss5 = [] loss, params, grads = lr.linear_train(X_train, y_train, 0.001, 100000) loss5.append(loss) score = np.mean(loss5) print('five kold cross validation score is', score) y_pred = lr.predict(X_valid, params) valid_score = np.sum(((y_pred - y_valid) ** 2)) / len(X_valid) print('valid score is', valid_score)