sklearn之线性回归实现—阿里云天池二手车交易价格预测赛
最近整理了線性回歸的原理及代碼實現,想要用實際數據來測試模型,正好看到阿里云天池數據賽正在進行二手車交易價格預測算法賽,正好能用線性回歸模型進行預測,就在這里分享一下代碼。
一、賽題介紹
賽題以預測二手車的交易價格為任務,該數據來自某交易平臺的二手車交易記錄,總數據量超過40w,包含31列變量信息,其中15列為匿名變量。其中抽取15萬條作為訓練集,5萬條作為測試集A,5萬條作為測試集B。
特征如下:
二、數據預處理
數據預處理是跑模型之前最重要的一步,做好預處理,模型也就成功了一半。
import pandas as pd import numpy as np data=pd.read_csv('./train.csv',encoding='big5') #讀取訓練集 data=data.iloc[:,2:] #只取有用字段為了方便讀取數據,我將原始數據中price(價格)字段移到最后一列。
x_data=data.iloc[:,:28] #取特征字段 y_data=data.iloc[:,28] #取目標值price字段 x=np.array(x_data.values.tolist()) #將數據展開成二維數據 y=np.array(y_data.values.tolist()) #將數據展開成二維數據在進行預處理之前,先做特征分析,看看各個特征的分布。
查看數據的特征字段名稱:
查看該特征數據分布:
作特征數據分布圖:
與Y值做散點圖:
對所有特征數據做歸一化,保持特征量綱統一。
將訓練集按8:2比例分為組內訓練集與測試集,測試模型訓練效果。
import math x_train_set = x[: math.floor(len(x) * 0.9), :] y_train_set = y[: math.floor(len(y) * 0.9)] x_validation = x[math.floor(len(x) * 0.9): , :] y_validation = y[math.floor(len(y) * 0.9):]三、線性回歸模型代碼實現
我嘗試直接利用手寫線性回歸算法代碼實現模型訓練。
dim = 28+1 #之所以+1是留出誤差項b的位置 w = np.ones([dim, 1]) #w就是待學習參數 x_1 = np.concatenate((np.ones([len(x_train_set), 1]), x_train_set), axis = 1).astype(float) learning_rate = 100 #初始化學習率設置為100 iter_time = 1000 #訓練次數為1000次 adagrad = np.zeros([dim, 1]) #adagrad自適應學習率方法 eps = 0.0000000001 #adagrad中防止分母為0的極小值 for t in range(iter_time):loss = np.sqrt(np.sum(np.power(np.dot(x_1, w) - y,2)) / len(x_train_set)) #損失函數if(t%100==0): #每隔100次輸出一次誤差值print(str(t) + ":" + str(loss))gradient = 2 * np.dot(x_1.transpose(), np.dot(x_1, w) - y) ##計算的梯度adagrad=adagrad+gradient ** 2 w = w - learning_rate * gradient / np.sqrt(adagrad + eps) #更新w的值結果遇到報錯"MemoryError: Unable to allocate 151. GiB for an array with shape (135000, 150000) and data type float64" ,意思就是待訓練矩陣過大導致內存不足無法計算。
在嘗試盡量縮小訓練數據量后,發現計算機最多只能計算數千條數據,我轉而求助sklearn包來實現線性回歸。
四、sklearn代碼實現
sklearn是目前python中十分流行的用來實現機器學習的第三方包,其中包含了多種常見算法如:決策樹,邏輯回歸、集成算法(如隨機森林)等等。
用sklearn實現多元線性回歸:
參數 fit_intercept,選擇是否需要計算截距,默認為True;
參數 normalize,選擇是否需要標準化(中心化),默認為false;
預測組內測試集,查看均方誤差大小。
作圖查看預測效果,數據集數據量太大,只取前100個預測結果查看擬合效果:
y_pred_p=y_pred[:100] #取預測結果 y_train_set_p=y_validation[:100] #取組內測試集結果 plt.figure(dpi=100) plt.plot(range(len(y_pred_p)),y_pred_p,'b',label="predict") plt.plot(range(len(y_train_set_p)),y_train_set_p,'r',label="test")可以看到預測結果大體上還是和測試集相符的:
五、比賽得分
將訓練的模型用于待預測數據集,輸出結果提交到比賽中。
testdata = pd.read_csv('./test.csv', encoding='big5') test_data = testdata.iloc[:, 2:] test_x = np.array(test_data.values.tolist()) # 將其轉換為數組 # 下面是Normalize,且必須跟training data是同一種方法進行Normalize for i in range(len(test_x)): #12 * 471for j in range(len(test_x[0])): #18 * 9 if std_x[j] != 0:test_x[i][j] = (test_x[i][j] - mean_x[j]) / std_x[j]預測結果:
y_pred_test=reg.predict(test_x)將結果輸出到csv文件中:
import csv with open('./result.csv', mode='w', newline='') as submit_file:csv_writer = csv.writer(submit_file)header = ['SaleID', 'price']print(header)csv_writer.writerow(header)for i in range(50000):if y_pred_test[i]<0 :y_pred_test[i]=0 #如果預測結果小于0,就為0,因為價格不可能小于0row = [str(i+150000), y_pred_test[i]]csv_writer.writerow(row)print(row)以下為提交結果后獲得的誤差分數與排名,可以看到和其他人提交的結果還是有很大差距的。
六、模型優化
面對不佳的預測效果,我回頭檢查數據發現了一些數據缺失和數據移位的問題,進行數據補齊后重新訓練模型,但預測分數沒有得到顯著提升。
于是我思考基于sklearn優化現有線性回歸模型。
(1) 嶺回歸
嶺回歸在損失函數中增加了正則項,也叫L2范數,以限制模型參數對異常樣本的匹配程度,進而提高模型面對多數正常樣本的擬合精度。
from sklearn.linear_model import Ridge,RidgeCV Lambdas=np.logspace(-0.5,1,5) #構造不同的lambda值#設置交叉驗證的參數,使用均方誤差評估 ridge_cv=RidgeCV(alphas=Lambdas,normalize=True,scoring='neg_mean_squared_error',cv=10) ridge_cv.fit(x_train_set,y_train_set)#基于最佳lambda值建模 ridge=Ridge(alpha=ridge_cv.alpha_,normalize=True) ridge.fit(x_train_set,y_train_set)#輸出預測結果 ridge_pred=ridge.predict(x_validation)#評估模型效果 MSE=metrics.mean_squared_error(y_validation,ridge_pred) print(MSE)提交比賽結果后,模型預測表現沒有得到顯著提升。
(2)LASSO回歸
嶺回歸無法剔除變量,而LASSO回歸模型,將懲罰項由L2范數變為L1范數,可以將一些不重要的回歸系數縮減為0,達到剔除變量的目的。
from sklearn.linear_model import Lasso,LassoCV Lambdas=np.logspace(-0.5,1,2)#設置交叉驗證的參數,使用均方誤差評估 lasso_cv=LassoCV(alphas=Lambdas,normalize=True,cv=10,max_iter=10000) lasso_cv.fit(x_train_set,y_train_set)#基于最佳lambda值建模 lasso=Lasso(alpha=lasso_cv.alpha_,normalize=True,max_iter=10000) lasso.fit(x_train_set,y_train_set)#輸出預測結果 lasso_pred=lasso.predict(x_validation)#評估模型效果 MSE=metrics.mean_squared_error(y_validation,lasso_pred) print(MSE)提交比賽結果后,模型預測表現沒有得到顯著提升。
至此,線性回歸模型在二手車交易價格預測賽中的代碼如上。
小記:
1、線性回歸在sklearn上實現即方便又快速。
2、我看到二手車交易價格預測賽論壇中,排名靠前的模型都是神經網絡實現的,下一步我將用神經網絡框架實現價格預測模型,對比現有模型效果。
總結
以上是生活随笔為你收集整理的sklearn之线性回归实现—阿里云天池二手车交易价格预测赛的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2013/06 事情发生之后都会显得云淡
- 下一篇: 算法——最短路径应用