Сортируйте оценки сходства косинусов перед добавлением ребер на график - PullRequest
0 голосов
/ 09 апреля 2019

Я пытался найти пример для подобия jaccard здесь , чтобы работать для сходства косинусов, но хотел ограничить количество созданных ссылок для 10 лучших результатов.

Я просмотрел https://gist.github.com/dkuppitz/79e0b009f0c9ae87db5a, но не смог понять, как пропустить фрагмент создания края, чтобы отсортировать его раньше и получить те же результаты, что и по ссылке выше.

Основываясь на приведенном выше примере с jaccard, я пришел к такому выводу:

g.V().
    match(
     __.as('v1').outE('RECOMMENDS').values('amount').fold().as('v1rec'),
     __.as('v1').V().as('v2'),
     __.as('v2').outE('RECOMMENDS').values('amount').fold().as('v2rec'),
     __.as('v1').out().dedup().fold().as('v1n'),
     __.as('v2').out().dedup().fold().as('v2n')
    ).
    where('v1',lt('v2')).
         by(id).
    where('v1',neq('v2').and(without('v1n'))).
    where('v2',without('v1n')).
    project('v1','v2','n','d1','d2').
     by(select('v1')).
     by(select('v2')).
     by(
         select('v1rec','v2rec') <-- this does not work, can't get dot product from this
     ).
     by(coalesce(
            select('v1rec').
                unfold().
                math('_ ^ 2').
                sum(),
             constant(0))).
     by(coalesce(
            select('v2rec').
                unfold().
                math('_ ^ 2').
                sum(),
            constant(0))).
    filter(select('d1').is(gt(0))).
    filter(select('d2').is(gt(0))).
    project('v1','v2','cosine').
         by(select('v1')).
         by(select('v2')).
         by(math('n/(sqrt(d1)*sqrt(d2))')).
    sort{-it.cosine}.
    toList()[0..9].
    each {
         r -> g.V(r['v2']).as('v2').
         V(r['v1']).
         addE('PREDICTED_COSINE').
         to('v2').
         property('score', r['cosine']).
         toList()
    }

но не могу понять, как получить точечное произведение в третьем шаге с помощью select ('v1rec', 'v2rec'). Пожалуйста, помогите.

UPDATE:

Я не смог уместить это в комментарии, поэтому размещаю здесь:

Я попробовал другой подход, который приближает меня (я думаю), но у меня все еще есть проблема, перебирающая каждый список карт для извлечения значений из каждого:

g.V().
    match(
        __.as('v1').outE().as('e1'),
        __.as('v1').V().as('v2'),
        __.as('v2').outE().as('e2'),
        __.as('v1').out().dedup().fold().as('v1n'),
        __.as('v2').out().dedup().fold().as('v2n')).
    where('v1',neq('v2').
        and(without('v1n'))).
    where('v2',without('v1n')).
    project('v1','v2','a1','a2').
        by(select('v1')).
        by(select('v2')).
        by(select('e1').by('amount')).
        by(select('e2').by('amount')).
    project('v1','v2','n','d1','d2').
        by(select('v1')).
        by(select('v2')).
        by(math('a1 * a2')).
        by(math('a1 * a1')).
        by(math('a2 * a2')).
    group().
        by(select('v1','v2')).
        unfold()

Одна строка вывода:

==>{v1=v[4240], v2=v[8320]}=[{v1=v[4240], v2=v[8320], n=210.0, d1=196.0, d2=225.0}, {v1=v[4240], v2=v[8320], n=182.0, d1=196.0, d2=169.0}, {v1=v[4240], v2=v[8320], n=182.0, d1=196.0, d2=169.0}, {v1=v[4240], v2=v[8320], n=45.0, d1=9.0, d2=225.0}, {v1=v[4240], v2=v[8320], n=39.0, d1=9.0, d2=169.0}, {v1=v[4240], v2=v[8320], n=39.0, d1=9.0, d2=169.0}, {v1=v[4240], v2=v[8320], n=45.0, d1=9.0, d2=225.0}, {v1=v[4240], v2=v[8320], n=39.0, d1=9.0, d2=169.0}, {v1=v[4240], v2=v[8320], n=39.0, d1=9.0, d2=169.0}]

Моя цель - суммировать все значения "n", "d1" и "d2" из карт, чтобы я мог вычислить сходство как сумму (n) / (sqrt (сумма (d1))) * sqrt ( сумма (d2))) для каждого ключа (например, {v1 = v [4240], v2 = v [8320]} вне списка из примера, поэтому n будет равно 210 + 182 + 182 + 45 + 39 + 39 + 45 + 39 + 39 = 820). Я хочу сделать это для группы графиков, поэтому у меня нет одного конкретного для этого. Имеет смысл сейчас?

1 Ответ

1 голос
/ 12 апреля 2019

Вот что я наконец-то придумал:

g.V().
    match(
        __.as('v1').outE().as('e1'),
        __.as('v1').V().as('v2'),
        __.as('v2').outE().as('e2'),
        __.as('v1').out().dedup().fold().as('v1n'),
        __.as('v2').out().dedup().fold().as('v2n')
    ).
    where('v1',neq('v2').
        and(without('v1n'))).
    where('v2',without('v1n')).
    project('v1','v2','a1','a2').
        by(select('v1')).
        by(select('v2')).
        by(select('e1').by('amount')).
        by(select('e2').by('amount')).
    project('v1','v2','n','d1','d2').
        by(select('v1')).
        by(select('v2')).
        by(math('a1 * a2')).
        by(math('a1 * a1')).
        by(math('a2 * a2')).
    group().
        by(select('v1','v2')).
        unfold().
    project('v1','v2','n','d1','d2').
        by(select(keys).select('v1')).
        by(select(keys).select('v2')).
        by(select(values).local(unfold().select('n').sum())).
        by(select(values).local(unfold().select('d1').sum())).
        by(select(values).local(unfold().select('d2').sum())).
    project('v1','v2','c').
        by(select('v1')).
        by(select('v2')).
        by(math('n / (sqrt(d1) * sqrt(d2))')).
    sort{ -it.c }.
    toList()[0..9]

Спасибо за помощь.

...