python线性回归实例 python一元线性回归分析代码( 三 )

接下来,让我们创建一个定制的train_test_split函数,将我们的数据拆分为一个训练和测试集:
# 拆分训练和测试集def train_test_divide(X,y,test_size=0.3,random_state=42):np.random.seed(random_state)train_size = 1 - test_sizearr_rand = np.random.rand(X.shape[0])split = arr_rand < np.percentile(arr_rand,(100*train_size))X_train = X[split]y_train = y[split]X_test =X[~split]y_test = y[~split]return X_train, X_test, y_train, y_testX_train,X_test,y_train,y_test = train_test_divide(X,y,test_size=0.3,random_state=42)基本上,我们在进行

  1. 得到测试集大小 。
  2. 设置一个随机种子,以确保我们的结果和可重复性 。
  3. 根据测试集大小得到训练集大小
  4. 从我们的特征中随机抽取样本
  5. 将随机选择的实例拆分为训练集和测试集
我们的成本函数我们将实现MSE或均方误差,一个用于回归任务的常见成本函数:
def mse(preds,y):m = len(y)return 1/(m) * np.sum(np.square((y - preds)))
  • M指的是训练实例的数量
  • yi指的是我们标签向量中的一个实例
  • preds指的是我们的预测
为了编写干净、可重复和高效的代码,并遵守软件开发实践,我们将创建一个线性回归类:
class LinReg:def __init__(self,X,y):self.X = Xself.y = yself.m = len(y)self.bgd = False
  • bgd是一个参数,它定义我们是否应该使用批量梯度下降 。
现在我们将创建一个方法来添加截距项:
def add_intercept_term(self,X):X = np.insert(X,1,np.ones(X.shape[0:1]),axis=1).copy()return X这基本上是在我们的特征开始处插入一个列 。它只是为了矩阵乘法 。
如果我们不加上这一点,那么我们将迫使超平面通过原点,导致它大幅度倾斜,从而无法正确拟合数据
缩放我们的特征:
def feature_scale(self,X):X = (X - X.mean()) / (X.std())return X接下来,我们将随机初始化权重:
def initialise_thetas(self):np.random.seed(42)self.thetas = np.random.rand(self.X.shape[1])现在,我们将使用以下公式从头开始编写标准方程:
def normal_equation(self):A = np.linalg.inv(np.dot(self.X.T,self.X))B = np.dot(self.X.T,self.y)thetas = np.dot(A,B)return thetas基本上,我们将算法分为三个部分:
  1. 我们得到了X转置后与X的点积的逆
  2. 我们得到重量和标签的点积
  3. 我们得到两个计算值的点积
这就是标准方程!还不错!现在,我们将使用以下公式实现批量梯度下降:
def batch_gradient_descent(self,alpha,n_iterations):self.cost_history = [0] * (n_iterations)self.n_iterations = n_iterationsfor i in range(n_iterations):h = np.dot(self.X,self.thetas.T)gradient = alpha * (1/self.m) * ((h - self.y)).dot(self.X)self.thetas = self.thetas - gradientself.cost_history[i] = mse(np.dot(self.X,self.thetas.T),self.y)return self.thetas在这里,我们执行以下操作:
  1. 我们设置alpha,或者学习率,和迭代次数
  2. 我们创建一个列表来存储我们的成本函数历史记录,以便以后在折线图中绘制
  3. 循环n_iterations 次,
  4. 我们得到预测,并计算梯度(函数切线的斜率) 。
  5. 我们更新权重以沿梯度负方向移动
  6. 我们使用我们的自定义MSE函数记录值
  7. 重复,完成后,返回结果
让我们定义一个拟合函数来拟合我们的数据:
def fit(self,bgd=False,alpha=0.158,n_iterations=4000):self.X = self.add_intercept_term(self.X)self.X = self.feature_scale(self.X)if bgd == False:self.thetas = self.normal_equation()else:self.bgd = Trueself.initialise_thetas()self.thetas = self.batch_gradient_descent(alpha,n_iterations)在这里,我们只需要检查用户是否需要梯度下降,并相应地执行我们的步骤 。

推荐阅读