Khôi phục tên các tính năng của giải thích_variance_ratio_ trong PCA với sklearn


78

Tôi đang cố gắng để phục hồi từ một PCA thực hiện với scikit-học, trong đó tính năng được chọn là có liên quan .

Một ví dụ cổ điển với bộ dữ liệu IRIS.

import pandas as pd
import pylab as pl
from sklearn import datasets
from sklearn.decomposition import PCA

# load dataset
iris = datasets.load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)

# normalize data
df_norm = (df - df.mean()) / df.std()

# PCA
pca = PCA(n_components=2)
pca.fit_transform(df_norm.values)
print pca.explained_variance_ratio_

Điều này trả lại

In [42]: pca.explained_variance_ratio_
Out[42]: array([ 0.72770452,  0.23030523])

Làm cách nào để khôi phục hai tính năng nào cho phép hai phương sai giải thích này giữa tập dữ liệu? Nói cách khác, làm cách nào tôi có thể lấy chỉ mục của các tính năng này trong iris.feature_names?

In [47]: print iris.feature_names
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']

Cảm ơn trước sự giúp đỡ của bạn.


4
pca.components_là những gì bạn đang tìm kiếm.
exAres

Nếu bạn muốn tải single most important feature nametrên một PC cụ thể (hoặc trên tất cả các PC), hãy xem câu trả lời của tôi ở cuối trang này.
seralouk

Câu trả lời:


86

Thông tin này được bao gồm trong các pcathuộc tính: components_. Như được mô tả trong tài liệu , pca.components_xuất ra một mảng [n_components, n_features], vì vậy, để có được cách các thành phần có liên quan tuyến tính với các tính năng khác nhau, bạn phải:

Lưu ý : mỗi hệ số thể hiện mối tương quan giữa một cặp thành phần và tính năng cụ thể

import pandas as pd
import pylab as pl
from sklearn import datasets
from sklearn.decomposition import PCA

# load dataset
iris = datasets.load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)

# normalize data
from sklearn import preprocessing
data_scaled = pd.DataFrame(preprocessing.scale(df),columns = df.columns) 

# PCA
pca = PCA(n_components=2)
pca.fit_transform(data_scaled)

# Dump components relations with features:
print(pd.DataFrame(pca.components_,columns=data_scaled.columns,index = ['PC-1','PC-2']))

      sepal length (cm)  sepal width (cm)  petal length (cm)  petal width (cm)
PC-1           0.522372         -0.263355           0.581254          0.565611
PC-2          -0.372318         -0.925556          -0.021095         -0.065416

QUAN TRỌNG: Như một nhận xét bên lề, hãy lưu ý rằng dấu hiệu PCA không ảnh hưởng đến cách giải thích của nó vì dấu hiệu không ảnh hưởng đến phương sai có trong mỗi thành phần. Chỉ các dấu hiệu tương đối của các đặc điểm hình thành thứ nguyên PCA là quan trọng. Trên thực tế, nếu bạn chạy lại mã PCA, bạn có thể nhận được kích thước PCA với các dấu hiệu đảo ngược. Để có trực giác về điều này, hãy nghĩ về một vectơ và âm của nó trong không gian 3-D - cả hai về cơ bản đều đại diện cho cùng một hướng trong không gian. Kiểm tra bài đăng này để tham khảo thêm.


Các thành phần thực sự là sự kết hợp của các tính năng, vì vậy bất kỳ tính năng cụ thể nào (ở một mức độ nhất định) đều tương quan với các thành phần khác nhau ....
Rafa

3
Vì vậy, giả sử bạn muốn biết đối tượng địa lý gốc nào là quan trọng nhất, bạn có nên chỉ lấy các giá trị tuyệt đối và tính tổng chúng không? Ý tôi là, bắt đầu từ dòng cuối cùng từ câu trả lời: pd.DataFrame (pca.components_, column = data_scaled.columns, index = ['PC-1', 'PC-2']). Abs (). Sum (axis = 0), dẫn đến các giá trị: 0,894690 1,188911 0,602349 0,631027. Chúng ta có thể nói rằng chiều rộng lá đài quan trọng nhất, sau đó là chiều dài lá đài?
Guido

10
Để hiểu các tính năng nào là quan trọng, bạn cần chú ý đến các mối tương quan. Ví dụ, chiều rộng lá đài và PC-2 có tương quan chặt chẽ (nghịch) vì hệ số tương quan là -0,92. Mặt khác, chiều dài cánh hoa và PC-2 hoàn toàn không tương quan vì corr coef là -0,02. Vì vậy, PC-2 phát triển khi chiều rộng lá đài giảm và PC-2 không phụ thuộc vào những thay đổi về chiều dài cánh hoa. Đó là, đối với PC-2, chiều rộng đài hoa là quan trọng trong khi chiều dài cánh hoa thì không. Phân tích tương tự mà bạn có thể tiến hành cho các biến khác xem xét hệ số tương quan nằm trong khoảng [-1, 1]
Rafa

Câu trả lời hữu ích! Với mục đích của mình, tôi muốn có một khung dữ liệu được xoay vòng để các thành phần là các cột. Tôi đã sử dụngpd.DataFrame(pca.components_.T, index=data_scaled.columns)
Laura

Nếu bạn muốn tải single most important feature nametrên một PC cụ thể (hoặc trên tất cả các PC), hãy xem câu trả lời của tôi ở cuối trang này.
seralouk

51

Chỉnh sửa: như những người khác đã nhận xét, bạn có thể nhận được các giá trị tương tự từ .components_thuộc tính.


Mỗi thành phần chính là một tổ hợp tuyến tính của các biến ban đầu:

pca-coef

trong đó X_is là các biến ban đầu, và Beta_is là trọng số tương ứng hay còn gọi là hệ số.

Để có được các trọng số, bạn có thể chỉ cần chuyển ma trận nhận dạng cho transformphương thức:

>>> i = np.identity(df.shape[1])  # identity matrix
>>> i
array([[ 1.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.],
       [ 0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  1.]])

>>> coef = pca.transform(i)
>>> coef
array([[ 0.5224, -0.3723],
       [-0.2634, -0.9256],
       [ 0.5813, -0.0211],
       [ 0.5656, -0.0654]])

Mỗi cột của coefma trận ở trên hiển thị các trọng số trong kết hợp tuyến tính thu được thành phần chính tương ứng:

>>> pd.DataFrame(coef, columns=['PC-1', 'PC-2'], index=df.columns)
                    PC-1   PC-2
sepal length (cm)  0.522 -0.372
sepal width (cm)  -0.263 -0.926
petal length (cm)  0.581 -0.021
petal width (cm)   0.566 -0.065

[4 rows x 2 columns]

Ví dụ, ở trên cho thấy rằng thành phần chính thứ hai ( PC-2) chủ yếu được căn chỉnh với sepal width, có trọng số cao nhất về 0.926giá trị tuyệt đối;

Vì dữ liệu đã được chuẩn hóa, bạn có thể xác nhận rằng các thành phần chính có phương sai 1.0tương đương với mỗi vectơ hệ số có định mức 1.0:

>>> np.linalg.norm(coef,axis=0)
array([ 1.,  1.])

Người ta cũng có thể xác nhận rằng các thành phần chính có thể được tính dưới dạng tích số chấm của các hệ số trên và các biến ban đầu:

>>> np.allclose(df_norm.values.dot(coef), pca.fit_transform(df_norm.values))
True

Lưu ý rằng chúng ta cần sử dụng numpy.allclosethay vì toán tử bình đẳng thông thường, vì lỗi độ chính xác dấu chấm động.


3
Câu trả lời tuyệt vời và đầy đủ, cảm ơn bạn rất nhiều!
mazieres

5
Không cần ma trận nhận dạng đó: của bạn coefgiống như pca.components_.T. Các nhà ước lượng scikit-learning luôn đặt các tham số đã học của họ trong các thuộc tính công khai.
Fred Foo

4
Tại sao không trực tiếp sử dụng pca.components_?
exAres

2
Sử dụng ma trận nhận dạng không hoạt động vì hàm biến đổi nghịch đảo thêm giá trị trung bình thực nghiệm của mỗi đối tượng. Kết quả cho trọng số (hệ số) bằng nhau cho tất cả các biến ban đầu. (Xem câu trả lời này ). Bằng cách sử dụng pca.components_, bạn sẽ có câu trả lời đúng.
Rahul Murmuria

33

Cách diễn đạt câu hỏi này gợi cho tôi sự hiểu lầm về Phân tích thành phần nguyên tắc khi tôi lần đầu tiên cố gắng tìm ra nó. Tôi muốn xem qua nó ở đây với hy vọng rằng những người khác sẽ không mất nhiều thời gian trên con đường vô định như tôi đã làm trước khi đồng xu cuối cùng giảm xuống.

Khái niệm về tên tính năng “phục hồi” cho thấy PCA xác định những tính năng quan trọng nhất trong tập dữ liệu. Điều đó không hoàn toàn đúng.

PCA, như tôi hiểu, xác định các tính năng có phương sai lớn nhất trong tập dữ liệu và sau đó có thể sử dụng chất lượng này của tập dữ liệu để tạo tập dữ liệu nhỏ hơn với mức hao hụt tối thiểu về sức mạnh mô tả. Ưu điểm của tập dữ liệu nhỏ hơn là nó đòi hỏi ít năng lượng xử lý hơn và dữ liệu sẽ ít nhiễu hơn. Nhưng các tính năng của phương sai lớn nhất không phải là các tính năng "tốt nhất" hoặc "quan trọng nhất" của tập dữ liệu, trong chừng mực có thể nói những khái niệm như vậy tồn tại.

Để đưa lý thuyết đó vào thực tế của mã mẫu của @ Rafa ở trên:

# load dataset
iris = datasets.load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)

# normalize data
from sklearn import preprocessing
data_scaled = pd.DataFrame(preprocessing.scale(df),columns = df.columns) 

# PCA
pca = PCA(n_components=2)
pca.fit_transform(data_scaled)

xem xét những điều sau:

post_pca_array = pca.fit_transform(data_scaled)

print data_scaled.shape
(150, 4)

print post_pca_array.shape
(150, 2)

Trong trường hợp này, post_pca_arraycó cùng 150 hàng dữ liệu data_scaled, nhưng data_scaledbốn cột của đã được giảm từ bốn xuống hai.

Điểm mấu chốt ở đây là hai cột - hoặc các thành phần, nhất quán về mặt thuật ngữ - post_pca_arraykhông phải là hai cột "tốt nhất" của data_scaled. Họ là hai cột mới, xác định bởi các thuật toán đằng sau sklearn.decompositioncủa PCAmodule. Cột thứ hai, PC-2trong ví dụ của @ Rafa, được thông báo bởi sepal_widthnhiều hơn bất kỳ cột nào khác, nhưng các giá trị trong PC-2data_scaled['sepal_width']không giống nhau.

Do đó, mặc dù rất thú vị khi tìm hiểu xem mỗi cột trong dữ liệu gốc đã đóng góp bao nhiêu vào các thành phần của tập dữ liệu hậu PCA, nhưng khái niệm tên cột “khôi phục” hơi sai lầm và chắc chắn đã đánh lừa tôi trong một thời gian dài. Tình huống duy nhất có sự trùng khớp giữa các cột sau PCA và ban đầu sẽ là nếu số lượng các thành phần nguyên tắc được đặt bằng số lượng các cột trong bản gốc. Tuy nhiên, sẽ chẳng ích gì khi sử dụng cùng một số cột vì dữ liệu sẽ không thay đổi. Bạn sẽ chỉ đến đó để quay lại lần nữa, như nó đã từng.


Cảm ơn Aziz. Tôi rất vui vì bạn đã có thể nhận được điều gì đó từ nó.
amunnelly

Cảm ơn. Điều này đã giúp tôi tiết kiệm rất nhiều thời gian vì về cơ bản tôi đã hiểu sai thuật toán đang làm gì.
Thomas

Tôi đã ở trên con đường vô định .. Cảm ơn
David Holkup

9

Các tính năng quan trọng là những đặc điểm ảnh hưởng nhiều hơn đến các thành phần và do đó, có giá trị / hệ số / tải trọng tuyệt đối lớn trên thành phần.

Nhận the most important feature nametrên PC :

from sklearn.decomposition import PCA
import pandas as pd
import numpy as np
np.random.seed(0)

# 10 samples with 5 features
train_features = np.random.rand(10,5)

model = PCA(n_components=2).fit(train_features)
X_pc = model.transform(train_features)

# number of components
n_pcs= model.components_.shape[0]

# get the index of the most important feature on EACH component i.e. largest absolute value
# using LIST COMPREHENSION HERE
most_important = [np.abs(model.components_[i]).argmax() for i in range(n_pcs)]

initial_feature_names = ['a','b','c','d','e']

# get the names
most_important_names = [initial_feature_names[most_important[i]] for i in range(n_pcs)]

# using LIST COMPREHENSION HERE AGAIN
dic = {'PC{}'.format(i+1): most_important_names[i] for i in range(n_pcs)}

# build the dataframe
df = pd.DataFrame(sorted(dic.items()))

Bản in này:

     0  1
 0  PC1  e
 1  PC2  d

Kết luận / Giải thích:

Vì vậy, trên PC1, tính năng được đặt tên elà quan trọng nhất và trên PC2 là d.


6

Với công cụ ước tính phù hợp của bạn pca, các thành phần sẽ được tìm thấy trong pca.components_đó đại diện cho các hướng của phương sai cao nhất trong tập dữ liệu.

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.