上工具力。
# 序
我相信使用便利的 modules 能使得实现机器学习算法简单一点。本帖使用 sklearn 实现多元线性回归梯度下降。最后再简单记录一下 matplotlib 的出图心得,就当是学习绘图了。
# import modules
引入 numpy 来进行数据读取和存储,没有用到数据框所以不引用 pandas 。使用 scikit-learn 执行特征缩放和梯度下降。
matplotlib 用于绘图。import pandas
import numpy
from sklearn import preprocessing
from sklearn.linear_model import LinearRegression, SGDRegressor
from matplotlib import pyplot
# data processing
使用 numpy.loadtxt() 加载2022-Machine-Learning-Specialization所提供的数据,并做一个特征缩放的数据预处理工作。
def load_data():
data = numpy.loadtxt('houses.txt', delimiter=',')
cols = data.shape[1]
X = data[:, 0:cols-1]
y = data[:, cols-1]
return X, y
# 从txt中加载数据
X_train, y_train = load_data()
X_features = ['sqft', 'bedrooms', 'floors', 'age']
# Z-score标准化
scaler = preprocessing.StandardScaler()
X_zsnorm = scaler.fit_transform(X_train)
# stochastic gradient descent
使用 scikit-learn.SGDRegressor() 进行随机梯度下降,比自己写代码便利太多。
# 实例化一个随机梯度下降对象
sgdr = SGDRegressor(max_iter=1000)
sgdr.fit(X_zsnorm, y_train)
# 梯度下降计算出的系数和截距,只做展示,预测时直接使用sklearn提供的方法
w_norm = sgdr.coef_
b_norm = sgdr.intercept_
使用 fit() 方法执行随机梯度下降,执行完毕后得到特征的系数 coef_ 和截距项 intercept_ 等属性。
# 绘图
为了能更直观观看预测的效果,需要计算出预测值。计算预测值的方法有两个,一是通过计算出的特征系数和截距项来计算,二是通过 predict() 函数来计算。后者简单很多。
下述代码可以绘制一张图,直接用 pyplot.plot() 会自动分配一个坐标轴,然后在这个坐标轴上 scatter() 。之前一直没讲, scatter() 是用来绘制散点图的。
直接使用 pyplot.plot() 自动分配一个坐标轴画图,和使用 fig, ax = pyplot.subplots() 然后在 ax 上 scatter() 效果是一样的。
# 使用sklearn的方法计算出预测值
y_pred = sgdr.predict(X_zsnorm) #也可以使用numpy.dot(X_norm, w_norm) + b_norm来计算预测值
# 绘图
pyplot.scatter(X_train[:, 1], y_train, color='blue')
pyplot.scatter(X_train[:, 1], y_pred, color='orange')
pyplot.show()
上面的代码只是绘出一张图,在课程代码中绘制出了四张图,代码如下。
# 使用sklearn的方法计算出预测值
y_pred = sgdr.predict(X_zsnorm) #也可以使用numpy.dot(X_norm, w_norm) + b_norm来计算预测值
# 绘图
fig, ax = pyplot.subplots(1, 4, sharey=True, figsize=(13, 4))
for i in range(len(ax)):
ax[i].scatter(X_train[:, i], y_train, color='blue', label='target')
ax[i].scatter(X_train[:, i], y_pred, color='orange', label='predict')
ax[i].set_xlabel(X_features[i])
ax[0].set_ylabel('Price')
ax[0].legend()
fig.suptitle('target versus prediction using z-score normalized model') # pyplot.suptitle()也行
pyplot.show()
通过点来绘制线段(或折线)
查资料时偶然发现了这种用法,记录下。
ypoints = np.array([3, 8, 1, 10])
pyplot.plot(ypoints, linestyle = 'dotted') #linestyle可以=dashed、solid、dashdot、None
pyplot.show()
# 或使用subplots(),如果只有一张图,subplots()括号里留空,则ax是不可标下标的,也就是说不能写成ax[0]
ypoints = numpy.array([1, 3, 5, 1, 3, 9])
fig, ax = pyplot.subplots()
# linestyle可以写成ls
ax.plot(ypoints, ls=':')
pyplot.show()