Menu

LUIS se va de vacaciones en agosto

Usamos LUIS (LUIS Language Understanding Intelligent Service) para detectar, entre otras cosas, cuándo un usuario introduce una fecha.

Si lo usamos con cultura es-ES, cuando el texto introducido contiene “agosto”, LUIS no es capaz de detectar la entidad preconstruida DateTimeV2.

Este caso sólo se da con el mes de agosto por escrito. Si escribimos 01/08/2018 lo pilla estupendamente. También detecta a la perfección el resto de los meses.

Echa un ojo al los valores que nos devuelve la entidad datetimeV2 hacemos la consulta “31 de agosto”:

 

"entities": [
{
  "entity": "31 de agosto",
  "type": "builtin.datetimeV2.date",
  "startIndex": 0,
  "endIndex": 11,
  "resolution": {
    "values": [
      {
        "timex": "XXXX-00-00",
        "type": "date",
        "value": "0002-01-01"
      }
    ]
  }
}

Algo de este tipo es lo que devuelve una consulta que va bien, e.g. “30 de julio”:

"entities": [
{
  "entity": "30 de julio",
  "type": "builtin.datetimeV2.date",
  "startIndex": 0,
  "endIndex": 10,
  "resolution": {
    "values": [
      {
        "timex": "XXXX-07-30",
        "type": "date",
        "value": "2017-07-30"
      },
      {
        "timex": "XXXX-07-30",
        "type": "date",
        "value": "2018-07-30"
      }
    ]
  }
}
]

El bug ya está reportado, peeero hasta que tengamos arreglado el fallito, hemos preparado una ñapilla, comúnmente llamada workaround.

Consiste en utilizar una expresión regular que capture las fechas que contengan “agosto”; y parsearlo a DateTime.

Aquí tienes:

private bool TryGetAugustDate(string query, out DateTime datetime)
    {
        datetime = DateTime.MinValue;
        Match match = Regex.Match(query,
            @"(^\s)?(?<DAY>([1-9]|[0-2][0-9])|3[0-1])\s?(de)?\sagosto(\sde)?(l)?(\s(?<YEAR>\d{2,4}))?",
            RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);

        if (match.Success)
        {
            int day = int.Parse(match.Groups["DAY"].ToString());
            int year;
            
            if (match.Groups["YEAR"].Success)
            {
                year = int.Parse(match.Groups["YEAR"].ToString());
            }
            else
            {
                if (DateTime.Now.Month < 8 || DateTime.Now.Month == 8 && DateTime.Now.Day <= day)
                    year = DateTime.Now.Year;
                else
                    year = DateTime.Now.Year + 1;
            }

            datetime = new DateTime(year, 8, day);
        }
        return datetime != DateTime.MinValue;
    }

Hacemos la llamada a este método cuando la cultura del hilo es es-ES, y la consulta que íbamos a hacer a LUIS contiene “agosto”.

Si se te ocurre alguna mejora, ¡dime!, que estamos todos aquí para aprender 😊