TL;DR
- äž»æååæã§æšæºåïŒæšæºåå·®ã§å²ãïŒããã®ãå¿ ããããããšã¯éããªã
- ããã©ãããæšæºåå·®ã§å²ãããšã®æªåœ±é¿ããã
- æšæºåãã¹ããã©ããã¯ãã©ãã§äž»æååæã䜿ããïŒå¯èŠåãšããŠäœ¿ãã®ãããã€ãã©ã€ã³ãšããŠäœ¿ãã®ãïŒã«ãã£ãŠãç°ãªããããããã¡ãããšèããŸããã
äž»æååæã«ãæšæºåå·®ã§å²ãäŸãšå²ããªãäŸããã
ãäž»æååæãããéã«ã¯æšæºåïŒæ£èŠåïŒãããŸãããããšèšãããããšã¯ãããããŸãããå®ã¯ããæ¢ããšå²ã£ãŠããäŸãšå²ã£ãŠããªãäŸããããŸããã©ã¡ãã§èª¬æããŠãããã¯åŠè ã®éã§ãæèŠãåãããŠããããã§ããäž»æååæãå®è¡ããåã®å€æ°å€æãã
ã±ãŒã¹1ïŒå¹³åã ãåŒãã$X-\mu$
ã±ãŒã¹2ïŒå¹³åã§åŒããŠæšæºåå·®ã§å²ãã$\frac{X-\mu}{\sigma}$
ãšãã2éãã§ãã倧åŠãåºããŠããè³æãèŠãŠã¿ãŸããããã±ãŒã¹1ã¯ãªã¿ãŽå€§åŠãåºããŠããPDF 12ããŒãžç®ããsubtract meanããšã ãæžããŠãã£ãŠdivide by standard deviationãšã¯æžããŠããŸããã
ã±ãŒã¹2ã¯çãããåç¥Andrew Ngå
çã®ã¹ã¿ã³ãã©ãŒã倧åŠã®è¬çŸ©è³æã2ããŒãžç®ããReplace each $x_j^{(i)}$ with $x_j^{(i)} / \sigma_j$ããšãããæšæºåå·®ã§å²ãããšã瀺ããŠããŸãã
ãŸããé«åŽçµæžå€§åŠãåºããŠããPDFãããã¯ãšãŠãããããããè³æã§ãã35ããŒãžç®ã«äžè¬çãªp次å
ã®ããŒã¿ã«å¯ŸããŠäž»æååæãè¡ãå ŽåãäžããããããŒã¿ã«å¯ŸããŠæšæºåãè¡ãããè¡ããšããã30ããŒãžç®ã®äŸã®è§£èª¬ã§å¹³åã§åŒãæšæºåå·®ã§å²ãæäœãæšæºåãšããŠããã®ã§ãã±ãŒã¹2ãšèããããã§ãããã
ã±ãŒã¹1ãã±ãŒã¹2ãèæ
®ããŠããäŸãããããããã倿°æŽŸãªã®ã§ã¯ãªãã§ãããããã«ãªãã©ã«ãã¢å·ç«å€§åŠã®ããŒãžã§ã¯æšæºåå·®ã§å²ããã«äž»æååæããå Žåã®åé¡ç¹ã瀺ããæ¬¡ã®ããŒãžã§ä»£æ¿æ¡ãšããŠæšæºåããã±ãŒã¹ãåºããŠããŸãã
æ±äº¬å€§åŠã®è¬çŸ©è³æã®8ããŒãžç®ã§ã¯æšæºåã«ã€ããŠè§£èª¬ã¯ããŠãããã®ã®ãããã«ã¯æ³šææžããããããäž»æååæã«ãããŠã¯åæ£ã¯ïŒã«æããªãå Žåãå€ãããšãããŸãã
åå¿ç€Ÿå€§åŠã®ããŒãžã§ã¯æ¬è³ªçãªèª¬æããã£ãŠãRã§ã®è§£èª¬ã§ããã颿°prcompã«ã¯åŒæ°scaleããããããŒã¿ã®æšæºå(ããŒã¿ã®ã¹ã±ãŒã«ãçµ±äž)ãå¿
èŠãªãšãã¯scale=TRUEãæå®ãããããã©ã«ãã«ã¯scale=FALSEã«ãªã£ãŠãããscale=TRUEã«ãããšå
ã®ããŒã¿ã®çžé¢è¡åãçšããäž»æåã«çããããšãããŸãã
Numpyããäœãäž»æååæ
ã±ãŒã¹1ãšã±ãŒã¹2ã®ã©ã¡ããè¯ãããçè§£ããã«ã¯ãSklearnã§PCAã䜿ããã ãã§ã¯ãªããäž»æååæã®è£ã§äœããã£ãŠããããç¥ãå¿ èŠããããŸããNumpyããŒã¹ã§çè§£ããŸãããã
äž»æååæã®æ°åŠçãªçè§£ã¯ãäž»æååæãšã¯åæ£å ±åæ£è¡åãåºæå€åè§£ïŒç¹ç°å€åè§£ïŒããŠãåºæå€ãšåºæãã¯ãã«ãæ±ãããã®ã§ããããçŽæçã§æå³çãªçè§£ã¯ãããŒã¿ã«å¯ŸããŠåæ£ãæã衚çŸã§ããæ°ããè»žãæ¢ãããšã§ããã€ãŸãxyãšãã£ã軞ã®ïŒåºåºã®ïŒå€æãªãã§ããã
ãã®ãããªãµã³ãã«ããŒã¿ãçšæããŸããã
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
X = np.random.randn(100, 1) * 0.5 + 5
y = X * 3 + 2 + np.random.randn(100, 1)
data = np.c_[X, y]
plt.plot(X, y, ".")
plt.show()
ä»ããŒã¿ã¯å¹³åã§åŒããæšæºåå·®ã§å²ãããŠãããã®ãšããŸããã€ãŸãå çšã®ã±ãŒã¹2ãšããŸãã
data = (data - np.mean(data, axis=0)) / np.std(data, axis=0)
äž»æååæã¯ä»¥äžã®ã³ãŒãã§ããããããŸãã
cov = np.cov(data, rowvar=False)
U, S, _ = np.linalg.svd(cov)
print(cov) # 忣å
±åæ£è¡å
print(U) # åºæãã¯ãã«
print(S) # åºæå€
åŸã»ã©ç¢ºãããŸãããç¹ç°å€åè§£ã§ãã£ãŠãåºæå€åè§£ïŒlinalg.eigïŒã§ãã£ãŠãã©ã¡ãã§ãããã§ã1ãç¹ç°å€åè§£ã®ã»ãããµããŒãããŠãããã¬ãŒã ã¯ãŒã¯ãå€ãæ°ãããã®ã§ç¹ç°å€åè§£ã§æžããŸããã
Scikit-learnã®PCAã§ã¯ãåæ£å ±åæ£è¡åãåºæãã¯ãã«ãåºæå€ã«ããããã©ã¡ãŒã¿ãŒã¯ä»¥äžã®ããã«ããŠæ±ããããŸãã
from sklearn.decomposition import PCA
pca = PCA()
pca.fit(data)
print("Sklearn : PCA")
print(pca.get_covariance()) # 忣å
±åæ£è¡å
print(pca.components_.T) # åºæãã¯ãã«
print(pca.explained_variance_) # åºæå€
åæ£å ±åæ£è¡åïŒpca.get_covariance()ãåºæãã¯ãã«ïŒpca.componets_ã®è»¢çœ®ãåºæå€=pca.explained_variance_ã®å¯Ÿå¿ã«ãªããŸããåºæãã¯ãã«ãcomponents_ã®è»¢çœ®ã«ãªãããšã«ã€ããŠã§ãããSklearn v0.20.0ã§ã¯$M=U\Sigma V^T$ãšããç¹ç°å€åè§£ã«å¯ŸããŠã$U$ã§ã¯ãªã$V^T$ãexplained_varianceã«å²ãåœãŠãŠããããïŒè©²åœãœãŒã¹ã³ãŒãã¯ãã¡ãïŒãpca.explained_variance_ã®çµæã転眮ããããšSVDã®çµæãšã»ãŒåãã«ãªãã¯ãã§ãã
çµæãæ¯èŒãããšæ¬¡ã®éãã§ãããããããåæ£å ±åæ£è¡åãåºæãã¯ãã«ãåºæå€ã®é ã§ããæ£ããå®è£ ã§ããŠããã®ã確èªã§ããŸãã
Numpy : SVD
[[1.01010101 0.85394847]
[0.85394847 1.01010101]]
[[-0.70710678 -0.70710678]
[-0.70710678 0.70710678]]
[1.86404948 0.15615254]
Sklearn : PCA
[[1.01010101 0.85394847]
[0.85394847 1.01010101]]
[[-0.70710678 -0.70710678]
[-0.70710678 0.70710678]]
[1.86404948 0.15615254]
åºæãã¯ãã«ã®ç¬Šå·ã¯å転ããããšããã
ã»ãŒåããšãã£ãã®ã¯ããã©ã¹ãã€ãã¹ã¯å転ããããšããããšããããšã§ããç¹ç°å€åè§£ã® åºæãã¯ãã«ã¯æ°ããè»žãæ¢ããã®ãªã®ã§ã笊å·ãå転ããŠããŠãç¹ã«åé¡ã¯ãããŸããããªããªããxy座æšäžã§(-1, 0)ã§ã(1, 0)ã§ãã©ã¡ããx軞ãæããŠããããšã«ã¯å€ãããŸããã®ã§ã
ããå°ã詳ããæžããšãäžè¬ã«$M=U\Sigma V^T$ãšããç¹ç°å€åè§£ã«ãããŠã¯ã$\Sigma$ã¯äžæã«å®ãŸã£ãŠãã$U, V$ã¯äžæã«å®ãŸããªãããšãããããã§ãã詳ããã¯ãã¡ãã
ã¡ãªã¿ã«ãäžè¬ã®SVDã§ã¯$U$ãš$V$ã®æ¬¡å ã¯ç°ãªããŸãããäž»æååæã§ã¯åæ£å ±åæ£è¡åãæ£æ¹è¡åãã€å¯Ÿç§°è¡åïŒå¯Ÿç§°è¡åã¯æ£æ¹è¡åã®ç¹å¥ãªå Žåãªã®ã§ã察称è¡åãšèšã£ããšãã¯å¿ ãæ£æ¹è¡åã§ãïŒãšããç¹æ®ãªæ¡ä»¶ãããã®ã§ã$U$ãš$V$ã笊å·ãé€ãã°ã»ãŒçãããªããŸãã以äžã®ã³ãŒãã§ç¢ºãããããŸãã
# æ£æ¹è¡åã®å Žå
X = np.arange(9).reshape(3,3)
U, S, V = np.linalg.svd(X)
print(X)
print(U)
print(V.T) # ç°ãªããSVDã§æ±ããŠããã®ã¯V.Tã§ããã®ã«æ³šæ
print()
# 察称è¡åã®å Žå
X = np.array([[1,3,5],[3,2,4],[5,4,7]])
U, S, V = np.linalg.svd(X)
print(X)
print(U)
print(V.T) # ã»ãŒåã
[[0 1 2]
[3 4 5]
[6 7 8]]
[[-0.13511895 0.90281571 0.40824829]
[-0.49633514 0.29493179 -0.81649658]
[-0.85755134 -0.31295213 0.40824829]]
[[-0.4663281 -0.78477477 -0.40824829]
[-0.57099079 -0.08545673 0.81649658]
[-0.67565348 0.61386131 -0.40824829]]
[[1 3 5]
[3 2 4]
[5 4 7]]
[[-0.46038935 0.88384959 -0.08277408]
[-0.43679051 -0.30671769 -0.84565851]
[-0.7728232 -0.35317724 0.52726667]]
[[-0.46038935 -0.88384959 0.08277408]
[-0.43679051 0.30671769 0.84565851]
[-0.7728232 0.35317724 -0.52726667]]
笊å·ã¯ç°ãªã£ãŠã¯ãããã®ã®ã2ã€ç®ã®å¯Ÿç§°è¡åã®å Žå$U$ãš$V$ã¯ã»ãŒåãã§ããã®ã確èªã§ããŸãã1ã€ç®ã®ãã æ£æ¹è¡åã ã£ãå Žåã¯ãåºæãã¯ãã«ã®å·ŠåŽã¯ããªããããŠããŸãã
ãã®ãããäž»æååæã«ãããŠNumpyã§äœã£ããã®ãšSklearnã®çµã¿èŸŒã¿ãæ¯èŒãããšãã¯ãSVDã®$U$ãšãSklearnã®pca.componets_ã®è»¢çœ®ïŒå éšçã«ã¯SVDã®$M=U\Sigma V^T$ã®$V$ïŒãåäžã®ãã®ãšèããŠãããšããããšãããããŸãã
åºæå€ãšç¹ç°å€ã®é¢ä¿
ã¡ãªã¿ã«SVDã¯ç¹ç°å€åè§£ã§ããããããªããåºæå€ãåºæãã¯ãã«ããšããããåºæå€åè§£ã«ãšåãããã«èšã£ãŠããç¹ã«ã€ããŠã確èªããŠãããŸããããè¡åMã察称è¡åã®å Žåã¯ãç¹ç°å€ãšåºæå€ãäžèŽãããšããæ§è³ªããããŸããäž»æååæã§ã¯åæ£å ±åæ£è¡åãšãã察称è¡åã«å¯ŸããŠç¹ç°å€åè§£ã»åºæå€åè§£ãããããããèšããã®ã§ãã
å°ãããã確èªããŸãããã
import numpy as np
import matplotlib.pyplot as plt
def eigen_svd(matrix):
print()
print("â
è¡å â
")
print(matrix)
eigen_value, eigen_vector = np.linalg.eig(matrix)
U, S, V = np.linalg.svd(matrix)
print("åºæå€")
print(eigen_value)
print("SVDã®S")
print(S)
print("åºæãã¯ãã«")
print(eigen_vector)
print("SVDã®U")
print(U)
# æ£æ¹è¡åã®å Žå
X = np.arange(4).reshape(2,2)
eigen_svd(X)
# 察称è¡åã®å Žå
X = np.array([[3,1],[1,2]])
eigen_svd(X)
2ã€ç®ã®ã±ãŒã¹ã®ã¿å¯Ÿç§°è¡åã§ãã察称è¡åã®å Žåã®ã¿ãåºæå€ãšç¹ç°å€ãäžèŽããŠããããšã確èªã§ããŸãã1ã€ç®ã®ã±ãŒã¹ã§ã¯åºæå€ã®çµ¶å¯Ÿå€ãå€ãã£ãŠãããããåºæãã¯ãã«ãå šãå¥ã®ãã®ã«ãªã£ãŠããŸãã
â
è¡å â
[[0 1]
[2 3]]
åºæå€
[-0.56155281 3.56155281]
SVDã®S
[3.70245917 0.54018151]
åºæãã¯ãã«
[[-0.87192821 -0.27032301]
[ 0.48963374 -0.96276969]]
SVDã®U
[[-0.22975292 -0.97324899]
[-0.97324899 0.22975292]]
â
è¡å â
[[3 1]
[1 2]]
åºæå€
[3.61803399 1.38196601]
SVDã®S
[3.61803399 1.38196601]
åºæãã¯ãã«
[[ 0.85065081 -0.52573111]
[ 0.52573111 0.85065081]]
SVDã®U
[[-0.85065081 -0.52573111]
[-0.52573111 0.85065081]]
ã¡ãªã¿ã«ãã®äŸïŒ2ã€ç®ïŒã§ã¯éè¯ãåºæå€ãšç¹ç°å€ãäžèŽããŸããããnp.linalg.eigã§æ±ããåºæå€ãšãnp.linalg.svdã§æ±ããç¹ç°å€ã§ç¬Šå·ãå€ããããšããããŸããããããå®è£
ã®éãã§ããããããããã®é¢æ°ãå¿
èŠã«ãªã£ããã©ã¡ãã®é¢æ°ã䜿ããçµ±äžããã»ãããããããããŸããã
以äžãnp.linalg.svdã®$S$ãåºæå€ã$U$ãåºæãã¯ãã«ãšããŸãã
å¹³åã§åŒãããšã®æå³
åé ã®ã±ãŒã¹1ã§ãã±ãŒã¹2ã§ãå¹³åã§äºåã«åŒããŠãããŸããããããã¯åæ£å ±åæ£è¡åãèšç®ããéœåã«ãããã®ã§ããåæ£å ±åæ£è¡åã®å®çŸ©ã§ãããªåŒãèŠãããšã¯ãªãã§ããããã
$$\rm{Cov}(X)=\frac{X^T X}{n-1} $$
転眮ã®é åºãéã«ãªã£ãŠããŠãæ§ããŸããããã®åŒã¯ããå°ãç¶ãããã£ãŠãå¹³åãåŒããªãå Žåã¯ãããªããŸãã
$$\rm{Cov}(X)=\frac{X^T X}{n-1} - \mu^T\mu$$
ããã§$\mu$ã¯å¹³åã®ãã¯ãã«ã§ããå¹³åãåŒããŠããå Žåã¯$\mu$ãå šãŠ0ã«ãªãã®ã§ãåŒãç®ã®éšåãçç¥ã§ãããšããããã§ããã確ãã«æåã®åŒã§åæ£å ±åæ£è¡åãæ±ããã®ãªãå¹³åã§åŒãæå³ã¯ãããŸãã
ã¡ãªã¿ã«ãåæ£å ±åæ£è¡åã®å€ã¯å¹³åãåŒãããåŒããªããããå€ãããŸããããªããªãå ±åæ£ã¯å¹³åã§åŒããå€å士ã®ç©ã ããã§ããå ±åæ£ã®å®çŸ©ãæãåºããŸãããã
$$\rm{Cov}(x_i, x_j) = E[(x_i-\mu_{x_i})(x_j-\mu_{x_j})] = \frac{(x_i-\mu_{x_i})(x_j-\mu_{x_j})}{n-1}$$
ãïŒ/(n-1)ããšããã®ã¯np.covãäžå忣ã§èšç®ããããããã«åãããŸãããnp.cov()ã®ãããªé¢æ°ã§æ±ããå Žåã§ããå¹³åãåŒãåŠçã¯ãã£ãŠãããŸãããŸããå¹³åã®åŠçã®æç¡ã¯åºæå€ãšåºæãã¯ãã«ã«åœ±é¿ãäžããŸããïŒæšæºåå·®ã®åŠçã¯åœ±é¿ãäžããŸãïŒã
np.random.seed(0)
X = np.random.randn(100, 1) * 0.5 + 5
y = X * 3 + 2 + np.random.randn(100, 1)
data = np.c_[X, y]
def view_eigen_vectors(data):
cov = np.cov(data, rowvar=False)
U, S, V = np.linalg.svd(cov)
print(S) # åºæå€
print(U) # åºæãã¯ãã«
mean = np.mean(data, axis=0, keepdims=True)
view_eigen_vectors(data)
print()
view_eigen_vectors(data-mean)
[3.92993728 0.06970263]
[[-0.21999051 -0.97550201]
[-0.97550201 0.21999051]]
[3.92993728 0.06970263]
[[-0.21999051 -0.97550201]
[-0.97550201 0.21999051]]
ã§ã¯å¹³åã§åŒãã®ãæå³ããªãããšãããšããã¯éããŸããå¹³åãåŒãæ¬åœã®æå³ãšã¯ãåæžããæ¬¡å ã«æå°ããããåæžããæ¬¡å ãæ»ããããããšãã«ãããŸãããããå¹³åã§åŒããªãå ŽåãNumpyã§ã¯ä»¥äžã®ããã«æžããªããšæ£ããå€ãè¿ããŸããã
def numpy_pca(data):
cov = np.cov(data, rowvar=False)
U, S, V = np.linalg.svd(cov)
print("次å
åæžã®åºæãã¯ãã«")
U_reduce = U[:, :1]
print(U_reduce)
# 次å
åæž
mean = np.mean(data, axis=0, keepdims=True)
project = np.dot(data-mean, U_reduce)
# 次å
ã®åŸ©å
data_rec = np.dot(project, U_reduce.T)+mean
print("次å
åæžâ埩å
")
print(data_rec[:5, :])
from sklearn.decomposition import PCA
def sklearn_pca(data):
pca = PCA(n_components=1)
pca.fit(data)
print("次å
åæžã®åºæãã¯ãã«")
print(pca.components_.T)
# 次å
åæž
project = pca.transform(data)
# 次å
ã®åŸ©å
data_rec = pca.inverse_transform(project)
print("次å
åæžâ埩å
")
print(data_rec[:5, :])
print("Numpy")
numpy_pca(data)
print()
print("Scikit-learn")
sklearn_pca(data)
numpy_pca()ã®æ¬¡å ã®åæžãšåŸ©å ã®éšåã«æ³šç®ãæ£çŽã次å ãåæžãããšãã«å¹³åãåŒããŠã埩å ãããšãã«å¹³åãè¶³ãããé¢åã§ãããããããªã®ãã°ã®å ã§ããæåããå¹³åãåŒããŠ0ã«ããŠããŸãã°äžçºè§£æ±ºã§ãã
Numpy
次å
åæžã®åºæãã¯ãã«
[[-0.21999051]
[-0.97550201]]
次å
åæžâ埩å
[[ 6.00626874 21.50121063]
[ 4.84086798 16.3334842 ]
[ 5.05769772 17.2949704 ]
[ 5.97521052 21.36348945]
[ 5.38621196 18.75169826]]
Scikit-learn
次å
åæžã®åºæãã¯ãã«
[[-0.21999051]
[-0.97550201]]
次å
åæžâ埩å
[[ 6.00626874 21.50121063]
[ 4.84086798 16.3334842 ]
[ 5.05769772 17.2949704 ]
[ 5.97521052 21.36348945]
[ 5.38621196 18.75169826]]
ã¡ãªã¿ã«åºæãã¯ãã«ã®ç¬Šå·ã¯ãåæžâ埩å ãããšãã®å€ã«å·Šå³ããªãããã§ããæ°ã«ãªãæ¹ã¯ç¢ºãããŠã¿ãŠãã ããã
æšæºåãããããªãå Žåã§ãäžé·äžç
å眮ããé·ããªã£ãŠããŸããŸããããäž»æååæã«ãããŠã**ãæšæºåããã»ããªãã«ããã¡ãªããããã¡ãªããã**ãèããŠã¿ãããšæããŸãã
æšæºåããªããã¡ãªãã/æšæºåããã¡ãªãã
ããã¯æçœã§ãããããã倿°ã®ã¹ã±ãŒã«ãç°ãªãã®ã§ãåäžã®ã¹ã±ãŒã«ã§æ¯èŒåºãŸããããæ¯èŒããããšãããšãã¹ãªãŒããèµ·ããããããªããŸãã
ããããããã®ã¯äž»æå軞ã§ããå¹³åã§åŒããªãã±ãŒã¹ãå¹³åã§åŒããã±ãŒã¹ãå¹³åã§åŒããŠæšæºåå·®ã§åŒããïŒæšæºåããïŒã±ãŒã¹ã§äž»æååæãè¡ããäž»æå軞ãããããããŠã¿ãŸããã
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
X = np.random.randn(100, 1) * 0.5 + 5
y = X * 3 + 2 + np.random.randn(100, 1)
data = np.c_[X, y]
def plot_principal_axis(data, title):
cov = np.cov(data, rowvar=False)
U, S, V = np.linalg.svd(cov)
mean = np.mean(data, axis=0, keepdims=True)
color = ["red", "blue"]
plt.plot(data[:,0], data[:,1], ".")
for i in range(len(S)):
lines = np.dot(np.arange(-2.0,2.0,0.1).reshape(-1,1), U[:,i].reshape(1,-1)) + mean
plt.plot(lines[:,0], lines[:,1], color=color[i])
plt.title(title)
plt.show()
plot_principal_axis(data, "No mean adjust")
data_mean_adj = data - np.mean(data, axis=0, keepdims=True)
plot_principal_axis(data_mean_adj, "Mean adjust")
data_norm = data_mean_adj / np.std(data, axis=0, keepdims=True)
plot_principal_axis(data_norm, "Mean-std adjust (Normalize)")
äžãããå¹³åã§åŒããªãã±ãŒã¹ïŒNo mean adjustïŒãå¹³åã§åŒããã±ãŒã¹ïŒMean adujustïŒãæšæºåããã±ãŒã¹ïŒMean-std adjust(Normalize)ïŒ
æšæºåå·®ã§å²ããªãå Žå以å€ã軞ãããããïŒçŽäº€ããŠããªãããã«ïŒèŠããŸãããããã¯ã°ã©ãã®çœ ã§ãã**å šéšã®ã±ãŒã¹ã§è»žã¯çŽäº€ããŠããŸãïŒ**äŸãã°äžçªæåã®ã±ãŒã¹ã§ã暪軞ã0ïœ15ã瞊軞ã10ïœ25ãšå¹ ãåºå®ããŠã¿ããã©ãã§ããããïŒããã¯plot_principal_axisã®é¢æ°ã®forã«ãŒãã®äžã«æ¬¡ã®ããã«ã³ãŒãã远å ããŸãã
plt.plot(lines[:,0], lines[:,1], color=color[i])
# 以äžã远å
plt.xlim((0,15))
plt.ylim((10,25))
å®ã¯ã¡ãããšã¹ã±ãŒã«ãçŽãã°çŽäº€ããŠããã®ã§ããããå°ãå®éçãªè§£èª¬ãããŸããããããã¯é«æ ¡æ°åŠã®å 容ã§ããããããã¯ãã«$\vec{a}, \vec{b}$ã®2ã€ãçŽäº€ãããšã以äžã®åŒãæºãããŸãã
$$\vec{a}\cdot\vec{b} =0$$
2ã€ã®ãã¯ãã«ãçŽäº€ãããšããã®å ç©ã¯0ã§ãããããã³ãŒãã§æ€èšŒããŠã¿ãŸãããã
def check_orthogonal(data):
cov = np.cov(data, rowvar=False)
U, S, V = np.linalg.svd(cov)
inner = np.dot(U[:,0], U[:,1])
print(inner)
check_orthogonal(data)
check_orthogonal(data_mean_adj)
check_orthogonal(data_norm)
çµæã¯ä»¥äžã®éãã§ããå šãŠã®ã±ãŒã¹ã§å ç©ã0ïŒèª€å·®ã¬ãã«ïŒãšããçµæã«ãªããŸãããã€ãŸããå¹³åã§åŒããããæšæºåå·®ã§å²ãããäž»æå軞ã¯çŽäº€ããŠããã®ã§ãã
-3.3306690738754696e-16
3.608224830031759e-16
-5.551115123125783e-17
ã¡ãªã¿ã«ãã®ãããªæ§è³ªãæã€è¡åãçŽäº€è¡åãšåŒã¶ããã§ããããå°ã詳ããæžããš$M^TM=MM^T=E $($E$ã¯åäœè¡å)ãæºããè¡åã®ããš2ãçŽäº€è¡åã¯å¿ ãæ£æ¹è¡åïŒå¯Ÿç§°è¡åãšäŒŒãŠããŠãçŽäº€è¡åãæ£æ¹è¡åã®ç¹å¥ãªå Žåã§ãïŒãªã®ã§ã転眮ã®é åºãå ¥ãæ¿ããŠãè¡åã®å€§ãããå€ããããšã¯ãããŸããã
ãããŠãSVDã§ç¹ç°å€åè§£ããã€ãŸã$M=U\Sigma V^T$ãšãããšãã$U, V$ã¯çŽäº€è¡åã«ãªããŸããåæ£å ±åæ£è¡åã¯å¯Ÿç§°è¡åãªã®ã§ãSVDã§ã®ç¹ç°å€ãšè¡åã®åºæå€ã¯ã»ãŒåäžãšã¿ãªããŸãããããã£ãŠãåºæãã¯ãã«ãçŽäº€è¡åã«ãªããã€ãŸãäž»æå軞ã¯å¿ ãçŽäº€ãããšããçµè«ã«ãªããŸãã
è±ç·ããŠããŸããŸããããæšæºåããªãå Žåã¯ä»¥äžã®ããšãèããããŸãã
- æšæºåå·®ã§å²ãããå²ããªãããããå¿ ãäž»æå軞ã¯çŽäº€ããŠãã
- ããããã°ã©ãã®ã¹ã±ãŒã«ã®éœåäžãæšæºåå·®ã§å²ããªãå Žåã¯è»žã®ã¹ã±ãŒã«ãããããããããäž»æå軞ãçŽäº€ããŠããªãããã«èŠããããšããã
- äž»æååæã¯ããŒã¿ã®å¯èŠåãšããŠéèŠãªåœ¹å²ãããã®ã§ãæšæºåå·®ã§å²ããªããŸãŸããŒã¿ã®åæããããšèª€ã£ãçµè«ãåºãããšããã
ããã§1ã€å€§äºãªããšãããããŸãããããã¯ãäž»æååæããã°ã©ããå«ããããŒã¿ã®åŸåãå ±éããèŠå ïŒå åïŒãèªã¿åãããå Žåã¯ãæšæºåå·®ã§å²ãã¹ããšããããšã§ããããã¯æããŠãããããã€ã³ãã§ãã
æšæºåãããã¡ãªãã/æšæºåããªãã¡ãªãã
ãã¡ãã¯é£ããã§ããããã€ãäŸãæããŸããä»¥åæžããPCA Color AugmentationãšããData Augmentationã¢ã«ãŽãªãºã ããããŸãã
ããã¯ç»åã«å¯ŸããŠã«ã©ãŒãã£ã³ãã«ãããã®äž»æååæãè¡ããŸããããã§æ±ããããåºæãã¯ãã«ã«ä¹±æ°ããããã«ã©ãŒãã£ã³ãã«ã«å€ãå ç®ãããšãããã®ã§ããããã«ãã1æã®ç»åããè€æ°ã®ç»åãã§ããããããããŒã¿ã倿°ãããããªæ£åå广ãåŸãããŸãã
ããå°ãçŽæçã«èšããšãç»åã®è²ã®ååžã«å¿ããŠè¶³ãéãæ±ºããŸããããšããããšã§ããäŸãã°ãèµ€ãå€ãç»åïŒäŸïŒå€çŒãïŒãªããèµ€ãå€ãè¶³ãä»ã®è²ãããŸãè¶³ããªããç·ãå€ãç»åïŒäŸïŒèã£ã±ïŒãªããç·ãå€ãè¶³ãä»ã®è²ãããŸãè¶³ããªããªã©ã
äŸãšããŠå€æ¥ã®ç»åãåºããŸãããããããsunset.jpgãšããŸãã

ãŸãã¯ããã®è²ã®ãã¹ãã°ã©ã ãèŠãŠã¿ãŸãã
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
img = np.asarray(Image.open("sunset.jpg").convert("RGB")).reshape(-1,3)
plt.hist(img, color=["red", "green", "blue"], histtype="step", bins=128)
plt.show()
èŠãç®éããèµ€ãå§åçã«å€ããŠãéã¯ã»ãšãã©ãããŸããããç·ãã»ã©ã»ã©ã«ãšããæãã§ããããã
ã«ã©ãŒãã£ã³ãã«ãããã®åæ£å ±åæ£è¡åã確èªããŸããããä»ãæšæºåå·®ã§ã¯å²ããŸããã
cov = np.cov(img, rowvar=False)
print(cov)
# [[2403.41386956 1724.76967548 211.41610039]
# [1724.76967548 1908.70599067 379.9284601 ]
# [ 211.41610039 379.9284601 204.43244419]]
R,G,Bã®ãã£ã³ãã«é ã§ãããã¯ãããã¹ãã°ã©ã ã§èŠãããã«èµ€ã®åæ£ãäžçªå€§ãããã€ãã§ç·ãéã®åæ£ã¯èµ€ã®åæ£ã®1/10æªæºãšããããšã«ãªããŸãã
ãããããããæšæºåå·®ã§å²ã£ãŠããŸããšå¥åŠãªããšãããããŸããå¹³åã§ãåŒããŠæšæºåããŠããŸãããä»ãŸã§ç¢ºèªããŠããããã«åæ£å ±åæ£è¡åã«å¹³åã®ã·ããã¯å¯äžããŸããã
img_normalized = (img - np.mean(img, axis=0, keepdims=True)) / np.std(img, axis=0, keepdims=True)
cov_noramlized = np.cov(img_normalized, rowvar=False)
print(cov_noramlized)
# [[1.00000242 0.80528268 0.3016129 ]
# [0.80528268 1.00000242 0.60821685]
# [0.3016129 0.60821685 1.00000242]]
ãªããšãèµ€ãšéã®åæ£ãåã1ãšè¡šçŸãããŠããŸã£ãã®ã§ããããšããšèµ€ã®åæ£ãéã®åæ£ã®10å以äžããã®ã«ãåäžåãããŠããŸãã®ã¯æããã«ããããã§ãã忣ãšããã®ã¯éèŠãªæ å ±ã§ãããã¯æ å ±ãèœã¡ãŠãããšèšããããåŸãŸããã
ã¡ãªã¿ã«æšæºåããå Žåã®åæ£å ±åæ£è¡åã¯ãåé ã®åå¿ç€Ÿå€§ã®å çãæžããŠããããã«çžé¢è¡åãšåãã§ã3ãçžé¢è¡åã¯np.corrcoefã§èšç®ã§ããŸãã
corr = np.corrcoef(img, rowvar=False)
print(corr)
# [[1. 0.80528073 0.30161217]
# [0.80528073 1. 0.60821538]
# [0.30161217 0.60821538 1. ]]
ã€ãŸããæšæºåããŠäž»æååæãããå Žåã¯ãåæ£å ±åæ£è¡åïŒçžé¢è¡åãšãªã£ãŠãçžé¢è¡åã®åºæãã¯ãã«ãæ±ããŠãããšããããšã«ãªããŸãã
ãæ å ±ãèœã¡ãããšããç¹ã«ã€ããŠè£è¶³ããŸããããäž»æååæã§ã¯ç¹ç°å€ïŒâåºæå€ïŒãå ã«èª¬æåæ£ãèšç®ããŠããŸããç¹ç°å€ã®çޝç©åãå šäœã®åã§4:å²ããšãpca.explained_variance_ratio_ãã«è¿ã説æåæ£æ¯ãèšç®ã§ããŸãã
def explained_variance_ratio(data):
cov = np.cov(data, rowvar=False)
U, S, V = np.linalg.svd(cov)
S_cumsum = np.cumsum(S)
print(S_cumsum / np.sum(S))
explained_variance_ratio(img)
explained_variance_ratio(img_normalized)
# [0.87305681 0.97964698 1. ]
# [0.72241881 0.95981481 1. ]
æšæºåããªãå Žåã¯åºæãã¯ãã«1ã€åãã°87%ã®åæ£ã説æã§ããã®ã«ãæšæºåãããšåºæãã¯ãã«1ã€ã§ã¯72%ã®åæ£ãã説æã§ããªããªã£ãŠããŸããŸãããããã¯æšæºåããããšã§åæ£ãåäžåãããŠããŸã£ãããšã«ããå¯äœçšãšèããããªãã§ããããã
ããã§1ã€è£è¶³ããŠããããã®ã¯ãæšæºåããåŸã®PCAã®ã»ãã説æåæ£æ¯ãèœã¡ããã€ãŸãæšæºåãããšäž»æååæã®ç²ŸåºŠãèœã¡ããšããããã§ã¯ãããŸãããããããæšæºåã«ãã£ãŠèª¬æããã忣ãå€ãã£ãŠããã®ã ãããæšæºåã«ãã£ãŠç®æšãå€ãã£ãŠããããã§ãããã®ç»åã®äŸã§ãããšãæšæºåããªããšèµ€ãšç·ã®ç»çŽ ã説æã§ããã°ã ãããé«åŸç¹ïŒé«ã忣æ¯ïŒãåºãããããèµ€ãšç·ã説æããããšã«éç¹ã眮ããããã ããæšæºåãããšèµ€ãç·ãéãåäžã«èª¬æããªããšãããªããããåºæãã¯ãã«1ã€åã£ãã ãã§ã¯ãªããªãé«ã忣æ¯ã¯åºããªããããšèããã®ããããããããšæããŸããç®æšãå€ãã£ãã®ã§ã忣æ¯ã®æå³åããå€ãã£ãŠãããã粟床ã¯åçŽã«ã¯æ¯èŒã§ããªãããšããããšã§ããããã
å
çšåºããPCA Color Augmentationã§ãæšæºåã«ããæªåœ±é¿ã¯ãã£ãŠãæšæºåãããšæ¬æ¥ã¯ãããŸã§ã¶ããªãã¯ãã®éã®ãã£ã³ãã«ãèµ€ã®ãã£ã³ãã«ãšåããããåããšããçŸè±¡ã確èªã§ããŸããããã¯çŽæçã«ããããã§ãããå
šäœã®è²åããæããŠããŸãå¯èœæ§ããããŸããïŒäžãæšæºåããäŸãäžãæšæºåããªãäŸã§ãïŒ

ããäžã€ã®äŸã§ãããè±èªã§ãããã®Quoraã®èšäºãç§éžã§ãäŸãšããŠãã€ãºããçæãããããŒã¿ã«å¯ŸããŠæšæºåãããŠäž»æååæããããšäž»æå軞ããã€ãºé§åã«ãªã£ãŠããŸããšããæªäŸãæããŠããŸããå°ãé·ãã³ãŒãã§ããåçŸããŠã¿ãŸããã
import numpy as np
import matplotlib.pyplot as plt
def make_data():
X = np.random.randn(100,2)
X[:,0] = X[:,0] * 0.25 + 2.0
return X
def calc_eigen_vectors(data):
cov = np.cov(data, rowvar=False)
U, S, V = np.linalg.svd(cov)
mean = np.mean(data, axis=0, keepdims=True)
return U, mean
def plot_principal_axis(data, ax, title):
U, mean = calc_eigen_vectors(data)
color = ["red", "blue"]
ax.plot(data[:,0], data[:,1], ".")
for i in range(U.shape[0]):
lines = np.dot(np.arange(-2.0,2.0,0.1).reshape(-1,1), U[:,i].reshape(1,-1)) + mean
ax.plot(lines[:,0], lines[:,1], color=color[i])
plt.title(title)
def main():
for i in range(20):
data = make_data()
plt.figure(figsize=(6,4))
plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1)
ax = plt.subplot(1,2,1)
plot_principal_axis(data, ax, "Disable normalize")
normlize = (data - np.mean(data, axis=0, keepdims=True)) / np.std(data, axis=0, keepdims=True)
ax = plt.subplot(1,2,2)
plot_principal_axis(normlize, ax, "Enable normalize")
plt.show()
if __name__ == "__main__":
main()
åç»ã«ãŸãšãããšæ¬¡ã®ããã«ãªããŸãã
å·ŠåŽïŒæšæºåããªãïŒå Žåã¯ããããx軞ãšy軞ãäž»æå軞ãšããŠè¡šç€ºãããŠããŸãããå³åŽïŒæšæºåïŒããå Žåã¯æå³ã®ãªã軞ã衚瀺ãããŠããŸããŸãããããã¯ç¢ºãã«å°ããŸãã
ãŸãšããã®ã倧å€ã§ãããäž»æååæã§æšæºåãããšå°ãäŸã¯æ¬¡ã®ããã«ãªããšæããŸãã
- PCA Color Augmentationã§å€æ¥ã®ç»åã®ããã«ãè²ã®ååžïŒåæ£ïŒãRGBã§å šç¶éãäŸãäž»æååæãå¯èŠåã®ç®çã§ã¯ãªãããã®åŸã®æ©æ¢°åŠç¿ã®ãã€ãã©ã€ã³ã«ã€ãªããããç®çãäŸãã°Data Augmentationã§äœ¿ãã±ãŒã¹ã
- å¯èŠåç®çã§ãããŒã¿ãã»ãŒãã€ãºããæ§æãããç¹æ®ãªäŸãæšæºåããŠåºãŠããäž»æå軞ãå šãæå³ããªããªãå Žåã
ãŸãšã
äºæ³ä»¥äžã«é·ãæçš¿ã«ãªã£ãŠããŸããèªãã§ããæ¹ã«è² æ ããããŠããŸããŸãããããããŸã§ã®å 容ããŸãšããŠãæšæºåã®ã¬ã€ãã©ã€ã³ãäœã£ãŠã¿ãŸãããã
- äž»æååæã«ã¯äž»ã«3ã€ã®äœ¿ãæ¹ãããã1ã€ç®ã¯ããŒã¿ã®å¯èŠåãããã¯ãšãŠã匷åã§æ£ããäœ¿ãæ¹ã2ã€ç®ã¯æ¬¡å åæžãããŒããŠã§ã¢ã®å¶çŽããã£ãŠäœ¿ããªãæå¹ãªäœ¿ãæ¹ã3ã€ç®ã¯PCA Color Augmentationã®ããã«ã次å åæžã§ããªãããŒã¿ãæ°Žå¢ãããããã®æ©æ¢°åŠç¿ã®ãã€ãã©ã€ã³ãšããŠäœ¿ãã±ãŒã¹ãããã¯äŸãå°ãªãã®ã§ãªããšãèšããªãã
- å¯èŠåç®çã ã£ãããåºæ¬çã«ã¯æšæºåãã¹ãããã€ãºããŒã¿ãããªããããªç¹æ®ãªäŸãããããå šäœããèŠãã°ããªãçããã®ã§ãç°ãªãã¹ã±ãŒã«ã§èª€ã£ãŠæ¯èŒããå Žåã«ãã¹ãªãŒãããéã®ãã¡ãªããã®ã»ããæããã«å€§ãããå¯èŠåã ãã§ã¯ãªãå ±éã®èŠå ãæ¢ããããªå Žåãåæ§ããã å¯èŠåããå Žåã§ããã€ãºããŒã¿ã®ããã«ãäž»æå軞ãæå³ããªããªããªãã±ãŒã¹ã¯ãããšããã®ã¯é ã®çé ã«çœ®ããŠããã¹ãã
- 次å åæžã®å Žåã¯ãªããšãèšããªããå¯èŠåã«è¿ããããªæ¬¡å åæžãªãæšæºåããã»ãããããããã€ãã©ã€ã³ã«è¿ããããªæ¬¡å åæžãªãæšæºåããªãã»ããåŸç¶ãããã€ãã©ã€ã³ã«ããå€ãã®æ å ±ãäŒãããããããããªããæšæºåèªäœã1ã€ã®ãã€ããŒãã©ã¡ãŒã¿ãŒãªã®ã§ãäž¡æ¹ãã£ãŠæçµçã«ç²ŸåºŠè¯ãã»ããåãã°ããã
- PCA Color Augmentationã®ããã«ãã€ãã©ã€ã³ãšããŠäœ¿ãã®ãªãããŸãæšæºåããªãè·¯ç·ã§èããã»ããããã®ã§ã¯ãªããã
- æšæºåãšã¯ç°ãªãã¹ã±ãŒã«ãçžå¯Ÿçãªã¹ã±ãŒã«ã«å€æããåäžã®ã¹ã±ãŒã«ã§è©äŸ¡ã§ããããã«ããããšãªã®ã§ãåäžã®ã¹ã±ãŒã«ã§è©äŸ¡ãã¹ããããããã¯å¥ã«ã¹ã±ãŒã«æããå¿ èŠããªãã®ãã§èãããšçè§£ãããããããããªãã
ãããŸã§ãšãŠãé·ãèšäºãèªãã§ãã ãã£ãŠããããšãããããŸããããã®æã®å°éå®¶ã§ããªãã§ããªãã®ã§ãåŒ·ãæ¹ã®ãæèŠããåŸ ã¡ããŠãããŸãã
-
åºæå€åè§£ã§ãç¹ç°å€åè§£ã§ãåºæãã¯ãã«ãåºæå€ã¯æ±ããããŸãã詳ããã¯ãã¡ããhttps://qiita.com/horiem/items/71380db4b659fb9307b4 â©
-
https://ja.wikipedia.org/wiki/%E7%9B%B4%E4%BA%A4%E8%A1%8C%E5%88%97 â©
-
ã°ã©ã è¡åããèŠãåæ£å ±åæ£è¡åãçžé¢è¡åã®é¢ä¿ã¯ãã¡ãã«æžããŸãããhttps://blog.shikoan.com/cov-corr-gram-matrix/ â©
-
Sklearnã®ãœãŒã¹ã³ãŒããèªããšãscipy.linalg.svdã§èšç®ããç¹ç°å€ã®2ä¹ã®çޝç©åã§èšç®ããŠããã®ã§ãããexplained_variance_ã§åºããŠããå€ãnp.lilalg.svdã§èšç®ããç¹ç°å€ãšäžèŽããã®ã§ãããã§ã¯ç¹ç°å€ã2ä¹ããã«ãã®ãŸãŸäœ¿ã£ãŠããŸããexplained_variance_ratio_ããªãã1ä¹ã§èšç®ããã»ãããã£ãŠããŸããäžæè°ããhttps://github.com/scikit-learn/scikit-learn/blob/bac89c2/sklearn/decomposition/pca.py#L444 â©






