一個完整詳細的二維SVR案例分析過程

文章目錄

案例介紹 #

首先,此次案例是以油氣開發爲背景,選取加粗樣式其中重要的兩個參數含油飽和度孔隙度分別作爲此次案例的自變量和因變量進行試驗。按照正常的案例分析步驟進行操作,此次爲了凸顯程序效果會加上許多繪圖效果。

數據預處理 #

導入Python庫與所需數據集:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
data = pd.read_excel(r"xxx\xx\x.xlsx")

查看數據集:

data

在這裏插入圖片描述
提取目標數據並刪除空值行:

targetCol = data.loc[:, ['含油飽和度','孔隙度']];#提取目標的列
dealTargetCol = targetCol.dropna(axis=0, how='any')#刪除空值行

查看目標數據:

dealTargetCol

在這裏插入圖片描述

函數擬合仿真 #

查看目標數據集的分佈狀態:

#解決中文亂碼
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
#查看目標數據的分佈情況
plt.figure(figsize=(12,4))
plt.subplot(121)
sns.distplot(dealTargetCol['含油飽和度'])
plt.subplot(122)
sns.distplot(dealTargetCol['孔隙度'])
plt.show()

在這裏插入圖片描述
有圖可見,孔隙度數據呈近似正態分佈而含油飽和度數據有輕微的偏態分佈,此處對於含油飽和度數據應該再給與一定的數值處理使其分佈較爲平衡一些,此處爲了簡便我就沒處理。
繪製目標數據之間的散點圖:

plt.plot(dealTargetCol['含油飽和度'],dealTargetCol['孔隙度'],'ro',label=len(dealTargetCol['含油飽和度']))
plt.xlabel('含油飽和度')
plt.ylabel('孔隙度')
plt.legend()
plt.show()

在這裏插入圖片描述

進行函數擬合:
在這裏插入圖片描述

SVR建模 #

劃分數據集:

#劃分數據集X和Y
X=dealTargetCol.iloc[:,:-1]
Y=dealTargetCol.iloc[:,-1]

分割測試集與訓練集:

from sklearn.model_selection import train_test_split
#分割數據集的函數,test_siz用於決定訓練集與測試集的分割比例,random_state表示按指定的數值來獲取指定的隨機分配
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,Y,test_size=0.2,random_state=42)
#恢復分割後的索引
for i in [Xtrain, Xtest, Ytrain, Ytest]:
    i.index = range(i.shape[0])

定義繪製建模曲線函數:

#繪製建模曲線
def svr_results(y_test, X_test, fitted_svr_model):
    print("C: {}".format(fitted_svr_model.C))
    print("gamma: {}".format(fitted_svr_model.gamma))
    print("Epsilon: {}".format(fitted_svr_model.epsilon))
    perc_within_eps = 100*np.sum(y_test - fitted_svr_model.predict(X_test) < eps) / len(y_test)
    print("Percentage within Epsilon = {:,.2f}%".format(perc_within_eps))
    plt.figure(figsize=(10,7))
    plt.scatter(x=dealTargetCol['含油飽和度'], y=dealTargetCol['孔隙度'],label="非支持向量")
    plt.plot(Xtrain.take(fitted_svr_model.support_,axis = 0),Ytrain.take(fitted_svr_model.support_,axis = 0),'ro',label="支持向量")
    plt.plot(X_test, fitted_svr_model.predict(X_test), color='red',label="預測函數")
    plt.plot(X_test, fitted_svr_model.predict(X_test)+eps, color='black',label="預測邊界函數")
    plt.plot(X_test, fitted_svr_model.predict(X_test)-eps, color='black')
    plt.xlabel('含油飽和度')
    plt.ylabel('孔隙度')
    plt.title('SVR Prediction')
    plt.legend()
    plt.show()

SVR建模:

from sklearn.svm import SVR
kernels = ['linear','poly','rbf','sigmoid']
eps = 3
for kernel in kernels:
    svr = SVR(kernel=kernel,epsilon=eps, C=1.0,gamma=0.1).fit(Xtrain,Ytrain)
    Ypredict = svr.predict(Xtest)
    print("kernel: {}".format(kernel))
    svr_results(Ytest, Xtest, svr)

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
其實這裏的有些繪製圖形應該用三維圖形來展示視覺效果應該會更好,這裏我也略過,有興趣的夥伴可以自己嘗試着玩玩。

模型調參 #

由上圖不難看出在同等參數的情況下,核函數rbf的表現最爲優異,所以我們將以rbf爲核函數內核進行進一步模型調參來尋找最優的參數C和參數gamma。
注:我的上述理論沒有嚴格的正確性,所以爲了確保數據的絕對可靠性,可以再把另外三個核函數的最優參數的情況也一律尋找出來。
尋找最優參數C:

import math
# C_range = np.logspace(-1,0,100)
C_range = np.linspace(0.01,100,1000)
max_perc = 0.8
predicts = []
for c in C_range:
    svr = SVR(kernel='rbf',epsilon=3,gamma=0.1,C=c).fit(Xtrain,Ytrain)#gramma無影響
    perc_within_eps = 100*np.sum(Ytest - svr.predict(Xtest) < 3) / len(Ytest)
    max_perc = max(max_perc,perc_within_eps)
    predicts.append(perc_within_eps)
print("Max percentage within Epsilon = {:,.2f}%".format(max_perc))
plt.figure()
plt.plot(C_range,predicts,c="blue")
plt.xlabel('c')
plt.ylabel('predict')
plt.show()

在這裏插入圖片描述
由上圖不難看出20就是其中的一個最優參數C值。
尋找最優參數gamma:

# gamma_range = np.logspace(-2,0,1000)
gamma_range = np.linspace(0.01,10,1000)
max_perc = 0.8
predicts = []
for gamma in gamma_range:
    svr = SVR(kernel='rbf',epsilon=3,gamma=gamma,C=20).fit(Xtrain,Ytrain)
    perc_within_eps = 100*np.sum(Ytest - svr.predict(Xtest) < 3) / len(Ytest)
    max_perc = max(max_perc,perc_within_eps)
    predicts.append(perc_within_eps)
print("Max percentage within Epsilon = {:,.2f}%".format(max_perc))
plt.figure()
plt.plot(gamma_range,predicts,c="red")
plt.xlabel('gamma')
plt.ylabel('predict')
plt.show()

在這裏插入圖片描述
由圖可見,最優的gamma值就是最初的默認gamma值–0.1。
到此,此次SVR案例就完整結束,此實驗的操作還是很粗糙有很多細節可以優化,希望我所列出的部分能對大家會有所幫助吧。

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