旋轉 PCA 組件以均衡每個組件的方差
我試圖通過對數據集執行 PCA 並丟棄最後幾台 PC 來減少數據集的維度和噪聲。之後,我想在剩餘的 PC 上使用一些機器學習算法,因此我想通過均衡 PC 的方差來規範化數據,以使算法更好地工作。
一種簡單的方法是將方差簡單地標準化為單位值。但是,第一台 PC 與原始數據集的差異比後面的多,我仍然想給它更多的“權重”。因此我想知道:有沒有一種簡單的方法來分割它的方差並與方差較小的 PC 共享?
另一種方法是將 PC 映射回原始特徵空間,但在這種情況下,維度也會增加到原始值。
我想最好保持結果列正交,但目前沒有必要。
我並不完全清楚你所問的是你真正需要的:機器學習中一個常見的預處理步驟是降維+白化,這意味著進行 PCA 和標準化組件,僅此而已。但我仍然會關注你的問題,因為它更有趣。
讓居中數據矩陣,數據點位於行中,變量位於列中。PCA相當於奇異值分解
在哪裡執行我們只保留的降維組件。這些組件的正交“因子旋轉”意味著選擇正交矩陣並將其插入分解:這裡是旋轉的標準化分量,第二項表示轉置的旋轉載荷。旋轉後各分量的方差由對應加載向量的平方和給出;在旋轉之前它只是. 旋轉之後就是另外一回事了。 現在我們準備用數學術語來表述這個問題:給定未旋轉的載荷, 找到旋轉矩陣這樣旋轉的載荷,, 每列的平方和相等。
讓我們解決它。旋轉後的列平方和等於對角線元素
這是有道理的:旋轉只是重新分配組件的方差,這些方差最初由下式給出,在他們之間,根據這個公式。我們需要重新分配它們,使它們都等於它們的平均值. 我認為對此沒有封閉形式的解決方案,實際上有許多不同的解決方案。但是可以輕鬆地以順序方式構建解決方案:
- 取第一個組件和-th 組件。第一個有差異最後一個有方差.
- 僅旋轉這兩個,使第一個的方差等於. 二維中的旋轉矩陣僅取決於一個參數並且很容易寫下方程併計算必要的. 的確,並且在轉換後第一台 PC 將得到方差我們立即從中獲得
- 第一個組件現在完成了,它有變化.
- 繼續下一對,取方差最大的分量和方差最小的分量。轉到#2。
這將通過一系列二維旋轉。將所有這些旋轉矩陣相乘將產生整體.
例子
考慮以下矩陣:
平均方差為. 我的算法將按如下方式進行:
- 第一步:旋轉PC1和PC4,使PC1得到方差. 結果,PC4 得到方差.
- 第二步:旋轉PC2(新的最大方差)和PC3,使PC2得到方差. 結果,PC3 得到方差.
- 第三步:旋轉PC4(新的最大方差)和PC3,使PC4得到方差. 結果,PC3 得到方差.
- 完畢。
我編寫了實現該算法的 Matlab 腳本(見下文)。對於這個輸入矩陣,旋轉角度的序列是:
48.1897 35.2644 45.0000
每個步驟後的組件方差(以行為單位):
10 6 3 1 5 6 3 6 5 5 4 6 5 5 5 5
最終的旋轉矩陣(三個二維旋轉矩陣的乘積):
0.6667 0 0.5270 0.5270 0 0.8165 0.4082 -0.4082 0 -0.5774 0.5774 -0.5774 -0.7454 0 0.4714 0.4714
和決賽矩陣是:
5.0000 0 3.1623 3.1623 0 5.0000 1.0000 -1.0000 3.1623 1.0000 5.0000 1.0000 3.1623 -1.0000 1.0000 5.0000
這是代碼:
S = diag([10 6 3 1]); mu = mean(diag(S)); R = eye(size(S)); vars(1,:) = diag(S); Supdated = S; for i = 1:size(S,1)-1 [~, maxV] = max(diag(Supdated)); [~, minV] = min(diag(Supdated)); w = (mu-Supdated(minV,minV))/(Supdated(maxV,maxV)-Supdated(minV,minV)); cosTheta = sqrt(w); sinTheta = sqrt(1-w); R2d = eye(size(S)); R2d([maxV minV], [maxV minV]) = [cosTheta sinTheta; -sinTheta cosTheta]; R = R * R2d; Supdated = transpose(R2d) * Supdated * R2d; vars(i+1,:) = diag(Supdated); angles(i) = acosd(cosTheta); end angles %// sequence of 2d rotation angles round(vars) %// component variances on each step R %// final rotation matrix transpose(R)*S*R %// final S matrix
這是@feilong提供的Python代碼:
def amoeba_rotation(s2): """ Parameters ---------- s2 : array The diagonal of the matrix S^2. Returns ------- R : array The rotation matrix R. Examples -------- >>> amoeba_rotation(np.array([10, 6, 3, 1])) [[ 0.66666667 0. 0.52704628 0.52704628] [ 0. 0.81649658 0.40824829 -0.40824829] [ 0. -0.57735027 0.57735027 -0.57735027] [-0.74535599 0. 0.47140452 0.47140452]] http://stats.stackexchange.com/a/177555/87414 """ n = len(s2) mu = s2.mean() R = np.eye(n) for i in range(n-1): max_v, min_v = np.argmax(s2), np.argmin(s2) w = (mu - s2[min_v]) / (s2[max_v] - s2[min_v]) cos_theta, sin_theta = np.sqrt(w), np.sqrt(1-w) R[:, [max_v, min_v]] = np.dot( R[:, [max_v, min_v]], np.array([[cos_theta, sin_theta], [-sin_theta, cos_theta]])) s2[[max_v, min_v]] = [mu, s2[max_v] + s2[min_v] - mu] return R
請注意,這個問題完全等價於以下問題:給定具有方差的不相關變量,找到將產生的旋轉(即新的正交基)具有相等方差的變量(但當然不再不相關)。