Мені не зовсім зрозуміло, що те, що ви запитуєте, те, що вам насправді потрібно: загальний крок попередньої обробки в машинному навчанні - це зменшення розмірності + відбілювання, що означає виконання PCA та стандартизацію компонентів, нічого іншого. Але я все ж зупинюсь на вашому питанні, як це сформульовано, адже це цікавіше.
Дозволяє Х бути центром n × dматриця даних із точками даних у рядках та змінними у стовпцях. PCA дорівнює сингулярному розкладанню величини
X =U S V⊤≈UкSкV⊤к,
де виконати зменшення розмірності, ми зберігаємо лише
ккомпоненти. Ортогональне "факторне обертання" цих компонентів передбачає вибір ортогонального
k × k матриця
R і підключивши його до розкладання:
X ≈UкSкV⊤к=UкR R⊤SкV⊤к=n - 1-----√U⊤кRПоворотстандартизовані бали⋅R⊤SкV⊤к/n - 1-----√Обертаються вантажі⊤.
Ось
n - 1-----√UкRобертаються стандартизованими компонентами, а другий член представляє поворотні вантажі, що переміщуються. Дисперсія кожного компонента після обертання задається сумою квадратів відповідного вектора навантаження; перед обертанням просто . Після обертання це щось інше.
s2i/(n−1)
Тепер ми готові сформулювати задачу в математичному відношенні: задані невратовані навантаження , знаходимо матрицю обертання таким, що обертові навантаження, , має рівну суму квадратів у кожному стовпчику.L=VkSk/n−1−−−−−√RLR
Давайте вирішимо. Сума стовпців квадратів після обертання дорівнює діагональним елементам Це має сенс: обертання просто перерозподіляє дисперсії компонентів, які спочатку задаються між ними, відповідно до цієї формули. Нам потрібно їх перерозподілити, щоб вони всі дорівнювали середньому значенню .
(LR)⊤LR=R⊤S2n−1R.
s2i/(n−1)μ
Я не думаю, що для цього є рішення закритої форми, і насправді існує багато різних рішень. Але рішення можна легко побудувати послідовно:
- Візьміть перший компонент і -й компонент. Перший має дисперсію а останній - дисперсію .kσmax>μσmin<μ
- Оберніть лише ці два так, щоб дисперсія першого стала рівною . Матриця обертання у 2D залежить лише від одного параметра і легко записати рівняння та обчислити необхідне . Дійсно, і після перетворення перший ПК отримає дисперсію з якого ми одержуємоμθθ
R2D=(cosθ−sinθsinθcosθ)
cos2θ⋅σmax+sin2θ⋅σmin=cos2θ⋅σmax+(1−cos2θ)⋅σmin=μ,
cos2θ=μ−σminσmax−σmin.
- Перший компонент зараз зроблений, він має дисперсію .μ
- Перехід до наступної пари, беручи компонент з найбільшою дисперсією та той, який має найменшу дисперсію. Гото №2.
Це дозволить перерозподілити всі дисперсії однаково послідовністю 2D обертів. Помноживши всі ці матриці обертання разом дасть загальну .(k−1)R
Приклад
Розглянемо таку матрицю :Середня дисперсія . Мій алгоритм діятиме так:S2/(n−1)
⎛⎝⎜⎜⎜10000060000300001⎞⎠⎟⎟⎟.
5
Крок 1: поверніть PC1 і PC4, щоб PC1 отримав дисперсію . В результаті PC4 отримує дисперсію .51+(10−5)=6
Крок 2: поверніть PC2 (нова максимальна дисперсія) та PC3, щоб PC2 отримав дисперсію . В результаті PC3 отримує дисперсію .53+(6−5)=4
Крок 3: поверніть PC4 (нова максимальна дисперсія) та PC3, щоб PC4 отримав дисперсію . В результаті PC3 отримує дисперсію .54+(6−1)=5
Зроблено.
Я написав сценарій 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
І остаточна матриця:(LR)⊤LR
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
Ось код на Python, наданий @feilong:
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
Зауважимо, що ця проблема повністю еквівалентна наступній: некорельованих змінних із відхиленнями , знайдіть обертання (тобто нову ортогональну основу), яка дасть змінних з однаковими відхиленнями (але, звичайно, більше не співвідносяться).kσ2ik