python用支持向量机回归(SVR)模型分析用电量预测电力消费
最近我們被客戶要求撰寫(xiě)關(guān)于支持向量機(jī)回歸的研究報(bào)告,包括一些圖形和統(tǒng)計(jì)輸出。
本文描述了訓(xùn)練支持向量回歸模型的過(guò)程,該模型用于預(yù)測(cè)基于幾個(gè)天氣變量、一天中的某個(gè)小時(shí)、以及這一天是周末/假日/在家工作日還是普通工作日的用電量。
【視頻】支持向量機(jī)SVM、支持向量回歸SVR和R語(yǔ)言網(wǎng)格搜索超參數(shù)優(yōu)化實(shí)例
支持向量機(jī)SVM、支持向量回歸SVR和R語(yǔ)言網(wǎng)格搜索超參數(shù)優(yōu)化實(shí)例
,時(shí)長(zhǎng)07:24
關(guān)于支持向量機(jī)的快速說(shuō)明
支持向量機(jī)是機(jī)器學(xué)習(xí)的一種形式,可用于分類或回歸。盡可能簡(jiǎn)單地說(shuō),支持向量機(jī)找到了劃分兩組數(shù)據(jù)的最佳直線或平面,或者在回歸的情況下,找到了在容差范圍內(nèi)描述趨勢(shì)的最佳路徑。
對(duì)于分類,該算法最大限度地減少了對(duì)數(shù)據(jù)進(jìn)行錯(cuò)誤分類的風(fēng)險(xiǎn)。
對(duì)于回歸,該算法使回歸模型在某個(gè)可接受的容差范圍內(nèi)沒(méi)有獲得的數(shù)據(jù)點(diǎn)的風(fēng)險(xiǎn)最小化。
導(dǎo)入一些包和數(shù)據(jù)
import pandas as pd # 對(duì)于數(shù)據(jù)分析,特別是時(shí)間序列 import numpy as np # 矩陣和線性代數(shù)的東西,類似MATLAB from matplotlib import pyplot as plt # 繪圖Scikit-learn是Python中的大型機(jī)器學(xué)習(xí)包之一。
from sklearn import svm from sklearn import cross_validation from sklearn import preprocessing as pre在此隨機(jī)插入更好的數(shù)據(jù)可視化。
# 設(shè)置顏色 graylight = '#d4d4d2' gray = '#737373' red = '#ff3700'我在這個(gè)模型中使用的數(shù)據(jù)是通過(guò)公寓中安裝的智能電表中獲得的。
USAGE "字段給出了該小時(shí)內(nèi)的用電度數(shù)。
elec.head(3)Out[5]:
天氣數(shù)據(jù)提取。
weather.head()?
預(yù)處理
合并電力和天氣
首先,我們需要將電力數(shù)據(jù)和天氣數(shù)據(jù)合并到一個(gè)數(shù)據(jù)框中,并去除無(wú)關(guān)的信息。
# 合并成一個(gè)Pandas數(shù)據(jù)框架pd.merge(weather, elec,True, True)# 從數(shù)據(jù)框架中刪除不必要的字段 del elec['tempm'], elec['cost']# 將風(fēng)速轉(zhuǎn)換為單位elec['wspdm'] * 0.62elec.head()?
fig = plt.figure(figsize=[14,8])elecweather['USAGE'].plot我想將典型的工作日與周末、假日和在家工作的日子區(qū)分開(kāi)來(lái)。所以現(xiàn)在所有的正常工作日都是0,所有的假期、周末和在家工作的日子都是1。
分類變量:平日與周末/假期/在家工作日
## 將周末和節(jié)假日設(shè)置為1,否則為0 elecwea['Day'] = np.zeros# 周末 elecwea['Atypical_Day'][(elecwea.index.dawe==5)|(elecwea.index.dawe==6)] = 1# 假期,在家工作日 假期 = ['2014-01-01','2014-01-20'] workhome = ['2014-01-21','2014-02-13','2014-03-03','2014-04-04']for i in range(len(holiday)):elecwea['Day'][elecwea.index.date==np.datetime64(holidays[i])] = 1 for i in range(len(workhome)):elecwea['Day'][elecwea.index.date==np.datetime64(workhome[i]) ] = 1elecwea.head(3)更多的分類變量:一周中的一天,小時(shí)
在這種情況下,一天中的每個(gè)小時(shí)是一個(gè)分類變量,而不是連續(xù)變量。做分析時(shí),需要對(duì)一天中的每一個(gè)小時(shí)進(jìn)行 "是 "或 "否 "的對(duì)應(yīng)。
# 為一天中的每個(gè)小時(shí)創(chuàng)建新的列,如果index.hour是該列對(duì)應(yīng)的小時(shí),則分配1,否則分配0for i in range(0,24):elecweat[i] = np.zeros(len(elecweat['USAGE'))elecweat[i][elecweat.index.hour==i] = 1# 例子 3am elecweat[3][:6]時(shí)間序列:需要附加上以前的用電需求的歷史窗口
由于這是一個(gè)時(shí)間序列,如果我們想預(yù)測(cè)下一小時(shí)的能耗,訓(xùn)練數(shù)據(jù)中任何給定的X向量/Y目標(biāo)對(duì)都應(yīng)該提供當(dāng)前小時(shí)的用電量(Y值,或目標(biāo))與前一小時(shí)(或過(guò)去多少小時(shí))的天氣數(shù)據(jù)和用量(X向量)。
# 在每個(gè)X向量中加入歷史用量# 設(shè)置預(yù)測(cè)的提前小時(shí)數(shù) hours = 1# 設(shè)置歷史使用小時(shí)數(shù) hourswin = 12for k in range(hours,hours+hourswin):elec_weat['USAGE-%i'% k] = np.zero(len(elec_weat['USAGE'])for i in range(hours+hourswi,len(elecweat['USAGE']))。)for j in range(hours,hours+hourswin):elec_weat['USAGE-%i'% j][i] = elec_weat['USAGE]i-j] 。elec_weat.head(3)分成訓(xùn)練期和測(cè)試期
由于這是時(shí)間序列數(shù)據(jù),定義訓(xùn)練期和測(cè)試期更有意義,而不是隨機(jī)的零星數(shù)據(jù)點(diǎn)。如果它不是一個(gè)時(shí)間序列,我們可以選擇一個(gè)隨機(jī)的樣本來(lái)分離出一個(gè)測(cè)試集。
# 定義訓(xùn)練和測(cè)試期 train_start = '18-jan-2014'(訓(xùn)練開(kāi)始)。 train_end = '24-march-2014'. test_start = '25-march-2014'(測(cè)試開(kāi)始)。 test_end = '31-march-2014'。 # 分成訓(xùn)練集和測(cè)試集(仍在Pandas數(shù)據(jù)幀中)。xtrain = elec_and_weather[train_start:train_end]。 del xtrain['US'] del xtrain['time_end']ytrain = elec_and_weather['US'][train_start:train_end] 。將訓(xùn)練集輸出成csv,看得更清楚。
X_train_df.to_csv('training_set.csv')scikit-learn包接收的是Numpy數(shù)組,而不是Pandas DataFrames,所以我們需要進(jìn)行轉(zhuǎn)換。
# 用于sklearn的Numpy數(shù)組X_train = np.array(X_train_df)標(biāo)準(zhǔn)化變量
所有的變量都需要進(jìn)行標(biāo)準(zhǔn)化。該算法不知道每個(gè)變量的尺度是什么。換句話說(shuō),溫度一欄中的73的值看起來(lái)會(huì)比前一小時(shí)的千瓦時(shí)使用量中的0.3占優(yōu)勢(shì),因?yàn)閷?shí)際值是如此不同。sklearn的預(yù)處理模塊中的StandardScaler()將每個(gè)變量的平均值去除,并將其標(biāo)準(zhǔn)化為單位方差。當(dāng)模型在按比例的數(shù)據(jù)上進(jìn)行訓(xùn)練時(shí),模型就會(huì)決定哪些變量更有影響力,而不是由任意的比例/數(shù)量級(jí)來(lái)預(yù)先決定這種影響力。
訓(xùn)練SVR模型
將模型擬合訓(xùn)練數(shù)據(jù)!
SVR_model = svm.SVR(kernel='rbf',C=100,gamma=.001).fit(X_train_scaled,y_train) print 'Testing R^2 =', round(SVR_model.score(X_test_scaled,y_test),3)預(yù)測(cè)和測(cè)試
計(jì)算下一小時(shí)的預(yù)測(cè)(預(yù)測(cè)!)我們預(yù)留了一個(gè)測(cè)試數(shù)據(jù)集,所以我們將使用所有的輸入變量(適當(dāng)?shù)目s放)來(lái)預(yù)測(cè) "Y "目標(biāo)值(下一小時(shí)的使用率)。
# 使用SVR模型來(lái)計(jì)算預(yù)測(cè)的下一小時(shí)使用量SVRpredict(X_test_scaled)# 把它放在Pandas數(shù)據(jù)框架中,以便于使用 DataFrame(predict_y)繪制測(cè)試期間的實(shí)際和預(yù)測(cè)電力需求的時(shí)間序列。
# 繪制預(yù)測(cè)值和實(shí)際值plt.plot(index,y_test_df,color='k') plt.plot(predictindex,predict_y)重新取樣的結(jié)果為每日千瓦時(shí)
### 繪制測(cè)試期間的每日總千瓦時(shí)圖y_test_barplot ax.set_ylabel('每日總用電量(千瓦時(shí))')# Pandas/Matplotlib的條形圖將x軸轉(zhuǎn)換為浮點(diǎn),所以需要找回?cái)?shù)據(jù)時(shí)間 ax.set_xticklabels([dt.strftime('%b %d') for dt in誤差測(cè)量
以下是一些精度測(cè)量。
len(y_test_df)均方根誤差
這實(shí)際上是模型的標(biāo)準(zhǔn)誤差,其單位與預(yù)測(cè)變量(或這里的千瓦時(shí))的單位相同。
calcRMSE(predict_y, y_test_df)平均絕對(duì)百分比誤差
用這種方法,計(jì)算每個(gè)預(yù)測(cè)值和實(shí)際值之間的絕對(duì)百分比誤差,并取其平均值;計(jì)量單位是百分比。如果不取絕對(duì)值,而模型中又沒(méi)有什么偏差,你最終會(huì)得到接近零的結(jié)果,這個(gè)方法就沒(méi)有價(jià)值了。
errorsMAPE(predict_y, y_test_df)平均偏置誤差
平均偏差誤差顯示了模型的高估或低估情況。初始SVM模型的平均偏差誤差為-0.02,這表明該模型沒(méi)有系統(tǒng)地高估或低估每小時(shí)的千瓦時(shí)消耗。
calcMBE(predict_y, y_test_df)變異系數(shù)
這與RMSE類似,只是它被歸一化為平均值。它表明相對(duì)于平均值有多大的變化。
這與RMSE類似,只是它被歸一化為平均值。它表明相對(duì)于平均值有多大的變化。
plot45 = plt.plot([0,2],[0,2],'k')總結(jié)
以上是生活随笔為你收集整理的python用支持向量机回归(SVR)模型分析用电量预测电力消费的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 智慧社区下的智慧物业
- 下一篇: qt中opengl窗口的创建