[LR]線性回歸:預測上海車牌成交價格

線性回歸:預測上海車牌成交價格 - 為程序員服務 http://ju.outofmemory.cn/entry/246310

上海是全國最早實行私人轎車牌照拍賣方式來控制交通流量的城市,需要通過投標拍賣的形式購買車牌。
而車牌的拍賣并不是簡單的價高者得, 服務器 只接受最低可成交價上下300元區間內的出價,意思就是說,如果現在最低成交價是60000,你出價范圍必須在57000~63000之間,并且這個最低成交價是在不斷變化的,到了最后幾分價格上漲太快根本來不及操作。
如果能提前根據歷年 數據 預測本次拍賣成交價格,那么成功率必定比盲拍要高很多。
下面就嘗試使用 scikit-learn 這個機器學習工具庫來進行價格預測。
收集數據
在 上海國拍競標網 等其他公告 網站 收集到了最近幾年的完整拍賣記錄:

線性回歸:預測上海車牌成交價格

另外,一些重要的 政策 搜集也很重要,如果出現異常值可以剔除:
2013年4月,開始有最低警示價的約束。
2013年10月,取消警示價。
2013年11月,重啟警示價。
2014年1月,試行車牌拍賣年度統一警示價72600元。同時,將實行個人、單位分場拍賣。
2014年4月,投標卡參拍增至6次。
2014年7月,拍牌者必須提交駕駛證件。
2014年11月,二手車牌照不能私下交易,買賣納入統一拍賣平臺。
2015 年1月,警示價設定標準為剔除價格波動異常月份后,取最近三個月拍賣成交均價的加權平均值。

加載數據
數據和政策都收集好了,接下來就是數據預處理部分。預處理主要是讀取數據并除掉無用的列,重命名中文列名等等:
df = pd.read_csv('data.csv')df.rename(columns={'拍賣時間':'date','投放數量':'number',/ '警示價':'start','最低成交價':'low', '平均成交價':'mean','投標人數':'enrollment'}, inplace=True)df = df[['date','number','start','low','mean','enrollment']]df = df[:-1]

這是瀏覽一下數據大概是這樣的:
date
number
start
low
mean
enrollment

0
2013-4
11000
83600
83900
84101
26174

1
2013-5
9000
79900
80700
80803
222243






33
2016-2
8363
80600
83200
83244
196470

初步觀察
我們可以初步瀏覽一下數據的關聯度。將發放的車牌數、警示價、最低成交價、參與人數四個數據作為 x 變量,將平均成交價作為 y 變量,繪制他們的散點圖觀察分布情況:
import seaborn as sns%matplotlib inlinesns.pairplot(df,x_vars=['number','start','low','enrollment'],y_vars='mean',size=7,kind='reg')

結果如下:


線性回歸:預測上海車牌成交價格

我看見了什么!一條直線!這簡直就是完美吻合啊!


線性回歸:預測上海車牌成交價格

定睛一看,是最低成交價。
線性回歸:預測上海車牌成交價格

這本就該完美吻合,最低成交價不會比平均成交價低超過300元。
然后再想一下,在預測價格的時候,我們可以獲取到的數據是:
日期:2016-3
投放數量:8310
警示價:80600
投標人數:目前未知,當天可知,假設為 200000

所以我們需要關注的是:投放數量、警示價、投標人數,之間的關系。
單獨繪制警示價和成交均價的柱狀圖:
df.plot(y=['start','mean'],kind='Bar',figsize=[16,6])

觀察一下警示價與成交均價之間的關系:


線性回歸:預測上海車牌成交價格

似乎差值十分接近啊,將每個月的差值單獨繪制看看:
df['mean-start'] = df['mean']-df['start']ax = df.plot(y=['mean-start'],figsize=(16,6))ax.set_xticks(df.index)ax.set_xticklabels(df.date,rotation=90)

繪制結果如下:

線性回歸:預測上海車牌成交價格

本來差值穩定在1000左右,結果到了2015年突然失去了控制。可能和人數陡增有關,也有可能和某些政策出臺有關,暫且就先這樣。
線性回歸
我們先用最基礎的線性回歸模型來 測試 一下。
首先先把 X 和 y 單獨取出來,選擇投放數量、警示價、投標人數作為 X 變量,將成交均價作為 y 變量:
feature_cols = ['number', 'start', 'enrollment']X = df[feature_cols]y = df['mean']

然后區分訓練集和測試集:
from sklearn.cross_validation import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)print X_train.shape # (25,3)print y_train.shape # (25,)print X_test.shape # (9,3)print y_test.shape # (9,)

然后進行線性回歸分析:
from sklearn.linear_model import LinearRegressionlinreg = LinearRegression()linreg.fit(X_train, y_train)

看一下各個特征的系數:
print linreg.intercept_# 991.359968817zip(feature_cols, linreg.coef_)# [('number', 0.31616020072308526),# ('start', 0.9541013878172625),# ('enrollment', 0.015502778511636449)]

也就是說,最后的公式是:
y = 991.36 + 0.316 *投放數量 + 0.954 *警示價 + 0.0155 * 投標人數

這個結果合情合理,和我們一開始觀察數據的結果接近。
接下來評測一下這個模型的準確性,用模型預測測試數據集,計算預測結果和真實結果的 RMSE 值:
from sklearn import metricsy_pred = linreg.predict(X_test)zip(y_test,y_pred)print np.sqrt(metrics.mean_squared_error(y_test, y_pred))

計算結果是:RMSE = 1174.38,并不是很理想。RMSE 可以用于模型評價,后面優化 參數 的時候可以進行模型之間的對比。
直觀對比一下原始數據和預測數據:
fig, ax = plt.subplots()x = np.arange(len(y_test))ax.bar(x,y_test-y_pred,width=w)fig.show()

顯示結果如下:


線性回歸:預測上海車牌成交價格

而理論上,誤差值不能超過300才能搶到牌照。可見預測的結果并沒太多作用。
觀察到模型中投標人數的影響似乎不是很大,不妨把投標人數從模型中去除,看看結果如何:
feature_cols = ['number', 'start']X = df[feature_cols]y = df['mean']X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)linreg.fit(X_train, y_train)y_pred = linreg.predict(X_test)print np.sqrt(metrics.mean_squared_error(y_test, y_pred))

計算結果是:RMSE = 1318.04,似乎誤差更大了。
模型雖然不準,不過預測一下2016年3月的成交均價還是可以的。從公告來看,發放牌照8310張,警示價80600,假設參與人數為20000,那么預計成交價:
linreg.predict([[8310,80600,200000]])

結果是:83619.78 元。
小結
在 Coursera 上跟著學 Machine Learning 也有段時間了,一直是跟著教程使用 GraphLab Create 來做。今天第一次用 scikit-learn 進行數據分析,即使是最最最簡單的線性回歸也是一路磕磕絆絆,學藝不精吶。
如果有更好的想法歡迎和我交流:)
從結果來看,這個模型預測的結果誤差會在 2000 元以內,并不能達到最后需要的 300 元的要求,只能使用其他方法來解決了。
預知后事如何。

線性回歸:預測上海車牌成交價格

我解決了也不會告訴你。
原文http ://blog.callmewhy.com/2016/03/13/predict-plate-price-with-linear-regression/

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容