Fuente (Bubobubo2, CC BY-SA 3.0, via Wikimedia Commons)
El modelo FastText fue introducido por primera vez por Facebook en 2016 como una extensión y supuestamente una mejora del modelo vainilla de Word2Vec.
Está basado en el artículo original titulado Enriching Word Vectors with Subword Information de Mikolov et al. que es una lectura excelente para obtener una comprensión profunda de cómo funciona este modelo. En general, FastText es un marco para el aprendizaje de representaciones de palabras y también para realizar una clasificación de texto sólida, rápida y precisa.
FastText es de código abierto desarrollado en Facebook y disponible GitHub. Facebook afirma que el producto dispone de lo siguiente:
De acuerdo con los autores, en general, los modelos predictivos como el modelo Word2Vec suelen considerar cada palabra como una entidad distinta (por ejemplo la palabra donde) y generan una incrustación densa para la palabra.
Sin embargo, esto representa una seria limitación con los idiomas que tienen un vocabulario masivo y muchas palabras raras que pueden no aparecer mucho en diferentes corpus. El modelo Word2Vec
normalmente ignora la estructura morfológica de cada palabra y considera una palabra como una sola entidad.
El modelo FastText considera cada palabra como una bolsa de n-gramas de caracteres. Esto también se denomina modelo de subpalabras en el documento.
Se agregan símbolos de límites especiales al principio y al final de las palabras. Esto permite distinguir prefijos y sufijos de otras secuencias de caracteres. También incluyen la propia palabra d en el conjunto de sus n-gramas, para aprender una representación de cada palabra (además de su carácter n-gramas).
Tomando la palabra donde como ejemplo, con n = 3 (tri-gramas) estará representada por la lista de n-gramas:
Tenga en cuenta que la secuencia, correspondiente a la palabra [don] es diferente del trigrama [don] de la palabra donde. En la práctica, el artículo recomienda extraer todos los n-gramas para $3\le n \le 6$ Este es un enfoque muy simple, y se podrían considerar diferentes conjuntos de n-gramas, por ejemplo, tomando todos los prefijos y sufijos.
Normalmente asociamos una representación vectorial (incrustación) a cada n-grama de una palabra. Por tanto, podemos representar una palabra mediante la suma de las representaciones vectoriales de sus n-gramas o el promedio de la incrustación de estos n-gramas.
Según los autores, debido a este efecto de aprovechar los n-gramas de palabras individuales basadas en sus caracteres, existe una mayor probabilidad de que las palabras raras obtengan una buena representación, ya que sus n-gramas basados en caracteres deben aparecer en otras palabras del corpus.
Vamos a la práctica.
$ git clone https://github.com/facebookresearch/fastText.git
$ cd fastText
$ sudo pip install .
$ # or :
$ sudo python setup.py install
Si todo va bien, el siguiente comando debería funcionar:
import fasttext as ft
help(ft.FastText)
Help on module fasttext.FastText in fasttext: NAME fasttext.FastText DESCRIPTION # Copyright (c) 2017-present, Facebook, Inc. # All rights reserved. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. FUNCTIONS cbow(*kargs, **kwargs) load_model(path) Load a model given a filepath and return a model object. read_args(arg_list, arg_dict, arg_names, default_values) skipgram(*kargs, **kwargs) supervised(*kargs, **kwargs) tokenize(text) Given a string of text, tokenize it and return a list of tokens train_supervised(*kargs, **kwargs) Train a supervised model and return a model object. input must be a filepath. The input text does not need to be tokenized as per the tokenize function, but it must be preprocessed and encoded as UTF-8. You might want to consult standard preprocessing scripts such as tokenizer.perl mentioned here: http://www.statmt.org/wmt07/baseline.html The input file must must contain at least one label per line. For an example consult the example datasets which are part of the fastText repository such as the dataset pulled by classification-example.sh. train_unsupervised(*kargs, **kwargs) Train an unsupervised model and return a model object. input must be a filepath. The input text does not need to be tokenized as per the tokenize function, but it must be preprocessed and encoded as UTF-8. You might want to consult standard preprocessing scripts such as tokenizer.perl mentioned here: http://www.statmt.org/wmt07/baseline.html The input field must not contain any labels or use the specified label prefix unless it is ok for those words to be ignored. For an example consult the dataset pulled by the example script word-vector-example.sh, which is part of the fastText repository. DATA BOW = '<' EOS = '</s>' EOW = '>' absolute_import = _Feature((2, 5, 0, 'alpha', 1), (3, 0, 0, 'alpha', 0... displayed_errors = {} division = _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 1310... print_function = _Feature((2, 6, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0)... unicode_literals = _Feature((2, 6, 0, 'alpha', 2), (3, 0, 0, 'alpha', ... unsupervised_default = {'autotuneDuration': 300, 'autotuneMetric': 'f1... FILE /home/alvaro/miniconda3/envs/ia/lib/python3.8/site-packages/fasttext-0.9.2-py3.8-linux-x86_64.egg/fasttext/FastText.py
dir(ft)
['BOW', 'EOS', 'EOW', 'FastText', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'absolute_import', 'cbow', 'division', 'load_model', 'print_function', 'skipgram', 'supervised', 'tokenize', 'train_supervised', 'train_unsupervised', 'unicode_literals']
Como podemos observar, contamos con dos modelos: unsupervised y supervised.
Veamos cómo funcionan.
Para este ejemplo de juguete, usemos los poemas de Daniel.
model = ft.train_unsupervised('../Datos/Poemas_Todo.txt')
Read 0M words Number of words: 184 Number of labels: 0 Progress: 100.0% words/sec/thread: 159899 lr: 0.000000 avg.loss: 4.119662 ETA: 0h 0m 0s
Veamos qué tiene el modelo por dentro:
dir(model)
print(model.words)
['</s>', 'y', 'de', 'que', 'la', 'el', 'en', 'las', 'con', 'los', 'por', 'un', 'se', 'tu', 'del', 'a', 'una', 'no', 'mi', 'te', 'es', 'me', 'como', 'su', 'mis', 'para', 'sin', 'tus', 'entre', 'porque', 'más', 'lo', 'sus', 'nos', 'noche', 'ese', 'cada', 'hasta', 'pero', 'al', 'todo', 'manos', 'Y', 'cielo', 'cuerpo', 'día', 'ojos', 'ni', 'sueño', 'cuando', 'son', 'ser', 'qué', 'le', 'o', 'Me', 'Te', 'labios', 'ya', 'palabras', 'cuerpos', 'luna', 'cosas', 'si', 'mundo', 'vida', 'eres', 'mujer', 'sobre', 'esa', 'sólo', 'donde', 'este', 'toda', 'sueños', 'jamás', 'En', 'piel,', 'amor', 'e', 'Es', 'siempre', 'Ese', 'va', 'hay', 'visto', 'tan', 'he', 'gusta', 'sueños,', 'lleno', 'imagen', 'contra', 'mar', 'dos', 'Yo', 'He', 'rostro', 'La', 'noche,', 'pasión', 'nuestra', 'quien', 'deseo', 'ha', 'nubes', 'puedo', 'frío', 'abismo', 'alma', 'aire', 'lejos', 'profundo', 'éste', 'volando', 'ésta', 'aún', 'dulce', 'colores', 'cara', 'mismo', 'música', 'El', 'vez', 'letras', 'formas', 'apenas', 'ojos,', 'piel', 'dónde', 'desde', 'ante', 'mirando', 'tiempo', 'veces', 'somos', 'así', 'hacia', 'besos', 'brisa', 'entonces', 'nuestro', 'misma', 'esperar', 'A', 'tí', 'algún', 'busco', 'frase', 'suaves', 'No', 'Déjame', 'tí,', 'agua', 'luces', 'yo', 'mí', 'emociones', 'sonido', 'dame', 'casi', 'Un', 'soy', 'ideas', 'veo', 'mano', 'permanente', 'caricias', 'mientras', 'hace', 'Vivo', 'luz', 'polvo', 'esperando', 'lugar', 'quiero', 'fue', 'seres', 'sol', 'sirve', 'bajo', 'ver', 'colores,', 'brazos,', 'Ayer', 'culpa', 'hora', 'estar', 'llena', 'Con', 'pecho', 'maraña', 'voz', 'interminable', 'espacio', 'sé', 'lágrimas', 'aroma', 'noches', 'caen', 'fuego,', 'sueño,', 'gustó', 'suave', 'caminar', 'tú', 'Sé', 'fuego', 'noche.', 'locos', 'brillo', 'estado', 'queriendo', 'Por', 'nubes,', 'Mi', 'has', 'calor', 'engaño', 'vas', 'paraísos,', 'juntar', 'palabras,', 'silencio', 'De', 'respiro', 'pide', 'alto', 'tarde', 'labios,', 'pasión,', 'alma,', 'salir', 'digo', 'alguna', 'fiel', 'cruel', 'Ud.', 'dentro', 'caída', 'melodías', 'culpa,', 'horas', 'placer', 'tal', 'pobre', 'así,', 'unos', 'cómo', 'pensamientos', 'tanto', 'medio', 'llama', 'espalda,', 'nada', 'deseos,', 'rincón', 'canto,', 'mañana,', 'pobres', 'hacer', 'centro', 'Todo', 'ahora', 'misterio', 'Aquí', 'miran', 'claro', 'viento', 'Allá', 'deseo,', 'sentir', 'pecho,', 'iban', 'Tengo', 'viaje', 'viento,', 'cuerpo,', 'partes', 'esos', 'repleta', 'almas', 'demás', 'piernas', 'espalda', 'capaz', 'canto', 'exquisito,', 'descansar', 'versos', 'pies,', 'goce', 'rojo', 'pliegues', 'querer,', 'hombre', 'hemos', 'mar,', 'punto', 'está', 'frente', 'manos,', 'entonces,', 'pequeños', 'placeres', 'soñando,', 'nada,', 'posa', 'besos,', 'miradas', 'Porque', 'existe', 'peligro', 'Ya', 'mirar', 'sonidos', 'iba', 'hecho', 'ciudad', 'color', 'era', 'destrucción', 'tango', 'habían', 'the', 'peligroso', 'Como', 'íntimo', 'roce', 'azul', 'brisa,', 'guerra', 'éstos', 'tiempo,', 'frases', 'Si', 'pues', 'imaginación,', 'escribir', 'beso', 'ir', 'puede', 'ausente', 'árboles', 'eso', 'lugares', 'formación', 'pequeña', 'vulnerable', 'matemática', 'pretendes', 'caprichos,', 'dado', 'decepciones,', 'dibuja', 'bello', 'pequeño', 'miras', 'cosa', 'cosmos', 'solo', 'Mójate', 'sueña.', 'locura', 'conduce', 'tú,', 'paraíso', 'nosotros', 'todas', 'imágenes', 'gran', 'tristeza,', 'allí', 'mí,', 'viajar', 'palabra', 'lado', 'figura', 'escuchar', 'Somos', 'vivir', 'cortas', 'caricias,', 'junto', 'manos.', 'infernal', 'despertar', 'líneas', 'Cómo', 'nocturno', 'ausentes,', 'estos', 'buenos', 'Para', 'algo', 'todo,', 'barco', 'felicidad,', 'tristeza', 'todos', 'é', 'ella', 'tristes', 'caer', 'sienes', 'verdugo', 'poder', 'sonrisa', 'frío,', 'cama', 'máscara', 'seré', '¿Qué', 'alba,', 'otro,', 'sino', 'nuestras', 'da', 'allá', 'vuelo', 'inspiración', 'mástil,', 'apacible', 'compartir', 'velas', 'mortal', 'esta', 'infinita', 'escuchen,', 'despacio,', 'dejando', 'cansados', 'teclas', 'miel,', 'eres,', 'estruendoso,', 'además', 'cobre', 'alas', 'amor,', 'verdad', 'cascabel,', 'Dice', 'poco', 'ninfas', 'pozo', 'loco,', 'sos', 'baila', 'piedra', 'melodía', 'inútil', 'Vendrás', 'Pero', 'señal,', 'sentirme', 'estar,', 'qué,', 'pensamiento', 'hombros', 'olvido', 'aliento', 'lenguaje', 'condenado', 'historia', 'aire,', 'sigues...', 'ojos.', 'les', 'puedan', 'círculo', 'atardecer', 'mezclas', '(no', 'constante', 'mausoleo', 'han', 'actos', 'otoño,', 'llegar', 'ritmo', 'bohemia', 'cuello,', 'soledad', 'vuelta,', 'fuerte', 'tomarte', 'bailar', 'duradero', 'venido', 'presión', 'sean', 'perderme', 'perfumes', 'distancia', 'ti,', 'madrugada,', 'acerca', 'despacio', 'valentía', 'camino', 'eterno', 'realidad', 'lecho', 'copas', 'fija', 'olor', 'tanta', 'final', 'pequeñas', 'crea', 'entero,', 'nuevos', 'nuestros', 'mil', 'triste', 'anhelos.', 'pesar', 'simple', 'pura', 'conocer', 'esconden', 'repletas', 'noche;', 'excelsa', 'impiden', 'maravillas', 'ven', 'desnuda', 'desesperación', 'gota', 'breves', 'vida,', 'mía,', 'gusto', 'veo,', 'prisa,', 'muerte', 'sutil,', 'fría,', 'terciopelo,', 'flor', 'seda', 'fuerzas', 'caos', 'puertas', 'repleto', 'amar,', 'mujeres', 'belleza,', 'sí,', 'inefable', 'carne', 'tengo', 'lienzo', 'eclipse', '¿Estás', 'posaba', 'ropa,', 'vuela', 'bocas', 'gardenias', 'universo,', 'belleza', 'Tu', 'fondo', 'razón,', 'troncos', 'queda', 'placer...', 'máscaras,', 'eterna', 'anhelos,', 'hecha', 'forma', 'mañana', 'pensar', 'viajan', 'saltan', 'límite,', 'suerte', 'fin', 'saber', 'felizmente', 'pintura', 'tirando', 'estás', 'dolor', 'sí', 'ilumina', 'observas', 'estancia', 'Qué', 'base', 'total', 'única', 'destino', 'sola', 'nadie', 'incesante', 'Siente', 'respiro,', 'perderse', 'aquel', 'Hoy', 'completa', 'obra', 'pliegues;', 'llevarme', 'aviones', 'inundando', 'tibios', 'Eres', 'bailando', 'tranquilidad', 'siluetas', 'Regálame', 'tienes', 'Mujer,', 'deja', 'dar', 'danza', 'calles', 'júbilo', 'final.', 'vuelven', 'cielo,', 'pipa', 'transformar', 'amada', 'infinito.', 'concretar', 'razones,', 'sensaciones', 'iré', 'cromáticos,', 'esperaría', 'suspiro', 'dice', 'cigarrillo', 'fielmente', 'especie', 'envolvente', 'cuidando', 'vientos', 'trabajo.', 'olvidado', 'allí,', 'estucado', 'ecos', 'enlazan', 'retoma', 'estrellas,', 'arrulla', 'bifurcados...', 'Mira', 'pies', 'última', 'observa', 'quizá', 'bonito', 'espejos', 'nadan', 'recuerdo', 'Soñaré', 'otoño', 'furia', 'musas', 'alba.', 'van', 'llueve', 'imagen,', 'conciencia', 'universo', 'dedos', 'Seremos', 'ellos,', 'suelo,', 'repente', 'espacio,', 'sienten', 'pintar', 'milongas', 'miedos,', 'tratan', 'habitación', 'tiene', 'sabor', 'duerme...', 'Entre', 'conciencia.', 'Sin', 'suelo', 'importar', 'crueldad', 'rota', 'darle', 'tibio,', 'culpas,', 'existirá', 'duda', 'hablo,', 'inerte.', 'recurso,', 'golondrinas,', 'extinción', 'déjame', 'versos,', 'así...', 'magia', 'quiere', 'Así', 'fluye', 'demencial.', 'Piazzolla', 'dulces', 'pensamiento,', 'milonga...', 'obra,', 'pintura,', 'pincel.', 'estoy', 'eco', 'muerte.', 'Esa', 'susurra', 'lejanía.', 'mares', 'jugaban', 'indiferencia,', 'confesar,', 'vengador,', 'inunda', 'exquisito', 'ventanas', 'están', 'modernidad...', 'sacudir...', 'vidrio', 'habrán', 'pasa,', 'adicta', 'vueltas', 'Vuélvete', 'mundo,', 'basura', 'hablan', 'libros', 'acercando', 'angustia,', 'moralidad', 'sistema', 'contaminadas', 'fábulas', 'allá,', 'sexual', 'Entonces', 'vaivén', 'aquí', 'cuerpos,', 'alegrías', 'figuras', 'placeres,', 'moldes', 'decirte', 'río', 'iniciado', 'torneado', 'engaño,', 'bossa,', 'minutos', 'controlado', 'efímeras,', 'ciclo', 'tristezas,', 'sed', 'mentiras,', 'escapar,', 'decir', 'momento', 'placer,', 'refiero.', 'cariño,', 'desespero', 'letras,', 'bella', 'escorpiones,', 'calmar', 'rocosa,', 'dirigirte', 'Una', 'mirarte', 'haciendo', 'gozo', 'sucios', 'valles', 'sábanas', 'vive', 'juego', 'refleja,', 'tiempo.', 'huesos', 'dragones', 'sábana...', 'recorriendo', 'propia', 'llegue', '(la', 'arena', 'mutan', 'repetición,', 'Despertemos', 'dejar', 'dormir', 'recordarás.', 'cuello', 'monstruo', 'jardín', 'aquello', '¿Lo', 'ves?', 'fantasea', 'ráfagas', 'igual.', 'loco', 'Las', 'satisfacer', 'sombra', 'mujer,', 'volátil.', 'último', 'Más', 'tumultuosas,', 'siento', 'ramas', 'fíjate,', 'grabado', 'Cuando', 'quedar', 'voy', 'ajenos...', 'multiplica', 'manera', 'combina', 'convertirá', 'aguarda']
len(model.words)
184
soy_vector = model.get_word_vector("soy")
soy_vector
array([-3.0347307e-03, 6.1599063e-03, -1.3848637e-03, -3.1608273e-03, 6.5026223e-03, 6.3184551e-03, -4.6846778e-03, -2.2446606e-03, 8.9806495e-03, 3.7756080e-03, 1.1548055e-03, -4.1064568e-04, 1.2033727e-03, 7.6985159e-03, -5.0652046e-03, -2.6354317e-03, -2.4917696e-03, 7.0066674e-04, -6.4257701e-04, -4.5810528e-03, 7.7987812e-04, 2.5302153e-03, 1.4552932e-03, -3.1920432e-03, 4.0789871e-03, -2.7199865e-03, 3.3235915e-03, -2.0251921e-03, -2.2953239e-03, 6.2371460e-03, -3.2799956e-03, 8.9811842e-04, -2.5823724e-03, -4.4579767e-03, -7.3911683e-03, -1.6582392e-04, 2.8145671e-04, -3.2918619e-03, -2.6939313e-03, -5.1317532e-03, 2.5532853e-03, 6.5070619e-03, 1.0551591e-03, 3.2300127e-03, -1.1547272e-03, -1.2535534e-03, 1.4361716e-03, 1.7629942e-03, -2.8988889e-03, 2.0974237e-03, -5.8227698e-03, 8.1397137e-03, -2.8023466e-03, 9.3555875e-04, -5.7098031e-04, -1.3912616e-03, -2.5984519e-03, -1.8401010e-03, 4.7945334e-03, 4.0792683e-03, -9.1515179e-04, 1.2824327e-03, 8.2337502e-03, 3.5726540e-03, 1.2970364e-03, -7.8641268e-04, -4.6819295e-03, -2.3468505e-04, 1.1813758e-03, 2.1915610e-03, -5.0192545e-03, 5.6051221e-03, 3.9733844e-03, -1.9811334e-03, -3.3446504e-03, -4.9200305e-04, 8.0256257e-03, 3.2809959e-03, 2.6104650e-03, -1.7321646e-03, 2.1246636e-04, 2.4007384e-03, 7.8085684e-03, -2.1588639e-03, -1.0148875e-03, -6.3766371e-03, 7.4433633e-06, 4.0005501e-03, -2.1610935e-03, -1.7342754e-03, 9.3174335e-03, 4.0063281e-03, 5.8194166e-03, -6.3449475e-03, 3.4241099e-03, -5.0236946e-03, 5.8575752e-03, 1.3908240e-03, -8.8924175e-04, -1.1105216e-03], dtype=float32)
soy_vector.shape
(100,)
model.save_model("../Modelos/Poemas.bin")
model = ft.load_model("../Modelos/Poemas.bin")
Por defecto, el modelo entrenado es skip-gram, pero también tenemos disponible la arquitectura cbow.
Modelos BOW y Skip-gram
Fuente: Alvaro Montenegro
# model_cbow = fasttext.train_unsupervised('../Datos/Poemas_Todo.txt', "cbow")
En palabras de Facebook,
*In practice, we observe that skipgram models works better with subword information than cbow.*
Dependiendo del problema, puede ser que los parámetros por defecto no sean los más adecuados.
Para conocer todos los parámetros de FastText, podemos ingresar aquí
Por ejemplo, modifiquemos los parámetros mínimos y máximos de los n-gramas permitidos, la dimensión del vector, las epochs y la frecuencia mínima de palabras:
import fasttext as ft
model = ft.train_unsupervised('../Datos/Poemas_Todo.txt', minCount=2, minn=2, maxn=5, dim=300)
Read 0M words Number of words: 846 Number of labels: 0 Progress: 100.0% words/sec/thread: 80034 lr: 0.000000 avg.loss: 3.471876 ETA: 0h 0m 0s
Verifiquemos la longitud de las palabras:
model.get_word_vector("soy").shape
(300,)
Como cada palabra en el corpus tiene un vector asociado, podemos obtener palabras cercanas usando la similitud de coseno:
model.get_nearest_neighbors('sueño')
[(0.999998927116394, 'sueño,'), (0.9999988079071045, 'sueños,'), (0.9999986290931702, 'contra'), (0.9999985694885254, 'sueños'), (0.9999983906745911, 'suelo,'), (0.9999983906745911, 'cielo'), (0.9999983906745911, 'mundo'), (0.9999982714653015, 'manera'), (0.9999982118606567, 'lienzo'), (0.9999982118606567, 'repletas')]
Primero que todo, obtengamos los datos que necesitamos:
# Corpus Completo
#!wget https://dumps.wikimedia.org/enwiki/latest/enwiki-latest-pages-articles.xml.bz2 -o ../Datos/enwiki-latest-pages-articles.xml.bz2
# Corpus 1 billón de bytes (1 Giga)
!wget -c http://mattmahoney.net/dc/enwik9.zip -P ../Datos
--2021-11-19 16:13:05-- http://mattmahoney.net/dc/enwik9.zip Resolving mattmahoney.net (mattmahoney.net)... 67.195.197.24 Connecting to mattmahoney.net (mattmahoney.net)|67.195.197.24|:80... connected. HTTP request sent, awaiting response... 206 Partial Content Length: 322592222 (308M), 294168810 (281M) remaining [application/zip] Saving to: ‘../Datos/enwik9.zip’ enwik9.zip 100%[+==================>] 307,65M 566KB/s in 8m 28s 2021-11-19 16:21:34 (565 KB/s) - ‘../Datos/enwik9.zip’ saved [322592222/322592222]
Como el formato viene en .zip
, descomprimamos el contenido
!unzip ../Datos/enwik9.zip -d ../Datos
Archive: ../Datos/enwik9.zip inflating: ../Datos/enwik9
Miremos algo de información:
!head -c 2000 ../Datos/enwik9
<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.3/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.3/ http://www.mediawiki.org/xml/export-0.3.xsd" version="0.3" xml:lang="en"> <siteinfo> <sitename>Wikipedia</sitename> <base>http://en.wikipedia.org/wiki/Main_Page</base> <generator>MediaWiki 1.6alpha</generator> <case>first-letter</case> <namespaces> <namespace key="-2">Media</namespace> <namespace key="-1">Special</namespace> <namespace key="0" /> <namespace key="1">Talk</namespace> <namespace key="2">User</namespace> <namespace key="3">User talk</namespace> <namespace key="4">Wikipedia</namespace> <namespace key="5">Wikipedia talk</namespace> <namespace key="6">Image</namespace> <namespace key="7">Image talk</namespace> <namespace key="8">MediaWiki</namespace> <namespace key="9">MediaWiki talk</namespace> <namespace key="10">Template</namespace> <namespace key="11">Template talk</namespace> <namespace key="12">Help</namespace> <namespace key="13">Help talk</namespace> <namespace key="14">Category</namespace> <namespace key="15">Category talk</namespace> <namespace key="100">Portal</namespace> <namespace key="101">Portal talk</namespace> </namespaces> </siteinfo> <page> <title>AaA</title> <id>1</id> <revision> <id>32899315</id> <timestamp>2005-12-27T18:46:47Z</timestamp> <contributor> <username>Jsmethers</username> <id>614213</id> </contributor> <text xml:space="preserve">#REDIRECT [[AAA]]</text> </revision> </page> <page> <title>AlgeriA</title> <id>5</id> <revision> <id>18063769</id> <timestamp>2005-07-03T11:13:13Z</timestamp> <contributor> <username>Docu</username> <id>8029</id> </contributor> <minor /> <comment>addi
Como un archivo raw de Wikipedia contiene toneladas de datos HTML/XML, preprocesaremos la información con el archivo wikifil.pl, escrito por Matt Mahoney y puede ser encontrado el script original en su página personal aquí.
El script asociado funciona usando el lenguaje de programación PERL, y se ejecuta a continuación:
!perl ../Datos/wikifil.pl ../Datos/enwik9 > ../Datos/fil9
Podemos ver algo del resultado obtenido con el siguiente comando:
#!head -c 2000 ../Datos/fil9
model = ft.train_unsupervised('../Datos/fil9')
Read 124M words3M words Number of words: 218316 Number of labels: 0 Progress: 31.5% words/sec/thread: 45623 lr: 0.034237 avg.loss: 0.601562 ETA: 0h51m49sm 8s lr: 0.049049 avg.loss: 1.546121 ETA: 1h16m37s 1.495166 ETA: 1h17m48s 4.0% words/sec/thread: 42449 lr: 0.047977 avg.loss: 1.451111 ETA: 1h18m 2s words/sec/thread: 42355 lr: 0.046572 avg.loss: 1.341497 ETA: 1h15m55sh16m 3s% words/sec/thread: 44134 lr: 0.045075 avg.loss: 1.130582 ETA: 1h10m31s 16.0% words/sec/thread: 45933 lr: 0.041981 avg.loss: 0.870252 ETA: 1h 3m 6s 17.8% words/sec/thread: 45410 lr: 0.041112 avg.loss: 0.814919 ETA: 1h 2m31sh 2m25s 44928 lr: 0.038916 avg.loss: 0.719204 ETA: 0h59m48s57m30s 25.7% words/sec/thread: 45038 lr: 0.037161 avg.loss: 0.668852 ETA: 0h56m58s 0h54m58s 0.035755 avg.loss: 0.635238 ETA: 0h54m46s 30.9% words/sec/thread: 45385 lr: 0.034537 avg.loss: 0.608555 ETA: 0h52m32s
model.get_nearest_neighbors('asparagus')
model.get_nearest_neighbors('pidgey')
model.get_analogies("berlin", "germany", "france")
Para este ejemplo, usaremos el conjunto de datos de preguntas de the cooking section of Stackexchange:
!wget https://dl.fbaipublicfiles.com/fasttext/data/cooking.stackexchange.tar.gz && tar xvzf cooking.stackexchange.tar.gz
!head cooking.stackexchange.txt
!wc cooking.stackexchange.txt
!head -n 12404 cooking.stackexchange.txt > cooking.train
!tail -n 3000 cooking.stackexchange.txt > cooking.valid
import fasttext as ft
model = fasttext.train_supervised(input="cooking.train")
model.predict("Which baking dish is best to bake a banana bread ?")
model.test("cooking.valid")
!cat cooking.stackexchange.txt | sed -e "s/\([.\!?,'/()]\)/ \1 /g" | tr "[:upper:]" "[:lower:]" > cooking.preprocessed.txt
!head -n 12404 cooking.preprocessed.txt > cooking.train
!tail -n 3000 cooking.preprocessed.txt > cooking.valid
model = fasttext.train_supervised(input="cooking.train")
model.test("cooking.valid")
model = fasttext.train_supervised(input='cooking.train', autotuneValidationFile='cooking.valid')
model.test("cooking.valid")