梯度下降 线性回归2021-04-16( 三 )


数据的下载:
鸢尾花数据下载链接
代码实现:
def MGD_train(X, y, alpha=0.0001, maxIter=1000, theta_old=None):'''MGD训练线性回归传入:X:已知数据y:标签alpha:学习率maxIter :总迭代次数 返回:theta : 权重参数'''# 初始化权重参数theta = np.ones(shape=(X.shape[1],))if not theta_old is None:# 假装是断点续训练theta = theta_old.copy()#axis=1 表示横轴,方向从左到右;axis=0 表示纵轴,方向从上到下for i in range(maxIter):# 预测y_pred = np.sum(X * theta, axis=1)# 全部数据得到的梯度gradient = np.average((y - y_pred).reshape(-1, 1) * X, axis=0)# 更新学习率theta += alpha * gradientreturn thetadef SGD_train(X, y, alpha=0.0001, maxIter=1000, theta_old=None):'''SGD训练线性回归传入:X:已知数据y:标签alpha:学习率maxIter :总迭代次数返回:theta : 权重参数'''# 初始化权重参数theta = np.ones(shape=(X.shape[1],))if not theta_old is None:# 假装是断点续训练theta = theta_old.copy()# 数据数量data_length = X.shape[0]for i in range(maxIter):# 随机选择一个数据index = np.random.randint(0, data_length)# 预测y_pred = np.sum(X[index, :] * theta)# 一条数据得到的梯度gradient = (y[index] - y_pred) * X[index, :]# 更新学习率theta += alpha * gradientreturn thetadef MBGD_train(X, y, alpha=0.0001, maxIter=1000, batch_size=10, theta_old=None):'''MBGD训练线性回归传入:X:已知数据y:标签alpha:学习率maxIter:总迭代次数batch_size :没一轮喂入的数据数返回:theta : 权重参数'''# 初始化权重参数theta = np.ones(shape=(X.shape[1],))if not theta_old is None:# 假装是断点续训练theta = theta_old.copy()# 所有数据的集合all_data = http://www.kingceram.com/post/np.concatenate([X, y.reshape(-1, 1)], axis=1)for i in range(maxIter):# 从全部数据里选 batch_size 个 itemX_batch_size = np.array(random.choices(all_data, k=batch_size))# 重新给 X, y 赋值X_new = X_batch_size[:, :-1]y_new = X_batch_size[:, -1]# 将数据喂入,更新 thetatheta = MGD_train(X_new, y_new, alpha=0.0001, maxIter=1, theta_old=theta)return thetadef GD_predict(X, theta):'''用于预测的函数传入:X: 数据theta : 权重返回:y_pred: 预测向量'''y_pred = np.sum(theta * X, axis=1)# 实数域空间 -> 离散三值空间,则需要四舍五入y_pred = (y_pred + 0.5).astype(int)return y_pred def calc_accuracy(y, y_pred):'''计算准确率传入:y: 标签y_pred: 预测值返回:accuracy : 准确率'''return np.average(y == y_pred)*100
# 读取数据iris_raw_data = http://www.kingceram.com/post/pd.read_csv('iris.data', names=['sepal length', 'sepal width', 'petal length', 'petal width', 'class'])# 将三种类型映射成整数Iris_dir = {'Iris-setosa': 1, 'Iris-versicolor': 2, 'Iris-virginica': 3}iris_raw_data['class'] = iris_raw_data['class'].apply(lambda x:Iris_dir[x])# 训练数据 Xiris_data = iris_raw_data.values[:, :-1]# 标签 yy = iris_raw_data.values[:, -1]# 用 MGD 训练的参数start = time.time()theta_MGD = MGD_train(iris_data, y)run_time = time.time() - starty_pred_MGD = GD_predict(iris_data, theta_MGD)print("MGD训练1000轮得到的准确率{:.2f}% 运行时间是{:.2f}s".format(calc_accuracy(y, y_pred_MGD), run_time))# 用 SGD 训练的参数start = time.time()theta_SGD = SGD_train(iris_data, y)run_time = time.time() - starty_pred_SGD = GD_predict(iris_data, theta_SGD)print("SGD训练1000轮得到的准确率{:.2f}% 运行时间是{:.2f}s".format(calc_accuracy(y, y_pred_SGD), run_time))# 用 MBGD 训练的参数start = time.time()theta_MBGD = MBGD_train(iris_data, y)run_time = time.time() - starty_pred_MBGD = GD_predict(iris_data, theta_MBGD)print("MBGD训练1000轮得到的准确率{:.2f}% 运行时间是{:.2f}s".format(calc_accuracy(y, y_pred_MBGD), run_time))