PCA แบบ numpy และ sklearn ให้ผลลัพธ์ที่ต่างกัน


21

ฉันเข้าใจผิดบางอย่าง นี่คือรหัสของฉัน

ใช้ sklearn

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn import decomposition
from sklearn import datasets
from sklearn.preprocessing import StandardScaler

pca = decomposition.PCA(n_components=3)

x = np.array([
        [0.387,4878, 5.42],
        [0.723,12104,5.25],
        [1,12756,5.52],
        [1.524,6787,3.94],
    ])
pca.fit_transform(x)

เอาท์พุท:

array([[ -4.25324997e+03,  -8.41288672e-01,  -8.37858943e-03],
   [  2.97275001e+03,  -1.25977271e-01,   1.82476780e-01],
   [  3.62475003e+03,  -1.56843494e-01,  -1.65224286e-01],
   [ -2.34425007e+03,   1.12410944e+00,  -8.87390454e-03]])

ใช้วิธีการ numpy

x_std = StandardScaler().fit_transform(x)
cov = np.cov(x_std.T)
ev , eig = np.linalg.eig(cov)
a = eig.dot(x_std.T)

เอาท์พุต

array([[ 0.06406894,  0.94063993, -1.62373172],
   [-0.35357757,  0.7509653 ,  0.63365168],
   [ 0.29312477,  0.6710958 ,  1.11766206],
   [-0.00361615, -2.36270102, -0.12758202]])
I have kept all 3 components but it doesnt seem to allow me to retain my original data.

ฉันขอทราบเหตุผลได้ไหม

ถ้าฉันต้องการได้เมทริกซ์ดั้งเดิมคืนมาฉันควรทำอย่างไร?


รหัส numpy ของคุณผิด IMHO (เช่นกันมันใช้Xซึ่งไม่ได้กำหนดไว้) ตรวจสอบอีกครั้งของคุณคณิตศาสตร์
Anony-Mousse - Reinstate Monica

ฉันกำลังใช้สมุดบันทึก ipython ดังนั้นฉันจึงสามารถคัดลอกโดยเซลล์เท่านั้น คณิตศาสตร์ของฉันผิด ส่วนใดของ @ Anony-Mousse
aceminer

@ anony-มูใช่ฉันตระหนักข้อผิดพลาดของฉัน แต่ก็ยังไม่ตรง
aceminer

@aceminer ฉันอยากรู้ว่าทำไมคุณคำนวณเมทริกซ์ความแปรปรวนร่วมของ x_std.T ไม่ใช่ x_std?
Evgeni Nabokov

@EvgeniNabokov มันยาวเกินไป Sry ฉันจำไม่ได้แล้ว
aceminer

คำตอบ:


21

ความแตกต่างคือเพราะdecomposition.PCAไม่ได้ทำให้ตัวแปรของคุณเป็นมาตรฐานก่อนที่จะทำ PCA ในขณะที่การคำนวณด้วยตนเองของคุณคุณเรียกร้องStandardScalerให้ทำมาตรฐาน ดังนั้นคุณกำลังสังเกตเห็นความแตกต่างนี้: PCA เกี่ยวกับสหสัมพันธ์หรือความแปรปรวนร่วมหรือไม่

หากคุณเปลี่ยน

pca.fit_transform(x)

กับ

x_std = StandardScaler().fit_transform(x)
pca.fit_transform(x_std)

คุณจะได้รับผลลัพธ์เช่นเดียวกับการคำนวณด้วยตนเอง ...

... แต่ขึ้นอยู่กับคำสั่งของพีซีเท่านั้น นั่นเป็นเพราะเมื่อคุณวิ่ง

ev , eig = np.linalg.eig(cov)

คุณได้รับค่าลักษณะเฉพาะไม่จำเป็นต้องอยู่ในลำดับที่ลดลง ฉันเข้าใจ

array([ 0.07168571,  2.49382602,  1.43448827])

ดังนั้นคุณจะต้องการสั่งซื้อด้วยตนเอง Sklearn ทำเพื่อคุณ


เกี่ยวกับการสร้างตัวแปรดั้งเดิมใหม่โปรดดูวิธีการย้อนกลับ PCA และสร้างตัวแปรดั้งเดิมจากองค์ประกอบหลักหลายประการ


แค่ต้องการตรวจสอบ จำเป็นหรือไม่ที่จะต้องสร้างเมทริกซ์ให้เป็นมาตรฐานโดยการเบี่ยงเบนมาตรฐาน ฉันเห็นตัวอย่างที่พวกเขาไม่ทำ
aceminer

มันไม่จำเป็นมันเป็นเพียงวิธีหนึ่งในการทำมัน ดูลิงค์ที่ฉันใส่ไว้ในย่อหน้าแรก: stats.stackexchange.com/questions/53 - มันเป็นเรื่องเกี่ยวกับคำถามนี้จริงๆ หากคุณสร้างมาตรฐานให้คุณทำ PCA ตามความสัมพันธ์ ถ้าคุณทำไม่ได้คุณทำ PCA กับพันธมิตร
อะมีบาพูดว่า Reinstate Monica

9

นี่คือการใช้งานที่ดีพร้อมการสนทนาและคำอธิบายของ PCA ใน python การใช้งานนี้นำไปสู่ผลลัพธ์เช่นเดียวกับ scikit PCA นี่เป็นอีกตัวบ่งชี้ว่า PCA ของคุณผิด

import numpy as np
from scipy import linalg as LA

x = np.array([
        [0.387,4878, 5.42],
        [0.723,12104,5.25],
        [1,12756,5.52],
        [1.524,6787,3.94],
    ])

#centering the data
x -= np.mean(x, axis = 0)  

cov = np.cov(x, rowvar = False)

evals , evecs = LA.eigh(cov)

คุณต้องจัดเรียงค่าลักษณะเฉพาะ (และค่าลักษณะเฉพาะตามลำดับ) จากมากไปน้อย

idx = np.argsort(evals)[::-1]
evecs = evecs[:,idx]
evals = evals[idx]

a = np.dot(x, evecs) 

โดยทั่วไปฉันแนะนำให้คุณตรวจสอบรหัสของคุณโดยการใช้ตัวอย่างง่ายๆ (ง่ายที่สุดเท่าที่จะทำได้) และคำนวณค่าความต้านทานที่ถูกต้องด้วยมือ (และผลลัพธ์ระดับกลาง) ด้วยมือ สิ่งนี้จะช่วยคุณระบุปัญหา


1
รักคำตอบนี้ มันแก้ไขปัญหาของฉัน!
Jinhua Wang
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.