Domanda

Questo è in realtà un problema di classificazione dell'apprendimento automatico, ma immagino che ci sia un modo perfetto per farlo. Voglio mappare una stringa che descriva una squadra NFL, come "San Francisco" o "49ers" o "San Francisco 49ers" o "SF quarantanove" a un nome canonico per la squadra. (Esistono 32 squadre NFL, quindi significa solo trovare il più vicino dei 32 bin per inserire una determinata stringa.)

Le stringhe in arrivo non sono in realtà totalmente arbitrarie (provengono da fonti di dati strutturate come questa: http://www.repole.com/sun4cast/stats/nfl2008lines.csv ), quindi non è davvero necessario gestire tutti i casi pazzi come nell'esempio 49ers sopra.

Dovrei anche aggiungere che nel caso in cui qualcuno fosse a conoscenza di una fonte di dati contenente sia le probabilità di Las Vegas sulla linea di vincita sia i risultati di gioco effettivi degli ultimi anni di giochi NFL, ciò eviterebbe la necessità di ciò. Il motivo per cui ho bisogno della canonicalizzazione è di abbinare questi due insiemi di dati disparati, uno con probabilità e uno con risultati:

Sono benvenute idee per fonti di dati migliori, più analizzabili!

Aggiunto: l'idea di corrispondenza della sottostringa potrebbe essere sufficiente per questi dati; Grazie! Potrebbe essere reso un po 'più robusto selezionando il nome della squadra con la distanza levenshtein più vicina?

È stato utile?

Soluzione

Ecco qualcosa di molto robusto anche per l'input dell'utente arbitrario, credo. Innanzitutto, mappa ogni squadra (sto usando un codice di 3 lettere come nome canonico per ogni squadra) su una versione completamente scritta con il nome della città e della squadra, nonché tutti i soprannomi tra parentesi tra la città e il nome della squadra.

Scan[(fullname[First@#] = #[[2]])&, {
  {"ari", "Arizona Cardinals"},                 {"atl", "Atlanta Falcons"}, 
  {"bal", "Baltimore Ravens"},                  {"buf", "Buffalo Bills"}, 
  {"car", "Carolina Panthers"},                 {"chi", "Chicago Bears"}, 
  {"cin", "Cincinnati Bengals"},                {"clv", "Cleveland Browns"}, 
  {"dal", "Dallas Cowboys"},                    {"den", "Denver Broncos"}, 
  {"det", "Detroit Lions"},                     {"gbp", "Green Bay Packers"}, 
  {"hou", "Houston Texans"},                    {"ind", "Indianapolis Colts"}, 
  {"jac", "Jacksonville Jaguars"},              {"kan", "Kansas City Chiefs"}, 
  {"mia", "Miami Dolphins"},                    {"min", "Minnesota Vikings"}, 
  {"nep", "New England Patriots"},              {"nos", "New Orleans Saints"}, 
  {"nyg", "New York Giants NYG"},               {"nyj", "New York Jets NYJ"}, 
  {"oak", "Oakland Raiders"},                   {"phl", "Philadelphia Eagles"}, 
  {"pit", "Pittsburgh Steelers"},               {"sdc", "San Diego Chargers"}, 
  {"sff", "San Francisco 49ers forty-niners"},  {"sea", "Seattle Seahawks"}, 
  {"stl", "St Louis Rams"},                     {"tam", "Tampa Bay Buccaneers"}, 
  {"ten", "Tennessee Titans"},                  {"wsh", "Washington Redskins"}}]

Quindi, per ogni data stringa, trova la sottosequenza comune più lunga per ciascuno dei nomi completi delle squadre. Per dare la preferenza alla corrispondenza delle stringhe all'inizio o alla fine (ad esempio, "auto" deve corrispondere a "pantere carolina" piuttosto che a "cardinali Arizona") sandwich sia la stringa di input che i nomi completi tra gli spazi. Qualunque sia il nome completo del team che ha la [sic:] la sottosequenza comune più lunga più lunga con la stringa di input è il team che restituiamo. Ecco un'implementazione di Mathematica dell'algoritmo:

teams = keys@fullnames;

(* argMax[f, domain] returns the element of domain for which f of that element is
   maximal -- breaks ties in favor of first occurrence. *)
SetAttributes[argMax, HoldFirst];
argMax[f_, dom_List] := Fold[If[f[#1] >= f[#2], #1, #2] &, First@dom, Rest@dom]

canonicalize[s_] := argMax[StringLength@LongestCommonSubsequence[" "<>s<>" ", 
                                 " "<>fullname@#<>" ", IgnoreCase->True]&, teams]

Altri suggerimenti

L'ispezione rapida a vista mostra che entrambi i set di dati contengono le posizioni dei team (vale a dire "Minnesota"). Solo uno di loro ha i nomi delle squadre. Cioè, un elenco appare come:

Denver
Minnesota
Arizona
Jacksonville

e l'altro sembra

Denver Broncos
Minnesota Vikings
Arizona Cardinals
Jacksonville Jaguars

Sembra che, in questo caso, un abbinamento di sottostringhe piuttosto semplice lo farebbe.

Se conosci i nomi di origine e di destinazione, devi solo mapparli. In php, useresti semplicemente un array con chiavi dall'origine dati e valori dalla destinazione. Quindi li faresti come:

$map = array('49ers' => 'San Francisco 49ers',
             'packers' => 'Green Bay Packers');

foreach($incoming_name as $name) {
   echo $map[$name];
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top