先来回顾一下相关公式:
当 是不可逆时,称为奇异阵或退化阵,也称伪逆阵。
原因:
(1)多余的功能(线性相关性),一个特征是平方英尺,一个特征是平方米。
(2)特征太多,删除一些特征, 或使用正则化
theta=np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y)
J = (1.0/(2*m))*np.sum(np.square(X.dot(theta)-y))
J = (1.0/(2*m))*(X.dot(theta)-y).T.dot(X.dot(theta)-y)
deltaTheta = (1.0/m)*(X.T.dot(X.dot(theta)-y))
theta = theta-alpha*deltaTheta
或 Theta = theta-alpha*(1.0/m))*X.T.dot(X.dot(theta)-y)
求得最优线性回归一般有两种方式,一种是正解方程,一种是梯度下降
代码里都有相关解释,两种方式都有实现
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 在图中正确显示中文
# 数据预处理
x = np.array([1.5,0.8,2.6,1.0,0.6,2.8,1.2,0.9,0.4,1.3,1.2,2.0,1.6,1.8,2.2])
y = np.array([3.1,1.9,4.2,2.3,1.6,4.9,2.8,2.1,1.4,2.4,2.4,3.8,3.0,3.4,4.0])
# 特征x前拼接数据1
x = np.c_[np.ones((len(x), 1)), x.T] # 按列方向组合,X=[[1, x(1)], [1, x(2)]…]
y = np.c_[y.T] # 按列方向组合, y=[[y(1)],[y(2)]…]
# 模型
def model(x, theta):
h = x.dot(theta) # 预估值h
return h
# 代价函数
def cost(h, y):
m = len(h) # 计算样本数
e = h - y # 误差
J = 1.0/(2*m)*np.sum(e.T.dot(e)) # 计算代价
return J
#梯度下降求最优解
# alpha=0.001学习率
# count_iter=15000迭代次数
def gradDesc(x, y, alpha=0.01, count_iter=15000):
m, n = x.shape # sharp返回值是元组(行,列)并赋值给m,n
theta = np.zeros((n, 1)) # 定义theta初始值,theta为矩阵(从初始值开始,沿着初始值下降)
jarr = np.zeros(count_iter) # 代价数组(多维数组)[0. 0. 0. ... 0. 0. 0.]
# 对theta进行更新
for i in range(count_iter):
h = model(x, theta) # 计算预估值
jarr[i] = cost(h, y) # 计算代价并存入数组
e = h - y # 计算误差
deltatheta = (1.0/m)*x.T.dot(e) # 计算deltatheta(梯度下降)
theta -= alpha*deltatheta # 更新deltatheta(迭代)
return jarr, theta
# 正解方程
def eqution(x, y):
theta = np.dot(np.linalg.inv(x.T.dot(x)),x.T.dot(y))
return theta
#模型得分,精度(模型的准确性,越接近1越准确)
def score(h, y):
u = np.sum((h-y)**2) # 误差平方和
v = np.sum((y-y.mean())**2) # 方差 mean()求平均数
return 1-u/v
# 训练模型
# 调用正解方程得到最优模型
# theta= eqution(x ,y)
# 调用梯度下降得到最优模型
jarr, theta = gradDesc(x, y)
# 预估值
h = model(x,theta)
print("线性回归精度:", score(h, y))
# 画代价曲线
# plt.plot(jarr)
# plt.title("代价曲线")
# plt.show()
# 画样本数据散点图和线性模型图
plt.figure('单变量线性回归') # 定义图形窗口(名称)
plt.scatter(x[:,-1], y, c='b',marker='x', label='原值') # 画样本数据的散点图 (默认线形 ’·’,marker定义散点样式)
plt.plot(x[:,-1], h, c='r') # 画模型
plt.title('线性回归和散点图') # 定义图形标题
plt.legend(loc='upper left') # 显示图例
plt.show() # 显示图形
梯度下降 | 正规方程 |
---|---|
需要选择学习率α | 不需要 |
需要多次迭代 | 一次运算得出 |
当特征数量n大时也能较好的shi适用 | 特征数量n较大则运算代价大,因为矩阵逆的计算时间复杂度为o(n³),通常来说当n小于10000时还是可以接受的 |
适用于各种类型模型 | 只适用于线性模型,不适合逻辑回归模型等其他模型 |
1.梯度下降是一个用来求函数最小值的算法,我们将使用梯度下降算法来求出代价函数J(θ0,θ1) 的最小值。
2.梯度下降背后的思想是:开始时我们随机选择一个参数的组合(θ0,θ1),计算代价函数,然后我们寻找下一个能让代价函数值下降最多的参数组合。
1.α是学习率(learning rate),大于0的一个很小经验值,它决定沿着能让代价函数下降的程度有多大。
2.每一次都同时让所有的参数减去学习速率乘以代价函数的导数。
3.“批量梯度下降”,指的是在梯度下降的每一步中,都要用到了所有的训练样本,因为代价函数是所有训练样本估计误差的平方和。
注意:
如果 α 太小,梯度下降就会变慢。
如果α太大,梯度下降法可能会越过最低点。甚至可能无法收敛,或者偏离。