36

共起行列を持つという問題を解決しようとしています。トランザクションとアイテムのデータファイルがあり、アイテムが一緒に表示されるトランザクション数のマトリックスを表示したいと考えています。

私は R プログラミングの初心者であり、特定のループを作成するのではなく、R が持つすべてのショートカットを見つけることを楽しんでいます (以前は C を使用していましたが、現在は Excel マクロと SPSS のみに固執しています)。ここで解決策を確認しましたが、機能する解決策が見つかりませんでした (最も近いのは、ここに示されている解決策です: Co-occurrence matrix using SAC? - しかし、projecting_tm を使用するとエラー メッセージが表示されました。私の場合は成功しました。

基本的に、次を含むテーブルがあります。

TrxID Items Quant
Trx1 A 3
Trx1 B 1
Trx1 C 1
Trx2 E 3
Trx2 B 1
Trx3 B 1
Trx3 C 4
Trx4 D 1
Trx4 E 1
Trx4 A 1
Trx5 F 5
Trx5 B 3
Trx5 C 2
Trx5 D 1, etc.

次のようなものを作成したい:

   A B C D E F
A  0 1 1 0 1 1
B  1 0 3 1 1 0
C  1 3 0 1 0 0
D  1 1 1 0 1 1
E  1 1 0 1 0 0
F  0 1 1 1 0 0

私がしたことは次のとおりです(そして、あなたはおそらく私の新人Rのアプローチを笑うでしょう):

library(igraph)
library(tnet)

trx <- read.table("FileName.txt", header=TRUE) 
transID <- t(trx[1])
items <- t(trx[2])

id_item <- cbind(items,transID)
item_item <- projecting_tm(id_item, method="sum")
item_item <- tnet_igraph(item_item,type="weighted one-mode tnet")
item_matrix <-get.adjacency(item_item,attr="weight")
item_matrix

上記のように、cbind はおそらく失敗したため、projecting_tm で結果が得られませんでした。

私の方法に対する代替アプローチまたは修正はありますか?

あなたの助けは大歓迎です!

4

5 に答える 5

37

上記のいずれかの回答の「dat」を使用して、次のことを試しcrossprodtableください。

V <- crossprod(table(dat[1:2]))
diag(V) <- 0
V
#      Items
# Items A B C D E F
#     A 0 1 1 1 1 0
#     B 1 0 3 1 1 1
#     C 1 3 0 1 0 1
#     D 1 1 1 0 1 1
#     E 1 1 0 1 0 0
#     F 0 1 1 1 0 0
于 2014-03-26T12:23:44.063 に答える
20

reshape2 パッケージと行列代数を組み合わせて使用​​します。

#read in your data
dat <- read.table(text="TrxID Items Quant
Trx1 A 3
Trx1 B 1
Trx1 C 1
Trx2 E 3
Trx2 B 1
Trx3 B 1
Trx3 C 4
Trx4 D 1
Trx4 E 1
Trx4 A 1
Trx5 F 5
Trx5 B 3
Trx5 C 2
Trx5 D 1", header=T)

#making the boolean matrix   
library(reshape2)
dat2 <- melt(dat)
w <- dcast(dat2, Items~TrxID)
x <- as.matrix(w[,-1])
x[is.na(x)] <- 0
x <- apply(x, 2,  function(x) as.numeric(x > 0))  #recode as 0/1
v <- x %*% t(x)                                   #the magic matrix 
diag(v) <- 0                                      #repalce diagonal
dimnames(v) <- list(w[, 1], w[,1])                #name the dimensions
v

多分グラフ化のために...

g <- graph.adjacency(v, weighted=TRUE, mode ='undirected')
g <- simplify(g)
# set labels and degrees of vertices
V(g)$label <- V(g)$name
V(g)$degree <- degree(g)
plot(g)
于 2012-11-08T02:36:19.940 に答える
16

効率的な理由から、特にスパース データでは、スパース マトリックスを使用することをお勧めします。

dat <- read.table(text="TrxID Items Quant
Trx1 A 3
Trx1 B 1
Trx1 C 1
Trx2 E 3
Trx2 B 1
Trx3 B 1
Trx3 C 4
Trx4 D 1
Trx4 E 1
Trx4 A 1
Trx5 F 5
Trx5 B 3
Trx5 C 2
Trx5 D 1", header=T)

library("Matrix")

# factors for indexing matrix entries and naming dimensions
trx.fac <- factor(dat[,1])
itm.fac <- factor(dat[,2])

s <- sparseMatrix(
        as.numeric(trx.fac), 
        as.numeric(itm.fac),
        dimnames = list(
                as.character(levels(trx.fac)), 
                as.character(levels(itm.fac))),
        x = 1)

# calculating co-occurrences
v <- t(s) %*% s

# setting transactions counts of items to zero
diag(v) <- 0
v

このスレッドに投稿された各ソリューションを試してみました。それらのどれも大きな行列では機能しませんでした (私は 1,500 x 2,000,000 の行列で作業していました)。

トピックから少し外れます:共起行列を計算した後、通常、個々のアイテム間の距離を計算したいと思います。コサイン類似度/距離は、次のように共起行列で効率的に計算できます。

# cross-product of vectors (numerator)
num <- v %*% v

# square root of square sum of each vector (used for denominator)
srss <- sqrt(apply(v^2, 1, sum))

# denominator
den <- srss %*% t(srss)

# cosine similarity
v.cos.sim <- num / den

# cosine distance
v.cos.dist <- 1 - v.cos.sim
于 2014-07-08T08:41:12.357 に答える
13

これには xtabs を使用します。

dat <- read.table(text="TrxID Items Quant
Trx1 A 3
Trx1 B 1
Trx1 C 1
Trx2 E 3
Trx2 B 1
Trx3 B 1
Trx3 C 4
Trx4 D 1
Trx4 E 1
Trx4 A 1
Trx5 F 5
Trx5 B 3
Trx5 C 2
Trx5 D 1", header=T)


term_doc <- xtabs(~ TrxID + Items, data=dat, sparse = TRUE)
co_occur <- crossprod(term_doc, term_doc)
diag(co_occur) <- 0
co_occur

を入れてsparse = TRUE、これが非常に大きなデータ セットで機能することを示しました。

于 2015-04-25T01:38:17.550 に答える
6

これは、最初に2部グラフを作成する場合、実際には非常に簡単でクリーンです。ここで、上のノードはトランザクションであり、下のノードはアイテムです。次に、最下位ノードへの投影を作成します。

dat <- read.table(text="TrxID Items Quant
Trx1 A 3
Trx1 B 1
Trx1 C 1
Trx2 E 3
Trx2 B 1
Trx3 B 1
Trx3 C 4
Trx4 D 1
Trx4 E 1
Trx4 A 1
Trx5 F 5
Trx5 B 3
Trx5 C 2
Trx5 D 1", header=T)

library(igraph)
bip <- graph.data.frame(dat)
V(bip)$type <- V(bip)$name %in% dat[,1]

## sparse=TRUE is a good idea if you have a large matrix here
v <- get.adjacency(bipartite.projection(bip)[[2]], attr="weight", sparse=FALSE)

## Need to reorder if you want it alphabetically
v[order(rownames(v)), order(colnames(v))]

#   A B C D E F
# A 0 1 1 1 1 0
# B 1 0 3 1 1 1
# C 1 3 0 1 0 1
# D 1 1 1 0 1 1
# E 1 1 0 1 0 0
# F 0 1 1 1 0 0
于 2012-11-09T03:05:14.003 に答える