2014-10-09 3 views
5

Ich habe einen sehr großen und komplexen Datensatz mit vielen Beobachtungen von Unternehmen. Einige der Beobachtungen der Unternehmen sind redundant und ich muss einen Schlüssel erstellen, um die redundanten Beobachtungen auf eine einzige abzubilden. Die einzige Möglichkeit zu sagen, ob sie tatsächlich dasselbe Unternehmen repräsentieren, liegt in der Ähnlichkeit einer Vielzahl von Variablen. Ich denke, der geeignete Ansatz ist eine Art von Clustering basierend auf einer Vielzahl von Bedingungen oder vielleicht sogar einer Art von Neigungs-Score-Matching. Vielleicht brauche ich nur flexible Werkzeuge, um eine komplexe Art von Ähnlichkeitsmatrix zu erstellen.Clustering/Matching über viele Dimensionen in R

Leider bin ich nicht ganz sicher, wie ich das in R machen soll. Die meisten Tools, die ich für Clustering und Kategorisierung gesehen habe, scheinen dies entweder mit numerischen Entfernungen oder kategorischen Daten zu tun, scheinen dies aber nicht zu erlauben mehrere Bedingungen oder benutzerdefinierte Bedingungen.

Im Folgenden habe ich versucht, ein kleineres, öffentliches Beispiel für die Art von Daten, mit denen ich arbeite, und das Ergebnis, das ich versuche, zu erstellen. Es gibt einige Bedingungen, die gelten müssen, z. B. muss der Standort identisch sein. Es gibt einige Features, die miteinander verknüpft werden können, z. B. var1 und var2. Dann gibt es einige Features, die einander zuordnen können, aber sie dürfen keinen Konflikt verursachen, wie zB var3.

Eine zusätzliche Komplexitätsebene besteht darin, dass die Art der Assoziation, die ich verwende, um die redundante Beobachtung abzubilden, variiert. Zum Beispiel sind id1 und id2 dasselbe Unternehmen, das doppelt in die Daten redundant eingegeben wird. An einer Stelle heißt er "Äpfel" und andere "rote Äpfel". Sie teilen den gleichen Speicherort, var1 Wert und var3 (nach der Anpassung für die Formatierung). Ähnlich sind die IDs 3, 5 und 6 auch wirklich nur eine Firma, obwohl ein großer Teil der Eingabe für jeden anders ist. Einige Cluster würden mehrere Beobachtungen identifizieren, andere nur eine. Idealerweise würde ich gerne einen Weg finden, um die Beobachtungen basierend auf verschiedenen Bedingungen zu kategorisieren oder zu assoziieren, zum Beispiel: 1. Testen Sie, ob der Ort derselbe ist 2. Testen Sie, ob var3 anders ist 3. Testen Sie, ob der Name ein Teilstring ist anderer 4. Testen Sie die edit-Distanz von Namen 5. Testen Sie die Ähnlichkeit von var1 und var2 zwischen Beobachtungen

Anyways, hoffentlich gibt es bessere, flexiblere Werkzeuge dafür als das, was ich bin zu finden oder hat jemand Erfahrung mit diesem Art der Datenarbeit in R. Alle Vorschläge und Ratschläge werden sehr geschätzt!

Daten

id name  location var1 var2 var3 
1 apples  US  1  abc  12345 
2 red apples US  1  NA  12-345 
3 green apples Mexico 2  def  235-92 
4 bananas  Brazil 2  abc  NA 
5 oranges  Mexico 2  NA  23592 
6 green apple Mexico NA  def  NA 
7 tangerines Honduras NA  abc  3498 
8 mango   Honduras 1  NA  NA 
9 strawberries Honduras NA  abcd 3498 
10 strawberry Honduras NA  abc  3498 
11 blueberry  Brazil 1  abcd 2348 
12 blueberry  Brazil 3  abc  NA 
13 blueberry  Mexico NA  def  1859 
14 bananas  Brazil 1  def  2348 
15 blackberries Honduras NA  abc  NA 
16 grapes  Mexico 6  qrs  NA 
17 grapefruits Brazil 1  NA  1379 
18 grapefruit Brazil 2  bcd  1379 
19 mango   Brazil 3  efaq NA 
20 fuji apples US  4  NA  189-35 

Ergebnis

id name  location var1 var2 var3  Result 
1 apples  US  1  abc  12345  1 
2 red apples US  1  NA  12-345  1 
3 green apples Mexico 2  def  235-92  3 
4 bananas  Brazil 2  abc  NA   4 
5 oranges  Mexico 2  NA  23592  3 
6 green apple Mexico NA  def  NA   3 
7 tangerines Honduras NA  abc  3498  7 
8 mango   Honduras 1  NA  NA   8 
9 strawberries Honduras NA  abcd 3498  7 
10 strawberry Honduras NA  abc  3498  7 
11 blueberry  Brazil 1  abcd 2348  11 
12 blueberry  Brazil 3  abc  NA   11 
13 blueberry  Mexico NA  def  1859  13 
14 bananas  Brazil 1  def  2348  11 
15 blackberries Honduras NA  abc  NA   15 
16 grapes  Mexico 6  qrs  NA   16 
17 grapefruits Brazil 1  NA  1379  17 
18 grapefruit Brazil 2  bcd  1379  17 
19 mango   Brazil 3  efaq NA   19 
20 fuji apples US  4  NA  189-35  20 

Vielen Dank im Voraus für Ihre Zeit und Hilfe!

+0

Was Sie hier haben, nennen wir ein "hartes" Problem. Ich denke, eine Möglichkeit, eine numerische Entfernung innerhalb jeder Variablen zu erstellen, wäre http://en.wikipedia.org/wiki/Levenshtein_distance. Sie können dann eine Toleranz für die Gesamtentfernung für die Übereinstimmung definieren. EDIT: Ich werde versuchen, etwas nachzuahmen. – stanekam

+0

Es gibt auch Pakete, die Ihnen helfen, die Ähnlichkeit mit Zeichen zu überprüfen. Es wird Ihnen erlauben, zu dem Schluss zu kommen, dass "Apfel" und "roter Apfel" im selben Cluster sind. –

+0

@Adii_ Es wird kein Paket geben, das '" Äpfel "' '' 'roten Äpfeln" "entspricht und keine der anderen Äpfel darin. – stanekam

Antwort

0
library(stringdist) 
getMatches <- function(df, tolerance=6){ 
    out <- integer(nrow(df)) 
    for(row in 1:nrow(df)){ 
    dists <- numeric(nrow(df)) 
    for(col in 1:ncol(df)){ 
     tempDist <- stringdist(df[row, col], df[ , col], method="lv") 

     # WARNING: Matches NA perfectly. 
     tempDist[is.na(tempDist)] <- 0 
     dists <- dists + tempDist 
    } 
    dists[row] <- Inf 

    min_dist <- min(dists) 
    if(min_dist < tolerance){ 
     out[row] <- which.min(dists) 
    } 
    else{ 
     out[row] <- row 
    } 
    } 
    return(out) 
} 

test$Result <- getMatches(test[, -1]) 

Wo test ist Ihre Daten. Dies erfordert sicherlich einige Verfeinerung und erfordert sicherlich einige Nachbearbeitung. Dies erstellt eine Spalte mit dem Index der nächsten Übereinstimmung. Wenn es innerhalb der gegebenen Toleranz keine Übereinstimmung findet, gibt es den Index von sich selbst zurück.

EDIT: Ich werde später mehr versuchen.

+0

Danke für die Hilfe. Ich bastle ein bisschen herum und schaue, ob ich so etwas zum Funktionieren bekomme. – DaedalusBloom