Usamos un pequeño conjunto de datos proporcionado por Kavle Leetaru para ilustrar la API de Timeseries Insights. El conjunto de datos se deriva del proyecto GDETX, una base de datos global que realiza un seguimiento de los eventos mundiales y la cobertura de los medios. Este conjunto de datos contiene las menciones de entidades en las URL de noticias de abril de 2019.
Objetivos
- Conoce el formato de datos para la API de Timeseries Insights.
- Aprende a crear, consultar, actualizar y borrar conjuntos de datos.
Costos
La vista previa no tiene costo.
Antes de comenzar
Configura un proyecto de Cloud y habilita la API de Series Series Insights en Primeros pasos.
Conjunto de datos del instructivo
El conjunto de datos incluye anotaciones de entidades sobre ubicaciones, organizaciones, personas, entre otras.
La API de Timeseries Insights toma entradas de formato JSON. Un Event de muestra para este conjunto de datos es
{
"groupId":"-6180929807044612746",
"dimensions":[{"name":"EntityORGANIZATION","stringVal":"Medina Gazette"}],
"eventTime":"2019-04-05T08:00:00+00:00"
}
Cada evento debe tener un campo eventTime
para la marca de tiempo del evento y un groupId
con valor largo a fin de marcar eventos relacionados. Las propiedades de eventos se incluyen como dimensions
, cada una de las cuales tiene un name
y uno de stringVal
, boolVal
, longVal
o doubleVal
.
NOTA: Las API de Google Cloud aceptan mayúsculas y minúsculas (como camelCase
) y caso de serpiente (como snake_case
) para los nombres de campo JSON. Por lo general, las documentación se escriben como mayúsculas camellos.
NOTA: Debido a que los valores largos JSON (números) son valores flotantes con solo precisións de números enteros, groupId
y longVal
están efectivamente limitados a 53 dígitos binarios si JSON. utiliza números. Para proporcionar datos int64, el valor JSON debe estar entre comillas. Una groupId
suele ser un ID numérico o se genera con una función hash determinista, lo que cumple con la restricción anterior.
NOTA: Se supone que los campos name
y stringVal
son valores alfanuméricos, incluido '_'
. No se admiten los caracteres especiales, incluido el espacio.
NOTA: Cuando se lee desde una fuente de datos estática de Google Cloud Storage, se supone que cada evento JSON es una sola línea de la siguiente manera:
{"groupId":"-6180929807044612746","dimensions":[{"name":"EntityORGANIZATION","stringVal":"Medina Gazette"}],"eventTime":"2019-04-05T08:00:00+00:00"}
Mostrar lista de conjuntos de datos
projects.datasets.list muestra todos los conjuntos de datos en ${PROJECT_ID}
. Ten en cuenta que gcurl
es un alias y PROJECT_ID
es una variable de entorno que se configura en Primeros pasos.
$ gcurl https://timeseriesinsights.googleapis.com/v1/projects/${PROJECT_ID}/datasets
El resultado es una string JSON como la siguiente:
{
"datasets": [
{
"name": "example",
"state": "LOADED",
...
},
{
"name": "dataset_tutorial",
"state": "LOADING",
...
}
]
}
Los resultados muestran los conjuntos de datos que se encuentran actualmente en el proyecto. El campo state
indica si el conjunto de datos está listo para usarse. Cuando se crea un conjunto de datos, está en el estado LOADING
hasta que se completa la indexación y, luego, pasa al estado LOADED
. Si se produce algún error durante la creación y la indexación, estará en estado FAILED
. El resultado también incluye la información completa del conjunto de datos de la solicitud de creación original.
Crear un conjunto de datos
projects.datasets.create agrega un conjunto de datos nuevo al proyecto.
$ gcurl -X POST -d @create.json https://timeseriesinsights.googleapis.com/v1/projects/${PROJECT}/datasets
donde create.json
contiene lo siguiente:
{
name: "dataset_tutorial",
streaming: true,
ttl: "8640000s",
dataNames: [
"EntityCONSUMER_GOOD",
"EntityEVENT",
"EntityLOCATION",
"EntityORGANIZATION",
"EntityOTHER",
"EntityPERSON",
"EntityUNKNOWN",
"EntityWORK_OF_ART",
],
dataSources: [
{uri: "gs://data.gdeltproject.org/blog/2021-timeseries-insights-api/datasets/webnlp-201904.json"}
]
}
Esta solicitud crea un conjunto de datos llamado dataset_tutorial
a partir de GCS dataSources
, que contiene datos de evento en formato JSON. El sistema solo indexa y usa las dimensiones que aparecen en dataNames
. Si es streaming=true
, el conjunto de datos también acepta actualizaciones de transmisión después de que se completa la indexación inicial.
Sin embargo, se ignoran las actualizaciones de transmisión que tienen más de ttl
de antig.edad.
La solicitud de creación muestra éxito si el servidor de la API la acepta. El conjunto de datos estará en estado LOADING
hasta que se complete la indexación; luego, el estado se convierte en LOADED
y comienza a aceptar consultas y actualizaciones si hay alguna.
Conjunto de datos de consulta
projects.datasets.query realiza consultas de detección de anomalías.
$ gcurl -X POST -d @query.json https://timeseriesinsights.googleapis.com/v1/projects/${PROJECT}/datasets/dataset_tutorial:query
donde query.json
contiene lo siguiente:
{
dimensionNames: ["EntityLOCATION"],
testedInterval: {
startTime: "2019-04-15T00:00:00Z",
length: "86400s"
},
forecastParams: {
holdout: 10,
minDensity: 0,
forecastHistory: "1209600s",
maxPositiveRelativeChange: 1,
maxNegativeRelativeChange: 1,
forecastExtraWeight: 0,
seasonalityHint: "DAILY",
},
returnNonAnomalies: true
}
Queremos detectar si se produjo alguna anomalía durante el testedInterval
para las divisiones en las dimensiones proporcionadas por dimensionNames
. Un slice es un subconjunto de eventos en el conjunto de datos con valores fijos para algunas de sus dimensiones. Por ejemplo, {"name": "EntityLOCATION","stringVal": "Seine River"}
es una porción. Cualquier subconjunto de dataNames
de la definición del conjunto de datos se puede usar como dimensionNames
, la API agregará el evento sobre las dimensiones no mencionadas.
Esto es similar a una operación de "agrupar por" con "recuento(*)" en consultas de SQL.
Los eventos de cada una de las porciones se agregan en función de forecastParams.aggregatedDimension
. Si este campo está vacío, simplemente registraremos todos los eventos en la porción. Si no está vacío, esperamos que este campo sea un nombre de dimensión numérico válido presente en los eventos de esta porción.
Los valores numéricos se suman para formar la serie temporal.
Analizaremos cada porción para comprobar si es una anomalía por:
- Formar una serie temporal que va de
testedInterval.startTime - forecastParams.forecastHistory
atestedInterval.startTime + testedInterval.length
, en la que cada dato es un depósito de tiempo detestedInterval.length
y tiene su valor dado mediante la agregación de los eventos en ese depósito según lo especificado por el parámetroaggregatedDimension
. Si la serie temporal no tiene suficientes datos (como se especifica en el parámetrominDensity
), dejaremos de analizarla. - Una vez que calculamos la serie temporal para la porción, la analizaremos mediante técnicas de previsión comunes. El primer
(100 - holdout)%
de la serie temporal se usa para entrenar un modelo de predicción y se usa el últimoholdout%
a fin de probar la calidad del modelo. En función de las métricas de error, calcularemos los límites de confianza para el intervalo probado y, si el valor real no se encuentra dentro de estos límites por más de lo configurado, lo marcaremos de forma nominal. Para configurar la medida que el valor real puede estar fuera de los límites, verifica los parámetrosmaxPositiveRelativeChange
,maxNegativeRelativeChange
yforecastExtraWeight
.
El resultado de la consulta se ve de la siguiente manera:
{
"name": "projects/timeseries-staging/datasets/dataset_tutorial",
"anomalyDetectionResult": {
"anomalies": [
{
"dimensions": [
{
"name": "EntityLOCATION",
"stringVal": "Ile de la Cite"
}
],
"result": {
"holdoutErrors": {},
"trainingErrors": {
"mdape": 1,
"rmd": 1
},
"forecastStats": {
"density": "23",
"numAnomalies": 1
},
"testedIntervalActual": 440,
"testedIntervalForecastLowerBound": -1,
"testedIntervalForecastUpperBound": 1
},
"status": {}
},
{
"dimensions": [
{
"name": "EntityLOCATION",
"stringVal": "Seine"
}
],
"result": {
"holdoutErrors": {
"mdape": 0.1428571428571429,
"rmd": 0.1428571428571429
},
"trainingErrors": {
"mdape": 0.84615384615384626,
"rmd": 0.62459546925566334
},
"forecastStats": {
"density": "85",
"numAnomalies": 1
},
"testedIntervalActual": 586,
"testedIntervalForecast": 9.3333333333333339,
"testedIntervalForecastLowerBound": 8,
"testedIntervalForecastUpperBound": 10.666666666666668
},
"status": {}
},
{
"dimensions": [
{
"name": "EntityLOCATION",
"stringVal": "Notre Dame"
}
],
"result": {
"holdoutErrors": {
"mdape": 0.42857142857142855,
"rmd": 0.42857142857142855
},
"trainingErrors": {
"mdape": 0.19999999999999996,
"rmd": 0.65055762081784374
},
"forecastStats": {
"density": "100",
"numAnomalies": 1
},
"testedIntervalActual": 790,
"testedIntervalForecast": 7,
"testedIntervalForecastLowerBound": 4,
"testedIntervalForecastUpperBound": 10
},
"status": {}
},
...
],
"nonAnomalies": [
...
]
}
}
Contiene anomalías y, de manera opcional, evalúa las porciones que no se marcaron como anomalías, en el mismo formato de ForeSlicelice. result
muestra la hora de la anomalía, el valor real y el rango de valores de previsión. trainingErrors
y holdoutErrors
muestran métricas adicionales que se usan para la detección de anomalías.
Actualización de la transmisión
projects.datasets.appendEvents agrega registros de evento de forma de transmisión si la solicitud de creación especifica streaming: true
.
$ gcurl -X POST -d @append.json https://timeseriesinsights.googleapis.com/v1/projects/${PROJECT}/datasets/dataset_tutorial:appendEvents
donde append.json
contiene lo siguiente:
{
events: [
{
"groupId":"-5379487492185488040",
"dimensions":[{"name":"EntityPERSON","stringVal":"Jason Marsalis"}],
"eventTime":"2021-06-01T15:45:00+00:00"
},{
"groupId":"1324354349507023708",
"dimensions":[{"name":"EntityORGANIZATION","stringVal":"WAFA"}],
"eventTime":"2021-06-02T04:00:00+00:00"
}
]
}
Las actualizaciones transmitidas se indexan casi en tiempo real para que los cambios puedan responder con rapidez en los resultados de la consulta.
Borrar conjunto de datos
projects.datasets.delete marca el conjunto de datos para la eliminación.
$ gcurl -X DELETE https://timeseriesinsights.googleapis.com/v1/projects/${PROJECT}/datasets/dataset_tutorial
La solicitud se muestra de inmediato y el conjunto de datos no aceptará consultas ni actualizaciones adicionales. Puede tomar un tiempo hasta que los datos se quiten completamente del servicio, después de lo cual los conjuntos de datos de List no mostrarán este conjunto de datos.
¿Qué sigue?
- Conceptos de la API de estadísticas de serie temporal
- Una guía de compilación de consultas
- Obtén más información sobre la API de REST
Puedes encontrar otros ejemplos en el sitio web de GDETX.