2016-04-07 12 views
2

Ich versuche Einträge in einer riesigen Datenbank von Zeitungsartikeln zu sammeln, basierend auf der Ähnlichkeit der Artikel selbst.Gruppenketten durch Ähnlichkeit mit einem data.frame

Meine Daten sehen irgendwie wie folgt aus:

ID Source File Newspaper Date  Length Article 
1 aaa  The Guardian 07.30.2002 561  US scientist questions 
2 aaa  The Guardian 07.30.2002 426  Cash fine to clear elderly... 
3 aaa  The Guardian 07.30.2002 206  Token victory for HIV mother 
4 aab  Financial Times 07.29.2002 964  A tough question at the heart.. 
5 aab  The Guardian 07.29.2002 500  Media: 'We want van Hoogstr… 
6 aab  The Mirror  07.29.2002 43  IN BRIEF… 
7 aab  The Sun   07.29.2002 196  US scientist questions 
8 aab  The Sun   07.29.2002 140  ADDED VALUE 
9 aab  The Times  07.29.2002 794  US-scientist questions 
10 …  …    …   …  … 

Nachdem ich hier für eine Weile ich Erfolg hatte mit exakten Duplikaten mit dplyr:

Dup_info <- meta_articles.m %>% 
    group_by(Articles) %>% 
    summarise(IDs = toString(ID)) 

Es identifiziert richtig # 1 und # 7 als Duplikate und ich kann die Informationen nach dem Entfernen von doppelten Einträgen behalten. Leider fängt es # 9 nicht als Duplikat ab, da ein einzelnes Zeichen anders ist und ich dplyr nicht gut genug kenne, um herauszufinden, wie man eine 99% oder 95% Prozent Ähnlichkeitsschwelle implementiert. Weiß jemand, ob das überhaupt möglich ist?

dput(meta_articles.m) 
structure(list(ID = 1:9, Source.File = structure(c(1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L, 2L), .Label = c("aaa", "aab"), class = "factor"), 
    Newspaper = structure(c(2L, 2L, 2L, 1L, 2L, 3L, 4L, 4L, 5L 
    ), .Label = c("Financial Times", "The Guardian", "The Mirror", 
    "The Sun", "The Times"), class = "factor"), Date = structure(c(2L, 
    2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("07.29.2002", 
    "07.30.2002"), class = "factor"), Length = c(561L, 426L, 
    206L, 964L, 500L, 43L, 196L, 140L, 794L), Article = structure(c(8L, 
    3L, 6L, 1L, 5L, 4L, 8L, 2L, 7L), .Label = c("A tough question at the heart..", 
    "ADDED VALUE", "Cash fine to clear elderly...", "IN BRIEF…", 
    "Media: 'We want van Hoogstr…", "Token victory for HIV mother", 
    "US-scientist questions", "US scientist questions"), class = "factor")), .Names = c("ID", 
"Source.File", "Newspaper", "Date", "Length", "Article"), class = "data.frame", row.names = c(NA, 
-9L)) 
+0

Wenn Sie bieten die 'dput (meta_articles.m)' des Beispiels Sie ausführlichere Hilfe erhalten könnte –

+0

Sie können 'grep' oder' pmatch' oder 'stringdist' teilweise Übereinstimmungen zu identifizieren – akrun

+0

Sie suchen, könnte" Fuzzy-Matching "oder" Clustering "- aber nichts dergleichen ist in dplyr eingebaut. Sie können auch alle Sonderzeichen entfernen und alles in Kleinbuchstaben umwandeln, wenn Sie nichts Kompliziertes machen wollen. – Gregor

Antwort

1

Ich würde vorschlagen, eine Levenshtein Abstandsmetrik oder etwas ähnliches zu verwenden. Dies ist im Grunde der Bearbeitungsabstand zwischen 2 Saiten. Wird nicht perfekt sein, aber es wird dich beginnen.

Lesen Sie mehr über sich hier: https://stat.ethz.ch/R-manual/R-devel/library/utils/html/adist.html

erweiterte Funktionen können im stringdist Paket einschließlich der soundex Methode gefunden werden, so dass für ähnlich klingender Wörter effektiv zu gruppieren. Ein Blick wert ist auch das RecordLinkage Paket.

Ohne ein großes Beispiel (dput) kann ich kein implementiertes Beispiel bereitstellen.

Bearbeiten: adist(meta_articles.m$Article) wird eine Ähnlichkeitsmatrix erzeugen. Das Ignorieren der Diagonalen, können Sie diese Matrix analysieren Werte bei finden, was auch immer Ähnlichkeitsschwelle Sie wünschen Zeile

d <- adist(meta_articles.m$Article) 
d2 <- d 
d2[d2 > 2] <- NA #set the limit at distance = 1 
d2 

    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] 
[1,] 0 NA NA NA NA NA 0 NA 1 
[2,] NA 0 NA NA NA NA NA NA NA 
[3,] NA NA 0 NA NA NA NA NA NA 
[4,] NA NA NA 0 NA NA NA NA NA 
[5,] NA NA NA NA 0 NA NA NA NA 
[6,] NA NA NA NA NA 0 NA NA NA 
[7,] 0 NA NA NA NA NA 0 NA 1 
[8,] NA NA NA NA NA NA NA 0 NA 
[9,] 1 NA NA NA NA NA 1 NA 0 

So verfolgen [1] ist identisch mit sich selbst identisch zu [7] und in einem Bearbeitungsabstand von 1 aus [9], etc. Sie können dann zu Clustern nach Entfernung weitergehen, das heißt:

d <- adist(meta_articles.m$Article) 
rownames(d) <- meta_articles.m$Article 
hc <- hclust(as.dist(d)) 
plot(hc) 

dendogram

und schließlich alle Werte Gruppierung zusammen mit einem Bearbeitungsabstand von 2 oder weniger:

df <- data.frame(meta_articles.m$Article,cutree(hc,h=2)) 
df 

    meta_articles.m.Article cutree.hc..h...2. 
1   US scientist questions     1 
2 Cash fine to clear elderly...     2 
3 Token victory for HIV mother     3 
4 A tough question at the heart..     4 
5 Media: 'We want van Hoogstr…     5 
6      IN BRIEF…     6 
7   US scientist questions     1 
8      ADDED VALUE     7 
9   US-scientist questions     1 
+0

Vielen Dank! Es löst noch nicht mein ganzes Problem, sondern illustriert wirklich den Levenshtein-Distanzteil.Ich sehe mir die Pakete an, die Sie vorgeschlagen haben, sie sehen vielversprechend aus! – JonGrub

+0

@ JonGrub, machte ein paar Änderungen, um es für Sie einfacher zu machen, fortzufahren ... –

+0

Sie verwenden Variablen, die nicht für uns definiert sind. Was sind "Werte" und "Str"? –

Verwandte Themen