【迴歸預測】SVM基礎實戰篇之經典預測(三)

【玩點有趣的】這幾篇SVM介紹是從0到1慢慢學會支持向量機,將是滿滿的乾貨,都是我親自寫的,可以隨我一起從頭瞭解SVM,並在短期內能使用SVM做到想要的分類或者預測~我也將附上自己基礎訓練的完整代碼,可以直接跑,建議同我一樣初學者們,自己從頭到尾打一遍,找找手感,代碼不能光看看,實踐出真知!

回顧一下,上上篇,我們建立和比較了線性分類器和非線性分類器,比較了多元線性核函數和線性核函數,解決了類型數量不平衡問題,上篇,我們使用SVC做了簡單的分類,話不多說,今天我們開始SVR做迴歸預測,原理篇和實戰基礎一 請參見上幾篇博客,我們循序漸進慢慢貼近真實情景!解決生活問題


估算交通流量

首先做一個比較有趣的應用,我們使用了SVR來預測:在洛杉磯棒球隊進行主場比賽期間,體育場周邊馬路通過的汽車數量

如圖:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-DqfFG0tt-1588401100241)(D:\CSDN\pic\基於SVM的項目實戰\1588294745562.png)]

這裏一萬七千條記錄數據,分別表示:星期,時間,對手球隊名,比賽是否正在進行,通過汽車的數量

【完整代碼】上代碼:

import numpy as np
from sklearn import preprocessing
from sklearn.svm import SVR

input_file = 'traffic_data.txt'

X = []
count = 0
with open(input_file, 'r') as f:
    for line in f.readlines():
        data = line[:-1].split(',')
        X.append(data)

X = np.array(X)

label_encoder = []
X_encoded = np.empty(X.shape)
for i, item in enumerate(X[0]):
    if item.isdigit():
        X_encoded[:, i] = X[:, i]
    else:
        label_encoder.append(preprocessing.LabelEncoder())
        X_encoded[:, i] = label_encoder[-1].fit_transform(X[:, i])

X = X_encoded[:, :-1].astype(int)
y = X_encoded[:, -1].astype(int)

params = {'kernel': 'rbf', 'C': 10.0, 'epsilon': 0.2}
regressor = SVR(**params)
regressor.fit(X, y)

import sklearn.metrics as sm

y_pred = regressor.predict(X)
print("Mean absolute error =", round(sm.mean_absolute_error(y, y_pred), 2))
print('mean squared error=',round(sm.mean_squared_error(y, y_pred),2))
print('median absolute error=',round(sm.median_absolute_error(y, y_pred),2))
print('explained variance score=',round(sm.explained_variance_score(y, y_pred),2))
print('R2 score=',round(sm.r2_score(y, y_pred),2))
input_data = ['Tuesday', '13:35', 'San Francisco', 'yes']
input_data_encoded = [-1] * len(input_data)
count = 0
for i, item in enumerate(input_data):
    if item.isdigit():
        input_data_encoded[i] = int(input_data[i])
    else:
        input_data_encoded[i] = int(label_encoder[count].transform([input_data[i]]))
        count = count + 1 

input_data_encoded = np.array(input_data_encoded)

print("Predicted traffic:", int(regressor.predict([input_data_encoded])[0]))


解說一下:

X = []
count = 0
with open(input_file, 'r') as f:
    for line in f.readlines():
        data = line[:-1].split(',')
        X.append(data)

X = np.array(X)

使用文件操作逐行讀取並使用spilt通過逗號分割得出最後一列的數據(汽車通行量)append進到數組X中,構成我們的初始數據, 再通過sklearn.preprocessing.LabelEncoder()進行標準化標籤,將標籤值統一轉換成range(標籤值個數-1)範圍內 ,最後使用fit_transform(X[:, i])進行fit和transform轉換成計算機可讀的數字(矩陣)形式:
【數據預處理】代碼如下

label_encoder = []
X_encoded = np.empty(X.shape)
for i, item in enumerate(X[0]):
    if item.isdigit():
        X_encoded[:, i] = X[:, i]
    else:
        label_encoder.append(preprocessing.LabelEncoder())
        X_encoded[:, i] = label_encoder[-1].fit_transform(X[:, i])
print('標準化操作(數據預處理)\n', X_encoded)
X = X_encoded[:, :-1].astype(int)
y = X_encoded[:, -1].astype(int)
print('影響結果的各個維度:\n', X)
print('Label:\n', y)

看看結果:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-QG0fPetj-1588401100244)(D:\CSDN\pic\基於SVM的項目實戰\1588295593582.png)]

可以看出:每行每列,帶有英文的字符也被清洗成了數字,這其中是有邏輯含義的,可以用過查看源碼明白。同樣的也可以通過Pandas實現上述操作。然後我們使用切片操作分割出label和X

後續就是使用SVR構建預測器,然後“餵它數據”:

params = {'kernel': 'rbf', 'C': 10.0, 'epsilon': 0.2}
regressor = SVR(**params)
regressor.fit(X, y)

import sklearn.metrics as sm

y_pred = regressor.predict(X)
print("Mean absolute error =", round(sm.mean_absolute_error(y, y_pred), 2))
print('mean squared error=',round(sm.mean_squared_error(y, y_pred),2))
print('median absolute error=',round(sm.median_absolute_error(y, y_pred),2))
print('explained variance score=',round(sm.explained_variance_score(y, y_pred),2))
print('R2 score=',round(sm.r2_score(y, y_pred),2))
input_data = ['Tuesday', '13:35', 'San Francisco', 'yes']
input_data_encoded = [-1] * len(input_data)
count = 0
for i, item in enumerate(input_data):
    if item.isdigit():
        input_data_encoded[i] = int(input_data[i])
    else:
        input_data_encoded[i] = int(label_encoder[count].transform([input_data[i]]))
        count = count + 1 

input_data_encoded = np.array(input_data_encoded)

print("Predicted traffic:", int(regressor.predict([input_data_encoded])[0]))


最後我們直接看結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-OaEvUKWe-1588401100247)(D:\CSDN\pic\基於SVM的項目實戰\1588296430207.png)]

這是這個情況下的預測汽車數量,[‘Tuesday’, ‘13:35’, ‘San Francisco’, ‘yes’] Predicted traffic =29

[‘Thursday’, ‘23:10’, ‘Arizona’, ‘no’]下: Predicted traffic =14

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-esMqgEJb-1588401100254)(D:\CSDN\pic\基於SVM的項目實戰\1588296776182.png)]

我們來看一下這幾個判別情況:
Mean absolute error =7.28

mean squared error= 106.94
median absolute error= 4.91
explained variance score= 0.47
R2 score= 0.47

介紹一下:

建立迴歸器後,需要建立評價迴歸器擬合效果的指標模型。

平均誤差(mean absolute error):這是給定數據集的所有數據點的絕對誤差平均值

均方誤差(mean squared error):給定數據集的所有數據點的誤差的平方的平均值,最流行

中位數絕對誤差(mean absolute error):給定數據集的所有數據點的誤差的中位數,可以消除異常值的干擾

解釋方差分(explained variance score):用於衡量我們的模型對數據集波動的解釋能力,如果得分爲1.0,表明我們的模型是完美的。

R方得分(R2 score):讀作R方,指確定性相關係數,用於衡量模型對未知樣本預測的效果,最好的得分爲1.0,值也可以是負數。

通常情況下,儘量保證均方誤差最低,而且解釋方差分最高。

可以看到,我們使用的這個SVR迴歸器不是那麼完美,甚至誤差有一些。

昨天也跟朋友有提高過:
機器學習算法和平常的數據結構與算法的區別:通俗的說,前者注重accuracy,recall,precision,F1_score,後者注重時間複雜度和空間複雜度,

那麼我們的SVR迴歸器的這個誤差當然是難以容忍的,我們來分析一下原因:

一:參數誤差:沒有通過網格搜索或者k折交叉驗證,貝葉斯優化調整超參數,svr的參數誤差很大,不同的參數,差別十萬八千里。

二:原始數據標準化過程:transform問題,或者未歸一化,

三:SVR容易欠擬合

這些都是待改進問題。

下面我們比較一下常用的迴歸與分類算法:

(資料來源百度,後期我們會把常用的算法介紹,並且實戰(實戰是理論的體現,兩者結合纔會綻放絢麗光芒))

一、樸素貝葉斯

  • 優點:小規模表現好,適合分類任務,適合增量訓練。
  • 缺點:對輸入形式敏感(數值型可以考慮二分?),很多時候要拉普拉斯平滑。

二、決策樹

  • 優點:計算簡單,可解釋型強,能處理缺失值,不相關特徵,能多分類。可以設計爲迴歸模型。
  • 缺點:過擬合問題(預剪枝、後剪枝)。RF可以解決一些,因爲對數據樣本的bagging加上對特徵的隨機選擇(比如選 n**0.5個特徵)引入了隨機,減小了過擬合。

三、logistic

  • 優點:實現簡單,速度快,存儲小。
  • 缺點:容易欠擬合,只能二分類(改進,1v1,1v多,多v多),對outlier比較敏感,不支持非線性劃分。

四、線性擬合(LSM/Ridge/Lasso)

  • 優點:實現簡單,計算簡單(close form,閉式解)。
  • 缺點:不能擬合非線性數據。

五、kNN

  • 優點:思路簡單(近朱者赤),理論成熟,可分類可迴歸,可非線性,對outlier不敏感。
  • 缺點:計算量大,樣本不平衡,大內存開銷。
  • 注:其實是免訓練的模型。也算優點吧。

六、SVM

  • 優點:可用於線性/非線性(核:高斯核、多項式核、字符串核、RBF、Logistic核),可以用於迴歸SVR,低泛化誤差,易解釋性,抗數據擾動(outlier),存儲小(支持向量)。
  • 缺點:需要手動選參數,選核函數,原始的SVM是二分類。

七、Adaboost

  • 優點:低泛化誤差,易實現,準確率高,參數少,多分類。降低偏差bias(預測與實際的差)。
  • 缺點:對outlier敏感(因爲會調誤分類權重),不能並行。
  • 注:和GBM(GBRT/GBDT)都是boosting,不同在於權重調整一個根據誤分類數據,一個根據梯度。

八、Random Forest

  • 優點:處理高維數據不用做特徵選擇;能給出特徵重要比;oob,使用無偏估計,泛化能力強;樹之間獨立,可並行,因而訓練快;不平衡數據可以平衡誤差;一部分特徵遺失仍然可以有精確度。不用剪枝。減低方差variance(數據擾動產生的不同結果)。
  • 缺點:在某些噪音較大的分類或者回歸問題上過擬合;對於不同取值的屬性的數據,取值劃分較多的屬性會對RF產生更大的影響,導致權值不可信。

九、xgboost

  • 基分類器除CART外還支持線性分類器,相當於LR、Ridge。
  • GBDT用一階,xgboost用一階和二階進行梯度優化。
  • 代價函數裏有L1和L2正則,控制複雜度減小過擬合。
  • shrinkage可以設置學習速率。
  • 借鑑了RF的列抽樣(選一些特徵),引入隨機(深度學習的dropout也是引入了隨機),降低過擬合,減少計算。
  • 缺失值的樣本也可以自動學習分裂方向。
  • 支持並行,不是tree粒度的,而是特徵粒度的。
  • 可並行的近似直方圖算法,高效生成候選的分割點。

十、k-means(屬於EM思想)

  • 優點:簡單快速,團狀效果好,O(nkt),通常局部收斂

  • 缺點:需要指定k,初始值敏感,需要指定距離定義/中心定義,數據形狀敏感(比如密度形狀的用DBSCAN,比如流形學習),對outlier敏感。

下一期我們先做一個真實項目實戰,後續我們遇到SVM問題,再繼續補充

這是我們的SVM第四期文章了,已經大致明白了他的原理和基本用法,我們使用了sklearn對SVM的封裝,也使用了numpy對SVM的復現,還可以使用libsvm和opencv對svm的封裝。接下來我們結合計算機視覺做有趣的實驗,先賣個關子(關注博主,下期繼續),上圖!

​		[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-uzlDA7ZB-1588401100257)(C:\Users\acer\AppData\Roaming\Typora\typora-user-images\1588310214408.png)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-rRoOpI1b-1588401100259)(D:\CSDN\pic\基於SVM的項目實戰\1588312745532.png)]

這是幫朋友做的畢業設計,其中有一些bug需要修復,一些問題,需要優化,並且,代碼不是我寫的,朋友給我的。我幫助他跑起來,並且現在開始幫助他修改,優化代碼,學C++,推薦算法去了,關注博主,敬請期待!

上海第二工業大學智能科學與技術大二 周小夏(CV調包俠)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章