IT TIP

sklearn을 사용하여 PCA에서 explain_variance_ratio_의 기능 이름 복구

itqueen 2020. 12. 14. 21:27
반응형

sklearn을 사용하여 PCA에서 explain_variance_ratio_의 기능 이름 복구


나는 scikit 배우기로 잘 된 PCA, 복구하기 위해 노력하고있어 기능은 다음과 같이 선택 관련 .

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_

이것은 반환

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

데이터 세트간에이 두 가지 설명 된 분산을 허용하는 두 기능을 어떻게 복구 할 수 있습니까? 다르게 말하면 iris.feature_names에서이 기능의 인덱스를 어떻게 얻을 수 있습니까?

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

도움을 주셔서 미리 감사드립니다.


이 정보는 pca속성에 포함됩니다 components_. 에서 설명한 것처럼 문서 , pca.components_의 배열을 출력 [n_components, n_features]하므로 구성 요소가 선형 적으로 당신이 가지고있는 다양한 기능과 어떻게 관련되는지를 얻을 :

참고 : 각 계수는 특정 구성 요소 쌍과 기능 간의 상관 관계를 나타냅니다.

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

중요 : 추가 의견으로 PCA 기호는 각 구성 요소에 포함 된 분산에 영향을주지 않으므로 해석에 영향을주지 않습니다. PCA 차원을 형성하는 기능의 상대적 기호 만 중요합니다. 실제로 PCA 코드를 다시 실행하면 부호가 반전 된 PCA 차원을 얻을 수 있습니다. 이것에 대한 직관을 위해 3 차원 공간에서 벡터와 그 음수를 생각해보십시오. 둘 다 본질적으로 공간에서 동일한 방향을 나타냅니다. 추가 참조를 위해이 게시물확인하십시오 .


편집 : 다른 사람들이 설명했듯이 .components_속성 에서 동일한 값을 얻을 수 있습니다 .


각 주성분은 원래 변수의 선형 조합입니다.

pca-coef

여기서 X_is는 원래 변수이고 Beta_is는 해당 가중치 또는 소위 계수입니다.

가중치를 얻으려면 간단히 단위 행렬을 transform메서드에 전달할 수 있습니다 .

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

coef위 행렬 의 각 열 은 해당 주성분을 얻는 선형 조합의 가중치를 보여줍니다.

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

예를 들어, 위는 두 번째 주성분 ( PC-2)이 대부분 절대 값에서 sepal width가중치가 가장 높은에 정렬되어 있음을 보여줍니다 0.926.

데이터가 정규화되었으므로 주성분이 1.0norm을 갖는 각 계수 벡터와 동일한 분산 가지고 있음을 확인할 수 있습니다 1.0.

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

One may also confirm that the principal components can be calculated as the dot product of the above coefficients and the original variables:

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

Note that we need to use numpy.allclose instead of regular equality operator, because of floating point precision error.


The way this question is phrased reminds me of a misunderstanding of Principle Component Analysis when I was first trying to figure it out. I’d like to go through it here in the hope that others won’t spend as much time on a road-to-nowhere as I did before the penny finally dropped.

The notion of “recovering” feature names suggests that PCA identifies those features that are most important in a dataset. That’s not strictly true.

PCA, as I understand it, identifies the features with the greatest variance in a dataset, and can then use this quality of the dataset to create a smaller dataset with a minimal loss of descriptive power. The advantages of a smaller dataset is that it requires less processing power and should have less noise in the data. But the features of greatest variance are not the "best" or "most important" features of a dataset, insofar as such concepts can be said to exist at all.

To bring that theory into the practicalities of @Rafa’s sample code above:

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

consider the following:

post_pca_array = pca.fit_transform(data_scaled)

print data_scaled.shape
(150, 4)

print post_pca_array.shape
(150, 2)

In this case, post_pca_array has the same 150 rows of data as data_scaled, but data_scaled’s four columns have been reduced from four to two.

The critical point here is that the two columns – or components, to be terminologically consistent – of post_pca_array are not the two “best” columns of data_scaled. They are two new columns, determined by the algorithm behind sklearn.decomposition’s PCA module. The second column, PC-2 in @Rafa’s example, is informed by sepal_width more than any other column, but the values in PC-2 and data_scaled['sepal_width'] are not the same.

As such, while it’s interesting to find out how much each column in original data contributed to the components of a post-PCA dataset, the notion of “recovering” column names is a little misleading, and certainly misled me for a long time. The only situation where there would be a match between post-PCA and original columns would be if the number of principle components were set at the same number as columns in the original. However, there would be no point in using the same number of columns because the data would not have changed. You would only have gone there to come back again, as it were.


Given your fitted estimator pca, the components are to be found in pca.components_, which represent the directions of highest variance in the dataset.


중요한 기능은 구성 요소에 더 많은 영향을 미치므로 구성 요소에 큰 절대 값 / 계수 / 부하를 갖는 것입니다.

가져 오기 the most important feature name는 PCS에 :

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

이것은 다음을 인쇄합니다.

     0  1
 0  PC1  e
 1  PC2  d

결론 / 설명 :

따라서 PC1에서는 이름 e지정된 기능 이 가장 중요하고 PC2에서는 d.

참고 URL : https://stackoverflow.com/questions/22984335/recovering-features-names-of-explained-variance-ratio-in-pca-with-sklearn

반응형