我們有一個數據集,其中包含有關“學習小時數”與“獲得的分數”之間關係的信息。已經觀察到許多學生,並記錄他們的學習時間和成績。這將是我們的訓練數據。目標是設計一個模型,給定學習時間,可以預測成績。使用訓練數據,獲得將會給出最小誤差的迴歸線。然後這個線性方程可以用於任何新的數據。也就是說,如果我們將學習時間作爲輸入,我們的模型應該以最小誤差預測它們的分數。
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)