疎な行列をRで扱う -R tips-
疎な行列(Sparse Matrix)
ユーザーの購入履歴において、ユーザーを行、アイテムを列、アイテムを購入したら1、アイテムを購入しなかったら0となるような行列や、自然言語処理で用いられる単語文書行列は単語を行、文書を列、単語の出現頻度(出現の有無)を値とする行列。こういう行列は、非常に0の多い行列になります。このような行列は、一般的に行数・列数も大きな行列となるので、普通の行列表現形式はメモリを大量に消費する上に、演算時間も非常にかかります。このような疎な行列をうまく扱う方法がRには存在しています。今回は、それを紹介します。
注意:残念ながら疎な行列クラスに適応できる関数は限られます。
Rで疎な行列を作るときは...
Rで疎な行列を作るためには「Matrix」というパッケージを使います。実際に、パッケージを使って疎な行列を作ってみます。簡単な操作はこんな感じです。
> library(Matrix)
> #疎な行列の作成
> i <- c(1,3,4) #非ゼロ要素の行番号
> j <- c(6,5,2) #非ゼロ要素の列番号
> x <- c(10,2,9) #非ゼロ要素の値
>
> #6*6の疎な行列を作成
> (sm <- sparseMatrix(i,j,x=x,dims=c(6,6)))
6 x 6 sparse Matrix of class "dgCMatrix"
[1,] . . . . . 10
[2,] . . . . . .
[3,] . . . . 2 .
[4,] . 9 . . . .
[5,] . . . . . .
[6,] . . . . . .
>
> #操作は一般的な行列と同じです
> (sm[1,1]<-6)
[1] 6
>
> #対角行列も作れるよ
> (d=Diagonal(nrow(sm),rep_len(c(3,0),nrow(sm))))
6 x 6 diagonal matrix of class "ddiMatrix"
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 3 . . . . .
[2,] . 0 . . . .
[3,] . . 3 . . .
[4,] . . . 0 . .
[5,] . . . . 3 .
[6,] . . . . . 0
>
> #対角行列の0要素を消しましょう
> (d <- drop0(d))
6 x 6 sparse Matrix of class "dtCMatrix"
[1,] 3 . . . . .
[2,] . . . . . .
[3,] . . 3 . . .
[4,] . . . . . .
[5,] . . . . 3 .
[6,] . . . . . .
>
> #疎な行列で結合もできる
> cBind(sm,d)
6 x 12 sparse Matrix of class "dgCMatrix"
[1,] 6 . . . . 10 3 . . . . .
[2,] . . . . . . . . . . . .
[3,] . . . . 2 . . . 3 . . .
[4,] . 9 . . . . . . . . . .
[5,] . . . . . . . . . . 3 .
[6,] . . . . . . . . . . . .
>
> #普通の行列形式に戻したりも!
> as.matrix(sm)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 6 0 0 0 0 10
[2,] 0 0 0 0 0 0
[3,] 0 0 0 0 2 0
[4,] 0 9 0 0 0 0
[5,] 0 0 0 0 0 0
[6,] 0 0 0 0 0 0
>
> #普通の行列を疎な行列へ変換
> as(diag(4,x=c(1,0,3,2)),"sparseMatrix")
4 x 4 sparse Matrix of class "dgCMatrix"
[1,] 1 . . .
[2,] . . . .
[3,] . . 3 .
[4,] . . . 2
この疎な行列を扱えるパッケージは?
このような疎な行列はe1071パッケージのsvm(サポートベクターマシーン)で計算するときに使えます。サポートベクターマシンの紹介も兼ねて、夏休み中にSVM + 疎な行列の話をしようと思います。