接下来,让我们创建一个定制的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)基本上,我们在进行
- 得到测试集大小 。
- 设置一个随机种子,以确保我们的结果和可重复性 。
- 根据测试集大小得到训练集大小
- 从我们的特征中随机抽取样本
- 将随机选择的实例拆分为训练集和测试集
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基本上,我们将算法分为三个部分:- 我们得到了X转置后与X的点积的逆
- 我们得到重量和标签的点积
- 我们得到两个计算值的点积
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在这里,我们执行以下操作:- 我们设置alpha,或者学习率,和迭代次数
- 我们创建一个列表来存储我们的成本函数历史记录,以便以后在折线图中绘制
- 循环n_iterations 次,
- 我们得到预测,并计算梯度(函数切线的斜率) 。
- 我们更新权重以沿梯度负方向移动
- 我们使用我们的自定义MSE函数记录值
- 重复,完成后,返回结果
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)在这里,我们只需要检查用户是否需要梯度下降,并相应地执行我们的步骤 。
推荐阅读
- 小编教你python安装Scrapy框架的操作方法 小编教你电脑c盘满了怎么清理
- 奥奇传说圣骑战队什么时候回归,《奥奇传说手游》7月2日开启限量测试
- 什么游戏龙神职业,龙神终于回归了
- 今日何云伟李菁几乎不再合作 何云伟李菁
- 弹弹堂回归礼包给什么用,为什么玩了5年的良心游戏
- 弹弹堂跑车怎么获得,假如老版弹弹堂回归
- 后期的武器怎么打,回归不知道怎么打流放者山脉
- 生死狙击最新回归大礼是什么,我在末世有套房最新章节
- 杨洋回归女主从胡冰卿变成了她 杨洋胡冰卿
- 老公背叛出轨想回归 突然知道老公十年前背叛
