UPDATE: 2021-09-23 02:01:40

1 はじめに

ここではデータ分析に必要な線形代数の基本的な事柄についてまとめていきます。主な範囲はベクトル、1次独立と基底、様々な行列、行列式、固有値、固有ベクトル、行列とベクトルの微分、重回帰分析、主成分分析あたりをまとめる予定です。下記を参考にしています。

2 行列の作成

行列を作成する際は、matrix()を利用する。byrowは行ごとに値を保存するか、列ごとに値を保存するかを決める引数。

A <- matrix(1:6, nrow = 2, ncol = 3, byrow = FALSE)
B <- matrix(1:6, nrow = 2, ncol = 3, byrow = TRUE)
# 列ごとに値が入る
A
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6
# 行ごとに値が入る
B
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6

3 行列の演算

足す、引く、スカラ倍は下記の通りです。

# 和算
A + B
##      [,1] [,2] [,3]
## [1,]    2    5    8
## [2,]    6    9   12
# 除算
A - B
##      [,1] [,2] [,3]
## [1,]    0    1    2
## [2,]   -2   -1    0
# スカラ倍
10 * A
##      [,1] [,2] [,3]
## [1,]   10   30   50
## [2,]   20   40   60

行列積を計算する場合は%*%演算子を利用します。

# [2×3][3×2]=[2×2]
A %*% t(B)
##      [,1] [,2]
## [1,]   22   49
## [2,]   28   64
# [3×2][2×3]=[3×3]
t(A) %*% B
##      [,1] [,2] [,3]
## [1,]    9   12   15
## [2,]   19   26   33
## [3,]   29   40   51

行列の要素ごとの掛け算は*演算子で計算できます。

A * B
##      [,1] [,2] [,3]
## [1,]    1    6   15
## [2,]    8   20   36

クロネッカー積を計算する場合は、%x%演算子を利用できます。

B %x% A
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
## [1,]    1    3    5    2    6   10    3    9   15
## [2,]    2    4    6    4    8   12    6   12   18
## [3,]    4   12   20    5   15   25    6   18   30
## [4,]    8   16   24   10   20   30   12   24   36

4 行列の次元

dim()に行列を渡すことで、行列の次元を調べることができます。

dim(A)
## [1] 2 3
dim(B %x% A)
## [1] 4 9

5 行列の結合

行列を結合する場合は、列方向に結合するcbind()と行方向に結合するrbind()が利用できます。

# 列方向に結合
cbind(A, B)
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    3    5    1    2    3
## [2,]    2    4    6    4    5    6
# 行方向に結合
rbind(A, B)
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6
## [3,]    1    2    3
## [4,]    4    5    6

6 行列の対角成分とトレース

行列から対角成分を抽出する場合は、diag()を利用する。トレースはそれを足し合わせることで得られます。

C <- matrix(1:9, nrow = 3, ncol = 3, byrow = TRUE)
C
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9
# 対角成分の抽出
diag(C)
## [1] 1 5 9
# トレース
sum(diag(C))
## [1] 15

diag(diag(x))と2重に関数を重ねることで、対角行列を得ることができます。

diag(diag(C))
##      [,1] [,2] [,3]
## [1,]    1    0    0
## [2,]    0    5    0
## [3,]    0    0    9

行列の積のトレースは、行列をかける順番によりません。

sum(diag(A %*% t(B)))
## [1] 86
sum(diag(B %*% t(A)))
## [1] 86

7 行列の転置

説明もなしに先程から使用していますが、行列を転置させる場合は、t()に行列を渡します。

A
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6
t(A)
##      [,1] [,2]
## [1,]    1    2
## [2,]    3    4
## [3,]    5    6

行列の積の結果を転置したものは、行列のかけ順を入れ替えて、行列の積の計算をしたものと一致します。

# 行列の積の結果を転置
t(A %*% t(B))
##      [,1] [,2]
## [1,]   22   28
## [2,]   49   64
B %*% t(A)
##      [,1] [,2]
## [1,]   22   28
## [2,]   49   64

8 行列式

行列式を計算する場合はdet()に行列を渡します。

det(C)
## [1] 6.661338e-16

9 行列の逆行列

行列の逆行列を計算した場合は、solve()に行列を渡すことで計算できます。

options(digits = 2)
a <- matrix(1:4, nrow = 2, ncol = 2, byrow = FALSE)
b <- matrix(2:5, nrow = 2, ncol = 2, byrow = TRUE)

# 逆行列の計算
solve(a) 
##      [,1] [,2]
## [1,]   -2  1.5
## [2,]    1 -0.5
# 逆行列の検証
solve(a) %*% a
##      [,1] [,2]
## [1,]    1    0
## [2,]    0    1
# 逆行列の検証
a %*% solve(a)
##      [,1] [,2]
## [1,]    1    0
## [2,]    0    1

逆行列の逆行列は、もとの行列にもどります。

solve(solve(a))
##      [,1] [,2]
## [1,]    1    3
## [2,]    2    4
a
##      [,1] [,2]
## [1,]    1    3
## [2,]    2    4

「行列の積を転置した行列の逆行列」と「行列の積の逆行列を転置した行列」は同じ行列になります。

solve(t(a %*% b))
##      [,1] [,2]
## [1,]  6.5 -5.0
## [2,] -4.5  3.5
t(solve(a %*% b))
##      [,1] [,2]
## [1,]  6.5 -5.0
## [2,] -4.5  3.5

他にも、「行列の積の逆行列」と「行列を入れ替えた行列の逆行列の行列の積」は同じ行列になります。

solve(a %*% b)
##      [,1] [,2]
## [1,]  6.5 -4.5
## [2,] -5.0  3.5
solve(b) %*% solve(a)
##      [,1] [,2]
## [1,]  6.5 -4.5
## [2,] -5.0  3.5

10 行列の固有値

行列の固有値を計算した場合は、eigen()に行列を渡すことで計算できます。返り値のvaluesが固有値で、vectorsが固有ベクトル。

D <- A %*% t(B)
eigen(D)
## eigen() decomposition
## $values
## [1] 85.58  0.42
## 
## $vectors
##       [,1]  [,2]
## [1,] -0.61 -0.92
## [2,] -0.79  0.40

11 行列の特異値分解

1つの行列を3つの行列に分解する方法が特異値分解。svd()に行列を渡すことで計算できます。返り値のuのことを左特異行列、dのことを特異値行列、vのことを右特異行列と呼びます。

svd(D)
## $d
## [1] 88.12  0.41
## 
## $u
##       [,1]  [,2]
## [1,] -0.61 -0.79
## [2,] -0.79  0.61
## 
## $v
##       [,1]  [,2]
## [1,] -0.40 -0.91
## [2,] -0.91  0.40

12 セッション情報

sessionInfo()
## R version 4.0.3 (2020-10-10)
## Platform: x86_64-apple-darwin17.0 (64-bit)
## Running under: macOS Big Sur 10.16
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRblas.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib
## 
## locale:
## [1] ja_JP.UTF-8/ja_JP.UTF-8/ja_JP.UTF-8/C/ja_JP.UTF-8/ja_JP.UTF-8
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## loaded via a namespace (and not attached):
##  [1] compiler_4.0.3    magrittr_2.0.1    ragg_1.1.3        tools_4.0.3      
##  [5] htmltools_0.5.1.1 yaml_2.2.1        stringi_1.5.3     rmarkdown_2.6    
##  [9] knitr_1.33        stringr_1.4.0     xfun_0.24         digest_0.6.27    
## [13] textshaping_0.3.5 systemfonts_1.0.2 rlang_0.4.10      evaluate_0.14