Недавно я очень заинтересовался связью записей и наткнулся на проект Duke, который предоставляет некоторые инструменты для решения этой проблемы. Я думал, что попробую.
Типичная проблема при связывании записей состоит в том, что у нас есть две записи из разных наборов данных, которые представляют одну и ту же сущность, но не имеют общего ключа, который мы можем использовать для их объединения. Поэтому нам нужно придумать эвристику, которая позволит нам это сделать.
У Герцога есть несколько примеров, демонстрирующих это в действии, и я решил пойти со связывающими странами . Здесь у нас есть страны из Dbpedia и базы данных Mondial, и мы хотим связать их вместе.
Первое, что нам нужно сделать, это построить проект:
1
2
|
export JAVA_HOME=` /usr/libexec/java_home ` mvn clean package -DskipTests |
На момент написания этого документа будет помещен файл zip fail, содержащий все, что нам нужно, в duke-dist / target / . Давайте распакуем это:
1
|
unzip duke-dist /target/duke-dist-1 .3-SNAPSHOT-bin.zip |
Далее нам нужно скачать файлы данных и файл конфигурации Duke:
1
2
3
4
|
wget https: //raw .githubusercontent.com /larsga/Duke/master/doc/example-data/countries-dbpedia .csv wget https: //raw .githubusercontent.com /larsga/Duke/master/doc/example-data/countries .xml wget https: //raw .githubusercontent.com /larsga/Duke/master/doc/example-data/countries-mondial .csv wget https: //raw .githubusercontent.com /larsga/Duke/master/doc/example-data/countries-test .txt |
Теперь мы готовы попробовать:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
java - cp "duke-dist-1.3-SNAPSHOT/lib/*" no.priv.garshol.duke.Duke --testfile=countries- test .txt --testdebug --showmatches countries.xml ... NO MATCH FOR: ID: '7706' , NAME: 'guatemala' , AREA: '108890' , CAPITAL: 'guatemala city' , MATCH 0.9825124555160142 ID: '10052' , NAME: 'pitcairn islands' , AREA: '47' , CAPITAL: 'adamstown' , ID: 'http://dbpedia.org/resource/Pitcairn_Islands' , NAME: 'pitcairn islands' , AREA: '47' , CAPITAL: 'adamstown' , Correct links found: 200 / 218 (91.7%) Wrong links found: 0 / 24 (0.0%) Unknown links found: 0 Percent of links correct 100.0%, wrong 0.0%, unknown 0.0% Records with no link: 18 Precision 100.0%, recall 91.74311926605505%, f-number 0.9569377990430622 |
Мы можем заглянуть в файл country.xml, чтобы увидеть, как вычисляется сходство между записями:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
< schema > < threshold >0.7</ threshold > ... < property > < name >NAME</ name > < comparator >no.priv.garshol.duke.comparators.Levenshtein</ comparator > < low >0.09</ low > < high >0.93</ high > </ property > < property > < name >AREA</ name > < comparator >no.priv.garshol.duke.comparators.NumericComparator</ comparator > < low >0.04</ low > < high >0.73</ high > </ property > < property > < name >CAPITAL</ name > < comparator >no.priv.garshol.duke.comparators.Levenshtein</ comparator > < low >0.12</ low > < high >0.61</ high > </ property > </ schema > |
Таким образом, мы выясняем сходство столицы и страны, вычисляя расстояние Левенштейна, т.е. минимальное количество односимвольных правок, необходимых для преобразования одного слова в другое.
Это работает очень хорошо, если в одном из наборов данных есть опечатка или разница в написании. Однако мне было любопытно, что произойдет, если в стране будет два совершенно разных названия, например, Кот-д’Ивуар иногда называют Кот-д’Ивуар. Давайте попробуем изменить название страны в одном из файлов:
1
|
"19147" , "Cote dIvoire" , "Yamoussoukro" , "322460" |
1
2
3
4
|
java - cp "duke-dist-1.3-SNAPSHOT/lib/*" no.priv.garshol.duke.Duke --testfile=countries- test .txt --testdebug --showmatches countries.xml NO MATCH FOR: ID: '19147' , NAME: 'ivory coast' , AREA: '322460' , CAPITAL: 'yamoussoukro' , |
Я также попробовал это с отчетами о матчах BBC и ESPN в матче «Манчестер Юнайтед» против «Тоттенхэма» — BBC называет игроков по фамилии, а у ESPN есть их полные имена.
Когда я сравнивал полное имя с фамилией с помощью компаратора Левенштейна, совпадений, как и следовало ожидать, не было. Мне пришлось разделить имена ESPN на имя и фамилию, чтобы получить ссылку на работу.
Точно так же, когда я изменил название команды на «Манчестер Юнайтед», а не «Манчестер Юнайтед» и «Тоттенхэм», а не «Тоттенхэм Хотспур», это тоже не сработало.
Я думаю, что мне, вероятно, нужно написать специфичный для предметной области компаратор, но мне также любопытно, смогу ли я придумать кучу обучающих примеров, а затем обучить модель, чтобы определить, что делает две записи похожими. Это было бы менее детерминированным, но, возможно, более надежным.
Ссылка: | Рекордная связь: игра с Дьюком от нашего партнера по JCG Марка Нидхэма в блоге Марка Нидхэма . |