一.作业介绍
目标:通过liner regression模型来预测PM2.5的值
数据:train data:已知2014/1/1至2014/12/20的18种污染物(其中包含需要预测的PM2.5) test data:一段时间连续10小时的各种污染物(包含需要预测的PM2.5)给定前9个小时预测第10小时的(PM2.5)。
二.数据处理
因为test data是在给定的9小时上去预测第10个小时,因此训练数据也拆分整合成每10个小时为一个训练样本,前9个小时的数据去训练数据,第10个小时去计算los值。
三.模型搭建
首先是linear function 参数有18*9(162)个,y=b+W*X
''' linear_function ''' def linear_model(data,W,b): ''' :param W: :param b: :param data: :return:返回更新后的W,b,Loss ''' X=np.array(data.iloc[:,0:-1]).astype(np.float64) X=X.reshape(18*9,1) y=data.iloc[:,-1].reset_index(drop=True) try: y_true = float(y[9]) except: print(y) y_model=b+np.dot(W,X) print('训练前误差为'+str(y_true-y_model[0][0])) W,b,Loss=loss_function(y_true,W,b,X) y_model = b + np.dot(W, X) print('训练后误差为' + str(y_true - y_model[0][0])) return W,b,Loss
然后是Loss function
Loss function: L=∑(y_ture-(b+∑Wi*Xi))^2+λ∑(Wi)^2
gradient descent:∂L/∂Wi=∑2*(y_ture-(b+∑Wi*Xi))*(-Xi)+2*λ*Wi ∂L/∂b=∑2*(y_ture-(b+∑Wi*Xi))*(-1)
''' Loss function ''' def loss_function(y_true,W,b,X): ''' Loss function: L=∑(y_ture-(b+∑Wi*Xi))^2+λ∑(Wi)^2 gradient descent:∂L/∂Wi=∑2*(y_ture-(b+∑Wi*Xi))*(-Xi)+2*λ*Wi ∂L/∂b=∑2*(y_ture-(b+∑Wi*Xi))*(-1) :param y_true: :param W: :param b: :param X: :return:更新后的W与b ''' new_W=np.empty((1,162)) new_b=b λ=0.1#平滑参数 Π=0.000001#学习率 #对每一个W参数都进行更新 for index in range(0,len(W[0])): #每一个Wi的更新梯度 gradient_descent_Wi=2*(y_true-(b+np.dot(W,X)[0][0]))*(-X[index][0])+2*λ*W[0][index] #更新参数,原来Wi减去学习率与更新梯之积 new_Wi=W[0][index]-Π*gradient_descent_Wi new_W[0][index]=new_Wi #b的更新梯度 gradient_descent_b=2*(y_true-(b+np.dot(W,X)))*(-1) #更新后的b new_b=b-Π*gradient_descent_b[0][0] #计算误差 Loss=(y_true-(b+np.dot(new_W,X)[0][0]))**2 for index in range(0,len(new_W[0])): Loss+=λ*(W[0][index])**2 return new_W,new_b,Loss
控制函数
''' 模型训练控制 ''' def model_control(): Loss_list=list() Loss_min=float('inf') W_min=0 #初始化参数 W,b=initialize_W_b() train_data_list=data_processing() index=1 # print('------初始化-----') # print(W,b) for train_data in train_data_list: print('------------第'+str(index)+"次训练------------") temp_W,temp_b,Loss=linear_model(train_data,W,b) print('----------------------------------------------') index+=1 W=temp_W b=temp_b if Loss<Loss_min: W_min=temp_W Loss_min=Loss Loss_list.append(Loss) print('最小loss'+str(Loss_min)) print(W_min) x_index=[i for i in range(len(Loss_list))] plt.plot(x_index, Loss_list, color='red', linewidth=2.0, linestyle='-') plt.title('3600次每一次迭代的Loss值') plt.ylabel('Loss值') plt.xlabel('次数') plt.show()
四.训练结果测试
当学习率为0.000001时,3600次训练最低loss值为4.38。每一次训练的loss值折线图如下
发现训练的次数越多,误差居然越大。
看一下前300次训练的结果:
前300次的训练误差最好是7.72,已经和3600次最优结果4.38很接近了。