PCA trong numpy và sklearn tạo ra kết quả khác nhau


20

Có phải tôi đang hiểu nhầm điều gì đó. Đây là mã của tôi

sử dụng 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)

Đầu ra:

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]])

Sử dụng phương pháp 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)

Đầu ra

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.

Tôi có thể biết tại sao nó lại như vậy không?

Nếu tôi muốn lấy lại ma trận gốc của mình thì phải làm sao?


Mã numpy của bạn là sai IMHO (ngoài ra, nó sử dụng Xkhông được xác định). Kiểm tra lại toán học của bạn .
Anony-Mousse -Reinstate Monica

Tôi đang sử dụng ipython notebook nên tôi chỉ có thể sao chép bằng các ô. Toán của tôi sai? Phần nào @ Anony-Mousse
aceminer

@ Anony-Mousse Có tôi nhận ra lỗi của mình nhưng nó vẫn không khớp
aceminer

@aceminer Tôi tò mò tại sao bạn tính ma trận hiệp phương sai của x_std.T chứ không phải x_std?
Evgeni Nabokov

@EvgeniNabokov đã quá lâu. Vì vậy, tôi không thể nhớ được
aceminer

Câu trả lời:


21

Sự khác biệt là do decomposition.PCAkhông chuẩn hóa các biến của bạn trước khi thực hiện PCA, trong khi trong tính toán thủ công của bạn, bạn gọi StandardScalerđể thực hiện tiêu chuẩn hóa. Do đó, bạn đang quan sát sự khác biệt này: PCA về tương quan hay hiệp phương sai?

Nếu bạn thay thế

pca.fit_transform(x)

với

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

bạn sẽ nhận được kết quả tương tự như với tính toán thủ công ...

... nhưng chỉ theo thứ tự của PC. Đó là bởi vì khi bạn chạy

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

bạn nhận được giá trị riêng không nhất thiết phải theo thứ tự giảm dần. tôi có

array([ 0.07168571,  2.49382602,  1.43448827])

Vì vậy, bạn sẽ muốn đặt hàng chúng bằng tay. Sklearn làm điều đó cho bạn.


Về việc xây dựng lại các biến ban đầu, vui lòng xem Làm thế nào để đảo ngược PCA và tái cấu trúc các biến ban đầu từ một số thành phần chính?


Chỉ muốn kiểm tra. Có thực sự cần thiết để chuẩn hóa ma trận bằng độ lệch chuẩn của nó? Tôi đã thấy những ví dụ mà họ không làm điều đó
aceminer

Nó không cần thiết , nó chỉ là một cách để làm điều đó. Xem liên kết mà tôi đặt trong đoạn đầu tiên: stats.stackexchange.com/questions/53 - đó thực sự là tất cả về câu hỏi này. Nếu bạn chuẩn hóa, bạn làm PCA về các mối tương quan. Nếu bạn không, bạn làm PCA trên hiệp phương sai.
amip nói rằng Phục hồi lại

9

Đây là một triển khai tốt với thảo luận và giải thích về PCA trong python. Việc thực hiện này dẫn đến kết quả tương tự như PCA scikit. Đây là một chỉ số khác cho thấy PCA của bạn sai.

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)

bạn cần sắp xếp các giá trị riêng (và các hàm riêng cho phù hợp) giảm dần

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

a = np.dot(x, evecs) 

Nói chung, tôi khuyên bạn nên kiểm tra mã của mình bằng cách thực hiện một ví dụ đơn giản (càng đơn giản càng tốt) và tính toán bằng tay chính xác (và kết quả trung gian). Điều này giúp bạn xác định vấn đề.


1
Yêu câu trả lời này. Nó giải quyết vấn đề của tôi!
Kim Hoa Vương
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.