演算法金 | 再見,PCA 主成分分析!

算法金「全网同名」發表於2024-06-04


​大俠幸會,在下全網同名[演算法金] 0 基礎轉 AI 上岸,多個演算法賽 Top [日更萬日,讓更多人享受智慧樂趣]

1. 概念:資料降維的數學方法

定義

  • 主成分分析(PCA)是一種統計方法,透過正交變換將一組可能相關的變數轉換為一組線性不相關的變數,這組新的變數稱為主成分。
  • 大白話,PCA能夠從資料中提取出最重要的特徵,透過減少變數的數量來簡化模型,同時保留原始資料集中的大部分資訊。

特點

  • PCA是最廣泛使用的資料降維技術之一,能夠有效地揭示資料的內部結構,減少分析問題的複雜度。

應用領域

  • 影像處理:影像壓縮和特徵提取。
  • 金融資料分析:風險管理、股票市場分析。
  • 生物資訊學:基因資料分析、疾病預測。
  • 社會科學研究:問卷資料分析、人口研究。

2 核心原理:方差最大化

  • 方差最大化:
  • PCA透過找到資料方差最大的方向來確定主成分,然後找到次大方向,且這些方向必須是相互正交的。
  • 這樣做的目的是保證降維後的資料能夠保留最多的原始資料資訊。

  • 計算步驟:
  1. 資料標準化:使得每個特徵的平均值為0,方差為1。
  2. 計算協方差矩陣:反映變數之間的相關性。
  3. 計算協方差矩陣的特徵值和特徵向量:特徵向量決定了PCA的方向,特徵值決定了方向的重要性。
  4. 選擇主成分:根據特徵值的大小,選擇最重要的幾個特徵向量,構成新的特徵空間。

3 優缺點分析

  • 優點:
  • 降維效果顯著:能夠有效地減少資料的維度,同時儘可能地保留原始資料的資訊。
  • 揭示資料結構:有助於發現資料中的模式和結構,便於進一步分析。
  • 無需標籤資料:PCA是一種無監督學習演算法,不需要資料標籤。
  • 缺點:
  • 線性限制:PCA只能捕捉到資料的線性關係和結構,對於非線性結構無能為力。
  • 方差並非資訊量的唯一衡量:有時候資料的重要性並不僅僅體現在方差上,PCA可能會忽略掉一些重要資訊。
  • 對異常值敏感:異常值可能會對PCA的結果產生較大影響。

4 PCA 實戰

介紹一個用於主成分分析的 Python 庫

PCA的核心是構建在sklearn功能之上,以便在與其他包結合時實現最大的相容性。

除了常規的PCA外,它還可以執行SparsePCA和TruncatedSVD。

其他功能包括:

  • 使用Biplot繪製載荷圖
  • 確定解釋的方差
  • 提取效能最佳的特徵
  • 使用載荷繪製的散點圖
  • 使用Hotelling T2和/或SPE/Dmodx進行異常值檢測
pip install pca

from pca import pca  # 匯入PCA模組
import numpy as np
import pandas as pd

# Dataset
from sklearn.datasets import load_iris  # 匯入鳶尾花資料集

# 從鳶尾花資料集中建立DataFrame物件
X = pd.DataFrame(data=load_iris().data, columns=load_iris().feature_names, index=load_iris().target)

# 初始化PCA模型,指定主成分數量為3,並進行資料標準化
model = pca(n_components=3, normalize=True)

# 擬合併轉換資料
out = model.fit_transform(X)

# 建立只包含方向的圖
fig, ax = model.biplot(textlabel=True, legend=False, figsize=(10, 6))

下面我們使用 sklearn 裡面的 PCA 工具,在一組人臉資料上直觀感受下,


# 匯入必要的庫
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_olivetti_faces
from sklearn.decomposition import PCA

# 載入Olivetti人臉資料集
faces_data = fetch_olivetti_faces()
X = faces_data.data

# 視覺化原始影像和對應的主成分
n_images = 4  # 每行顯示的影像數量
n_rows = 4    # 總共的行數

fig, axes = plt.subplots(n_rows, 2*n_images, figsize=(16, 10), subplot_kw={'xticks':[], 'yticks':[]})

# 使用PCA降維
n_components = 50  # 設定PCA保留的主成分數量
pca = PCA(n_components=n_components, whiten=True, random_state=42)
X_pca = pca.fit_transform(X)

for r in range(n_rows):
    for i in range(n_images):
        index = r * n_images + i
        
        axes[r, 2*i].imshow(X[index].reshape(64, 64), cmap='gray')
        axes[r, 2*i].set_title(f'大俠 {index+1} 影像', fontproperties='SimHei')  # 手動設定字型

        axes[r, 2*i+1].imshow(pca.inverse_transform(X_pca[index]).reshape(64, 64), cmap='bone')
        axes[r, 2*i+1].set_title(f'大俠 {index+1} 主成分', fontproperties='SimHei')  # 手動設定字型

plt.tight_layout()
plt.show()

我們保留了前 50 個主成分

透過視覺化對比圖直觀感受下,資訊保留了多多少,損失了多少

透過對比圖可以看到,某一張人臉的基本資訊都保留了下來

如果保留 前 100 個主成分,那就更接近原始圖片了

你也可以試下,保留 1 個主成分會怎樣?透過保留的資訊你還認得出來哪過大俠是哪過嗎

[ 演算法金,碎碎念 ]

  • 最近 【不上班】 這個詞頻繁出現在朋友圈,貌似很火
  • 不上班,站著把錢賺了,大機率不可能的
  • 不上班,躺著把錢賺了(別想歪了),更是絕大機率不可能的
  • 有些圈子,天然就是靠博眼球來篩選使用者,真的很可怕
  • 想到了一句話【當大家都有病時,你就不覺得這是病了】
  • 在這種圈子呆久了,大機率會淪陷的,別以外自己不會,咱都是普通人
  • 大部分人都是普通人,普通人通常都不信機率,而機率恰恰是反映常態 分佈的
  • 悲劇,卒~

全網同名,日更萬日,讓更多人享受智慧樂趣

煩請大俠多多 分享、在看、點贊,助力演算法金又猛又持久、很黃很 BL 的日更下去;我們一起,讓更多人享受智慧樂趣

同時邀請大俠 關注、星標 演算法金,圍觀日更萬日,助你功力大增、笑傲江湖

相關文章