python打卡day21

常見的降維算法

知識點回顧:

  1. LDA線性判別
  2. PCA主成分分析
  3. t-sne降維

之前學了特征降維的兩個思路,特征篩選(如樹模型重要性、方差篩選)和特征組合(如SVD/PCA)。

現在引入特征降維的另一種分類:無/有監督降維。無監督降維只需要特征數據本身,在降維過程中不使用任何關于數據樣本的標簽信息(比如類別標簽、目標值等),僅僅根據數據點本身的分布、方差、相關性、局部結構等特性來尋找低維表示,典型算法是PCA、t-SNE等

相應的,降維時使用標簽信息的有監督降維,典型算法就是LDA(特征篩選可以是無監督或有監督,取決于是否使用標簽,比如之前特征篩選的學習中除了方差篩選其他都是有監督降維)

1.PCA(主成分分析)

PCA這種無監督降維方法的目標是保留數據的最大方差(即主成分),將數據投影到由這些最重要的主成分構成的新的、維度更低子空間上,這些方差大的方向不一定是對分類最有用的方向。PCA本質上就是在SVD之前對數據進行了均值中心化,均值中心化就是把每個特征"挪到原點附近"的操作,比如:

都提到了最大方差,那PCA和方差篩選有什么不一樣呢?假設有兩個高度相關的特征:

  • 方差篩選可能只保留其中一個,每個特征來計算獨立的方差
  • PCA會生成一個融合兩者的主成分,操作對象是特征的線性組合

所以PCA是一種線性降維,對于數據結構高度非線性(例如“瑞士卷”、“S型曲線”),PCA會將其投影到一個線性子空間,這可能會丟失關鍵的非線性關系,在這種情況下,非線性降維技術(如 t-SNE, UMAP, LLE, Isomap, 核PCA, 自編碼器)會是更好的選擇

降維維度可以根據解釋方差來選擇:

from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix
import time
import numpy as np # 確保numpy導入# 假設 X_train, X_test, y_train, y_test 已經準備好了# 步驟 1: 特征縮放
scaler_pca = StandardScaler()
X_train_scaled_pca = scaler_pca.fit_transform(X_train)
X_test_scaled_pca = scaler_pca.transform(X_test) # 使用在訓練集上fit的scaler# 步驟 2: PCA降維
pca_expl = PCA(random_state=42) # 創建PCA對象(暫不指定降維維度)
pca_expl.fit(X_train_scaled_pca) # 在標準化后的數據上擬合PCA模型
cumsum_variance = np.cumsum(pca_expl.explained_variance_ratio_) # 計算累計解釋方差比例
n_components_to_keep_95_var = np.argmax(cumsum_variance >= 0.95) + 1 # 找到第一個使累計解釋方差≥95%的維度
print(f"為了保留95%的方差,需要的主成分數量: {n_components_to_keep_95_var}")# ----------- 打印結果 -----------
為了保留95%的方差,需要的主成分數量: 26

也可以自己手動指定降維維度,這里以降到10個特征為例:

from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix
import time
import numpy as np # 確保numpy導入# 假設 X_train, X_test, y_train, y_test 已經準備好了# 步驟 1: 特征縮放
scaler_pca = StandardScaler()
X_train_scaled_pca = scaler_pca.fit_transform(X_train)
X_test_scaled_pca = scaler_pca.transform(X_test) # 使用在訓練集上fit的scaler# 步驟 2: PCA降維
n_components_pca = 10
pca_manual = PCA(n_components=n_components_pca, random_state=42) # 現在創建PCA對象時,指定降維維度為10X_train_pca = pca_manual.fit_transform(X_train_scaled_pca)
X_test_pca = pca_manual.transform(X_test_scaled_pca) # 使用在訓練集上fit的pcaprint(f"PCA降維后,訓練集形狀: {X_train_pca.shape}, 測試集形狀: {X_test_pca.shape}")
start_time_pca_manual = time.time()
# 步驟 3: 訓練隨機森林分類器
rf_model_pca = RandomForestClassifier(random_state=42)
rf_model_pca.fit(X_train_pca, y_train)# 步驟 4: 在測試集上預測
rf_pred_pca_manual = rf_model_pca.predict(X_test_pca)
end_time_pca_manual = time.time()print(f"手動PCA降維后,訓練與預測耗時: {end_time_pca_manual - start_time_pca_manual:.4f} 秒")print("\n手動 PCA + 隨機森林 在測試集上的分類報告:")
print(classification_report(y_test, rf_pred_pca_manual))
print("手動 PCA + 隨機森林 在測試集上的混淆矩陣:")
print(confusion_matrix(y_test, rf_pred_pca_manual))

2.t-SNE(t-分布隨機鄰域嵌入)

PCA 的目標是保留數據的全局方差,而 t-SNE 的核心目標是在高維空間中相似的數據點,在降維后的低維空間中也應該保持相似(即彼此靠近),而不相似的點則應該相距較遠。特別擅長于將高維數據集投影到二維或三維空間進行可視化,從而揭示數據中的簇結構或流形結構

總的來說,t-SNE是一種適合非線性數據可視化的降維算法,而非數據處理中普適的降維;同時PCA同樣適合聚類前的可視化,但PCA更適合一般數據預處理

  • Perplexity (困惑度):這個參數對結果影響較大。常見的取值范圍是 5 到 50。較小的困惑度關注非常局部的結構,較大的困惑度則考慮更廣泛的鄰域。通常需要嘗試不同的值
  • n_iter (迭代次數):需要足夠的迭代次數讓算法收斂。默認值通常是1000。如果可視化結果看起來還不穩定,可以嘗試增加迭代次數
  • learning_rate (學習率):也可能影響收斂
from sklearn.manifold import TSNE
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix
import time
import numpy as np
import matplotlib.pyplot as plt # 用于可選的可視化
import seaborn as sns # 用于可選的可視化# 步驟 1: 特征縮放
scaler_tsne = StandardScaler()
X_train_scaled_tsne = scaler_tsne.fit_transform(X_train)
X_test_scaled_tsne = scaler_tsne.transform(X_test) # 使用在訓練集上fit的scaler# 步驟 2: t-SNE 降維
n_components_tsne = 2    # 更典型的t-SNE用于分類的維度,如果想快速看到結果# 如果你想嚴格對比PCA的10維,可以將這里改為10,但會很慢
# 對訓練集進行 fit_transform
tsne_model_train = TSNE(n_components=n_components_tsne,perplexity=30,    # 常用的困惑度值n_iter=1000,      # 足夠的迭代次數init='pca',       # 使用PCA初始化,通常更穩定learning_rate='auto', # 自動學習率 (sklearn >= 1.2)random_state=42,  # 保證結果可復現n_jobs=-1)        # 使用所有CPU核心
print("正在對訓練集進行 t-SNE fit_transform...")
start_tsne_fit_train = time.time()
X_train_tsne = tsne_model_train.fit_transform(X_train_scaled_tsne)
end_tsne_fit_train = time.time()
print(f"訓練集 t-SNE fit_transform 完成,耗時: {end_tsne_fit_train - start_tsne_fit_train:.2f} 秒")# 對測試集進行 fit_transform
# 再次強調:這是獨立于訓練集的變換
tsne_model_test = TSNE(n_components=n_components_tsne,perplexity=30,n_iter=1000,init='pca',learning_rate='auto',random_state=42, # 保持參數一致,但數據不同,結果也不同n_jobs=-1)
print("正在對測試集進行 t-SNE fit_transform...")
start_tsne_fit_test = time.time()
X_test_tsne = tsne_model_test.fit_transform(X_test_scaled_tsne) # 注意這里是 X_test_scaled_tsne
end_tsne_fit_test = time.time()
print(f"測試集 t-SNE fit_transform 完成,耗時: {end_tsne_fit_test - start_tsne_fit_test:.2f} 秒")print(f"t-SNE降維后,訓練集形狀: {X_train_tsne.shape}, 測試集形狀: {X_test_tsne.shape}")start_time_tsne_rf = time.time()
# 步驟 3: 訓練隨機森林分類器
rf_model_tsne = RandomForestClassifier(random_state=42)
rf_model_tsne.fit(X_train_tsne, y_train)# 步驟 4: 在測試集上預測
rf_pred_tsne_manual = rf_model_tsne.predict(X_test_tsne)
end_time_tsne_rf = time.time()print(f"t-SNE降維數據上,隨機森林訓練與預測耗時: {end_time_tsne_rf - start_time_tsne_rf:.4f} 秒")
total_tsne_time = (end_tsne_fit_train - start_tsne_fit_train) + \(end_tsne_fit_test - start_tsne_fit_test) + \(end_time_tsne_rf - start_time_tsne_rf)
print(f"t-SNE 總耗時 (包括兩次fit_transform和RF): {total_tsne_time:.2f} 秒")print("\n手動 t-SNE + 隨機森林 在測試集上的分類報告:")
print(classification_report(y_test, rf_pred_tsne_manual))
print("手動 t-SNE + 隨機森林 在測試集上的混淆矩陣:")
print(confusion_matrix(y_test, rf_pred_tsne_manual))

3.LDA(線性判別)

在分類任務中,LDA通常比PCA更直接有效,會更注重類別信息,不像PCA選擇方差大的方向,而是會選擇能讓不同類別的點盡量分開的方向,即使這個方向數據整體方差不是最大的

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix
import time
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D # 如果需要3D繪圖
import seaborn as sns# 步驟 1: 特征縮放
scaler_lda = StandardScaler()
X_train_scaled_lda = scaler_lda.fit_transform(X_train)
X_test_scaled_lda = scaler_lda.transform(X_test) # 使用在訓練集上fit的scaler# 步驟 2: LDA 降維
n_features = X_train_scaled_lda.shape[1]
if hasattr(y_train, 'nunique'):n_classes = y_train.nunique()
elif isinstance(y_train, np.ndarray):n_classes = len(np.unique(y_train))
else:n_classes = len(set(y_train))max_lda_components = min(n_features, n_classes - 1)# 設置目標降維維度
n_components_lda_target = 10if max_lda_components < 1:print(f"LDA 不適用,因為類別數 ({n_classes})太少,無法產生至少1個判別組件。")X_train_lda = X_train_scaled_lda.copy() # 使用縮放后的原始特征X_test_lda = X_test_scaled_lda.copy()   # 使用縮放后的原始特征actual_n_components_lda = n_featuresprint("將使用縮放后的原始特征進行后續操作。")
else:# 實際使用的組件數不能超過LDA的上限,也不能超過我們的目標(如果目標更小)actual_n_components_lda = min(n_components_lda_target, max_lda_components)if actual_n_components_lda < 1: # 這種情況理論上不會發生,因為上面已經檢查了 max_lda_components < 1print(f"計算得到的實際LDA組件數 ({actual_n_components_lda}) 小于1,LDA不適用。")X_train_lda = X_train_scaled_lda.copy()X_test_lda = X_test_scaled_lda.copy()actual_n_components_lda = n_featuresprint("將使用縮放后的原始特征進行后續操作。")else:print(f"原始特征數: {n_features}, 類別數: {n_classes}")print(f"LDA 最多可降至 {max_lda_components} 維。")print(f"目標降維維度: {n_components_lda_target} 維。")print(f"本次 LDA 將實際降至 {actual_n_components_lda} 維。")lda_manual = LinearDiscriminantAnalysis(n_components=actual_n_components_lda, solver='svd')X_train_lda = lda_manual.fit_transform(X_train_scaled_lda, y_train)X_test_lda = lda_manual.transform(X_test_scaled_lda)print(f"LDA降維后,訓練集形狀: {X_train_lda.shape}, 測試集形狀: {X_test_lda.shape}")start_time_lda_rf = time.time()
# 步驟 3: 訓練隨機森林分類器
rf_model_lda = RandomForestClassifier(random_state=42)
rf_model_lda.fit(X_train_lda, y_train)# 步驟 4: 在測試集上預測
rf_pred_lda_manual = rf_model_lda.predict(X_test_lda)
end_time_lda_rf = time.time()print(f"LDA降維數據上,隨機森林訓練與預測耗時: {end_time_lda_rf - start_time_lda_rf:.4f} 秒")print("\n手動 LDA + 隨機森林 在測試集上的分類報告:")
print(classification_report(y_test, rf_pred_lda_manual))
print("手動 LDA + 隨機森林 在測試集上的混淆矩陣:")
print(confusion_matrix(y_test, rf_pred_lda_manual))

收獲心得:

講實話關于特征降維這一兩節內容學的有點麻,以后再認真看看

@浙大疏錦行

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

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

相關文章

專業級軟件卸載工具:免費使用,徹底卸載無殘留!

在數字生活節奏日益加快的今天&#xff0c;我們的電腦就像每天都在"吃進"各種軟件。但您是否注意到&#xff0c;那些看似消失的程序其實悄悄留下了大量冗余文件&#xff1f;就像廚房角落里積攢的調味瓶空罐&#xff0c;日積月累就會讓系統變得"消化不良"。…

【Linux】基礎 IO(一)

&#x1f4dd;前言&#xff1a; 這篇文章我們來講講Linux——基礎IO主要包括&#xff1a; 文件基本概念回顧 C文件的操作介紹系統關于文件的基本操作 &#x1f3ac;個人簡介&#xff1a;努力學習ing &#x1f4cb;個人專欄&#xff1a;Linux &#x1f380;CSDN主頁 愚潤求學 …

Java 原生實現代碼沙箱之Java 程序安全控制(OJ判題系統第2期)——設計思路、實現步驟、代碼實現

在看這一期之前&#xff0c;需要先看上一期的文章&#xff1a; Java 原生實現代碼沙箱&#xff08;OJ判題系統第1期&#xff09;——設計思路、實現步驟、代碼實現-CSDN博客 Java 程序可能出現的異常情況 1、執行超時 占用時間資源&#xff0c;導致程序卡死&#xff0c;不釋…

常見的降維算法

作業&#xff1a; 自由作業&#xff1a;探索下什么時候用到降維&#xff1f;降維的主要應用&#xff1f;或者讓ai給你出題&#xff0c;群里的同學互相學習下。可以考慮對比下在某些特定數據集上t-sne的可視化和pca可視化的區別。 一、什么時候用到降維&#xff1f; 降維通常…

理解Yocto項目中`${D}`作為模擬目標系統根文件結構的臨時目錄

在Yocto項目中,理解${D}作為模擬目標系統根文件結構的臨時目錄,可以通過以下具象化的比喻和結構解析來把握其核心邏輯: 一、沙盒模型:構建系統的“實驗場地” ${D}的作用類似于建筑師在施工前搭建的1:1實體模型。它完全模仿目標設備的文件系統布局(如/usr/bin、/etc等目錄…

第十課認識約數

課堂學習&#xff1a; 情景引入&#xff1a; 今天我們來認識一下數學中的約數關系&#xff0c;上節課我們了解完倍數之后就已經對約數有了基本的概念&#xff01; 我們按照是否有余數&#xff0c;可以把他們分成兩類 在整數除法中&#xff0c;如果商是整數沒有余數&#x…

【Vue】vuex的getters mapState mapGetters mapMutations mapActions的使用

目錄 一、getters 二、 mapState 三、 mapGetters 四、 mapMutations 五、 mapActions 學到這兒來個小總結&#xff1a;四個map方法的使用 總結不易~ 本章節對我有很大的收獲&#xff0c; 希望對你也是&#xff01;&#xff01;&#xff01; 本節素材已上傳至Gitee&…

html object標簽介紹(用于嵌入外部資源通用標簽)(已不推薦使用deprecated,建議使用img、video、audio標簽)

文章目錄 HTML <object> 標簽詳解基本語法與核心屬性關鍵屬性解析1. **data**2. **type**3. **width & height**4. **name** 嵌入不同類型的資源1. **嵌入圖像**2. **嵌入音頻**3. **嵌入視頻**4. **嵌入 PDF** 參數傳遞與回退內容**參數&#xff08;<param>&a…

警備,TRO風向預警,In-N-Out Burgers維權風暴來襲

本案是TME律所代理的5月首案&#xff0c;傳奇連鎖快餐品牌In-N-Out Burgers委托維權&#xff01; 案件基本情況&#xff1a; 起訴時間&#xff1a;2025-5-1 案件號&#xff1a;25-cv-04767 品牌&#xff1a;In-N-Out 原告&#xff1a;In-N-Out Burgers 原告律所&#xff…

數據結構算法習題通關:樹遍歷 / 哈夫曼 / 拓撲 / 哈希 / Dijkstra 全解析

已知一棵二叉樹先序遍歷和中序遍歷分別為 ABDEGCFH 和 DBGEACHF&#xff0c;請畫出這個二叉樹的邏輯結構并寫出后序遍歷的序列。 先序遍歷&#xff1a;ABDEGCFH 中序遍歷&#xff1a;DBGEACHF 先序遍歷看出根為A&#xff0c;左子樹DBGE&#xff0c;右子樹CHF A的左子樹 再…

C++GO語言微服務和服務發現

目錄 01 03-go-micro簡介 02 04-服務發現的簡單認識 03 05-consul的安裝 04 06-consul常用的命令 05 07-注冊服務到consul并驗證 06 08-consul健康檢查 07 09-consul結合grpc使用-上&#xff08;只實現grpc遠程調用&#xff09; 08 10-consul結合grpc使用-中&#xff08…

HDFS 常用基礎命令詳解——快速上手分布式文件系統

簡介&#xff1a; 本文面向剛接觸 Hadoop HDFS&#xff08;Hadoop 分布式文件系統&#xff09;的讀者&#xff0c;結合 CSDN 博客風格&#xff0c;系統梳理最常用的 HDFS 客戶端命令&#xff0c;并配以示例和注意事項&#xff0c;幫助你在開發和運維中快速掌握 HDFS 的文件管理…

VUE CLI - 使用VUE腳手架創建前端項目工程

前言 前端從這里開始&#xff0c;本文將介紹如何使用VUE腳手架創建前端工程項目 1.預準備&#xff08;編輯器和管理器&#xff09; 編輯器&#xff1a;推薦使用Vscode&#xff0c;WebStorm&#xff0c;或者Hbuilder&#xff08;適合剛開始練手使用&#xff09;&#xff0c;個…

make和makefile的使用,以及寫一個簡單的進度條程序

1.自動化構建-make/makefile 1.1 背景 一個工程文件中的文件不計其數&#xff0c;其按類型、功能、模塊放在若干目錄中&#xff0c;makefile定義了一系列規則來指定哪些文件需要先編譯&#xff0c;哪些文件需要后編譯&#xff0c;哪些文件需要重新編譯&#xff0c;甚至于過呢…

數據結構中的棧與隊列:原理、實現與應用

前言&#xff1a;棧和隊列是計算機科學中兩種最基礎的線性數據結構&#xff0c;它們的獨特操作規則和廣泛的應用場景使其成為每一位開發者必須掌握的核心知識。本文將通過生活案例、代碼實現和實際應用場景&#xff0c;帶您深入理解這兩種數據結構的精髓。 1.棧&#xff08;Sta…

如何選擇自己喜歡的cms

選擇內容管理系統cms what is cms1.whatcms.org2.IsItWP.com4.Wappalyzer5.https://builtwith.com/6.https://w3techs.com/7. https://www.netcraft.com/8.onewebtool.com如何在不使用 CMS 檢測器的情況下手動檢測 CMS 結論 在開始構建自己的數字足跡之前&#xff0c;大多數人會…

SDC命令詳解:使用all_outputs命令進行查詢

相關閱讀 SDC命令詳解https://blog.csdn.net/weixin_45791458/category_12931432.html all_outputs命令用于創建一個輸出端口對象集合&#xff0c;關于設計對象和集合的更詳細介紹&#xff0c;可以參考下面的博客。 Synopsys&#xff1a;設計對象https://chenzhang.blog.csdn…

vue 中的ref

vue 中的ref vue 中的ref 1. ??ref?? ** 的基本作用** 在 Vue 中&#xff0c;ref 是用來獲取 DOM 元素或者組件實例的一種方式。對于 <el-form> 組件&#xff0c;通過 ref 可以獲取到該表單組件的實例&#xff0c;進而調用表單組件提供的各種方法和訪問其屬性。 …

數據庫版本控制工具--flyway

一. 什么是Flyway Flyway 是一款開源的數據庫遷移工具。它采用簡單直觀的方式管理數據庫變更&#xff0c;通過版本化的遷移腳本確保數據庫結構的一致性和可重復性。無論是開發環境、測試環境還是生產環境&#xff0c;Flyway 都能確保數據庫變更按照預期順序執行&#xff0c;避…

C++使用PoDoFo庫處理PDF文件

&#x1f4da; PoDoFo 簡介 PoDoFo 是一個用 C 編寫的自由開源庫&#xff0c;專用于 讀取、寫入和操作 PDF 文件。它適用于需要程序化處理 PDF 文件的應用程序&#xff0c;比如批量生成、修改、合并、提取元數據、繪圖等。 &#x1f31f; 核心特點 特性說明&#x1f4c4; P…