2014-10-09 9 views
5

Ho un set di dati molto grande e complesso con molte osservazioni delle aziende. Alcune delle osservazioni delle aziende sono ridondanti e ho bisogno di creare una chiave per mappare le osservazioni ridondanti a una singola. Tuttavia, l'unico modo per dire se stanno effettivamente rappresentando la stessa azienda è attraverso la somiglianza di una varietà di variabili. Penso che l'approccio appropriato sia una sorta di clustering basato su una varietà di condizioni o forse anche una sorta di abbinamento del punteggio di propensione. Forse ho solo bisogno di strumenti flessibili per creare un tipo complesso di matrice di similarità.Clustering/Matching su molte dimensioni in R

Sfortunatamente, non sono abbastanza sicuro su come farlo in R. La maggior parte degli strumenti che ho visto per il clustering e la categorizzazione sembrano farlo con distanza numerica o dati categoriali, ma non sembrano consentire condizioni multiple o condizioni specificate dall'utente.

Di seguito ho cercato di creare un esempio più piccolo e pubblico del tipo di dati con cui sto lavorando e del risultato che sto cercando di produrre. Ci sono alcune condizioni che devono essere applicate, ad esempio, la posizione deve essere la stessa. Ci sono alcune funzionalità che possono associarsi tra loro, ad esempio var1 e var2. Poi ci sono alcune funzionalità che possono associarne una con un'altra, ma non devono entrare in conflitto, come var3.

Un ulteriore livello di complessità è che il tipo di associazione che sto tentando di utilizzare per mappare l'osservazione ridondante varia. Ad esempio, id1 e id2 sono la stessa azienda immessa in ridondanza nei dati due volte. In un posto il suo nome è "mele" e un altro "mele rosse". Condividono la stessa posizione, valore var1 e var3 (dopo aver regolato la formattazione). Allo stesso modo, gli ID 3, 5 e 6 sono anche solo una compagnia, anche se molti degli input per ciascuno sono diversi. Alcuni cluster identificerebbero più osservazioni, altre ne avrebbero solo una. Idealmente mi piacerebbe trovare un modo per categorizzare o associare le osservazioni in base a diverse condizioni, ad esempio: 1. Verificare che la posizione sia la stessa 2. Verificare se var3 è diverso 3. Verificare se i nomi sono una sottostringa degli altri 4. Verificare la distanza di modifica dei nomi 5. Verificare la somiglianza di var1 e var2 tra osservazioni

in ogni modo, si spera ci sono meglio, strumenti più flessibili per questo rispetto a quello che sto trovando o qualcuno ha esperienza con questo tipo di dati funzionano in R. Qualsiasi e tutti i suggerimenti e consigli sono molto apprezzati!

dati

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 

risultati

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 

Grazie in anticipo per il vostro tempo e aiuto!

+0

Quello che hai qui è quello che chiamiamo un problema "difficile". Penso che un modo per creare una distanza numerica all'interno di ciascuna variabile sia utilizzare http://en.wikipedia.org/wiki/Levenshtein_distance. È quindi possibile definire una tolleranza per la distanza totale per la corrispondenza. EDIT: proverò a prendere in giro qualcosa. – stanekam

+0

Esistono anche pacchetti che ti aiuteranno a verificare la somiglianza con i personaggi. Ti permetterà di concludere che "mela" e "mela rossa" si trovano nello stesso ammasso. –

+0

@Adii_ Non ci sarà alcun pacchetto che abbinerà '' mele "' a '" mele rosse "' e nessuna delle altre mele lì dentro. – stanekam

risposta

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]) 

Dove test sono i tuoi dati. Questo probabilmente ha sicuramente bisogno di un po 'di raffinazione e ha sicuramente bisogno di qualche postelaborazione. Questo crea una colonna con l'indice della corrispondenza più vicina. Se non riesce a trovare una corrispondenza entro la tolleranza data, restituisce l'indice di se stesso.

EDIT: Proverò un po 'più tardi.

+0

Grazie per l'aiuto. Ci penserò un po 'e vedrò se riesco a far funzionare qualcosa del genere. – DaedalusBloom

Problemi correlati