Question

Il s’agit en fait d’un problème de classification par apprentissage automatique, mais j’imagine qu’il existe une méthode très simple et rapide pour le faire. Je souhaite mapper une chaîne décrivant une équipe de la NFL, telle que "San Francisco". ou " 49ers " ou "San Francisco 49ers" ou "SF quarante-neuf", en un nom canonique pour l'équipe. (Il y a 32 équipes de la NFL, cela signifie donc simplement trouver le plus proche des 32 bacs pour y placer une chaîne donnée.)

Les chaînes entrantes ne sont en réalité pas totalement arbitraires (elles proviennent de sources de données structurées telles que: http://www.repole.com/sun4cast/stats/nfl2008lines.csv ), il n'est donc pas vraiment nécessaire de gérer tous les cas délirants comme dans l'exemple de 49ers ci-dessus.

Je devrais également ajouter que si quelqu'un connaissait une source de données contenant à la fois les cotes Moneyline Vegas ainsi que les résultats réels des jeux pour les dernières années de jeux de la NFL, cela en éviterait la nécessité. La raison pour laquelle j'ai besoin de la canonisation est de faire correspondre ces deux ensembles de données disparates, l'un avec les probabilités et l'autre avec les résultats:

Idées pour mieux, plus analysables, les sources de données sont les bienvenues!

Ajouté: L'idée de correspondance de sous-chaîne pourrait bien suffire pour ces données; Merci! Pourrait-il être un peu plus robuste en choisissant le nom de l'équipe avec la distance la plus proche de levenshtein?

Était-ce utile?

La solution

Voilà quelque chose d'assez robuste, même pour une entrée utilisateur arbitraire, je pense. Tout d’abord, mappez chaque équipe (j’utilise un code de 3 lettres comme nom canonique de chaque équipe) en une version entièrement épelée avec la ville et le nom de l’équipe, ainsi que tous les surnoms entre parenthèses entre la ville et le nom de l’équipe.

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

Ensuite, pour toute chaîne donnée, recherchez la sous-séquence commune la plus longue pour chacun des noms complets des équipes. Pour donner la préférence aux chaînes qui correspondent au début ou à la fin (par exemple, "voiture" doit correspondre à "carolina panthers" plutôt qu'à "arizona cardinals") qui prennent en sandwich la chaîne d'entrée et les noms complets entre les espaces. Quel que soit le nom complet de l’équipe qui porte le [sic:] plus longue séquence la plus longue-commune-commune avec la chaîne en entrée est l’équipe que nous retournons. Voici une implémentation de l’algorithme Mathematica:

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]

Autres conseils

Une inspection rapide à vue montre que les deux ensembles de données contiennent les emplacements des équipes ("Minnesota"). Un seul d'entre eux porte le nom des équipes. C'est-à-dire qu'une liste ressemble à ceci:

Denver
Minnesota
Arizona
Jacksonville

et l'autre ressemble à

Denver Broncos
Minnesota Vikings
Arizona Cardinals
Jacksonville Jaguars

On dirait que, dans ce cas, une correspondance de sous-chaîne assez simple le ferait.

Si vous connaissez les noms de source et de destination, il vous suffit de les mapper. En php, vous utiliseriez simplement un tableau avec des clés de la source de données et des valeurs de la destination. Ensuite, vous les référencerez comme:

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

foreach($incoming_name as $name) {
   echo $map[$name];
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top