가중 주성분 분석


17

몇 가지 검색을 한 후에, 나는 관측 분동 / 측정 오차를 주요 성분 분석에 포함시키는 것에 대해 거의 발견하지 못했습니다. 내가 찾은 것은 가중치를 포함하기 위해 반복적 인 접근 방식에 의존하는 경향이 있습니다 (예 : here ). 내 질문은 왜이 접근법이 필요한가? 가중 공분산 행렬의 고유 벡터를 사용할 수없는 이유는 무엇입니까?


1
아래 답변 외에도 thread stats.stackexchange.com/q/141754/3277을 참조하십시오 . 가중 PCA (열 및 / 또는 행에 가중이있는)는 주로 가중 (일반화 된) svd / 바이 플롯.
ttnphns

답변:


33

그것은 당신의 체중이 정확히 무엇에 적용되는지에 달려 있습니다.

행 가중치

하자 열의 변수와 데이터 행렬 N 관측 X 열로. 각 관측이 연관된 무게가있는 경우 w I를 , 참으로 PCA에 이러한 가중치를 통합 할 간단합니다.Xnxiwi

먼저 가중 평균 μ = 1 을 계산해야합니다.중앙에 맞추기 위해 데이터에서 빼십시오.μ=1wiwixi

그런 다음 가중 공분산 행렬 1을 계산합니다., 여기서W=diag(wi)는 가중치의 대각선 행렬이며 표준 PCA를 적용하여 분석합니다.1wiXWXW=diag(wi)

세포 무게

하여 용지 Tamuz 외., 2013 상이한 가중치 때 발견,보다 복잡한 경우를 고려 각각 적용되는 요소 데이터 매트릭스. 그런 다음 실제로 분석 솔루션이 없으며 반복적 인 방법을 사용해야합니다. 저자들이 인정한 바에 따르면 , 1979 년 가브리엘과 자 미르 (Gabriel and Zamir, 1979, 임의의 무게를 가진 최소 제곱에 의한 행렬의 낮은 순위 근사치) 에서 그와 같은 일반적인 무게가 확실히 고려 되었기 때문에 바퀴를 재창조했다 . 이것 또한 여기에서 논의되었습니다 .wij

추가 설명 : 가중치 변수와 관측치에 따라 변하지 만 대칭 적이 어서 w i j = w j i 인 경우 분석 솔루션을 다시 사용할 수 있습니다. Koren and Carmel, 2004, Robust Linear Dimensionality Reduction 참조 .wijwij=wji


명확하게 해 주셔서 감사합니다. 대각선 이외의 무게로 분석 솔루션을 사용할 수없는 이유를 설명 할 수 있습니까? 나는 이것이 Tamuz et al 2013과 Gabriel과 Zamir 1979에서 놓친 것입니다.
noname

@ noname : 나는 그런 증거를 알지 못하며, 그것이 알려지지 않았다면 놀라지 않을 것입니다. 무언가가 불가능하다는 것 , 특히 무언가가 분석적으로 불가능 하다는 것을 증명하는 것은 일반적으로 매우 까다 롭습니다 . 각의 3 등분의 불가능은 유명 ... 2000 년 이상 그 증거를 기다렸다 (계속.)
아메바는 분석 재개 모니카 말한다

3
i,jwij(XijAij)2Aq
아메바의 말에 따르면 Reinstate Monica

2
+1. 답변의 첫 번째 섹션은 여기에 설명 된대로 가중 (일반화 된) Biplot 측면에서 개념화 할 수 있습니다 . PCA가 Biplot의 "특정 사례"인 방법을 명심하십시오.
ttnphns

@ ttnphns : 귀하의 의견과 다른 스레드가 중복으로 닫힌 후 답변을 다시 읽고 행 가중치를 처리하는 방법에 대한 설명을 확장했습니다. 가중 평균으로 중심을 언급하지 않았기 때문에 이전에는 완전히 정확하지 않았거나 적어도 완료되지 않았다고 생각합니다. 더 이해가 되길 바랍니다!
amoeba는 Reinstate Monica가

5

행 가중치에 대한 통찰력을 주셔서 대단히 감사합니다. 나는 이것이 스택 오버 플로우가 아니라는 것을 알고 있지만 행 가중 PCA의 구현을 설명하는 데 어려움이 있었으며 이는 가중 PCA에 대한 인터넷 검색의 첫 번째 결과 중 하나이므로 솔루션을 첨부하는 것이 좋을 것이라고 생각했습니다. 같은 상황에서 다른 사람들을 도울 수 있습니다. 이 Python2 코드 스 니펫에서는 위에서 설명한 것과 같은 RBF 커널이 적용된 PCA를 사용하여 2D 데이터 세트의 탄젠트를 계산합니다. 피드백을 많이 받겠습니다.

def weighted_pca_regression(x_vec, y_vec, weights):
    """
    Given three real-valued vectors of same length, corresponding to the coordinates
    and weight of a 2-dimensional dataset, this function outputs the angle in radians
    of the line that aligns with the (weighted) average and main linear component of
    the data. For that, first a weighted mean and covariance matrix are computed.
    Then u,e,v=svd(cov) is performed, and u * f(x)=0 is solved.
    """
    input_mat = np.stack([x_vec, y_vec])
    weights_sum = weights.sum()
    # Subtract (weighted) mean and compute (weighted) covariance matrix:
    mean_x, mean_y =  weights.dot(x_vec)/weights_sum, weights.dot(y_vec)/weights_sum
    centered_x, centered_y = x_vec-mean_x, y_vec-mean_y
    matrix_centered = np.stack([centered_x, centered_y])
    weighted_cov = matrix_centered.dot(np.diag(weights).dot(matrix_centered.T)) / weights_sum
    # We know that v rotates the data's main component onto the y=0 axis, and
    # that u rotates it back. Solving u.dot([x,0])=[x*u[0,0], x*u[1,0]] gives
    # f(x)=(u[1,0]/u[0,0])x as the reconstructed function.
    u,e,v = np.linalg.svd(weighted_cov)
    return np.arctan2(u[1,0], u[0,0]) # arctan more stable than dividing


# USAGE EXAMPLE:
# Define the kernel and make an ellipse to perform regression on:
rbf = lambda vec, stddev: np.exp(-0.5*np.power(vec/stddev, 2))
x_span = np.linspace(0, 2*np.pi, 31)+0.1
data_x = np.cos(x_span)[:-1]*20-1000
data_y = np.sin(x_span)[:-1]*10+5000
data_xy = np.stack([data_x, data_y])
stddev = 1 # a stddev of 1 in this context is highly local
for center in data_xy.T:
    # weight the  points based on their euclidean distance to the current center
    euclidean_distances = np.linalg.norm(data_xy.T-center, axis=1)
    weights = rbf(euclidean_distances, stddev)
    # get the angle for the regression in radians
    p_grad = weighted_pca_regression(data_x, data_y, weights)
    # plot for illustration purposes
    line_x = np.linspace(-5,5,10)
    line_y = np.tan(p_grad)*line_x
    plt.plot(line_x+center[0], line_y+center[1], c="r")
    plt.scatter(*data_xy)
    plt.show()

그리고 샘플 출력 (모든 점에서 동일하게 수행됨) : 여기에 이미지 설명을 입력하십시오

건배,
안드레스

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.