Твит от RiparianData привлек мой взгляд на днях:
В этом году # HCIR Задача: эксперт и открытие экспертизы (полезно, скажем , в отборе кандидатов работы) ripar.in/LJ0xOj @ dtunkelang
Я создал getvouched.com с этой идеей «экспертизы и экспертизы», используя ручное управление, основанное на навыках, отрегулированное расстоянием от искателя до цели, как способ найти ранг. Так что я покопался и обнаружил, что поиск информации о человеке и компьютере (HCIR) объединяет исследования в области взаимодействия человека с компьютером (HCI) и поиска информации (IR), делая упор на участие человека в поисковой деятельности.
Задача HCIR для симпозиума этого года включает «наем», «составление программы конференции» и «поиск людей для проведения патентных исследований или показаний экспертов», как резюмировал Патрик Дурусау .
Я опоздал на вечеринку (поскольку крайний срок для получения доступа к данным Mendeley прошел), но Уильям Ганн и Даниэль Тункеланг были достаточно любезны, чтобы предоставить мне доступ.
Я получил данные через Dropbox, в основном это данные, разделенные табуляцией, за одним исключением — дамп JSON публикаций.
Мне нужно было импортировать это в Neo4j, поэтому я следовал примерам из Batch Importer Часть 2 и Batch Importer Часть 3 для создания ETL, но сначала мне нужно было загрузить данные в Postgresql, чтобы я мог сопоставить два формата. Я обрисовал в общих чертах, как я сделал это на репозитории HCIR github .
В итоге я получил этот график:
publication -[:by_discipline]-> discipline publication -[:by_country]-> country publication -[:by_academic_status]-> academic_status publication -[:authored_by]-> author publication -[:published_in]-> journal author -[:has_profile]-> profile profile -[:interested_in]-> discipline profile -[:member_of]-> group profile -[:knows]-> profile
Я также создал полнотекстовый индекс «вершины» и полнотекстовый индекс «ребра», чтобы облегчить мою жизнь. Просто чтобы убедиться, что он импортирован нормально, я протестировал
START authors = node:vertices('type:author') RETURN authors.name LIMIT 3;
Хорошо смотритесь:
==> +------------------+ ==> | authors.name | ==> +------------------+ ==> | "Dominik Papies" | ==> | "Felix Eggers" | ==> | "Nils Wlömert" | ==> +------------------+
Интересно, кто самый плодовитый автор?
START authors = node:vertices('type:author') MATCH authors <-[:authored_by]- publication RETURN authors.name, count(publication) AS cnt ORDER BY cnt DESC LIMIT 5;
«Тимоти Э Хьюитт» является автором большинства публикаций в нашем наборе данных.
==> +--------------------------+ ==> | authors.name | cnt | ==> +--------------------------+ ==> | "Timothy E Hewett" | 339 | ==> | "Gregory D Myer" | 226 | ==> | "Kevin R Ford" | 202 | ==> | "Felix Gugerli" | 144 | ==> | "K Darowicki" | 143 | ==> +--------------------------+
Интересно, сколько у него соавторов?
START author = node:vertices('type:author AND name:"Timothy E Hewett"') MATCH author <-[:authored_by]- publication -[:authored_by]-> co_authors RETURN count(DISTINCT co_authors);
Это тонна соавторов.
==> +----------------------------+ ==> | count(DISTINCT co_authors) | ==> +----------------------------+ ==> | 280 | ==> +----------------------------+
Давайте выберем одного автора сверху и сосредоточимся на них.
START me = node:vertices('name:"Felix Eggers"') RETURN me;
Похоже, он у нас есть как автор, и у нас есть его профиль.
==> +-------------------------------------------------------------------+ ==> | me | ==> +-------------------------------------------------------------------+ ==> | Node[17]{name:"Felix Eggers",type:"author",node_id:"17"} | ==> | Node[400573]{name:"Felix Eggers",type:"profile",node_id:"400573"} | ==> +-------------------------------------------------------------------+
Допустим, что Феликс пытается нанять кого-то вроде него или собрать программу конференции по интересующей его теме. Мы можем попытаться найти людей, похожих на Феликса, несколькими способами:
По контактам:
Мы можем начать с простого случая, кого знает Феликс?
START me = node:vertices('type:profile AND name:"Felix Eggers"') MATCH me -[:knows]-> profiles RETURN DISTINCT profiles.name LIMIT 5;
5 из 7 авторов Феликс знает:
==> +-------------------+ ==> | profiles.name | ==> +-------------------+ ==> | "Jens Hogreve" | ==> | "Mathias Lin" | ==> | "Fabian Eggers" | ==> | "Tillmann Wagner" | ==> | "Andreas Neus" | ==> +-------------------+
Феликс не знает многих других авторов, давайте расширим его сеть еще на один уровень.
START me = node:vertices('type:profile AND name:"Felix Eggers"') MATCH me -[:knows]-> () -[:knows]-> profiles RETURN DISTINCT profiles.name; LIMIT 5;
5 из 16 контактов его контакты знают:
==> +------------------------+ ==> | profiles.name | ==> +------------------------+ ==> | "Victor Henning" | ==> | "Jens Hogreve" | ==> | "Charles Hofacker" | ==> | "Stephanie Feiereisen" | ==> | "Alexander Stich" | ==> +------------------------+
Члены тех же групп:
Давайте посмотрим, в каких исследовательских группах находится Феликс, и кто еще в этих группах.
START me = node:vertices('type:profile AND name:"Felix Eggers"') MATCH me -[:member_of]-> group <-[:member_of]- other_profiles RETURN DISTINCT other_profiles.name, COLLECT(DISTINCT group.name) ORDER BY COUNT(*) DESC LIMIT 5;
Мы находим Джереми и Майкла в одной группе с Феликсом.
==> +-----------------------------------------------------------------------------+ ==> | other_profiles.name | COLLECT(DISTINCT group.name) | ==> +-----------------------------------------------------------------------------+ ==> | "Jeremy Chen" | ["Conjoint Analysis and Discrete Choice Experiments"] | ==> | "Michael Waltinger" | ["Conjoint Analysis and Discrete Choice Experiments"] | ==> +-----------------------------------------------------------------------------+
Они в каких-либо других группах, которые могут помочь нам расширить сеть Феликса?
START me = node:vertices('type:profile AND name:"Felix Eggers"') MATCH me -[:member_of]-> group <-[:member_of]- team_members -[:member_of]-> other_group <-[:member_of]- other_profiles RETURN DISTINCT other_profiles.name, COLLECT(DISTINCT other_group.name) ORDER BY COUNT(*) DESC LIMIT 5;
Некоторые из этих людей находятся в куче групп, давайте просто посчитаем их, чтобы их было легче отобразить.
START me = node:vertices('type:profile AND name:"Felix Eggers"') MATCH me -[:member_of]-> group <-[:member_of]- team_members -[:member_of]-> other_group <-[:member_of]- other_profiles RETURN DISTINCT other_profiles.name, COUNT( DISTINCT other_group.name) ORDER BY COUNT(*) DESC LIMIT 5;
==> +-----------------------------------------------------------+ ==> | other_profiles.name | COUNT( DISTINCT other_group.name) | ==> +-----------------------------------------------------------+ ==> | "ABDUL SALAM YUSSIF" | 12 | ==> | "Nicholas Overton" | 9 | ==> | "Ashley Cooke" | 7 | ==> | "Joe Reevy" | 6 | ==> | "Moeez Khademhoseiny" | 6 | ==> +-----------------------------------------------------------+
Соавторы:
START me = node:vertices('type:author AND name:"Felix Eggers"') MATCH me <-[:authored_by]- publication -[:authored_by]-> co_authors RETURN DISTINCT co_authors.name;
Эти люди являются соавторами публикации с Феликсом, поэтому им должно понравиться работать вместе и иметь схожие исследовательские интересы.
==> +--------------------------+ ==> | co_authors.name | ==> +--------------------------+ ==> | "Victor Henning" | ==> | "Thorsten Hennig-Thurau" | ==> | "Dominik Papies" | ==> | "Fabian Eggers" | ==> | "Henrik Sattler" | ==> | "Mark B Houston" | ==> | "Nils Wlömert" | ==> +--------------------------+
Это не куча людей, давайте попробуем его соавторскую сеть 2-го уровня:
START me = node:vertices('type:author AND name:"Felix Eggers"') MATCH me <-[:authored_by]- my_publications -[:authored_by]-> co_authors <-[:authored_by]- their_publications -[:authored_by]-> their_co_authors WHERE me <> their_co_authors AND NOT(me <-[:authored_by]- my_publications -[:authored_by]-> their_co_authors) RETURN DISTINCT their_co_authors.name, COUNT(*) AS cnt ORDER BY cnt DESC LIMIT 5;
Мы исключаем Феликса и его соавторов из результата. Я нашел 18, но вот топ-5:
==> +-----------------------------+ ==> | their_co_authors.name | cnt | ==> +-----------------------------+ ==> | "Jan Reichelt" | 27 | ==> | "Jason J Hoyt" | 21 | ==> | "James Hammerton" | 15 | ==> | "Kris Jack" | 15 | ==> | "Dan Harvey" | 15 | ==> +-----------------------------+
В том же Журнале:
мы также можем взглянуть на авторов, которые появились в том же Журнале, что и Феликс, так как Журналы, как правило, ориентированы на конкретные темы и курируют высококачественный контент.
START me = node:vertices('type:author AND name:"Felix Eggers"') MATCH me <-[:authored_by]- my_publications -[:published_in]-> journal <-[:published_in]- other_publications -[:authored_by]-> authors RETURN DISTINCT authors.name, COUNT(*) AS cnt ORDER BY cnt DESC LIMIT 5;
Я нашел 35 авторов, которые были опубликованы в тех же журналах, но вот топ-5:
==> +--------------------------------+ ==> | authors.name | cnt | ==> +--------------------------------+ ==> | "Thorsten Hennig-Thurau" | 7 | ==> | "Victor Henning" | 4 | ==> | "Henrik Sattler" | 4 | ==> | "Tillmann Wagner" | 4 | ==> | "Richard J Lutz" | 2 | ==> +--------------------------------+
Мы можем перейти на 2-й уровень здесь, используя его соавторов:
START me = node:vertices('type:author AND name:"Felix Eggers"') MATCH me <-[:authored_by]- my_publications -[:authored_by]-> co_authors <-[:authored_by]- their_publications -[:published_in]-> journal <-[:published_in]- other_publications -[:authored_by]-> authors WHERE me <> authors AND NOT(me <-[:authored_by]- my_publications -[:authored_by]-> authors) RETURN DISTINCT authors.name, COUNT(*) AS cnt ORDER BY cnt DESC LIMIT 5;
Этот запрос возвращает 19,5 тыс. Авторов, вот первые 5:
==> +-------------------------+ ==> | authors.name | cnt | ==> +-------------------------+ ==> | "Thomas Cochrane" | 444 | ==> | "Amanda Peters" | 360 | ==> | "David Jones" | 336 | ==> | "DJ Riddell" | 312 | ==> | "J Lavoué" | 300 | ==> +-------------------------+
В этом списке представлены авторы, появившиеся в тех же журналах, что и его соавторы, упорядоченные по количеству существующих для них путей.
Интересуют те же дисциплины:
Мы действительно можем пойти несколькими путями здесь.
Из его профиля мы можем перейти к дисциплинам и найти другие профили, которые относятся к тем же дисциплинам.
START me = node:vertices('type:profile AND name:"Felix Eggers"') MATCH me -[:interested_in]-> disciplines <-[:interested_in]- other_profiles RETURN DISTINCT other_profiles.name, COLLECT(DISTINCT disciplines.name) ORDER BY COUNT(*) DESC LIMIT 5;
Это вернет тонну людей, которые также входят в бизнес-администрирование, вот 5 из них:
==> +----------------------------------------------------------+ ==> | other_profiles.name | COLLECT(DISTINCT disciplines.name) | ==> +----------------------------------------------------------+ ==> | "John Smith" | ["Business Administration"] | ==> | "Andreas Müller" | ["Business Administration"] | ==> | "abc abc" | ["Business Administration"] | ==> | "abc def" | ["Business Administration"] | ==> | "Luis Farinha" | ["Business Administration"] | ==> +----------------------------------------------------------+
Поскольку мы знаем, что Феликс интересуется бизнес-администрированием, мы также можем перейти от дисциплин к публикациям, другим авторам, которые могут не иметь профиля в системе.
START me = node:vertices('type:discipline AND name:"Business Administration"') MATCH me -[:by_discipline]- publications -[:authored_by]- author RETURN author.name, COUNT(*) AS cnt ORDER BY cnt DESC LIMIT 5;
==> +---------------------------+ ==> | author.name | cnt | ==> +---------------------------+ ==> | "Null Mancas Matei" | 11 | ==> | "Joanne Dyer" | 8 | ==> | "Nicholas J Turro" | 8 | ==> | "Steffen Jockusch" | 4 | ==> | "Angel A Martí" | 4 | ==> +---------------------------+
Во всяком случае, это было всего лишь исследование данных с Neo4j и Cypher . Я постараюсь создать сайт, который использует эти запросы до 31 августа. Оставьте комментарий, если у вас есть идеи или вы хотите помочь.