1.1.多变量线性回归
1)题目:
在本部分的练习中,需要预测房价,输入变量有两个特征,一是房子的面积,二是房子卧室的数量;输出变量是房子的价格。
数据链接: https://pan.baidu.com/s/1-u0iDFDibZc6tTGGx9_wnQ 提取码: 351j
2)知识点概括:
-
特征缩放:因为对于大多数的机器学习算法和优化算法来说,将特征值缩放到相同区间可以使得获取性能更好的模型。就梯度下降算法而言,例如有两个不同的特征,第一个特征的取值范围为1-10,第二个特征的取值范围为1-10000。在梯度下降算法中,代价函数为最小平方误差函数,所以在使用梯度下降算法的时候,算法会明显的偏向于第二个特征,因为它的取值范围更大,而且会导致多元梯度下降法收敛速度过慢。
常用的特征缩放算法有两种,归一化(normalization)和标准化(standardization)。归一化算法是通过特征的最大最小值将特征缩放到[0,1]区间范围内,而多于许多机器学习算法,标准化也许会更好,标准化是通过特征的平均值和标准差将特征缩放成一个标准的正态分布,均值为0,方差为1。 -
归一化(min-max规范化): 或
找大小的方法直接用np.max()和np.min()就行 -
标准化(Z-score规范化): (经过处理的数据服从 ,这在一定程度上改变了特征的分布)
-
Sigmoid函数: (Sigmoid函数是一个具有S形曲线的函数,是良好的阈值函数,在(0, 0.5)处中心对称,在(0, 0.5)附近有比较大的斜率而当数据趋向于正无穷和负无穷的时候,映射出来的值就会无限趋向于1和0)
-
如何判断收敛:
1)通过代价函数-迭代次数图找出平坦的那段所对应的迭代次数基本上就是收敛了;
2)自动收敛表示事先选定一个合适的阈值,使得代价函数在某次迭代中减少的数值小于阈值即可。
如果算法不收敛,可能是学习速率过大。
每隔3倍尝试学习速率,画出代价函数随学习速率变化的图,来选择较优的学习速率。
3)代码和结果:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
data = np.loadtxt('ex1data2.txt', delimiter=',')
x = data[:, 0:2] #这个范围是左闭右开的
y = data[:, 2]
m = y.size
'''特征放缩——均值归一化'''
#def sigmoid(x):
# return 1.0/(1+np.exp(-x))
def norm(x):
sigma = np.std(x, axis=0) # axis=0计算每一列的标准差,=1计算行的
mu = np.mean(x, axis=0)
x = (x-mu)/sigma
return x, mu, sigma
x, mu, sigma = norm(x)
x = np.c_[np.ones(m), x] #矩阵合并,第一列加1
'''梯度下降法'''
theta = np.zeros(3) #初始化theta的值
num_iteration = 100 #初始化迭代次数
alpha = 1 #初始化学习速率
J = np.zeros(num_iteration)
#定义代价函数
def costfun(theta, x=x, y=y, m=m):
h_x = x@theta #假设函数的shape是(47,3)
return np.sum((h_x-y)**2)/(2*m)
#迭代
def gradient_descent(theta, alpha):
for i in range(num_iteration):
J[i]=costfun(theta) #将每次迭代的代价函数值计入
theta = theta-(alpha/m)*(x.T@(x@theta-y))
return theta
theta = gradient_descent(theta, alpha)
plt.figure(0)
plt.plot(J) #打印代价函数-迭代次数图
plt.xlabel('Number of Iterations')
plt.ylabel('Cost Function Value')
plt.title('The Rate of Convergence')
print(theta)
'''正规方程法'''
theta = np.linalg.inv(x.T@x)@x.T@y #求矩阵的逆
#预测值
x2 = np.array([1650,3])
x2 = (x2-mu)/sigma
x2 = np.r_[1, x2]
price = x2@theta
最后梯度下降法出来的参数值和迭代图如下:
正规方程法结果: