人工智能與機器學習:Python從零實現K-Means 算法

🧠 向所有學習者致敬!

“學習不是裝滿一桶水,而是點燃一把火。” —— 葉芝


我的博客主頁: https://lizheng.blog.csdn.net

🌐 歡迎點擊加入AI人工智能社區!

🚀 讓我們一起努力,共創AI未來! 🚀


K-Means 可是我超喜歡的機器學習算法呢,因為它能幫我們發現數據里那些隱藏起來的模式呢。要是用得好的話,它能把你數據里的分組或者聚類情況展示得明明白白的,那可都是因為它背后那些嚴謹的數學原理呢。這在現實生活中可有不少厲害的應用呢。

比如說呀,要是你負責分析一個電商網站的點擊流數據呢,你就可以用 K-Means 把顧客按照他們點擊的內容、加入購物車的東西,還有購買的東西來分成不同的群組呢。這就能幫你搞出一套個性化策略呢,根據顧客所在的群組,把網站體驗調整得更符合他們的需求呢。好啦,現在咱們就來好好研究一下這個算法吧!

K-Means 算法

首先得跟大家說說,K-Means 算法是一種無監督機器學習算法哦。無監督機器學習模型的關鍵特點就是,咱們的數據里沒有目標值或者標簽呢。換句話說呢,咱們不是要預測啥東西,而是想給數據貼上標簽呢。在 K-Means 算法里呀,咱們的目標就是把數據分成不同的群組或者聚類呢。那怎么做到呢?首先呢,用戶可以指定要把數據分成多少個聚類呢。我為啥說“可以指定”呢,其實呢,這還是得講究一些最佳實踐呢。要是聚類數太少呢,可能會錯過一些對你用例很有價值的信息呢;要是聚類數太多呢,又會變得冗余啦。在給數據點分配聚類的時候呢,每個數據點都會被分配到離它最近的那個聚類呢。現在呢,還有更多細節要講,咱們接著往下看吧。

關鍵概念:歐幾里得距離

None

回想一下你以前上過的數學課吧。你可能還記得有個叫勾股定理的東西呢:

a 2 + b 2 = c 2 a2 + b2 = c2 a2+b2=c2

咱們用這個公式來計算直角三角形的斜邊長度呢(我以前叫它“長邊”)。要是想得到 c 的確切數值呢,就得對 a2 + b2 開平方根呢。你可能不知道呢,其實你已經學會了怎么計算坐標平面上兩個點之間的距離啦!這其實也是線性代數里的一個概念,叫 L2 范數呢。假設你有一個二維坐標平面,x 是水平軸,y 是垂直軸。給定兩個點,(x1,y1) 和 (x2,y2),咱們就可以用這個公式來計算它們之間的歐幾里得距離呢:

None

咱們也可以在超過兩個維度的情況下計算歐幾里得距離呢。比如說,這是計算三維空間中兩個點之間距離的公式呢:

None

那這和 K-Means 有啥關系呢?咱們接著往下看下一節就知道啦。

質心:初始化、迭代、收斂

先來舉個 K-Means 的簡單例子吧。下面這張圖呢,是我隨便編的一個有兩個維度的虛構數據集呢。要是你把單獨的數據點都畫出來呢,看起來大概就是這樣的。你可能覺得,用不著 K-Means 也能把這些數據分成不同的聚類呢,因為它們分組的方式看起來還挺明顯的呢。不過呢,我還是會給大家演示一下它是怎么工作的呢。

None

圖片來源:作者提供

就像我之前說的呢,咱們可以指定要把數據分成多少個聚類呢。在這個例子里呢,咱們就把它分成 3 個聚類吧。咱們先隨機生成三個坐標,當作初始的質心來開始這個過程呢。質心呢,就是用來代表一個聚類中心的坐標呢。咱們用星形來標記這些隨機生成的質心吧:

None

圖片來源:作者提供

接下來呢,咱們要根據歐幾里得距離來給數據點分配質心啦。換句話說呢,就是把每個數據點分配給離它最近的那個質心呢。你是不是已經看出來啦,歐幾里得距離在 K-Means 里可起著關鍵作用呢!

None

圖片來源:作者提供

完成初始化步驟之后呢,咱們要計算每個聚類里分配到的點的平均值呢,然后把得到的坐標當作新的質心呢。比如說呢,在這個例子里,有一個聚類里分配到了一組點呢,咱們就取這些點的 x 和 y 坐標的平均值呢,然后用得到的坐標作為新的質心或者聚類中心呢。結果大概會是這樣的(注意那個“紅色”聚類的質心正好就在一個數據點上,因為那個聚類里只有一個數據點呢):

None

圖片來源:作者提供

這些聚類看起來好像不太合理呢,對吧?別擔心,咱們還沒做完呢。咱們再重復一次給聚類分配數據點的過程吧。首先呢,咱們隨機初始化三個質心:

None

圖片來源:作者提供

然后呢,根據歐幾里得距離把數據點分配給最近的質心呢。

None

最后呢,咱們計算每個聚類里數據點的平均坐標呢,然后把得到的坐標當作新的質心呢。

None

圖片來源:作者提供

用肉眼看呢,K-Means 算法好像已經把這個數據集分成三個不同的聚類啦。不過呢,它自己還不知道已經找到了最優解呢。所以呢,咱們還得重復同樣的過程,不過這次咱們要檢查新的聚類和之前的聚類是不是有很大區別呢。關于這個概念,咱們很快就會展開說呢。先來看看收斂是怎么實現的吧。

你肯定已經知道流程啦,咱們先隨機生成質心:

None

圖片來源:作者提供

根據歐幾里得距離把數據點分配給最近的質心:

None

最后呢,咱們計算每個聚類里數據點的平均坐標呢,然后把得到的坐標當作新的質心呢。同時呢,咱們還要檢查新的質心和之前的質心之間的距離是不是低于咱們設定的閾值呢。在這個例子里呢,距離是 0,肯定已經滿足咱們的標準啦,算法已經收斂啦:

None

None

尋找最佳聚類數量

給定 k 個聚類數量呢,咱們現在知道怎么把數據分成 k 個聚類啦。不過呢,這還是留下了一個問題:最佳的聚類數量 k 到底是多少呢?

咱們可以用一些方法來解決這個問題呢,在咱們要搭建的 KMeans 對象里呢,咱們會找出來哪個聚類數量能得到最高的輪廓系數呢:

None

圖片來源:作者提供

a 是每個聚類里數據點和聚類質心之間的平均距離呢,而 b 是每個聚類質心和最近的相鄰聚類質心之間的平均距離呢。更實際地說呢,輪廓系數越高呢,就意味著聚類里的點越能很好地定義到自己的聚類里呢,而且各個聚類之間也分得更清楚呢。

KMeans 類

咱們已經了解了 KMeans 算法的所有必要概念啦!現在呢,該開始搭建咱們的對象啦。咱們先從創建初始化函數開始吧。就像你看到的呢,咱們要用到的庫只有 numpy、pandas、tqdm(用來顯示進度條)和 scikit-learn 里的 silhouette_score 對象呢(別擔心,這是咱們唯一從 sklearn 里用到的東西,這樣咱們就能真正從頭搭建這個算法啦)。咱們來聊聊這些屬性吧。

import numpy as np
import pandas as pd
from sklearn.metrics import silhouette_score
from tqdm import tqdmclass DIYKMeans:def __init__(self, max_k=10, max_iters=100, tol=1e-4, random_state=None):self.max_k = max_kself.max_iters = max_itersself.tol = tolself.random_state = random_stateself.k = Noneself.centroids = Noneself.labels_ = Noneself.X_scaled = Noneself.feature_means = Noneself.feature_stds = Noneself.stable_iterations = 0
  • max_k: 嘗試擬合模型時聚類數量的上限。
  • max_iters: 擬合模型時隨機初始化質心的最大嘗試次數。
  • tol: 計算新舊質心距離時的容差閾值。
  • random_state: 隨機狀態值,方便復現結果。
  • k, centroids, labels_: 找到基于輪廓系數的最佳 k 后,這些屬性就會被賦值。k 是最佳聚類數量,centroids 是最佳 k 對應的質心坐標,labels_ 是每個數據點的聚類標簽。
  • X_scaled, feature_means, feature_stds: 數據的標準化值,以及對應的均值和標準差。
  • stable_iterations: 用來記錄在容差范圍內的迭代次數,默認情況下,這個對象會在連續三次迭代滿足容差條件后認為算法已經收斂。

質心操作與標準化

接下來的這些方法呢,會涉及到 K-Means 算法的基本操作呢。這些內容應該都很熟悉啦,畢竟咱們之前已經講過啦。注意咱們還加了一個標準化數據的方法呢。為啥這個很重要呢?因為咱們的算法要求數據得在同一尺度上呢,不然那些取值范圍大的特征就會讓算法偏向它們呢。比如說呢,假設咱們想根據臥室數量、浴室數量和價格來聚類房屋數據呢。臥室和浴室的數量平均可能在 1 到 5 之間呢,但價格可能會達到幾十萬呢。要是不標準化的話,計算距離的時候大部分影響都會來自價格特征呢。所以呢,咱們必須標準化或者歸一化數據。在這個例子里呢,咱們的標準化方法用的是均值標準化呢。最后呢,咱們看看收斂方法是怎么實現的吧。我發現這個算法的一個缺點呢,就是確認算法收斂的時候,只要新舊質心之間的距離在容差范圍內變化一次就行啦。為了確保更穩定的收斂呢,咱們的方法會在連續三次迭代滿足容差條件后才認為算法已經收斂啦。

  • standardize_data: 把每個特征都標準化到同一尺度上。
  • initialize_centroids: 給定數據集的特征數量和 k,它會隨機生成 k 個維度和數據集特征數量相同的質心。
  • compute_distances: 利用 numpy 自帶的線性代數庫呢,這個函數用來計算歐幾里得距離呢,也就是兩個坐標之間形成的向量的長度。
  • assign_clusters: 給定一個數據點和質心,返回最小距離對應的索引。
  • compute_new_centroids: 把每個質心對應的點取出來呢,計算每個特征的均值呢,然后返回新的質心坐標。
  • has_converged: 給定一個容差值呢,檢查新質心和舊質心之間的差異是不是在容差范圍內呢。這個方法會檢查連續三次迭代是不是都滿足容差條件呢。要是滿足的話呢,就停止操作,認為算法已經收斂啦。
def standardize_data(self, X):self.feature_means = np.mean(X, axis=0)self.feature_stds = np.std(X, axis=0)self.feature_stds[self.feature_stds == 0] = 1return (X - self.feature_means) / self.feature_stdsdef initialize_centroids(self, X, k):np.random.seed(self.random_state)return X[np.random.choice(X.shape[0], k, replace=False)]def compute_distances(self, X, centroids):return np.linalg.norm(X[:, np.newaxis] - centroids, axis=2)def assign_clusters(self, distances):return np.argmin(distances, axis=1)def compute_new_centroids(self, X, labels, k):return np.array([X[labels == i].mean(axis=0) for i in range(k)])def has_converged(self, old_centroids, new_centroids, stable_threshold=3):if np.linalg.norm(new_centroids - old_centroids) < self.tol:self.stable_iterations += 1else:self.stable_iterations = 0return self.stable_iterations >= stable_threshold

擬合方法

這個方法就是把所有東西都整合到一起啦。根據咱們的 max_k 屬性呢,咱們會嘗試這個范圍內的所有 k 值呢。對于每個 k 呢,咱們會運行迭代過程呢,隨機初始化質心,給點分配聚類,然后重新計算質心,直到收斂為止呢。在這個過程中呢,咱們還會計算輪廓系數呢。哪個 k 值能得到最高的輪廓系數呢,咱們就會把數據集分成那個數量的聚類呢。從那以后呢,咱們的 k、centroids 和 labels_ 屬性就會被賦上最佳數據啦。

def fit(self, X):X = np.array(X)X = self.standardize_data(X)self.X_scaled = Xbest_k = Nonebest_score = -1best_labels = Nonebest_centroids = Noneprint("Fitting KMeans across different k values:")for k in tqdm(range(2, self.max_k + 1), desc="Searching for optimal k"):centroids = self.initialize_centroids(X, k)self.stable_iterations = 0for _ in range(self.max_iters):distances = self.compute_distances(X, centroids)labels = self.assign_clusters(distances)new_centroids = self.compute_new_centroids(X, labels, k)if self.has_converged(centroids, new_centroids):breakcentroids = new_centroidsscore = silhouette_score(X, labels)if score > best_score:best_k = kbest_score = scorebest_labels = labelsbest_centroids = centroidsself.k = best_kself.centroids = best_centroidsself.labels_ = best_labels

用信用卡數據來測試

現在呢,咱們來用 Kaggle 上的一個 信用卡數據集 來測試一下咱們自己搭建的 KMeans 對象吧。

假設你在一個信用卡公司當數據科學家呢,領導讓你找出顧客的分群呢。以前呢,業務團隊是根據顧客通常購買的東西和平均月余額來分群的呢。現在呢,領導想擴大這個邏輯,但又不知道怎么搞出一個能擴展的方案呢。這時候呢,咱們自己搭建的 KMeans 對象就派上用場啦。

咱們先從導入數據開始吧。

data = pd.read_csv('CC GENERAL.csv')

這個數據集里有很多特征呢,不過呢,咱們先別一下子把業務團隊嚇著,所以咱們只保留以下這幾列呢。這些定義都是從我下載數據的 Kaggle 頁面上直接拿過來的哦:

BALANCE_FREQUENCY: 余額更新的頻率,是一個 0 到 1 之間的分數(1 = 經常更新,0 = 不經常更新)

PURCHASES_FREQUENCY: 購買的頻率,是一個 0 到 1 之間的分數(1 = 經常購買,0 = 不經常購買)

CREDIT_LIMIT: 用戶的信用卡額度

PAYMENTS: 用戶支付的金額

PRCFULLPAYMENT: 用戶支付全額的比例

TENURE: 用戶使用信用卡服務的年限

cols_to_keep = ['BALANCE_FREQUENCY','PURCHASES_FREQUENCY','CREDIT_LIMIT','PAYMENTS','PRC_FULL_PAYMENT','TENURE']
data_for_kmeans = data[cols_to_keep]
data_for_kmeans = data_for_kmeans.dropna()

咱們先來做點簡單的探索性分析呢,看看這些特征的一些基本情況吧。以下是這個數據集的一些關鍵事實呢。

  • 咱們看到的是大約 8600 個有完整數據的顧客樣本呢。
  • 購買頻率高和購買頻率低的顧客各占一半呢。
  • 大多數顧客的信用卡額度都在 6500 美元以下呢。
  • 大多數顧客支付的金額在 2000 美元以下呢,但最高支付金額可以達到 50000 美元呢。
  • 大多數顧客支付的金額只占他們應付款項的 15% 左右呢。
  • 大多數顧客使用信用卡服務的年限是 12 年,而且變化不大呢。
data_for_kmeans.describe()

None

圖片來源:作者提供

用咱們自己搭建的 KMeans 模型來擬合

現在咱們已經對數據有了更好的了解啦,那就開始用咱們的模型來擬合它吧。

km = DIYKMeans(max_k=20)
km.fit(X=data_for_kmeans)

None

圖片來源:作者提供

print('最佳聚類數量:',km.k)

None

理解聚類結果

太棒啦!咱們自己搭建的 KMeans 對象把數據集分成了 7 個聚類呢。咱們的工作還遠遠沒有結束呢。現在咱們已經從數學上把顧客分成了不同的群組啦,那咱們就來好好探索一下每個群組里的關鍵模式吧。為了做到這一點呢,我搭建了一個自定義函數呢,它可以輸出每個群組的數量呢,還能顯示每個特征的平均值呢,還會生成一個熱力圖呢,這樣就能很方便地比較和對比啦。我在咱們的對象的 labels_ 屬性基礎上給數據集加了一個“Cluster”列呢。以下是我發現的關鍵模式呢:

  • 除了第 3 個聚類以外,每個聚類都包含使用信用卡服務年限接近 12 年的顧客呢。
  • 第 2 個聚類是唯一一個購買頻率高而且支付比例也高的群組呢,它的信用卡額度只是略高于平均水平呢。
  • 第 0 個、第 4 個和第 5 個聚類支付比例都非常低呢;不過呢,第 4 個聚類是這三個聚類里購買頻率最低的呢。
  • 第 6 個聚類是高消費群組呢,信用卡額度最高,支付金額也最大呢。
  • 第 5 個聚類和第 6 個聚類在消費方面很相似呢,不過呢,支付金額要低得多呢。

根據這些模式呢,咱們能實施哪些實用的策略或者方法呢?記得哦,信用卡公司是通過收取消費者的支付手續費和利息來賺錢的呢。所以呢,公司可能希望顧客不要一次性把賬單都還清呢,這樣公司就能賺取利息啦;不過呢,要是顧客欠款太多呢,公司又收不到全額還款啦。所以呢,我有以下幾個想法:

  • 讓第 5 個聚類的顧客支付比例接近第 6 個聚類呢。
  • 研究一下給第 2 個聚類的顧客提高信用卡額度呢,因為他們大多數都能按時還款呢。
  • 研究一下給第 0 個、第 4 個和第 5 個聚類的顧客降低信用卡額度呢,直到他們的支付比例提高呢。
data_for_kmeans['Cluster'] = km.labels_def summarize_by_cluster_with_heatmap(df, cluster_col='Cluster'):if cluster_col not in df.columns:raise ValueError(f"列 '{cluster_col}' 在 DataFrame 中找不到哦。")value_cols = [col for col in df.select_dtypes(include='number').columns if col != cluster_col]if not value_cols:raise ValueError("除了聚類列以外,沒有數值型列可以進行總結呢。")grouped = df.groupby(cluster_col)means = grouped[value_cols].mean().round(2).add_suffix('_mean')counts = grouped.size().to_frame('count')summary = pd.concat([counts, means], axis=1).reset_index()return summary.style.background_gradient(cmap='YlGnBu', subset=summary.columns[1:]).format("{:.2f}")summarize_by_cluster_with_heatmap(df=data_for_kmeans)

None

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

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

相關文章

【神經網絡與深度學習】訓練集與驗證集的功能解析與差異探究

引言 在深度學習模型的訓練過程中&#xff0c;訓練集和驗證集是兩個關鍵組成部分&#xff0c;它們在模型性能的提升和評估中扮演著不可替代的角色。通過分析這兩者的區別和作用&#xff0c;可以幫助我們深入理解模型的學習過程和泛化能力&#xff0c;同時為防止過擬合及優化超…

Macos m系列芯片環境下python3安裝mysqlclient系列問題

最近學習python3&#xff0c;在安裝mysqlclient的時候遇到了一些問題&#xff0c;直接使用哦pip install mysqlclient 直接報錯了&#xff0c;記錄一下解決方案。 環境信息 設備&#xff1a;Macbook Pro m1 系統&#xff1a;macos Sequoia 15.3.2 最終成功的python版本&#xf…

微信小程序-van-uploader的preview-size

preview-size支持數組格式 修改前修改后1、升級微信小程序里面的van版本:2、 重新構建npm3、重啟微信開發工具 修改前 引用van組件的上傳文件&#xff0c;設置預覽圖尺寸&#xff0c;剛開始設置的是preview-size“140”&#xff0c;出來的效果就是一個正方形。 修改后 1、升級…

2. 第一個網頁:前端基礎入門

第一個網頁&#xff1a;前端基礎入門 一、網頁文件基礎認知 1. 文件擴展名 .htm 或 .html 均為網頁文件后綴&#xff0c;二者功能完全一致擴展名隱藏方法 系統設置 → 文件夾選項 → 查看 → 取消勾選「隱藏已知文件類型的擴展名」 二、前端發展簡史 1. 瀏覽器戰爭與標準混…

云原生--核心組件-容器篇-7-Docker私有鏡像倉庫--Harbor

1、Harbor的定義與核心作用 定義&#xff1a; Harbor是由VMware開源的企業級容器鏡像倉庫系統&#xff0c;后捐贈給 CNCF (Cloud Native Computing Foundation)。它基于Docker Registry擴展了企業級功能&#xff0c;用于存儲、分發和管理容器鏡像&#xff08;如Docker、OCI標準…

Java項目與技術棧場景題深度解析

Java項目與技術棧場景題深度解析 在互聯網大廠Java求職者的面試中&#xff0c;經常會被問到關于Java項目或技術棧的場景題。本文通過一個故事場景來展示這些問題的實際解決方案。 第一輪提問 面試官&#xff1a;馬架構&#xff0c;歡迎來到我們公司的面試現場。請問您對Java…

SpringMVC 靜態資源處理 mvc:default-servlet-handler

我們先來看看效果,當我把這一行注釋掉的時候&#xff1a; 我們來看看頁面&#xff1a; 現在我把注釋去掉&#xff1a; 、 可以看到的是&#xff0c;這個時候又可以訪問了 那么我們就可以想&#xff0c;這個 <mvc:default-servlet-handler />它控制著我們頁面的訪問…

【leetcode】最長公共子路徑問題

滾動hash 滾動哈希&#xff08;rolling hash&#xff09;也叫 Rabin-Karp 字符串哈希算法&#xff0c;它是將某個字符串看成某個進制下的整數&#xff0c;并將其對應的十進制整數作為hash值。 滾動hash算法的推導 假設有一個長度為n的數組a[0],a[1],a[2],…a[n-1]&#xff0…

【Linux網絡】:套接字之UDP

一、UDP和TCP協議 TCP &#xff08;Transmission Control Protocol 傳輸控制協議&#xff09;的特點&#xff1a; 傳輸層協議有連接&#xff08;在正式通信前要先建立連接&#xff09;可靠傳輸&#xff08;在內部幫我們做可靠傳輸工作&#xff09;面向字節流 UDP &#xff08;U…

React19 useOptimistic 用法

用法 樂觀更新 發起異步請求時&#xff0c;先假設請求會成功立即更新 UI 給用戶反饋若請求最終失敗&#xff0c;再將 UI 恢復到之前的狀態 const [optimisticState, addOptimistic] useOptimistic(state, updateFn) 參數 state&#xff1a;實際值&#xff0c;可以是 useSta…

Deepseek-v3+cline+vscode java自動化編程

1、Deepseek DeepSeek 充值后&#xff0c;創建apikey 2、vscode Visual Studio Code - Code Editing. Redefined 3、下載插件cline 4、配置deepeseek-v3 的密鑰到cline 5、不可用 在開始的幾次調用能正常使用起來&#xff0c;用了幾次后&#xff0c;不能使用了&#xff0c;請求…

數據分析案例:環境數據分析

目錄 數據分析案例&#xff1a;環境數據分析1. 項目背景2. 數據加載與預處理2.1 數據說明2.2 讀取與清洗 3. 探索性數據分析&#xff08;EDA&#xff09;3.1 時序趨勢3.2 日內變化3.3 氣象與污染物相關性 4. 特征工程4.1 時間特征4.2 滯后與滾動統計4.3 目標變量 5. 模型構建與…

網絡原理 - 8

目錄 補充 網絡層 IP 協議 基本概念&#xff1a; 協議頭格式 地址管理 如何解決 IP 地址不夠用呢&#xff1f;&#xff1f;&#xff1f; 1. 動態分配 IP 地址&#xff1a; 2. NAT 機制&#xff08;網絡地址映射&#xff09; 3. IPv6 網段劃分 一些特殊的 IP 地址 …

向量檢索新選擇:FastGPT + OceanBase,快速構建RAG

隨著人工智能的快速發展&#xff0c;RAG&#xff08;Retrieval-Augmented Generation&#xff0c;檢索增強生成&#xff09;技術日益受到關注。向量數據庫作為 RAG 系統的核心基礎設施&#xff0c;堪稱 RAG 的“記憶中樞”&#xff0c;其性能直接關系到大模型生成內容的精準度與…

dify對接飛書云文檔,并且將圖片傳入飛書文檔

前面講了如何讓dify展示圖片&#xff0c;但是如果想讓智能體回答的帶圖片的內容生成個文檔該怎么弄呢&#xff1f;今天來實踐一下。 dify工具帶的有飛書云文檔&#xff0c;正好&#xff0c;咱們就利用飛書云文檔。 1、首先配置飛書云文檔的key跟secret 注意要開頭左側的權限&a…

Linux系統之設置開機啟動運行桌面環境

Linux 開機運行級別介紹與 Ubuntu 桌面環境配置指南 一、Linux 開機運行級別(Runlevel) 在傳統的 Linux 系統(如 SysV init 初始化系統)中,運行級別定義了系統啟動時加載的服務和資源。常見的運行級別如下: 運行級別模式用途0Halt(停機模式)關閉系統1Single User Mode…

Spring Cloud Gateway配置雙向SSL認證(完整指南)

本文將詳細介紹如何為Spring Cloud Gateway配置雙向SSL認證,包括證書生成、配置和使用。 目錄結構 /my-gateway-project ├── /certs │ ├── ca.crt # 根證書 │ ├── ca.key # 根私鑰 │ ├── gateway.crt # 網關證書 │ ├── …

【虛幻5藍圖Editor Utility Widget:創建高效模型材質自動匹配和資產管理工具,從3DMax到Unreal和Unity引擎_系列第二篇】

虛幻5藍圖Editor Utility Widget 一、基礎框架搭建背景&#xff1a;1. 創建Editor Utility Widget2.根控件選擇窗口3.界面功能定位與階段4.查看繼承樹5.目標效果 二、模塊化設計流程1.材質替換核心流程&#xff1a;2.完整代碼如下 三、可視化界面UI布局1. 添加標題欄2. 構建滾動…

LabVIEW實現DMM與開關模塊掃描測量

該程序基于 LabVIEW&#xff0c;用于控制數字萬用表&#xff08;DMM&#xff09;與開關模塊進行測量掃描。通過合理配置觸發源、測量參數等&#xff0c;實現對多路信號的自動化測量與數據獲取&#xff0c;在電子測試、工業測量等領域有廣泛應用。 ? 各步驟功能詳解 開關模塊…

OpenAvatarChat要解決UnicodeDecodeError

錯誤信息如下 ailed to import handler module client/h5_rendering_client/client_handler_lam Traceback (most recent call last):File "E:\Codes\Python\aigc\OpenAvatarChat\src\demo.py", line 82, in <module>main()File "E:\Codes\Python\aigc\O…