En las últimas semanas, he estado trabajando en Gearlytics, un proyecto que entre tantas características, tiene un monitor de sentimiento que evalúa las opiniones de un público sobre un producto o tópico en las redes sociales.

Como desarrollador, no tenía ninguna experiencia previa con el mundo del Procesamiento de Lenguaje Natural dado a que esto es más un campo de un científico de datos, sin embargo, era el momento oportuno para aprender algo nuevo y debo admitir que este tema me ha apasionado.

Como pequeña introducción, el Procesamiento de Lenguaje Natural (NLP por sus siglas en inglés), es un campo del Machine Learning, el cual a su vez es un campo de la Inteligencia Artificial, y se basa en el análisis de textos, para entre tantas cosas, reconocer entidades, analizar la sintaxis, detectar el idioma, clasificar el contenido y por supuesto, conocer el sentimiento.

El análisis de sentimiento nos permite conocer la opinión, sensación, actitud general que se desprende de un texto y clasificarlo por Positivo, Negativo y Neutral e incluso en algunos casos también por Combinado, que es una especie de texto cuya cantidad de sentencias Positivas y Negativas se cancelan entre sí. Si se requiere ser más específico al costo de complejidad, según la fuerza total de emoción se puede granular aún más y clasificar por Muy Positivo, Positivo, Neutral, Negativo y Muy Negativo, que casualmente coincide con un sistema de opinión basado en 5 estrellas.

Si bien los servicios de análisis de sentimiento de Amazon y Google son bastante buenos, de bajo costo y fácil de interactuar con sus API, cada uno tiene sus diferencias, por ejemplo, Amazon Comprehend devuelve la etiqueta (Positivo, Negativo, Neutral o Combinado) con la cual clasificó el texto, además del score con la probabilidad de cada etiqueta. Google Natural Language por su parte no responde la etiqueta sino que devuelve el score el cual difiere del de Amazon, dado a que es un número que oscila entre -1.0 y 1.0, siendo -1.0 muy negativo y 1.0 muy positivo, por lo que es necesario hacer manualmente un umbral que defina qué rango es considerado como Positivo, Neutral o Negativo. Además, nos devuelve un valor magnitude, que es la fuerza total de emoción, cuyo valor puede ir de 0 a infinito, con el que podemos mejorar nuestro umbral para clasificar también Muy Positivo y Muy Negativo, e incluso Combinado.

Para comparar estos dos servicios, voy a mostrar unas pruebas que fueron hechas con textos en español relacionados con el Parque nacional El Ávila, Caracas y fueron extraídos de Facebook. Asimismo, el umbral que voy a utilizar para Google, es el siguiente: NEGATIVE: -1.00 a -0.25, NEUTRAL: -0.24 a 0.24, POSITIVE: 0.25 a 1.00. Cabe mencionar que para no complicar los ejemplos, no voy a considerar el valor magnitude de Google.

Texto 1: Hermosaaaaaa la Sultana del Ávila

Google:

document_sentiment {
  magnitude: 0.10000000149011612
  score: 0.10000000149011612
}
language: "es"
sentences {
  text {
    content: "Hermosaaaaaa la Sultana del \303\201vila"
    begin_offset: -1
  }
  sentiment {
    magnitude: 0.10000000149011612
    score: 0.10000000149011612
  }
}
Sentimiento: NEUTRAL

Amazon:

{
    "Sentiment": {
        "Sentiment": "POSITIVE",
        "SentimentScore": {
            "Positive": 0.9807137846946716,
            "Negative": 0.00012411650095600635,
            "Neutral": 0.019138945266604424,
            "Mixed": 0.000023144522856455296
        }
    }
}
Sentimiento: POSITIVE

Texto 2: Bella Caracas, la cuna del libertador Simón Bolívar. Te queremos libre.

Google:

document_sentiment {
  magnitude: 1.0
  score: 0.5
}
language: "es"
sentences {
  text {
    content: "Bella Caracas, la cuna del libertador Sim\303\263n Bol\303\255var."
    begin_offset: -1
  }
  sentiment {
    magnitude: 0.800000011920929
    score: 0.800000011920929
  }
}
sentences {
  text {
    content: "Te queremos libre."
    begin_offset: -1
  }
  sentiment {
    magnitude: 0.10000000149011612
    score: 0.10000000149011612
  }
}
Sentimiento: POSITIVE

Amazon:

{
    "Sentiment": {
        "Sentiment": "NEUTRAL",
        "SentimentScore": {
            "Positive": 0.3058735430240631,
            "Negative": 0.02366298995912075,
            "Neutral": 0.42997294664382935,
            "Mixed": 0.24049054086208344
        }
    }
}
Sentimiento: NEUTRAL

Texto 3: Caracas con su verdor y su clima. Queremos verla libre para que recupere la majestuosidad que hizo que la llamaran la sucursal del cielo.

Google:

document_sentiment {
  magnitude: 1.100000023841858
  score: -0.10000000149011612
}
language: "es"
sentences {
  text {
    content: "Caracas con su verdor y su clima."
    begin_offset: -1
  }
  sentiment {
    magnitude: 0.4000000059604645
    score: 0.4000000059604645
  }
}
sentences {
  text {
    content: "Queremos verla libre para que recupere la majestuosidad que hizo que la llamaran la sucursal del cielo."
    begin_offset: -1
  }
  sentiment {
    magnitude: 0.699999988079071
    score: -0.699999988079071
  }
}
Sentimiento: NEUTRAL

Amazon:

{
    "Sentiment": {
        "Sentiment": "POSITIVE",
        "SentimentScore": {
            "Positive": 0.6664101481437683,
            "Negative": 0.002541585825383663,
            "Neutral": 0.33104294538497925,
            "Mixed": 0.000005248648903943831
        }
    }
}
Sentimiento: POSITIVE

Texto 4: Que bellisima! Como te extraño mi adorada Caracas! Te volvere a ver algun dia...

Google:

document_sentiment {
  magnitude: 1.5
  score: 0.5
}
language: "es"
sentences {
  text {
    content: "Que bellisima!"
    begin_offset: -1
  }
  sentiment {
    magnitude: 0.8999999761581421
    score: 0.8999999761581421
  }
}
sentences {
  text {
    content: "Como te extra\303\261o mi adorada Caracas!"
    begin_offset: -1
  }
  sentiment {
  }
}
sentences {
  text {
    content: "Te volvere a ver algun dia..."
    begin_offset: -1
  }
  sentiment {
    magnitude: 0.5
    score: 0.5
  }
}
Sentimiento: POSITIVE

Amazon:

{
    "Sentiment": {
        "Sentiment": "POSITIVE",
        "SentimentScore": {
            "Positive": 0.974430501461029,
            "Negative": 0.0011621364392340183,
            "Neutral": 0.022700805217027664,
            "Mixed": 0.0017064836574718356
        }
    }
}
Sentimiento: POSITIVE

Texto 5: La más maravillosa vista que tengo todas las mañanas desde mi ventana. Tengo el honor de verlo de punta a punta y disfrutarlo.

Google:

document_sentiment {
  magnitude: 1.399999976158142
  score: 0.699999988079071
}
language: "es"
sentences {
  text {
    content: "La m\303\241s maravillosa vista que tengo todas las ma\303\261anas desde mi ventana."
    begin_offset: -1
  }
  sentiment {
    magnitude: 0.8999999761581421
    score: 0.8999999761581421
  }
}
sentences {
  text {
    content: "Tengo el honor de verlo de punta a punta y disfrutarlo."
    begin_offset: -1
  }
  sentiment {
    magnitude: 0.5
    score: 0.5
  }
Sentimiento: POSITIVE

Amazon:

{
    "Sentiment": {
        "Sentiment": "POSITIVE",
        "SentimentScore": {
            "Positive": 0.9985781908035278,
            "Negative": 0.00009022330050356686,
            "Neutral": 0.0013302259612828493,
            "Mixed": 0.0000012950898735653027
        }
    }
}
Sentimiento: POSITIVE

Como podemos observar, Google y Amazon tienden a clasificar diferente en algunos casos. En mi opinión, Amazon ofrece un servicio listo para usar que pareciera que tiende a ser más preciso, pero por otro lado, Google da la libertad de poder jugar con los umbrales, lo cual puedes adaptar a una audiencia específica.

El análisis de sentimiento es muy subjetivo y los buenos resultados dependen de muchos factores, por ejemplo, la calidad del texto que se está evaluando. Textos en donde no se respeten los signos de puntuación o que contengan errores ortográficos tienden a resultar en un análisis de sentimiento erróneo.

En un principio, Gearlytics comenzó utilizando los servicios de NLP de Amazon y Google pero a medida que buscábamos desarrollar un producto único y agregarle un valor aún mayor, fue necesario comenzar a entrenar nuestros propios modelos de análisis de sentimiento que fuesen más orientados a un contexto particular, ya que no es lo mismo evaluar el sentimiento de un público que está opinando sobre política a otro que esté opinando sobre marketing, o peor aún cuando tenemos públicos que se expresan distinto según su país de origen.

Entrenar un modelo es un proceso mucho más complejo, ya que requiere en un principio de mucho trabajo manual, muchas iteraciones para perfeccionar la máquina y en general es mucho más costoso en recursos que utilizar uno de estos servicios como los de Amazon y Google los cuales son bastante buenos para comenzar.