实验目的:
掌握机器学习中的线性回归法,并能灵活使用解决解决实际问题
实验内容:
用 上 节 课 实 现 的 梯 度 下 降 法 和 本 次 试 验 中 的 sklearn 模 块 下 的
LinearRegression 对给出的数据进行线性回归
1. 解决思路
分别使用线性回归法和梯度下降法对所给出的 2005 年至 2015 年城镇公交车运营数
量(Buses,辆)以及人均国民生产总值(PGDP,元)的数据集进行一个训练和预测,并且
将所拟合出来的结果放到一个图中进行展示,进行一个结果的对比,其中线性回归法中利
用前八年的数据作为训练集,用后四年的数据进行一个预测,并且将预测结果显示出来,
在梯度下降法中,不断地进行学习率和迭代次数的调整得到一个最优的解,对比两个方法
得到的不同的结果。
2. 完成代码
import numpy as np import pandas as pd from matplotlib import pyplot as plt from sklearn.linear_model import LinearRegression # 步长 alpha = 0.000000000001 # 初始w initial_w = 0 # 初始b initial_b = 0 # 迭代次数 num_iter = 10 data=pd.read_csv("./data.csv"); def Plot(): plt.figure() plt.title('Data') plt.xlabel('Buses') plt.ylabel('PGDP(Yuan)') plt.grid(True) return plt def computer_cost(w, b, data): total_cost = 0 M = len(data) # 逐点计算平方损失误差,然后求平均数 for i in range(M): x = data['Bus'][i] y = data['PGDP'][i] print(x) print(y) total_cost += (y - w * x - b) ** 2 # 取平均 return total_cost / M def step_grad_desc(current_w, current_b, alpha, data): sum_grad_w = 0 sum_grad_b = 0 M = len(data) # 对每个点,代入公式求和 for i in range(M): x = data['Bus'][i] y = data['PGDP'][i] sum_grad_w += (current_w * x + current_b - y) * x sum_grad_b += current_w * x + current_b - y # 用公式求当前的梯度 grad_w = 2 / M * sum_grad_w grad_b = 2 / M * sum_grad_b # 梯度下降,更新当前的w和b updated_w = current_w - alpha * grad_w updated_b = current_b - alpha * grad_b return updated_w, updated_b def grad_desc(data, initial_w, initial_b, alpha, num_iter): w = initial_w b = initial_b # 定义一个list保存所有的损失函数值,用来显示下降的过程 cost_list = [] for i in range(num_iter): cost_list.append(computer_cost(w, b, data)) w, b = step_grad_desc(w, b, alpha, data) return [w, b, cost_list] if __name__ == '__main__': # buses: 城镇公交车运营数量 buses = data['Bus'] # pdgp: 人均国民生产总值 pgdp = data['PGDP'] # 绘制pgdp与buses之间的关系 plt = Plot() plt.plot(buses, pgdp, 'k.') # plt.show() # 损失函数是系数w,b的函数,另外还要传入数据x,y w,b,cost_list = grad_desc(data,initial_w,initial_b,alpha,num_iter) cost = computer_cost(w,b,data) print('w is :',w) print('b is :',b) print('cost is :',cost) # plt.plot(cost_list) # plt.show() plt.scatter(buses,pgdp) # 针对每一个x ,计算出预测的y值 pred_y = w*buses+b plt.plot(buses,pred_y,c='r') # plt.show() # 建立线性回归模型 model = LinearRegression() #建立训练集和测试集,用前八年的数据作为训练集其他作为测试集合 train = data[0:8] # 先取出想要的行数据 print(train) # 输出最终结果 test = data[8:] # 先取出想要的行数据 print(test) # 输出最终结果 # 数据预处理 X = np.array(train['Bus']).reshape(-1, 1) y = np.array(train['PGDP']).reshape(-1, 1) #模型训练 model.fit(X,y); X_pre=np.array(test['Bus']).reshape(-1,1) ## 获得预测的GDP序列 y_pre = model.predict(X_pre); # 在网格上绘制原始数据散点,图中黑色散点 plt.plot(X,y, 'k.') # 绘制预测的公交车-GDP曲线,图中绿色直线 plt.plot(X_pre ,y_pre, 'g-') plt.show()
3. 执行结果截图
图1.线性回归所得结果图
图2.梯度下降所得结果图
图3.对比图
图4.训练集和测试集数据
图5.梯度下降法所得结果参数
4.实验总结分析
项目中梯度下降法中的学习率设置为alpha = 0.000000000001,迭代次数为10次的时候就能得到一个比较理想的结果,所求出的w is : 0.07876775755048084,b is : 1.7174234732019216e-07,在线性回归方程中的斜率约为0.97,在对比图中可以看出线性回归法的预测准确率相比梯度下降法准确率更高一点,但是不可忽略的一点是在该组实验数据中的线性分布情况比较理想,比较明显呈线性分布,因此没有过多地干扰点,推测如果增加实验数据的数量或者改变数据点的分布使之更加的分散可能会出现不同的结果,两种方法的准确率可能又会有不同的结果显示,因此还需要进一步的进行实验验证对比。