线性学习中最基础的回归之一,本文从线性回归的数学假设,公式推导,模型算法以及实际代码运行几方面对这一回归进行全面的剖析~ 线性回归;准确地预测实值输出标记
一:线性回归的数学假设
1.假设输入的X和Y是线性关系,预测的y与X通过线性方程建立机器学习模型
2.输入的Y和X之间满足方程Y=X+e,e是误差项,噪音项,假设e是独立同分布的,服从IID(independent and identity distribution)和均值为0,方差为某一定数的正态分布(也叫高斯分布)e服从正态分布是由中新计值定理决定的
二、线性回归建模
2.1方程式表示:
数学形式:
矩阵形式:
其中,X矩阵是m行(n+1)列的,每一行是一个样本,每一列是样本的某一个特征
矩阵(n+1)行一列的,它是X的权重,也是线性回归要学习的参数
2.2 损失函数(Loss function)
对数极大似然和最小二乘的联系:
由线性函数的假设知道,噪音项满足高斯分布,其中一个样本的正态分布的数学表达为:
那么,通过极大估计求得似然函数为所有样本的乘积,如下:
经过数学运算和推导,求极大似然的最大值可以转化为求其log函数的最大值,推导过程如下:
要使得极大似然取得极大值,上式中的后一项就要最小,也可以将求线性回归的极大似然转化为求最小二乘的最小值,也就是常见到的线性函数的最小二乘求损失函数的数学形式:
由此就得到了线性函数的loss function
三、线性函数算法:求解参数
机器算法的目的就是通过建立模型并通过选择合适的算法来求出参数
下的y和实际的Y之间的差值尽量的小,也就是预测的准确率在训练集和测试集足够高
3.1 当矩阵
可逆(满秩)时,通过normal equation可以直接求解
目标函数转化为矩阵形式:
对其求导并求驻点
另上式为0,可求得
此算法的缺点是:当矩阵很大是,计算非常耗时且占用资源
3.2 当矩阵
不可逆(非满秩)时,通过梯度下降求解
初始化
,沿着负梯度方向进行迭代,知道
变化很小或者不变化
梯度下降中设计到的参数是,步长alpha,迭代次数t,这些对于计算最终的
都会影响,所以需要调参优化。
常用的梯度下降算法有SGD,BGD,mBGD,实际中以mBGD使用最多
四、线性回归防止overfitting
机器学习最忌讳的是死记硬背,像考试一样平时学习只记得死答案了,在考试的时候就不会做题目了,为了灵活变通,overfitting的方法就出现了,线性回归中最常用的是引入正则化项,也就惩罚项,给损失函数的参数
赋予一个约束项,使其不能任意的无限大或者无限小,加入正则化损失函数变为:
4.1当矩阵满秩时,引入正则项后的
变为:
4.2当矩阵不满秩时,引入正则项后的
变为:
import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets
'''
求逆矩阵
np.linalg.inv()
矩阵的转置:
X.T
在某个位置(列上面)前面插入相同的1
np.insert(X, 位置, 1, axis=1)
矩阵相乘:
X.dot(Y)
np.dot(X,Y)
'''
class LinearRegression():
def __init__(self):#新建变量
self.w = None
def fit(self, X, y):#训练集的拟合
X = np.insert(X, 0, 1, axis=1)#增加一个维度 axis 1列 0行
# X矩阵中,在第0列前面插入一列,全部为1
print (X.shape)
X_ = np.linalg.inv(X.T.dot(X))#公式求解
self.w = X_.dot(X.T).dot(y)
def predict(self, X):#测试集的测试反馈
#h(theta)=theta.T.dot(X)
# Insert constant ones for bias weights
X = np.insert(X, 0, 1, axis=1)
y_pred = X.dot(self.w)
return y_pred
def mean_squared_error(y_true, y_pred):
#真实数据与预测数据之间的差值(平方平均)
mse = np.mean(np.power(y_true - y_pred, 2))
return mse
def main():
#第一步:导入数据
# Load the diabetes dataset
diabetes = datasets.load_diabetes() #获取数据集
# Use only one feature
X = diabetes.data[:, np.newaxis, 2] #取出第三列的数据集,转化成列向量
print(X)
#第二步:将数据分为训练集以及测试集
# Split the data into training/testing sets
x_train, x_test = X[:-20], X[-20:]
# Split the targets into training/testing sets
y_train, y_test = diabetes.target[:-20], diabetes.target[-20:]
#第三步:导入线性回归类(之前定义的)
clf = LinearRegression()
clf.fit(x_train, y_train)#训练
y_pred = clf.predict(x_test)#测试
#第四步:测试误差计算(需要引入一个函数)
# Print the mean squared error
print ("Mean Squared Error:", mean_squared_error(y_test, y_pred))
#matplotlib可视化输出
# Plot the results
plt.scatter(x_test[:,0], y_test, color='black')#散点输出
plt.plot(x_test[:,0], y_pred, color='blue', linewidth=3)#预测输出
print(y_pred)
plt.show()
if __name__ == '__main__':
main()
import matplotlib.pyplot as plt import numpy as np from sklearn import datasets import pandas as pd ''' 房子大小与price的关系 预测房价 ''' import random house_size = [random.randrange(70,200) for i in range(10000)] distance_from_citycneter = [random.randrange(1,30) for i in range(10000)] floor = [random.randrange(1,20) for i in range(10000)] house_price = [] for i in range(10000): price = house_size[i]*random.randrange(5e4,10e4) + distance_from_citycneter[i] * -1e5 + floor[i]* 1e4 + random.randrange(1,1e6) house_price.append(price) X = [[1,house_size[i],distance_from_citycneter[i],floor[i]] for i in range(10000)] #print(X) X_matrix = np.array(X) print(X_matrix.shape) y_matrix = np.array(house_price) y_matrix = y_matrix.reshape(len(y_matrix),1) #10000 * 1 #print(y_matrix) theta = [0 for i in range(4)] theta_matrix = np.array(theta) theta_matrix = theta_matrix.reshape(len(theta_matrix),1) theta_matrix = theta_matrix.astype('float64') #print(theta_matrix) ''' def cost(): cost = 0 for i in range(10000): price = 0 for j in range(4): price +=X[i][j]*theta[j] cost+=(price - house_price[i])**2 return cost #print(house_size) print(cost()) def cost(): diff = X_matrix.dot(theta_matrix) - y_matrix cost = np.sum(np.power(diff,2)) return cost print(cost()) ''' #损失函数 def cost_function(X_,thrta_,y_): y_pred = X_.dot(thrta_) # 10000 * 1 #print(y_pred.shape) diff = y_pred - y_ squard_error = np.power(diff,2) return np.sum(squard_error)/(2*len(y_)) #print(cost_function(X_matrix,theta_matrix,y_matrix)) #梯度 def gradident(X_,thrta_,y_): y_pred = X_.dot(thrta_) # 10000 * 1 #print(y_pred.shape) diff = y_pred - y_ #print(diff.shape) gradient = (1/len(y_))*X_.T.dot(diff) # 4*10000 10000*4 return gradient #print(gradident(X_matrix,theta_matrix,y_matrix)) #print(theta_matrix.shape) max_iter = 20000 #迭代次数 learing_rate = 0.0000003 #[0.003,0.01,0.03,0.1,0.3] for i in range(max_iter): theta_matrix -=gradident(X_matrix,theta_matrix,y_matrix) * learing_rate if (i+1) % 20 == 0: print(cost_function(X_matrix,theta_matrix,y_matrix)) #print(X_matrix.dot(theta_matrix)) plt.scatter(X_matrix[:,1],y_matrix , color='black')#散点输出 plt.plot(X_matrix[:,1], X_matrix.dot(theta_matrix), color='blue', linewidth=0.3)#预测输出 plt.show()