Pregunta

Este es en realidad un problema de clasificación de aprendizaje automático, pero imagino que hay una forma muy buena y rápida de hacerlo. Quiero mapear una cadena que describa un equipo de la NFL, como "San Francisco" o "49ers" o "San Francisco 49ers" o "SF cuarenta y nueve", a un nombre canónico para el equipo. (Hay 32 equipos de la NFL, por lo que realmente significa encontrar el más cercano de 32 contenedores para colocar una cadena determinada).

Las cadenas entrantes en realidad no son totalmente arbitrarias (provienen de fuentes de datos estructurados como esta: http://www.repole.com/sun4cast/stats/nfl2008lines.csv ) por lo que no es realmente necesario manejar todos los casos de esquinas locas como en el ejemplo de 49ers anterior.

También debo agregar que, en caso de que alguien conozca una fuente de datos que contenga tanto las probabilidades de Moneyline Vegas como los resultados reales del juego en los últimos años de los juegos de la NFL, eso evitaría la necesidad de esto. La razón por la que necesito la canonicalización es hacer coincidir estos dos conjuntos de datos dispares, uno con probabilidades y otro con resultados:

¡Ideas para fuentes de datos mejores y más fáciles de analizar!

Agregado: la idea de coincidencia de subcadenas podría ser suficiente para estos datos; ¡Gracias! ¿Podría hacerse un poco más robusto eligiendo el nombre del equipo con la distancia nivenshtein más cercana?

¿Fue útil?

Solución

Aquí hay algo bastante robusto incluso para la entrada arbitraria del usuario, creo. Primero, asigne cada equipo (estoy usando un código de 3 letras como el nombre canónico para cada equipo) a una versión completamente detallada con la ciudad y el nombre del equipo, así como cualquier apodo entre paréntesis entre la ciudad y el nombre del equipo.

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"}}]

Luego, para cualquier cadena dada, encuentre la subsecuencia común más larga para cada uno de los nombres completos de los equipos. Para dar preferencia a las cadenas que coinciden al principio o al final (por ejemplo, "car" debe coincidir con "carolina panthers" en lugar de "cardenales de arizona") intercalan tanto la cadena de entrada como los nombres completos entre espacios. El nombre completo del equipo que tenga la [sic:] más larga más larga subsecuencia común con la cadena de entrada es el equipo que devolvemos. Aquí hay una implementación de Mathematica del 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]

Otros consejos

La inspección rápida a primera vista muestra que ambos conjuntos de datos contienen las ubicaciones de los equipos (es decir, `` Minnesota ''). Solo uno de ellos tiene los nombres de los equipos. Es decir, una lista se ve así:

Denver
Minnesota
Arizona
Jacksonville

y el otro parece

Denver Broncos
Minnesota Vikings
Arizona Cardinals
Jacksonville Jaguars

Parece que, en este caso, una coincidencia de subcadenas bastante simple lo haría.

Si conoce los nombres de origen y de destino, entonces solo necesita asignarlos. En php, simplemente usaría una matriz con claves del origen de datos y valores del destino. Entonces los referenciaría como:

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

foreach($incoming_name as $name) {
   echo $map[$name];
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top