Wir verwenden ein kleines Dataset von Kalev Leetaru, um die TimeSeries Insights API zu veranschaulichen. Das Dataset wird aus dem GDELT-Projekt abgeleitet, einem globalen Datenbanksystem zum Erfassen globaler Ereignisse und Medienabdeckung. Dieses Dataset enthält Entitätserwähnungen in Nachrichten-URLs im April 2019.
Ziele
- Weitere Informationen zum Datenformat für TimeSeries Insights API.
- Hier erfahren Sie, wie Sie Datasets erstellen, abfragen, aktualisieren und löschen.
Kosten
Für die Vorschau fallen keine Kosten an.
Hinweis
Richten Sie ein Cloud-Projekt ein und aktivieren Sie die Timeseries Insights API nach Erste Schritte.
Anleitungs-Dataset
Das Dataset enthält Entitätsanmerkungen von Standorten, Organisationen, Personen usw.
Die Timeseries Insights API akzeptiert Eingaben im JSON-Format. Ein Beispiel-Ereignis für dieses Dataset:
{
"groupId":"-6180929807044612746",
"dimensions":[{"name":"EntityORGANIZATION","stringVal":"Medina Gazette"}],
"eventTime":"2019-04-05T08:00:00+00:00"
}
Jedes Ereignis muss ein eventTime
-Feld für den Ereigniszeitstempel und ein Long-groupId
-Wert haben, um zugehörige Ereignisse zu kennzeichnen. Ereigniseigenschaften sind im dimensions
enthalten, von denen jedes eine name
und einer der folgenden Werte hat: stringVal
, boolVal
, longVal
oder doubleVal
.
HINWEIS: Google Cloud APIs akzeptieren für JSON-Feldnamen sowohl den Kamelfall (z. B. camelCase
) als auch die Schleuse (z. B. snake_case
). Die Dokumentation wird hauptsächlich als Kamel geschrieben.
HINWEIS: Da lange JSON-Werte (Zahlen) Gleitkommawerte mit nur genauen Genauigkeiten sind,groupId
undlongVal
sind maximal 53 Ziffern, wenn JSON Zahlen verwendet. Zur Bereitstellung von Int64-Daten muss der JSON-Wert als String in Anführungszeichen gesetzt werden. Eine groupId
ist in der Regel eine numerische ID oder wird mit einer deterministischen Hash-Funktion generiert und erfüllt die obige Einschränkung.
HINWEIS:Die Felder name
und stringVal
sollten alphanumerische Werte sein, einschließlich '_'
. Sonderzeichen wie das Leerzeichen werden nicht unterstützt.
HINWEIS:Beim Lesen aus einer statischen Google Cloud Storage-Datenquelle sollte jedes JSON-Ereignis wie folgt eine Zeile darstellen:
{"groupId":"-6180929807044612746","dimensions":[{"name":"EntityORGANIZATION","stringVal":"Medina Gazette"}],"eventTime":"2019-04-05T08:00:00+00:00"}
Datasets auflisten
projects.datasets.list zeigt alle Datasets unter ${PROJECT_ID}
an. gcurl
ist ein Alias und PROJECT_ID
eine Umgebungsvariable, die beide unter Erste Schritte eingerichtet werden.
$ gcurl https://timeseriesinsights.googleapis.com/v1/projects/${PROJECT_ID}/datasets
Das Ergebnis ist ein JSON-String wie
{
"datasets": [
{
"name": "example",
"state": "LOADED",
...
},
{
"name": "dataset_tutorial",
"state": "LOADING",
...
}
]
}
Die Ergebnisse zeigen die Datasets, die sich derzeit unter dem Projekt befinden. Das Feld state
gibt an, ob das Dataset verwendet werden kann. Wenn ein Dataset gerade erstellt wird, befindet es sich im Status LOADING
, bis die Indexierung abgeschlossen ist und dann in den Status LOADED
wechselt. Wenn während der Erstellung und Indexierung Fehler auftreten, erhält sie den Status FAILED
. Das Ergebnis enthält auch die vollständigen Dataset-Informationen aus der ursprünglichen Erstellungsanfrage.
Dataset erstellen
projects.datasets.create fügt dem Projekt ein neues Dataset hinzu.
$ gcurl -X POST -d @create.json https://timeseriesinsights.googleapis.com/v1/projects/${PROJECT}/datasets
Dabei enthält create.json
Folgendes:
{
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"}
]
}
Diese Anfrage erstellt ein Dataset mit dem Namen dataset_tutorial
aus GCS dataSources
, das Ereignisdaten im JSON-Format enthält. Nur in dataNames
aufgeführte Dimensionen werden indexiert und vom System verwendet. Mit der Einstellung streaming=true
akzeptiert das Dataset auch Streaming-Updates, nachdem die erste Indexierung abgeschlossen ist.
Streaming-Updates, die älter als ttl
sind, werden ignoriert.
Die Erstellungsanfrage gibt Erfolg zurück, wenn sie vom API-Server akzeptiert wird. Das Dataset befindet sich im Status LOADING
, bis die Indexierung abgeschlossen ist. Der Status wird zu LOADED
und akzeptiert Anfragen und Aktualisierungen, sofern vorhanden.
Abfrage-Dataset
projects.datasets.query führt eine Anomalieerkennung durch.
$ gcurl -X POST -d @query.json https://timeseriesinsights.googleapis.com/v1/projects/${PROJECT}/datasets/dataset_tutorial:query
Dabei enthält query.json
Folgendes:
{
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
}
Wir möchten herausfinden, ob Anomalien in den testedInterval
für Segmente aufgetreten sind, die auf die von dimensionNames
angegebenen Dimensionen aufgeteilt sind. Ein Slice ist eine Untermenge der Ereignisse im Dataset, bei denen einige ihrer Dimensionen feste Werte haben. Beispielsweise ist {"name": "EntityLOCATION","stringVal": "Seine River"}
ein Segment. Jede Teilmenge von dataNames
aus der Dataset-Definition kann als dimensionNames
verwendet werden. Die API aggregiert das Ereignis also über die nicht erwähnten Dimensionen.
Dies ähnelt einem "Gruppieren nach"-Vorgang mit "count(*)" in SQL-Abfragen.
Ereignisse in den einzelnen Segmenten werden anhand von forecastParams.aggregatedDimension
aggregiert. Ist dieses Feld leer, werden alle Ereignisse im Segment gezählt. Wenn das Feld nicht leer ist, erwarten wir, dass dieses Feld einen gültigen numerischen Dimensionsnamen in den Ereignissen dieses Segments enthält.
Die numerischen Werte werden addiert, um die Zeitachse zu bilden.
Wir analysieren jedes Segment, um zu überprüfen, ob es sich um eine Anomalie handelt:
- Erstellen einer Zeitachse aus
testedInterval.startTime - forecastParams.forecastHistory
bistestedInterval.startTime + testedInterval.length
, wobei jeder Datenpunkt ein Zeit-Bucket der LängetestedInterval.length
ist und durch die Angabe von Ereignissen in diesem Bucket seinen Wert angibt. angegeben, wie durch den ParameteraggregatedDimension
angegeben. Wenn die Zeitachsen nicht genügend Datenpunkte haben (wie im ParameterminDensity
angegeben), wird sie nicht mehr analysiert. - Nachdem wir die Zeitachse für das Segment berechnet haben, analysieren wir sie mithilfe gängiger Prognosetechniken. Mit dem ersten
(100 - holdout)%
der Zeitachse wird ein Vorhersagemodell trainiert und mit dem letztenholdout%
die Modellqualität getestet. Anhand der Fehlermesswerte berechnen wir Konfidenzgrenzen für das getestete Intervall. Wenn der tatsächliche Wert außerhalb dieser Grenzwerte liegt, wird er als Anomalie gekennzeichnet. Mit den ParameternmaxPositiveRelativeChange
,maxNegativeRelativeChange
undforecastExtraWeight
können Sie festlegen, wie viel der tatsächliche Wert außerhalb der Grenzen liegen darf.
Das Abfrageergebnis sieht so aus:
{
"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": [
...
]
}
}
Sie enthält Anomalien und optional bewertete Slices, die nicht als Anomalien markiert wurden, im selben PrognosePrognose-Format. result
gibt den Zeitpunkt der Anomalie, den tatsächlichen Wert und den Bereich der Prognosewerte an. trainingErrors
und holdoutErrors
zeigen zusätzliche Messwerte an, die zur Anomalieerkennung verwendet werden.
Streaming update
projects.datasets.appendEvents fügt Ereignisdatensätze im Streaming-Format hinzu, wenn die Anfrage zur Erstellung streaming: true
enthält.
$ gcurl -X POST -d @append.json https://timeseriesinsights.googleapis.com/v1/projects/${PROJECT}/datasets/dataset_tutorial:appendEvents
Dabei enthält append.json
Folgendes:
{
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"
}
]
}
Gestreamte Updates werden nahezu in Echtzeit indexiert, sodass Änderungen schnell in Abfrageergebnissen angezeigt werden können.
Dataset löschen
projects.datasets.delete markiert das Dataset zum Löschen.
$ gcurl -X DELETE https://timeseriesinsights.googleapis.com/v1/projects/${PROJECT}/datasets/dataset_tutorial
Die Anfrage wird sofort zurückgegeben und das Dataset akzeptiert keine weiteren Abfragen oder Updates. Es kann einige Zeit dauern, bis die Daten vollständig aus dem Dienst entfernt wurden. Danach wird für diese Datasets das Dataset nicht zurückgegeben.
Nächste Schritte
- Timelines Insights API – Konzepte
- Leitfaden zum Erstellen von Abfragen
- Weitere Informationen zur REST API
Weitere Beispiele finden Sie auf der GDELT-Website.