Seleccionar página

La intuición nos puede fallar

En la búsqueda de las características que mejor definan un documento de texto, la intuición se puede cruzar y llevarnos por caminos por los que no queríamos transitar. Por ejemplo, si queremos encontrar las palabras más significativas de un documento, la intuición nos dice que lo lógico sería buscar aquellas que aparecen con más frecuencia, pero esa estrategia puede que nos esté llevando precisamente en la dirección contraria.

Estamos asumiendo que nuestro corpus ya ha sido limpiado y no tiene las ruidosas stop words, así que damos por hecho que las palabras que aparecen con más frecuencia nunca serán del estilo de «el, la, los, la, en, a, …..».

Aún habiendo limpiado el corpus de stop words, la aparición frecuente de una palabra no tiene por qué estar asociada con su importancia. Por ejemplo, la palabra «cambio» es una palabra que podría aparecer con frecuencia en documentos relacionados con el deporte y realmente no nos diga nada relevante entre unos documentos y otros. Si quisiéramos clasificar los documentos por el deporte del que hablan, la palabra «cambio» puede que no sea de utilidad, a pesar de su frecuencia. En el otro extremo, y siguiendo con la analogía de documentos relacionados con deporte, la palabra «esperpéntico» seguramente aparecerá muy rara vez, pero tampoco nos va a indicar nada relevante, ya que es improbable que aparezca de forma consistente. Pero, ¿qué pasaría con la palabra «cuarto»? Es una palabra que puede que no aparezca un gran número de veces por documento, pero que sistemáticamente aparezca en todos (o casi todos) los documentos.

¿Tendremos que buscar entonces las palabras raras? ¿O quizás un punto intermedio?

Por tanto, necesitamos medios para identificar y cuantificar la importancia de las palabras en los documentos.

TF-IDF

Nos vemos en la obligación de tener que recurrir a aspectos más teóricos, pero intentaremos que sea lo menos doloroso posible.

TF-IDF significa Term Frequency times Inverse Document Frequency (es decir, TF x IDF) y es una métrica o score que establece un valor sobre la importancia de una palabra («p») en un documento («p»). Aquí term es análogo a palabra. Es decir, la palabra p para el documento d1 puede tener un score diferente al que tenga para el documento d2.

Esta métrica está compuesta por dos factores, como se puede ver en la fórmula: TF e IDF. Vayamos uno por uno:

  • TF recoge la frecuencia de la palabra p en el documento d, normalizado sobre el máximo número de ocurrencias de cualquier palabra en el documento d. Así que hablamos de TFp,d = fp,d / maxk fk,d:
    • fp,d indica el número de ocurrencias de la palabra d en el documento p.
    • maxk fk,d indica el máximo número de ocurrencias de cualquier palabra (k) en el documento d.
  • IDF recoge el número de documentos en los que la palabra p aparece (con independencia del número de veces que aparezca). Así que hablamos de IDFd = log2 (N/nd):
    • N es el número total de documentos.
    • nes número de documentos en los que aparece la palabra d.

Por cada palabra p presente en el documento p se hace el cálculo  TFp,d x IDFd y las palabras con mejor métrica / score serán las que mejor caracterizarán los temas que se tratan en cada documento.

Un poco de agua para aliviar el susto

Después de esta dosis de teoría, lo mejor es poner los conceptos en práctica. Esta vez, vamos a reproducir completamente el épico diálogo de Groucho Marx en la película Una noche en la ópera. Cada frase es un documento del corpus:

– Haga el favor de poner atención en la primera cláusula porque es muy importante. Dice que… la parte contratante de la primera parte será considerada como la parte contratante de la primera parte. ¿Qué tal, está muy bien, eh?
– No, eso no está bien. Quisiera volver a oírlo.
– Dice que… la parte contratante de la primera parte será considerada como la parte contratante de la primera parte.
– Esta vez creo que suena mejor.
– Si quiere se lo leo otra vez.
– Tan solo la primera parte.
– ¿Sobre la parte contratante de la primera parte?
– No, solo la parte de la parte contratante de la primera parte.
– Oiga, ¿por qué hemos de pelearnos por una tontería como ésta? La cortamos.
– Sí, es demasiado largo. ¿Qué es lo que nos queda ahora?
– Dice ahora… la parte contratante de la segunda parte será considerada como la parte contratante de la segunda parte.
– Eso si que no me gusta nada. Nunca segundas partes fueron buenas. Escuche: ¿por qué no hacemos que la primera parte de la segunda parte contratante sea la segunda parte de la primera parte?»

Aqui también vamos a utilizar una librería de Scikit-learn de Python para tokenizar el corpus, pero la labor de separación en documentos y limpieza la hemos hecho manualmente (para no olvidarnos de cómo hacerlo). 

Documentos del corpus:

Documento 1 = haga el favor de poner atención en la primera cláusula porque es muy importante dice que la parte contratante de la primera parte será considerada como la parte contratante de la primera parte qué tal está muy bien eh

Documento 2 = no eso no está bien quisiera volver oírlo

Documento 3 = dice que la parte contratante de la primera parte será considerada como la parte contratante de la primera parte

Documento 4 = esta vez creo que suena mejor

Documento 5 = si quiere se lo leo otra vez

Documento 6 = tan solo la primera parte

Documento 7 = sobre la parte contratante de la primera parte

Documento 8 = no solo la parte de la parte contratante de la primera parte

Documento 9 = oiga por qué hemos de pelearnos por una tontería como ésta la cortamos

Documento 10 = sí es demasiado largo qué es lo que nos queda ahora

Documento 11 = dice ahora la parte contratante de la segunda parte será considerada como la parte contratante de la segunda parte

Documento 12 = eso si que no me gusta nada nunca segundas partes fueron buenas escuche por qué no hacemos que la primera parte de la segunda parte contratante sea la segunda parte de la primera parte

 

Palabras con mayor score por documento del corpus:

Documento 1 = [(‘parte’, 0.483654381731612), (‘primera’, 0.39534733460602467), (‘contratante’, 0.2635648897373498), (‘haga’, 0.23375166585608662), (‘favor’, 0.23375166585608662)]

Documento 2 = [(‘quisiera’, 0.5172566287016166), (‘volver’, 0.5172566287016166), (‘oírlo’, 0.5172566287016166), (‘bien’, 0.4442260012569211), (‘haga’, 0.0)]

Documento 3 = [(‘parte’, 0.7326850536625904), (‘primera’, 0.39927283340099023), (‘contratante’, 0.39927283340099023), (‘dice’, 0.26864011349325434), (‘considerada’, 0.26864011349325434)]

Documento 4 = [(‘creo’, 0.5172566287016166), (‘suena’, 0.5172566287016166), (‘mejor’, 0.5172566287016166), (‘vez’, 0.4442260012569211), (‘haga’, 0.0)]

Documento 5 = [(‘quiere’, 0.5364329212987224), (‘leo’, 0.5364329212987224), (‘vez’, 0.46069482409390994), (‘si’, 0.46069482409390994), (‘haga’, 0.0)]

Documento 6 = [(‘tan’, 0.656112696286408), (‘solo’, 0.5634772050709476), (‘primera’, 0.3698974076156291), (‘parte’, 0.33938985986097164), (‘haga’, 0.0)]

Documento 7 = [(‘parte’, 0.7920734454138474), (‘primera’, 0.4316362224548798), (‘contratante’, 0.4316362224548798), (‘haga’, 0.0), (‘favor’, 0.0)]

Documento 8 = [(‘parte’, 0.7980248010305959), (‘solo’, 0.4416442933270728), (‘primera’, 0.28991958808582435), (‘contratante’, 0.28991958808582435), (‘haga’, 0.0)]

Documento 9 = [(‘oiga’, 0.4472135954999579), (‘pelearnos’, 0.4472135954999579), (‘tontería’, 0.4472135954999579), (‘ésta’, 0.4472135954999579), (‘cortamos’, 0.4472135954999579)]

Documento 10 = [(‘demasiado’, 0.5172566287016166), (‘largo’, 0.5172566287016166), (‘queda’, 0.5172566287016166), (‘ahora’, 0.4442260012569211), (‘haga’, 0.0)]

Documento 11 = [(‘parte’, 0.6418660148662156), (‘segunda’, 0.5328339335697898), (‘contratante’, 0.34978147996650094), (‘ahora’, 0.2664169667848949), (‘dice’, 0.2353411717888399)]

Documento 12 = [(‘parte’, 0.5084810414242387), (‘segunda’, 0.42210671257335786), (‘primera’, 0.27709404624164236), (‘gusta’, 0.24575046764511696), (‘nunca’, 0.24575046764511696)]

A pesar de que nuestro corpus de documentos es insignificante, se puede apreciar claramente los scores de cada palabra dentro de cada documento.

TF-IDF sobre los programas electorales

Al igual que hicimos con otros métodos, es el momento de utilizar TF-IDF sobre los programas electorales de los partidos políticos que concurren a las elecciones del 10-N, y ver qué score obtienen las palabras más usadas. Hemos seguido el siguiente proceso:

  1. Aplicar los pasos que se detallan en este post (leer los ficheros de los programas, limpiarlos de caracteres extraños, dividir en palabras y eliminar las stop words).
  2. Identificar las 5 palabras con mayor score en cada sección del programa de cada partido.
  3. Identificar las 20 palabras con mayor score considerando el programa completo de cada partido.
  4. Juntar todas las palabras identificadas y comparar los resultados entre partidos.

 

Vamos a mirar los binomios de palabras

El método TD-IDF también se puede aplicar sobre binomios de palabras, es decir, sobre todos los pares de palabras que aparecen de forma consecutiva en los documentos de los programas de los partidos. De hecho, realizando este análisis sobre binomios, se pueden ver mayores diferencias entre los diferentes partidos.

Si te interesa el código, aquí lo tienes

Takeaway

Encontrar las palabras que mejor caracterizan un documento no es sencillo, y requiere aplicar métodos que sepan ponderar moderadas apariciones de las palabras de una forma más o menos consistente en los diferentes documentos que componen el corpus. TD-IDF nos aporta mejores resultados que BOW en este respecto, y en este post hemos presentado tanto los aspectos teóricos como su funcionamiento sobre corpus reales.

Nuevamente los gráficos que presentamos ofrecen la oportunidad de interaccionar para que podáis sacar vuestras propias conclusiones.

 



Ver en Kaggle