Создание графа с iGraph и вычисление метрики сходства - PullRequest
0 голосов
/ 18 декабря 2018

Я пытаюсь создать график в igraph, используя CSV-файл, который выглядит следующим образом:

ID    Element1 Element2 Element3 Element4
12346  A        12       56       2
13007  Y        16       66       2
...    ...      ...      ...      ...

Столбец ID заполняется уникальными 4-значными идентификаторами, тогда как столбцы элементов заполняются числами (или буквы в элементе 1), которые повторяются.Моя цель состоит в том, чтобы вычислить попарно подобие Жакара всех идентификаторов, которое использует элементы, совместно используемые узлами идентификаторов.На выходе должна быть матрица NxN.

Я пытался создать график на igraph, используя функцию graph_from_data_frame, но это создает узлы из первых двух столбцов и помещает оставшиеся столбцы в качестве атрибутов ребра в отношениях между узлами, которые он создает.Любые идеи о лучшем способе создания графа, который позволит мне вычислить Jaccard между узлами идентификатора?

Для справки, цель состоит в том, чтобы использовать эту функцию igraph:

 similarity(graph, vids = V(graph), mode = c("all", "out", "in", "total"),
 loops = FALSE, method = c("jaccard", "dice", "invlogweighted"))

где graph - график, который я создаю, а vids являются только узлами идентификатора.

1 Ответ

0 голосов
/ 19 декабря 2018

Если вашей основной целью является вычисление схожести Jaccard между вашими идентификаторами, вы можете сделать это без необходимости сначала создавать график.Подобие Жакара определяется как пересечение, деленное на объединение J (A, B) = | A⋂B |/ | A⋃B |, что эквивалентно | A⋂B |/ (| A | + | B | - | A⋂B |).Таким образом, вы можете рассчитать его следующим образом:

## Example dataset
df = read.table(text = "ID    Element1 Element2 Element3 Element4
  12346  A        12       56       2
  13007  Y        16       66       2
  14008  B        14       56       3
  15078  A        15       56       4
  16000  Y        20       66       3"
,h=T,stringsAsFactors=F)

n = nrow(df)
m = matrix(0,n,n,dimnames=list(df[,1],df[,1]))
for(i in 1:n){
    for(j in i:n){
        m[i,j] = length(intersect(df[i,-1],df[j,-1]))/(2*(n-1)-length(intersect(df[i,-1],df[j,-1])))}}
## Making the matrix symmetrical
m[lower.tri(m)] = t(m)[lower.tri(m)]
> m
          12346     13007     14008     15078     16000
12346 1.0000000 0.1428571 0.1428571 0.3333333 0.0000000
13007 0.1428571 1.0000000 0.0000000 0.0000000 0.3333333
14008 0.1428571 0.0000000 1.0000000 0.1428571 0.1428571
15078 0.3333333 0.0000000 0.1428571 1.0000000 0.0000000
16000 0.0000000 0.3333333 0.1428571 0.0000000 1.0000000
...