日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

用Scikit-learn和TensorFlow进行机器学习(五)

發(fā)布時間:2025/3/19 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用Scikit-learn和TensorFlow进行机器学习(五) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 支持向量機(jī)(SVM)
  • 一、線性支持向量機(jī)分類
    • 1、硬間隔分類
    • 2、軟間隔分類
  • 二、非線性支持向量機(jī)分類
    • 1、多項式核(Polynomial Kernel)
    • 2、增加相似特征
    • 3、計算復(fù)雜度
  • 三、SVM回歸
    • 1、線性SVM回歸
    • 2、非線性SVM回歸
  • 四、SVM理論

支持向量機(jī)(SVM)

可做線性或者非線性的分類、回歸,甚至異常值檢測。
適用于:復(fù)雜但中小規(guī)模數(shù)據(jù)集的分類問題。

一、線性支持向量機(jī)分類

1、硬間隔分類


左圖雖紅線和紫線都可以區(qū)分不同類別,但是兩條直線都非常靠近樣本,如果有新的樣本加入,有比較大的可能會分類錯誤。

右圖為線性SVM結(jié)果,其的**思想:決策邊界在正確分類的同時離最近的樣本盡可能的遠(yuǎn)。**而這些最近的樣本(途中虛線上的點)即為支持向量(support vector)。因此只要沒有點在這些點劃分的區(qū)域之間,決策邊界就只由這些支持向量所決定。

注意:SVM對特征縮放敏感==》需先進(jìn)行
不足:

  • 只適用于線性可分?jǐn)?shù)據(jù)集;
  • 對異常值敏感,eg:如下圖所示

2、軟間隔分類

在sklearn中的SVM類,用 C 超參數(shù)(懲罰系數(shù),松弛因子) 來控制軟的程度:較小的 C 會導(dǎo)致更大的 “間隔”,但更多的“間隔”違規(guī)。

實現(xiàn):鳶尾花( Iris) 數(shù)據(jù)集, 縮放特征, 并訓(xùn)練一個線性 SVM 模型( 使用 LinearSVC 類, 超參數(shù) C=1 , hinge 損失函數(shù)) 來檢測 Virginica 鳶尾花, 生成的模型。

import numpy as np from sklearn import datasets from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from sklearn.svm import LinearSVCiris = datasets.load_iris() x = iris["data"][:,(2, 3)] # petal length, petal width y = (iris["target"] == 2).astype(np.float64)svm_clf = Pipeline((("scaler", StandardScaler()),("linear_svc",LinearSVC(C=1, loss="hinge")) )) svm_clf.fit(x, y) predict = svm_clf.predict([[5.5, 1.7]]) print(predict)

輸出結(jié)果

[1.]

注意:

  • SVM分類器不像 Logistic 回歸分類器一樣有 predict_proba() 方法來計算得分(概率),因為SVM只是靠支持向量來構(gòu)建決策線。
  • loss函數(shù)一定要記得填 hinge,因為默認(rèn)不是 hinge。

不同實現(xiàn):

  • SVC類 svc(kernel="linear", C=1),在較大訓(xùn)練集上慢,不推薦;
  • SGDClassifier 類,SGDClassifier(loss="hinge", alpha=1/(m*C)),這種使用隨機(jī)梯度下降方法來訓(xùn)練SVM,雖然沒有LinearSVC收斂快,但是能夠處理數(shù)據(jù)量龐大的訓(xùn)練集,而且能夠在線學(xué)習(xí)。

二、非線性支持向量機(jī)分類

處理非線性數(shù)據(jù)集方法:

  • 增加更多的特征(eg:多項式特征,然后采用線性SVM。例如添加 x2、x3x^2、x^3x2x3 特征)
  • 直接采用多項式的kernel,直接進(jìn)行非線性SVM的分類。

注意:

  • SVC中的 參數(shù)C 越大,對于訓(xùn)練集來說,其誤差越小,但是很容易發(fā)生過擬合;C 越小,則允許有更多的訓(xùn)練集誤分類,相當(dāng)于soft margin。
  • SVC中的 參數(shù)coef0 反映了高階多項式相對于低階多項式對模型的影響,如果發(fā)生了過擬合的現(xiàn)象,則可以減小 coef0;如果發(fā)生了欠擬合的現(xiàn)象,可以試著增大 coef0

1、多項式核(Polynomial Kernel)

from sklearn.datasets import make_moons from sklearn.pipeline import Pipeline from sklearn.preprocessing import PolynomialFeaturespolynomial_svm_clf = Pipeline((# 多項式特征("poly_features", PolynomialFeatures(degree=3)),("scaler", StandardScaler()),("svm_clf", LinearSVC(C=10, loss="hinge")) )) polynomial_svm_clf.fit(X, y)

增加多項式特征來進(jìn)行非線性分類。但是如果degree設(shè)置的比較小,則比較難分類比較復(fù)雜的數(shù)據(jù);如果degree設(shè)置的比較大,產(chǎn)生了大量模型,導(dǎo)致訓(xùn)練的非常慢。

解決方法:“核技巧(Kernel Trick)”
使用 3 階( degree=3 )的多項式核訓(xùn)練一個SVM分類器,超參數(shù) coef0 控制I高階多項式與低階多項式對模型的影響。

import numpy as np import matplotlib.pyplot as plt from sklearn.svm import SVC from sklearn.datasets import make_moonsdef plot_dataset(X, y, axes):plt.plot( x[:,0][y==0], x[:,1][y==0], "bs" )plt.plot( x[:,0][y==1], x[:,1][y==1], "g^" )plt.axis( axes )plt.grid( True, which="both" )plt.xlabel(r"$x_l$")plt.ylabel(r"$x_2$")# contour函數(shù)是畫出輪廓,需要給出X和Y的網(wǎng)格,以及對應(yīng)的Z,它會畫出Z的邊界(相當(dāng)于邊緣檢測及可視化) def plot_predict(clf, axes):x0s = np.linspace(axes[0], axes[1], 100)x1s = np.linspace(axes[2], axes[3], 100)x0, x1 = np.meshgrid( x0s, x1s )X = np.c_[x0.ravel(), x1.ravel()]y_pred = clf.predict( X ).reshape( x0.shape )y_decision = clf.decision_function( X ).reshape( x0.shape )plt.contour( x0, x1, y_pred, cmap=plt.cm.winter, alpha=0.5 )plt.contour( x0, x1, y_decision, cmap=plt.cm.winter, alpha=0.2 )x, y = make_moons(n_samples=100, noise=0.15, random_state=2019) poly_kernel_svm_clf = Pipeline((("scaler", StandardScaler()),("svm_clf", SVC(kernel="poly", degree=3, coef0=1, C=5)) )) poly_kernel_svm_clf.fit(x, y) plot_dataset( x, y, [-1.5, 2.5, -1, 1.5]) plot_predict(poly_kernel_svm_clf, [-1.5, 2.5, -1, 1.5]) plt.show()

輸出結(jié)果

==》超參數(shù)優(yōu)化:網(wǎng)格搜素

不同參數(shù)的影響

from sklearn.svm import SVCpoly_kernel_svm_clf = Pipeline([("scaler", StandardScaler()),("svm_clf", SVC(kernel="poly", degree=3, coef0=1, C=0.5)) ]) poly_kernel_svm_clf.fit(x, y) plt.figure(figsize=(9, 3)) plt.subplot(131) plot_dataset(x, y, [-1.5, 2.5, -1, 1.5]) plot_predict(poly_kernel_svm_clf, [-1.5, 2.5, -1, 1.5])poly_kernel_svm_clf = Pipeline([("scaler", StandardScaler()),("svm_clf", SVC(kernel="poly", degree=3, coef0=1, C=10)) ]) poly_kernel_svm_clf.fit(x, y) plt.subplot(132) plot_dataset(x, y, [-1.5, 2.5, -1, 1.5]) plot_predict(poly_kernel_svm_clf, [-1.5, 2.5, -1, 1.5])poly_kernel_svm_clf = Pipeline([("scaler", StandardScaler()),("svm_clf", SVC(kernel="poly", degree=3, coef0=100, C=0.5)) ]) poly_kernel_svm_clf.fit(x, y) plt.subplot(133) plot_dataset(x, y, [-1.5, 2.5, -1, 1.5]) plot_predict(poly_kernel_svm_clf, [-1.5, 2.5, -1, 1.5])plt.show()

2、增加相似特征

思路:使用相似函數(shù)(similarity function)計算每個樣本與特定地表(landmark)的相似度。
此處,定義相似函數(shù):高斯徑向基函數(shù)(Gaussian Radial Basis Function,RBF),設(shè)置 γ=0.3\gamma=0.3γ=0.3

Gaussian徑向基函數(shù):
Φγ(x,l)=e(?γ∣∣x?l∣∣2)\Phi_\gamma(x,l)=e^{(-\gamma||x-l||^2)}Φγ?(x,l)=e(?γx?l2)
其中,lll 表示地標(biāo),最簡單的地標(biāo)的選擇方法:在數(shù)據(jù)集中的每一個樣本的位置創(chuàng)建地標(biāo),在轉(zhuǎn)換特征之后,需刪除原始特征。缺點:當(dāng)訓(xùn)練集非常大,轉(zhuǎn)換后特征也非常大。

==》解決方法:高斯 RBF 核
當(dāng)數(shù)據(jù)在低維空間中不可分割的時候,可以嘗試將它們映射到高維空間,通過核函數(shù)來進(jìn)行這樣的映射操作。

rbf_kernel_svm_clf = Pipeline([("scaler", StandardScaler()),("svm_clf", SVC(kernel="rbf", gamma=5, C=0.001)) ]) rbf_kernel_svm_clf.fit(x, y) plt.figure(figsize=(6, 3)) plt.subplot(121) rbf_kernel_svm_clf.fit(x, y) plot_dataset(x, y, [-1.5, 2.5, -1, 1.5]) plot_predict(rbf_kernel_svm_clf, [-1.5, 2.5, -1, 1.5])rbf_kernel_svm_clf = Pipeline([("scaler", StandardScaler()),("svm_clf", SVC(kernel="rbf", gamma=0.1, C=0.001)) ]) plt.subplot(122) rbf_kernel_svm_clf.fit(x, y) plot_dataset(x, y, [-1.5, 2.5, -1, 1.5]) plot_predict(rbf_kernel_svm_clf, [-1.5, 2.5, -1, 1.5]) plt. plt.show()


增大 γ 使鐘型曲線更窄) , 導(dǎo)致每個樣本的影響范圍變得更小: 即判定邊界最終變得更不規(guī)則, 在單個樣本周圍環(huán)繞。 相反的, 較小的 γ 值使鐘型曲線更寬, 樣本有更大的影響范圍, 判定邊界最終則更加平滑。
==》 γ 是可調(diào)整的超參數(shù): 如果模型過擬合, 你應(yīng)該減小 γ 值, 若欠擬合, 則增大 γ ( 與超參數(shù) C 相似) 。

其他核函數(shù):字符串核(String Kernels)、SSK核、編輯距離的核函數(shù)。

核函數(shù)的選擇:一般先嘗試線性核函數(shù)(Linear比SVC(kernel=“l(fā)inear”)要快得多),尤其是訓(xùn)練集很大或有大量特征的情況下。若訓(xùn)練集不太大,則嘗試高斯徑向基核,其對大多數(shù)情況下都很有效。

3、計算復(fù)雜度

LinearSVC 類基于 liblinear 庫,是線性 SVM 的優(yōu)化算法,不支持核技巧,訓(xùn)練時間復(fù)雜度大約為 O(m×n)O(m × n)O(m×n)mmm 為樣本個數(shù),nnn 為特征數(shù)。

SVC 類基于 libsvm 庫,支持核技巧。訓(xùn)練時間復(fù)雜度:介于 O(m2×n)和O(m3×n)O(m^2\times n) 和 O(m^3\times n)O(m2×n)O(m3×n) 之間。適用于:復(fù)雜但小型或中等數(shù)量的數(shù)據(jù)集。可以對特征數(shù)量進(jìn)行縮放,尤其是稀疏特征(sparse features)。

三、SVM回歸

SVM也可以用于回歸問題,有線性SVM與非線性SVM回歸。

SVM回歸任務(wù)是限制間隔違規(guī)情況下,盡量放置更多的樣本在“間隔(margin)”上,“間隔(margin)”由超參數(shù) ?\epsilon? 控制。在間隔之內(nèi)添加數(shù)據(jù)樣本不會影響模型的預(yù)測,因此這個模型認(rèn)為是不敏感的(??insensitive\epsilon-insensitive??insensitive

1、線性SVM回歸

np.random.seed(42) m = 50 X = 2 * np.random.rand(m, 1) y = (4 + 3 * X + np.random.randn(m, 1)).ravel()## 找到訓(xùn)練集中所有支持向量的下標(biāo) def find_support_vectors(svm_reg, X, y):y_pred = svm_reg.predict(X)off_margin = np.abs(y - y_pred) >= svm_reg.epsilon## 返回 off_margin 中值為 True 的下標(biāo)return np.argwhere(off_margin)def plot_svm_regression(svm_reg, X, y, axes):x1s = np.linspace(axes[0], axes[1], 100).reshape(-1, 1)y_pred = svm_reg.predict(x1s)plt.plot(x1s, y_pred, "r-", linewidth=2, label="$\hat{y}$")plt.plot(x1s, y_pred - svm_reg.epsilon, "k--")plt.plot(x1s, y_pred + svm_reg.epsilon, "k--")plt.plot(X, y, "bo")plt.scatter(X[svm_reg.support_], y[svm_reg.support_], s=180, facecolors="#FFAAAA")plt.xlabel(r"$x_1$", fontsize=18)plt.legend(loc="upper left", fontsize=18)plt.axis(axes)svm_reg_1 = LinearSVR(epsilon=1.5, random_state=2019) svm_reg_2 = LinearSVR(epsilon=0.5, random_state=2019) svm_reg_1.fit(X, y) svm_reg_2.fit(X, y)svm_reg_1.support_ = find_support_vectors(svm_reg_1, X, y) svm_reg_2.support_ = find_support_vectors(svm_reg_2, X, y)eps_x1 = 1 eps_y_pred = svm_reg_1.predict([[eps_x1]]) plt.figure(figsize=(8, 3)) plt.subplot(121) plot_svm_regression(svm_reg_1, X, y, [0, 2, 3, 11]) plt.title(r"$\epsilon={}$".format(svm_reg_1.epsilon), fontsize=18) plt.ylabel(r"$y$", fontsize=18, rotation=0) plt.annotate('', xy=(eps_x1, eps_y_pred), xycoords='data',xytext=(eps_x1, eps_y_pred - svm_reg_1.epsilon),textcoords='data', arrowprops={'arrowstyle':'<->','linewidth':1.5} ) plt.text(0.9, 5.6, r"$\epsilon$",fontsize=20)plt.subplot(122) plot_svm_regression(svm_reg_2, X, y, [0, 2, 3, 11]) plt.title(r"$\epsilon={}$".format(svm_reg_2.epsilon), fontsize=18) plt.show()

2、非線性SVM回歸

多項式回歸,指定SVM的kernel為poly即可

from sklearn.svm import SVRnp.random.seed(42) m = 100 X = 2 * np.random.rand(m, 1) - 1 y = (0.2 + 0.1 * X + 0.5 * X ** 2 + np.random.randn(m, 1)/10).ravel() # svm_poly_reg1 = SVR(kernel="poly", degree=2, C=100, epsilon=0.1) svm_poly_reg2 = SVR(kernel="poly", degree=2, C=0.01, epsilon=0.1) svm_poly_reg1.fit(X, y) svm_poly_reg2.fit(X, y)plt.figure(figsize=(8, 3)) plt.subplot(121) plot_svm_regression(svm_poly_reg1, X, y, [-1, 1, 0, 1]) plt.title(r"$degree={}, C={}, \epsilon={}$".format(svm_poly_reg1.degree, svm_poly_reg1.C, svm_poly_reg1.epsilon), fontsize=18) plt.ylabel(r"$y$", fontsize=18, rotation=0) plt.subplot(122) plot_svm_regression(svm_poly_reg2, X, y, [-1, 1, 0, 1]) plt.title(r"$degree={}, C={}, \epsilon={}$".format(svm_poly_reg2.degree, svm_poly_reg2.C, svm_poly_reg2.epsilon), fontsize=18) plt.show()

四、SVM理論

(待補(bǔ)充)

總結(jié)

以上是生活随笔為你收集整理的用Scikit-learn和TensorFlow进行机器学习(五)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。