機器學習:支持向量機

支持向量機(Support Vector Machine)是一種二類分類模型,其基本模型定義為特征空間上的間隔最大的廣義線性分類器,其學習策略便是間隔最大化,最終可轉化為一個凸二次規劃問題的求解。

在這里插入圖片描述

假設兩類數據可以被 H = x : w T x + b ≥ c H = {x:w^Tx + b \ge c} H=x:wTx+bc分離,垂直于法向量 w w w,移動 H H H直到碰到某個訓練點,可以得到兩個超平面 H 1 H_1 H1? H 2 H_2 H2?,兩個平面稱為支撐超平面,題目分別支撐兩類數據。而位于 H 1 H_1 H1? H 2 H_2 H2?正中間的超平面是分離這兩類數據的最好選擇。支持向量就是離分隔超平面最近的那些點。

法向量 w w w有很多種選擇,超平面 H 1 H_1 H1? H 2 H_2 H2?之間的距離稱為間隔,這個間隔是 w w w的函數,**目的就是尋找這樣的 w w w使得間隔達到最大。

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在求解最優化問題中,拉格朗日乘子法(Lagrange Multiplier)和KKT(Karush Kuhn Tucker)條件是兩種最常用的方法。在有等式約束時使用拉格朗日乘子法,在有不等約束時使用KKT條件。

  • 拉格朗日乘子法

    拉格朗日乘子法是一種尋找多元函數在一組約束下的極值的方法。通過引入拉格朗日乘子,可將有 d d d個變量與 k k k個約束條件的最優化問題轉化為具有 d + k d+k d+k個變量的無約束優化問題求解。

  • 二次規劃

    二次規劃是一類典型的優化問題,包括凸二次優化和非凸二次優化。在此類問題中,目標函數是變量的二次函數,而約束條件是變量的線性不等式。
    m i n 1 2 x T Q x + c T x s . t . A ? x ? ≤ b ? min \frac{1} {2} x^T Q x + c^T x \\ s.t. \vec{A} \vec{x} \le \vec{b} min21?xTQx+cTxs.t.A x b

具體公式證明:【整理】深入理解拉格朗日乘子法(Lagrange Multiplier) 和KKT條件 - mo_wang - 博客園 (cnblogs.com)

序列最小優化(Sequential Minimal Optimization,SMO)

序列最小優化是將大優化問題分界成多個小優化問題來求解。

SMO算法工作原理:每次循環中選擇兩個變量進行優化處理。一旦找到一對合適的變量,那么就增大其中一個同時減小另一個。這里的“合適”指的是兩個變量必須要符合一定的條件,條件之一就是這兩個變量必須要在間隔邊界之外,而其第二個條件則是這兩個變量還沒有進行過區間化處理或者不在邊界上。

在這里插入圖片描述

代碼實現

參考《機器學習實戰》,代碼鏈接:https://github.com/golitter/Decoding-ML-Top10/tree/master/SVM

這里采用簡化的SMO代碼,數據集是https://blog.caiyongji.com/assets/mouse_viral_study.csv。

data_processing.py

import numpy as np
import pandas as pd# https://zhuanlan.zhihu.com/p/350836534
def data_processing():data_csv = pd.read_csv('mouse_viral_study.csv')data_csv = data_csv.dropna()# print(data_csv)X = data_csv.iloc[:-1, 0:2].values# print(X)Y = data_csv.iloc[:-1, 2].map({0: -1, 1: 1}).valuesY = Y.reshape(-1, 1)# print(Y.shape)return X, Y# X, Y = data_processing()
# print(X)

工具模塊,smo_assist.py

import random
def select_Jrandom(i:int, m:int) -> int:"""隨機選擇一個不等于 i 的整數"""j = iwhile j == i:j = int(random.uniform(0, m))return jdef clip_alpha(alpha_j:float, H:float, L:float) -> float:"""修剪 alpha_j"""if alpha_j > H:alpha_j = Hif alpha_j < L:alpha_j = Lreturn alpha_j

簡化SMO的代碼實現,smoSimple.py

from smo_assist import (select_Jrandom, clip_alpha)import numpy as np
import pdbdef smoSimple(data_mat_in:np.ndarray, class_labels:np.ndarray, C:float, toler:float, max_iter:int):"""data_mat_in: 數據集class_labels: 類別標簽C: 松弛變量toler: 容錯率max_iter: 最大迭代次數"""b = 0; # 初始化bm, n = np.shape(data_mat_in) # m: 樣本數, n: 特征數alphas = np.zeros((m, 1)) # 初始化alphaiter = 0 # 迭代次數while iter < max_iter:alphaPairsChanged = 0for i in range(m):fXi = float(np.multiply(alphas, class_labels).T @ (data_mat_in @ data_mat_in[i, :].T)) + b"""(1 , m) * (m, n) * (n, 1) = (1, 1) = 標量再 加上 b 就是 f(x) 的值"""Ei = fXi - float(class_labels[i])"""Ei = f(x) - y 預測誤差"""if (# 第一種情況:樣本被誤分類,且權重可以增加((class_labels[i] * Ei < -toler) # 預測誤差與標簽方向相反,且誤差大于容忍度and (alphas[i] < C)) # 當前權重小于正則化參數 C,可以增加權重or # 第二種情況:樣本被誤分類,且權重需要調整((class_labels[i] * Ei > toler) # 預測誤差與標簽方向相同,且誤差大于容忍度and (alphas[i] > 0)) # 當前權重大于 0,需要調整權重):j = select_Jrandom(i, m)fxj = float(np.multiply(alphas, class_labels).T @ (data_mat_in @ data_mat_in[j, :].T)) + bEj = fxj - float(class_labels[j])alpha_j_old = alphas[j].copy(); alpha_i_old = alphas[i].copy()if (class_labels[i] != class_labels[j]):L = max(0, alphas[j] - alphas[i]) # 左邊界H = min(C, C + alphas[j] - alphas[i]) # 右邊界else:L = max(0, alphas[j] + alphas[i] - C)H = min(C, alphas[j] + alphas[i])if L == H: continue # 跳出本次循環eta = 2.0 * data_mat_in[i, :] @ data_mat_in[j, :].T - data_mat_in[i, :] @ data_mat_in[i, :].T - data_mat_in[j, :] @ data_mat_in[j, :].T"""計算 eta = K11 + K22 - 2 * K12 = 2 * x_i * x_j - x_i * x_i - x_j * x_j """     if eta >= 0:continuealphas[j] -= class_labels[j] * (Ei - Ej) / eta # 更新權重alphas[j] = clip_alpha(alphas[j], H, L) # 調整權重if abs(alphas[j] - alpha_j_old) < 0.00001:continue # 跳出本次循環,不更新 ialphas[i] += class_labels[j] * class_labels[i] * (alpha_j_old - alphas[j]) # 更新權重b1 = b - Ei - class_labels[i] * (alphas[i] - alpha_i_old) * data_mat_in[i, :] @ data_mat_in[i, :].T - class_labels[j] *(alphas[j] - alpha_j_old) * data_mat_in[i, :] @ data_mat_in[j, :].Tb2 = b - Ej - class_labels[i] * (alphas[i] - alpha_i_old) * data_mat_in[i, :] @ data_mat_in[j, :].T - class_labels[j] *(alphas[j] - alpha_j_old) * data_mat_in[j, :] @ data_mat_in[j, :].T"""更新 b"""     if 0 < alphas[i] < C:b = b1elif 0 < alphas[j] < C:b = b2else:b = (b1 + b2) / 2.0alphaPairsChanged += 1if alphaPairsChanged == 0:iter += 1else:iter = 0return b, alphasif __name__ == '__main__':print(  smoSimple(np.array([[1, 2], [3, 4]]), np.array([[-1],[1]]), 0.6, 0.001, 40))

test.py

from data_processing import *
from smoSimple import *
import numpy as np
import matplotlib.pyplot as plt# 數據處理和 SVM 訓練
data_mat_in, class_labels = data_processing()
b, alphas = smoSimple(data_mat_in, class_labels, 0.6, 0.001, 40)# 打印結果
print("Bias (b):", b)
print("Non-zero alphas:", alphas[alphas > 0])# 打印數據形狀
print("Shape of data_mat_in:", np.shape(data_mat_in))
print("Shape of class_labels:", np.shape(class_labels))# 將 Y 轉換為一維數組(如果它是二維的)
Y = class_labels
# 提取不同類別的索引
class_1_indices = np.where(Y == 1)[0]  # 類別為 1 的樣本索引
class_2_indices = np.where(Y == -1)[0]  # 類別為 -1 的樣本索引
X = data_mat_in# 繪制散點圖
plt.figure(figsize=(8, 6))
plt.scatter(X[class_1_indices, 0], X[class_1_indices, 1], c='blue', label='Class 1', alpha=0.5)
plt.scatter(X[class_2_indices, 0], X[class_2_indices, 1], c='red', label='Class -1', alpha=0.5)# 計算權重向量 w
w = np.dot((alphas * Y).T, X).flatten()
# print(f"w: {w}")
print("Shape of X:", X.shape)  # 應該是 (m, n)
print("Shape of Y:", Y.shape)  # 應該是 (m, 1)
print("Shape of alphas:", alphas.shape)  # 應該是 (m, 1)# 繪制超平面
# 超平面方程:w[0] * x1 + w[1] * x2 + b = 0
# 解出 x2: x2 = -(w[0] * x1 + b) / w[1]
x1 = np.linspace(np.min(X[:, 0]), np.max(X[:, 0]), 100)
x2 = -(w[0] * x1 + b) / w[1]
print(f"w_shape: {w.shape}")
# 繪制超平面
plt.plot(x1, x2, label='SVM Hyperplane', color='green', linewidth=2)# 標出支持向量
support_vectors_indices = np.where(alphas > 0)[0]  # 找到所有支持向量的索引
plt.scatter(X[support_vectors_indices, 0], X[support_vectors_indices, 1], facecolors='none', edgecolors='k', s=50, label='Support Vectors')# 添加圖例和標簽
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('Scatter Plot of Data with SVM Hyperplane')
plt.legend()# 顯示圖形
plt.show()

在這里插入圖片描述

ML_AI_SourceCode-/支持向量機 at master · sjyttkl/ML_AI_SourceCode- (github.com)

機器學習:支持向量機(SVM)-CSDN博客

【整理】深入理解拉格朗日乘子法(Lagrange Multiplier) 和KKT條件 - mo_wang - 博客園 (cnblogs.com)

機器學習(四):通俗理解支持向量機SVM及代碼實踐 - 知乎 (zhihu.com)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/66789.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/66789.shtml
英文地址,請注明出處:http://en.pswp.cn/web/66789.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SQL-leetcode—1148. 文章瀏覽 I

1148. 文章瀏覽 I Views 表&#xff1a; ---------------------- | Column Name | Type | ---------------------- | article_id | int | | author_id | int | | viewer_id | int | | view_date | date | ---------------------- 此表可能會存在重復行。&#xff08;換句話說…

k8s資源預留

k8s資源預留 https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/reserve-compute-resources/ vim /var/lib/kubelet/config.yamlenforceNodeAllocatable: - pods kubeReserved: # 配置 kube 資源預留cpu: 500mmemory: 1Giephemeral-storage: 1Gi systemReserved: #…

[STM32 HAL庫]串口空閑中斷+DMA接收不定長數據

一、空閑中斷 STM32的串口具有空閑中斷&#xff0c;什么叫做空閑呢&#xff1f;如何觸發空閑中斷呢&#xff1f; 空閑&#xff1a;串口發送的兩個字符之間間隔非常短&#xff0c;所以在兩個字符之間不叫空閑。空閑的定義是總線上在一個字節的時間內沒有再接收到數據。觸發條件…

Unity Line Renderer Component入門

Overview Line Renderer 組件是 Unity 中用于繪制連續線段的工具。它通過在三維空間中的兩個或兩個以上的點的數組&#xff0c;并在每個點之間繪制一條直線。可以繪制從簡單的直線到復雜的螺旋線等各種圖形。 1. 連續性和獨立線條 連續性&#xff1a;Line Renderer 繪制的線條…

純 Python、Django、FastAPI、Flask、Pyramid、Jupyter、dbt 解析和差異分析

一、純 Python 1.1 基礎概念 Python 是一種高級、通用、解釋型的編程語言&#xff0c;以其簡潔易讀的語法和豐富的標準庫而聞名。“純 Python” 在這里指的是不依賴特定的 Web 框架或數據分析工具&#xff0c;僅使用 Python 原生的功能和標準庫來開發應用程序或執行任務。 1.…

SQL記錄學習日志

刪除表 DROP TABLE&#xff1a;徹底刪除表和其數據&#xff0c;無法恢復。 DROP TABLE IF EXISTS&#xff1a;在刪除之前檢查表是否存在。 TRUNCATE TABLE&#xff1a;刪除所有數據&#xff0c;但保留表的結構。 DELETE&#xff1a;刪除表中的所有數據&#xff0c;但保留表的結…

QT:tftp client 和 Server

1.TFTP簡介 TFTP&#xff08;Trivial File Transfer Protocol,簡單文件傳輸協議&#xff09;是TCP/IP協議族中的一個用來在客戶機與服務器之間進行簡單文件傳輸的協議&#xff0c;提供不復雜、開銷不大的文件傳輸服務。端口號為69。 FTP是一個傳輸文件的簡單協議&#xff0c;…

WPF5-x名稱空間

1. x名稱空間2. x名稱空間內容3. x名稱空間內容分類 3.1. x:Name3.2. x:Key3.3. x:Class3.4. x:TypeArguments 4. 總結 1. x名稱空間 “x名稱空間”的x是映射XAML名稱空間時給它取的名字&#xff08;取XAML的首字母&#xff09;&#xff0c;里面的成員&#xff08;如x:Class、…

前端jquery 實現文本框輸入出現自動補全提示功能

git倉庫&#xff1a;web_study/some-demos/inputAutoFit at main Cong0925/web_study (github.com) 壓縮包&#xff1a;已綁定到指定資源 示例圖&#xff1a; 實現說明: 1.首先&#xff0c;html部分設置好相關的定位標簽如圖&#xff1a; 2.主要函數 3.默認數據

緩存之美:萬文詳解 Caffeine 實現原理(上)

由于社區最大字數限制&#xff0c;本文章將分為兩篇&#xff0c;第二篇文章為緩存之美&#xff1a;萬文詳解 Caffeine 實現原理&#xff08;下&#xff09; 大家好&#xff0c;我是 方圓。文章將采用“總-分-總”的結構對配置固定大小元素驅逐策略的 Caffeine 緩存進行介紹&…

Qt實踐:一個簡單的絲滑側滑欄實現

Qt實踐&#xff1a;一個簡單的絲滑側滑欄實現 筆者前段時間突然看到了側滑欄&#xff0c;覺得這個抽屜式的側滑欄非常的有趣&#xff0c;打算這里首先嘗試實現一個簡單的絲滑側滑欄。 首先是上效果圖 &#xff08;C&#xff0c;GIF幀率砍到毛都不剩了&#xff09; QProperty…

工作流引擎Camunda與LiteFlow核心組件對比

以下為 Camunda 7 和 LiteFlow 詳細的介紹&#xff0c;包括它們的核心組件和用途。 1. Camunda 7 詳細介紹 Camunda 7 是一個基于 BPMN 2.0 標準的企業級工作流和決策自動化平臺。它被廣泛應用于復雜業務流程的管理和執行&#xff0c;其核心目標是通過流程自動化來提升企業效…

css動畫水球圖

由于echarts水球圖動畫會導致ios卡頓&#xff0c;所以純css模擬 展示效果 組件 <template><div class"water-box"><div class"water"><div class"progress" :style"{ --newProgress: newProgress % }"><…

iOS 權限管理:同時請求相機和麥克風權限的最佳實踐

引言 在開發視頻類應用時&#xff0c;我們常常會遇到需要同時請求相機和麥克風權限的場景。比如&#xff0c;在用戶發布視頻動態時&#xff0c;相機用于捕捉畫面&#xff0c;麥克風用于錄制聲音&#xff1b;又或者在直播功能中&#xff0c;只有獲得這兩項權限&#xff0c;用戶…

Java 泛型上下限詳解:以 Info 泛型類和方法實現為例

本文將通過一個實際示例&#xff0c;來深入講解 Java 泛型中的上下限及其應用場景。在這個示例中&#xff0c;我們會實現一個泛型類 Info 和兩個泛型方法 upperLimit 和 lowerLimit&#xff0c;并解釋其工作機制。 1. 什么是 Java 泛型上下限&#xff1f; Java 泛型的上下限是…

客戶服務創新:數字化時代的策略與實踐

在數字化時代背景下&#xff0c;客戶服務已成為企業競爭的關鍵領域。隨著消費者需求的日益多樣化和個性化&#xff0c;傳統的客戶服務模式已難以滿足市場的要求。因此&#xff0c;企業需要不斷探索和創新客戶服務策略&#xff0c;以適應數字化時代的變化。 一、數字化時代客戶服…

【PyCharm】遠程連接Linux服務器

【PyCharm】相關鏈接 【PyCharm】連接Jupyter Notebook【PyCharm】快捷鍵使用【PyCharm】遠程連接Linux服務器【PyCharm】設置為中文界面 【PyCharm】遠程連接Linux服務器 PyCharm 提供了遠程開發的功能&#xff0c;使得開發者可以在本地編輯代碼或使用服務器資源。 下面將詳…

十三、數據的的輸入與輸出(3)

數據的輸出 writeClipboard&#xff08;&#xff09;函數 writeClipboard&#xff08;&#xff09;函數可以將數據輸出至剪貼板。 例如&#xff0c;將R的內置數據集iris輸出到剪貼板&#xff0c;在進入Excel中點擊"粘貼"。 head(iris) #查看數據集Sepal.L…

PyQt5之QDialog

1.描述 QDialog是對話窗口的基類&#xff0c;對話窗口是頂級窗口&#xff0c;主要用于短期任務和與用戶的簡短通信。 可分為模態對話框和非模態對話框。 模態對話框又可以分為應用程序級別和窗口級別。 ? 應用程序級別&#xff1a;當該種模態的對話框出現時&#xff0c;用…

Next.js:構建大模型智能體GPT研究者應用的 Web開發框架

Next.js&#xff1a;構建大模型智能體GPT研究者應用的 Web開發框架 Next.js 基礎知識 Next.js 是由 Vercel 公司開發維護的框架&#xff0c;極大地簡化了 React 應用的開發流程。其核心特性包括&#xff1a; 服務器端渲染&#xff08;SSR&#xff09;與靜態站點生成&#xff…