一、线性回归的数学原理
二、无框架实现
from sklearn.datasets import load_svmlight_file
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import numpy as np
import random
import time
def load_data(filename):
data = load_svmlight_file(filename)
X_train, X_test, y_train, y_test = train_test_split(data[0], data[1], test_size=0.25)
X_train = X_train.toarray()
X_test = X_test.toarray()
return X_train, X_test, y_train, y_test
def train():
# 该路径需改为文件实际所在路径
filename = 'housing_scale.txt'
X_train, X_test, y_train, y_test = load_data(filename)
# 向Xtrain Xtest中粘贴一列1,代替bias
b = np.ones(379)
X_train = np.insert(X_train, 13, b, axis=1)
X_test = np.insert(X_test, 13, b[0:127], axis=1)
# 初始化参数,训练参数
weight = np.random.uniform(low=0.0, high=5.0, size=(1, 14))
learning_rate = 0.1
loss_test = []
loss_train = []
epoches = 15
batch_size = 200
start = time.time()
for epoch in range(epoches):
for x_batch, y_batch in batch_generator(X_train, y_train, batch_size):
y_hat = np.dot(weight, x_batch.T)
deviation = y_hat - y_batch.reshape(y_hat.shape)
gradient = 1/len(x_batch)* np.dot(deviation, x_batch)
weight = weight - learning_rate*gradient
loss1 = mse(y_train, np.dot(weight, X_train.T))
loss_train.append(loss1)
loss2 = mse(y_test, np.dot(weight, X_test.T))
loss_test.append(loss2)
print('epoch:{},loss:{:.4f}'.format(epoch+1,loss1))
print('weight:',weight)
print('time interval:{:.2f}'.format(time.time() - start))
return loss_train, loss_test
def batch_generator(x, y, batch_size):
nsamples = len(x)
batch_num = int(nsamples / batch_size)
indexes = np.random.permutation(nsamples)
for i in range(batch_num):
yield (x[indexes[i*batch_size:(i+1)*batch_size]], y[
indexes[i*batch_size:(i+1)*batch_size]])
def mse(y,y_hat):
m = len(y)
mean_square = np.sum((y - y_hat.reshape(y.shape))**2) / (2 * m)
return mean_square
# 画图
def plot(loss_train,loss_test):
x_axis = []
for i in range(len(loss_train)):
x_axis.append(i)
plt.figure()
plt.title("Linear Regression(SGD)")
plt.xlabel("training_num")
t = int(len(loss_train) * 0.95)
plt.annotate(round(loss_train[t], 2),
xy=(t, loss_train[t]), xycoords='data',
xytext=(+10, +30), textcoords='offset points', fontsize=12, color='blue',
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
plt.plot(x_axis, loss_train, label="loss_train", color='orange')
plt.plot(x_axis, loss_test, label="loss_test", color='blue')
plt.legend(loc='upper right')
plt.show()
if __name__ == "__main__":
loss_train,loss_test = train()
plot(loss_train,loss_test)
三、mxnet实现
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_svmlight_file
from mxnet.gluon import nn, Trainer
from mxnet.gluon import loss
from mxnet.gluon import data as gdata
from mxnet import init, autograd
import time
def load_data(filename):
data = load_svmlight_file(filename)
X_train, X_test, y_train, y_test = train_test_split(data[0], data[1], test_size=0.25)
X_train = mx.nd.array(X_train.toarray())
X_test = mx.nd.array(X_test.toarray())
y_train = mx.nd.array(y_train)
y_test = mx.nd.array(y_test)
return X_train, X_test, y_train, y_test
#该路径改为文件实际所在路径
filename = 'housing_scale.txt'
X_train, X_test, y_train, y_test = load_data(filename)
#定义模型
net = nn.Sequential()
net.add(nn.Dense(1))
# 初始化参数
net.initialize(init.Normal(sigma=0.01))
# 定义损失函数
loss_fn = loss.L2Loss()
# 定义训练器
trainer = Trainer(net.collect_params(), 'sgd', {'learning_rate':0.05})
epoches = 15
batch_size = 100
dataset = gdata.ArrayDataset(X_train,y_train)
data_iterator = gdata.DataLoader(dataset, batch_size, shuffle=True)
# 训练
start = time.time()
loss_train = []
loss_test = []
for epoch in range(epoches):
for batch_x, batch_y in data_iterator:
with autograd.record():
l = loss_fn(net(batch_x), batch_y)
l.backward()
# step:更新参数 需在bachward()后,record()外
trainer.step(batch_size)
l_test = loss_fn(net(X_test), y_test).mean().asscalar()
l_train = loss_fn(net(X_train),y_train).mean().asscalar()
loss_train.append(l_train)
loss_test.append(l_test)
print('epoch:{}, loss_train:{}, loss_test:{}'.format(
epoch+1, l_train, l_test))
print('weight:{}'.format(net[0].wright.data()))
print('weight:{}'.format(net[0].bias.data()))
print('time cost:{:.2f}'.format(time.time()-start))
#该plot函数与上面的plot函数一样
plot(loss_train,loss_test)
epoch:1, loss_train:75.00853729248047, loss_test:49.49179458618164
epoch:2, loss_train:42.98751449584961, loss_test:22.523841857910156
epoch:3, loss_train:37.35801696777344, loss_test:18.879819869995117
...
epoch:13, loss_train:24.04188346862793, loss_test:11.993124961853027
epoch:14, loss_train:23.269041061401367, loss_test:11.601088523864746
epoch:15, loss_train:22.554502487182617, loss_test:11.249677658081055
weight:
[[-5.618458 -1.7509187 -2.3361723 -1.0709537 -2.4252808 3.6514404
0.5393201 -3.1446304 -0.11790608 -0.9768715 -2.0322123 4.4219074
-5.982283 ]]
<NDArray 1x13 @cpu(0)>
weight:
[5.9945626]
<NDArray 1 @cpu(0)>
time cost:66.53
想要查看源码,可以访问