lsaというパッケージがあるので,そちらを使うと便利.
コサイン距離は以下で定義される.要するに二つのベクトル間の角度である.
#mimetex(cos(a,b) = \frac{\sum a_i \cdot b_i}{||a|| \cdot ||b||})
二つのベクトルが直行しているのならば 0 となり,重なっているのなら 1 となる.
さて上の式で分母の &mimetex(||a||); はベクトルの長さである.&mimetex(|\vec{a}|); と表記されていることもある.ベクトルの長さは,各要素を二乗して合計を求め,その平方根を取ることで求まる.R では次のように計算する.なお,この例は,『Rによるテキストマイニング入門』p.137から引用したものである.
> TD <- matrix(c(1,0,0,0,1,0, 0,1,0,1,0,1, 0,1,0,0,0,0, 0,1,0,0,0,0, 0,0,1,0,0,1, 1,1,1,1,0,0, 0,0,1,2,1,0, 1,1,0,0,0,0), nrow=8, byrow=T)
TD という行列の1列目(aとする)と2列目(bとする)のベクトルの長さを求めるには
> a <- sum(TD[,1]^2) # ベクトル a > b <- sum(TD[,2]^2) # ベクトル b
とする.それぞれの平方根の積が分母の値である.
> sqrt(a) * sqrt(b)
一方,分子の &mimetex(\sum a_i \cdot b_i); は 1列目(aとする)と2列目(bとする)のベクトルのそれぞれの要素同士を掛け合わせ,その合計を求めたものである.Rでは次のように計算する.
> TD[,1] %*% TD[,2] # 2
演算子は行列用の %*% を使うこと.通常の乗算演算子 * を使うと,各要素の積の一覧が表示されてしまう.
> TD[,1] * TD[,2] # [1] 0 0 0 0 1 1 0 0 0 0 0
さて,一般には行列のすべての列のコサイン距離を求めるのが普通なので,次のような関数を用意して実行する.
> myCosine <- function(x){ ret <- matrix(0,ncol=ncol(x),nrow=ncol(x)) # for(i in 1:ncol(x)){# for(j in 1:ncol(x)){ ret[i,j] <- (x[,i] %*% x[,j]) / (sqrt(sum(x[,i]^2)) * sqrt(sum(x[,j]^2))) } } ret } > myCosine(TD) [,1] [,2] [,3] [,4] [,5] [,6] [1,] 1.0000000 0.5163978 0.3333333 0.2357023 0.4082483 0.0000000 [2,] 0.5163978 1.0000000 0.2581989 0.3651484 0.0000000 0.3162278 [3,] 0.3333333 0.2581989 1.0000000 0.7071068 0.4082483 0.4082483 [4,] 0.2357023 0.3651484 0.7071068 1.0000000 0.5773503 0.2886751 [5,] 0.4082483 0.0000000 0.4082483 0.5773503 1.0000000 0.0000000 [6,] 0.0000000 0.3162278 0.4082483 0.2886751 0.0000000 1.0000000
1列目と3列目のコサイン距離は 0.33 と計算された.