一、主要学习内容简介
1、了解numpy库,使用numpy库做矩阵、向量运算
2、学习多元线性回归有关知识
3、使用多项式回归拟合非线性函数
4、使用sklearn库对前面学习过的模型的拟合、预测过程进行实现
5、下载pytorch
二、主要学习过程记录
1、学习numpy库常用的一些指令、函数
import numpy as np
# 1、设置显示精度
np.set_printoptions(precision=2)
# 2、生成一些随机的样例,生成值范围为[0,1]
# 与np.random.rand生成类似但接收参数不一,例如下面随机生成3行2列的矩阵。
np.random.random_sample((3,2)) # 元组参数
np.random.rand(3,2)
# 3、求和与均值
np.sum()/mean()
# 4、点积,dot product,在一维数组中点积为向量的内积
np.dot()
在python的numpy库使用np.dot计算点积比写for循环遍历取值计算要快的多。是因为 NumPy 库使用底层优化的线性代数库、矢量化指令和并行计算,以提供高性能和快速的矩阵乘法计算。
2、对多特征的数据回归预测(多元线性回归)
对房价进行预测,但是房价的决定因素有多维:房子尺寸、房间量、楼层数、房龄。
定义模型:
向量化表示上式:
个例:
给定权重W、偏置b以及输入x,测试点积np.dot函数:
输入x:
# 载入数据--------x0和x1
x = np.array([[2104, 5, 1, 45], [1416, 3, 2, 40])
权重W:
w_init = np.array([ 0.39133535, 18.75376741, -53.36032453, -26.42131618])
偏置b:
b_init = 785.1811367994083
构造预测函数:
def predict(x, w, b):
p = np.dot(x, w) + b
return p
预测:
x_vec = x[0,:]
f_wb = predict(x_vec,w_init, b_init)
print(f"prediction: {f_wb}")
有了np.dot可以很方便地计算
上面因测试np.dot,直接使用了一组给定的权重,下面使用梯度下降方法得到模型:
定义代价函数:
代价cost值计算函数实现:
def compute_cost(X, y, w, b):
m = X.shape[0]
cost = 0.0
for i in range(m):
f_wb_i = np.dot(X[i], w) + b
cost = cost + (f_wb_i - y[i])**2
cost = cost / (2 * m)
return cost
定义梯度下降公式:
偏导项:
计算梯度函数实现:
def compute_gradient(X, y, w, b):
m,n = X.shape
dj_dw = np.zeros((n,))
dj_db = 0
for i in range(m):
err = (np.dot(X[i], w) + b) - y[i] # 预测与实际误差
for j in range(n):
dj_dw[j] = dj_dw[j] + err * X[i, j]
dj_db = dj_db + err
dj_dw = dj_dw / m
dj_db = dj_db / m
return dj_db, dj_dw
梯度下降函数(迭代):
# alpha为学习率,num_iters为迭代次数
def gradient_descent(X, y, w_in, b_in, cost_function, gradient_function, alpha, num_iters):
# 记录代价cost的变化
J_history = []
w = copy.deepcopy(w_in)
b = b_in
for i in range(num_iters):
dj_db,dj_dw = gradient_function(X, y, w, b)
w = w - alpha * dj_dw
b = b - alpha * dj_db
if i<100000:
J_history.append( cost_function(X, y, w, b))
if i% math.ceil(num_iters / 10) == 0:
print(f"Iteration {i:4d}: Cost {J_history[-1]:8.2f} ")
return w, b, J_history
开始预测:
initial_w = np.zeros_like(w_init)
initial_b = 0.
iterations = 1000
alpha = 5.0e-7
w_final, b_final, J_hist = gradient_descent(X_train, y_train, initial_w, initial_b,compute_cost, compute_gradient, alpha, iterations)
fig, (ax1, ax2) = plt.subplots(1, 2, constrained_layout=True, figsize=(12, 4))
ax1.plot(J_hist)
ax2.plot(100 + np.arange(len(J_hist[100:])), J_hist[100:])
ax1.set_title("Cost vs. iteration"); ax2.set_title("Cost vs. iteration (tail)")
ax1.set_ylabel('Cost') ; ax2.set_ylabel('Cost')
ax1.set_xlabel('iteration step') ; ax2.set_xlabel('iteration step')
plt.show()
没有选择合适的学习率且使用与上周类似的思路来实现多特征的预测效果不佳,代价函数cost的走向失常:
J_hist记录的部分值,从第三次迭代起cost就在700以下,所以右图y轴度量较小时较能看清其下降过程。
另一种思路:
更换学习率:,至梯度下降较为合理:
载入房价与各个特征数据,作图发现之间关系(房子尺寸、年份对房价影响较大,呈线性相关关系):
X_train, y_train = load_house_data()
X_features = ['size(sqft)','bedrooms','floors','age']
fig,ax=plt.subplots(1, 4, figsize=(12, 3), sharey=True)
for i in range(len(ax)):
ax[i].scatter(X_train[:,i],y_train)
ax[i].set_xlabel(X_features[i])
ax[i].set_ylabel("Price (1000's)")
plt.show()
在迭代过程中,收敛较快,其它项收敛较慢:
在偏导项中,每次计算都需要乘以,而各个特征之间此项的数量级差别较大,这在更新权值时导致收敛的快慢,影响迭代的速度,如图所示:
引入特征缩放:
特征缩放是指在机器学习和数据分析中对特征进行归一化或标准化的过程。它是在对数据进行预处理之前或在模型训练之前常常需要进行的一个步骤。特征缩放的目的是消除特征之间的量纲差异,确保它们具有相似的尺度。当特征具有不同的量纲或范围时,某些机器学习算法可能会受到影响,导致对某些特征的权重分配不平衡,从而影响模型的性能。
定义Z-score过程:
样本均值:
标准差(standard deviation):
Z-score:
Z-score函数代码实现:
def zscore_normalize_features(X):
mu = np.mean(X, axis=0)
sigma = np.std(X, axis=0)
X_norm = (X - mu) / sigma
return (X_norm, mu, sigma)
使用Z-score预处理数据并对比,处理后各特征与代价cost的关系数量级相似,差别较小,成功进行标准化操作处理了数据:
# zscore_normalize_features函数
X_norm, X_mu, X_sigma = zscore_normalize_features(X_train)
fig,ax=plt.subplots(1, 4, figsize=(12, 3))
for i in range(len(ax)):
norm_plot(ax[i],X_train[:,i],)
ax[i].set_xlabel(X_features[i])
ax[0].set_ylabel("count");
fig.suptitle("distribution of features before normalization")
plt.show()
fig,ax=plt.subplots(1,4,figsize=(12,3))
for i in range(len(ax)):
norm_plot(ax[i],X_norm[:,i],)
ax[i].set_xlabel(X_features[i])
ax[0].set_ylabel("count");
fig.suptitle(f"distribution of features after normalization")
plt.show()
处理前:
处理后:
再次预测发现各特征收敛较快,不会出现个别快慢收敛的情况:
w_norm, b_norm, hist = run_gradient_descent(X_norm, y_train, 1000, 1.0e-1, )
3、构造高阶多项式函数来拟合非线性函数
定义多项式:
拟合的目标函数:
代码实现:
x = np.arange(0,20,1)
y = np.cos(x/2)
X = np.c_[x, x**2, x**3,x**4, x**5, x**6, x**7, x**8, x**9, x**10, x**11, x**12, x**13]
# z-score标准化
X = zscore_normalize_features(X)
model_w,model_b = run_gradient_descent_feng(X, y, iterations=1000000, alpha = 1e-1)
plt.scatter(x, y, marker='x', c='r', label="Actual Value"); plt.title("Normalized x x**2, x**3 feature")
plt.plot(x,X@model_w + model_b, label="Predicted Value"); plt.xlabel("x"); plt.ylabel("y"); plt.legend(); plt.show()
效果图:
4、使用Scikit-Learn库,快速搭建模型并使用
导入依赖:
import numpy as np
np.set_printoptions(precision=2)
from sklearn.linear_model import LinearRegression, SGDRegressor
from sklearn.preprocessing import StandardScaler
from lab_utils_multi import load_house_data
import matplotlib.pyplot as plt
dlblue = '#0096ff'; dlorange = '#FF9300'; dldarkred='#C00000'; dlmagenta='#FF40FF'; dlpurple='#7030A0';
plt.style.use('./deeplearning.mplstyle')
X_train, y_train = load_house_data()
X_features = ['size(sqft)','bedrooms','floors','age']
预处理数据,标准化数据:
scaler = StandardScaler()
X_norm = scaler.fit_transform(X_train)
建立模型,拟合,得到 W,b:
sgdr = SGDRegressor(max_iter=1000)
sgdr.fit(X_norm, y_train)
b_norm = sgdr.intercept_
w_norm = sgdr.coef_
预测:
y_pred_sgd = sgdr.predict(X_norm)
#使用Scikit-Learn库中的函数可以方便我们建立模型和使用模型预测,
#上面代码中predict函数底层实现类似下面代码,
#Scikit-Learn库封装了函数方便学习时使用:
# y_pred = np.dot(X_norm, w_norm) + b_norm
三、学习总结
这一周对机器学习中常用的库的一些简单函数进行学习,了解了如何用numpy库构造矩阵并运算。在多特征影响数据的情况下线性回归中,通过这周的学习,了解了alpha学习率如何选取、各个特征的标准化(数据预处理)对模型迭代过程中代价函数cost收敛情况的影响,学习使用了标准差公式来预处理数据。使用了机器学习库sklearn简单构造模型并使用模型预测。
在阅读了吴恩达2022机器学习中的Lab实验代码后,对多元线性回归、特征缩放(上述的标准化处理)、多项式回归拟合非线性函数有了初步的认识。
四、学习展望
下周将学习逻辑回归、了解训练过程中拟合的一些现象,学习神经网络部分理论知识。