Tutoriel : Répondre aux questions sur les données de revenus des séries chronologiques avec Cortex Analyst¶
Introduction¶
Cortex Analyst transforme les questions en langage naturel sur vos données en résultats en générant et en exécutant des requêtes SQL. Ce tutoriel décrit comment configurer Cortex Analyst pour répondre aux questions sur un ensemble de données de revenus en séries chronologiques.
Ce que vous apprendrez¶
Établir un modèle sémantique pour l’ensemble de données.
Créer une application Streamlit qui interroge Cortex Analyst.
Conditions préalables¶
Les prérequis suivants sont nécessaires à la réalisation de ce tutoriel :
Vous disposez d’un compte Snowflake et d’un utilisateur avec un rôle qui accorde les privilèges nécessaires pour créer une base de données, un schéma, des tables, une zone de préparation et des objets d’entrepôt virtuel.
Vous avez Streamlit installé sur votre système local.
Consultez les Snowflake en 20 minutes pour obtenir des instructions afin de répondre à ces exigences.
Étape 1 : Configuration¶
Obtenir les données d’échantillon¶
Vous utiliserez un exemple d’ensemble de données et un modèle sémantique correspondant téléchargé depuis Google Drive. Téléchargez les fichiers de données suivants sur votre système :
daily_revenue_combined.csv
daily_revenue_by_region_combined.csv
daily_revenue_by_product_combined.csv
Téléchargez également le modèle sémantique :
revenue_timeseries.yaml
Vous voudrez peut-être prendre un moment pour jeter un œil au fichier YAML, qui contient le modèle sémantique des données. Le modèle sémantique complète le schéma SQL de chaque table avec des informations supplémentaires qui aident Cortex Analyst pour comprendre les questions sur les données. Pour plus d’informations, voir Spécification du modèle sémantique Cortex Analyst.
Note
Dans un cadre non-tutoriel, vous apporteriez vos propres données, éventuellement déjà présentes dans une table Snowflake, et développeriez votre propre modèle sémantique.
Création des objets Snowflake¶
Utiliser Snowsight, l’UI Snowflake, pour créer les objets Snowflake nécessaires à ce tutoriel. Après avoir terminé le tutoriel, vous pouvez détruire ces objets.
Note
Utilisez un rôle capable de créer des bases de données, des schémas, des entrepôts, des zones de préparation et des tables.
Pour créer les objets :
Dans l’interface utilisateur Snowsight, sélectionnez Worksheets dans la barre de navigation de gauche, puis sélectionnez le bouton +. Une nouvelle feuille de calcul SQL apparaît.
Collez le code SQL ci-dessous dans la feuille de calcul, puis sélectionnez le Run All dans le menu déroulant en haut à droite de la feuille de calcul.
CREATE OR REPLACE DATABASE cortex_analyst_demo;
CREATE OR REPLACE SCHEMA revenue_timeseries;
CREATE OR REPLACE WAREHOUSE cortex_analyst_wh
WAREHOUSE_SIZE = 'large'
WAREHOUSE_TYPE = 'standard'
AUTO_SUSPEND = 60
AUTO_RESUME = TRUE
INITIALLY_SUSPENDED = TRUE
COMMENT = 'warehouse for cortex analyst demo';
USE WAREHOUSE cortex_analyst_wh;
CREATE STAGE raw_data DIRECTORY = (ENABLE = TRUE);
CREATE OR REPLACE TABLE CORTEX_ANALYST_DEMO.REVENUE_TIMESERIES.DAILY_REVENUE (
DATE DATE,
REVENUE FLOAT,
COGS FLOAT,
FORECASTED_REVENUE FLOAT
);
CREATE OR REPLACE TABLE CORTEX_ANALYST_DEMO.REVENUE_TIMESERIES.DAILY_REVENUE_BY_PRODUCT (
DATE DATE,
PRODUCT_LINE VARCHAR(16777216),
REVENUE FLOAT,
COGS FLOAT,
FORECASTED_REVENUE FLOAT
);
CREATE OR REPLACE TABLE CORTEX_ANALYST_DEMO.REVENUE_TIMESERIES.DAILY_REVENUE_BY_REGION (
DATE DATE,
SALES_REGION VARCHAR(16777216),
REVENUE FLOAT,
COGS FLOAT,
FORECASTED_REVENUE FLOAT
);
Le SQL ci-dessus crée les objets suivants :
Une base de données nommée
cortex_analyst_demo
Un schéma dans cette base de données appelée
revenue_timeseries
Trois tables dans ce schéma : DAILY_REVENUE, DAILY_REVENUE_BY_PRODUCT, et DAILY_REVENUE_BY_REGION
Une zone de préparation nommée
raw_data
qui contiendra les données brutes que nous chargerons dans ces tablesUn entrepôt virtuel nommé
cortex_analyst_wh
Notez que l’entrepôt virtuel est initialement suspendu et démarrera automatiquement lorsque cela sera nécessaire.
Étape 2 : charger les données dans Snowflake¶
Pour obtenir les données des fichiers CSV dans Snowflake, vous les téléchargerez sur la zone de préparation, puis chargerez les données de la zone de préparation dans les tables. En même temps, vous téléchargerez le fichier YAML du modèle sémantique à utiliser dans une étape ultérieure.
Les fichiers que vous téléchargerez sont :
daily_revenue_combined.csv
daily_revenue_by_region_combined.csv
daily_revenue_by_product_combined.csv
revenue_timeseries.yaml
Pour télécharger les fichiers dans Snowsight :
Dans la Snowsight UI, sélectionnez la Data icon dans la barre de navigation de gauche, puis Add Data. Dans la page Add Data, sélectionnez Load files into a stage.
Faites glisser les quatre fichiers que vous avez téléchargés à l’étape précédente dans la fenêtre Snowsight.
Choisissez la base de données
cortex_analyst_demo
et la zone de préparationraw_data
, puis sélectionnez le bouton Upload pour télécharger les fichiers.
Maintenant que vous avez téléchargé les fichiers, chargez les données à partir des fichiers CSV en exécutant les commandes SQL ci-dessous dans une feuille de calcul Snowsight.
COPY INTO CORTEX_ANALYST_DEMO.REVENUE_TIMESERIES.DAILY_REVENUE
FROM @raw_data
FILES = ('daily_revenue_combined.csv')
FILE_FORMAT = (
TYPE=CSV,
SKIP_HEADER=1,
FIELD_DELIMITER=',',
TRIM_SPACE=FALSE,
FIELD_OPTIONALLY_ENCLOSED_BY=NONE,
REPLACE_INVALID_CHARACTERS=TRUE,
DATE_FORMAT=AUTO,
TIME_FORMAT=AUTO,
TIMESTAMP_FORMAT=AUTO
EMPTY_FIELD_AS_NULL = FALSE
error_on_column_count_mismatch=false
)
ON_ERROR=CONTINUE
FORCE = TRUE ;
COPY INTO CORTEX_ANALYST_DEMO.REVENUE_TIMESERIES.DAILY_REVENUE_BY_PRODUCT
FROM @raw_data
FILES = ('daily_revenue_by_product_combined.csv')
FILE_FORMAT = (
TYPE=CSV,
SKIP_HEADER=1,
FIELD_DELIMITER=',',
TRIM_SPACE=FALSE,
FIELD_OPTIONALLY_ENCLOSED_BY=NONE,
REPLACE_INVALID_CHARACTERS=TRUE,
DATE_FORMAT=AUTO,
TIME_FORMAT=AUTO,
TIMESTAMP_FORMAT=AUTO
EMPTY_FIELD_AS_NULL = FALSE
error_on_column_count_mismatch=false
)
ON_ERROR=CONTINUE
FORCE = TRUE ;
COPY INTO CORTEX_ANALYST_DEMO.REVENUE_TIMESERIES.DAILY_REVENUE_BY_REGION
FROM @raw_data
FILES = ('daily_revenue_by_region_combined.csv')
FILE_FORMAT = (
TYPE=CSV,
SKIP_HEADER=1,
FIELD_DELIMITER=',',
TRIM_SPACE=FALSE,
FIELD_OPTIONALLY_ENCLOSED_BY=NONE,
REPLACE_INVALID_CHARACTERS=TRUE,
DATE_FORMAT=AUTO,
TIME_FORMAT=AUTO,
TIMESTAMP_FORMAT=AUTO
EMPTY_FIELD_AS_NULL = FALSE
error_on_column_count_mismatch=false
)
ON_ERROR=CONTINUE
FORCE = TRUE ;
Étape 3 : créez une application Streamlit pour communiquer avec vos données Cortex Analyst¶
Pour créer une application Streamlit qui utilise Cortex Analyst :
Créez un fichier Python appelé localement
analyst_demo.py
.Copiez le code ci-dessous dans le fichier.
Remplacez les valeurs par défaut par les détails de votre compte.
Exécutez l’application Streamlit en utilisant
streamlit run analyst_demo.py
.
from typing import Any, Dict, List, Optional
import pandas as pd
import requests
import snowflake.connector
import streamlit as st
DATABASE = "CORTEX_ANALYST_DEMO"
SCHEMA = "REVENUE_TIMESERIES"
STAGE = "RAW_DATA"
FILE = "revenue_timeseries.yaml"
WAREHOUSE = "cortex_analyst_wh"
# replace values below with your Snowflake connection information
HOST = "<host>"
ACCOUNT = "<account>"
USER = "<user>"
PASSWORD = "<password>"
ROLE = "<role>"
if 'CONN' not in st.session_state or st.session_state.CONN is None:
st.session_state.CONN = snowflake.connector.connect(
user=USER,
password=PASSWORD,
account=ACCOUNT,
host=HOST,
port=443,
warehouse=WAREHOUSE,
role=ROLE,
)
def send_message(prompt: str) -> Dict[str, Any]:
"""Calls the REST API and returns the response."""
request_body = {
"messages": [{"role": "user", "content": [{"type": "text", "text": prompt}]}],
"semantic_model_file": f"@{DATABASE}.{SCHEMA}.{STAGE}/{FILE}",
}
resp = requests.post(
url=f"https://{HOST}/api/v2/cortex/analyst/message",
json=request_body,
headers={
"Authorization": f'Snowflake Token="{st.session_state.CONN.rest.token}"',
"Content-Type": "application/json",
},
)
request_id = resp.headers.get("X-Snowflake-Request-Id")
if resp.status_code < 400:
return {**resp.json(), "request_id": request_id} # type: ignore[arg-type]
else:
raise Exception(
f"Failed request (id: {request_id}) with status {resp.status_code}: {resp.text}"
)
def process_message(prompt: str) -> None:
"""Processes a message and adds the response to the chat."""
st.session_state.messages.append(
{"role": "user", "content": [{"type": "text", "text": prompt}]}
)
with st.chat_message("user"):
st.markdown(prompt)
with st.chat_message("assistant"):
with st.spinner("Generating response..."):
response = send_message(prompt=prompt)
request_id = response["request_id"]
content = response["message"]["content"]
display_content(content=content, request_id=request_id) # type: ignore[arg-type]
st.session_state.messages.append(
{"role": "assistant", "content": content, "request_id": request_id}
)
def display_content(
content: List[Dict[str, str]],
request_id: Optional[str] = None,
message_index: Optional[int] = None,
) -> None:
"""Displays a content item for a message."""
message_index = message_index or len(st.session_state.messages)
if request_id:
with st.expander("Request ID", expanded=False):
st.markdown(request_id)
for item in content:
if item["type"] == "text":
st.markdown(item["text"])
elif item["type"] == "suggestions":
with st.expander("Suggestions", expanded=True):
for suggestion_index, suggestion in enumerate(item["suggestions"]):
if st.button(suggestion, key=f"{message_index}_{suggestion_index}"):
st.session_state.active_suggestion = suggestion
elif item["type"] == "sql":
with st.expander("SQL Query", expanded=False):
st.code(item["statement"], language="sql")
with st.expander("Results", expanded=True):
with st.spinner("Running SQL..."):
df = pd.read_sql(item["statement"], st.session_state.CONN)
if len(df.index) > 1:
data_tab, line_tab, bar_tab = st.tabs(
["Data", "Line Chart", "Bar Chart"]
)
data_tab.dataframe(df)
if len(df.columns) > 1:
df = df.set_index(df.columns[0])
with line_tab:
st.line_chart(df)
with bar_tab:
st.bar_chart(df)
else:
st.dataframe(df)
st.title("Cortex Analyst")
st.markdown(f"Semantic Model: `{FILE}`")
if "messages" not in st.session_state:
st.session_state.messages = []
st.session_state.suggestions = []
st.session_state.active_suggestion = None
for message_index, message in enumerate(st.session_state.messages):
with st.chat_message(message["role"]):
display_content(
content=message["content"],
request_id=message.get("request_id"),
message_index=message_index,
)
if user_input := st.chat_input("What is your question?"):
process_message(prompt=user_input)
if st.session_state.active_suggestion:
process_message(prompt=st.session_state.active_suggestion)
st.session_state.active_suggestion = None
Lorsque vous exécutez l’application, elle vous invite à saisir une question. Commencez par « Quelles questions puis-je poser ? » et essayez certaines de ses suggestions.
Étape 4 : Nettoyer¶
Nettoyer (facultatif)¶
Exécutez les commandes DROP <objet> suivantes pour remettre votre système dans son état initial avant de commencer le tutoriel :
DROP DATABASE IF EXISTS cortex_analyst_demo;
DROP WAREHOUSE IF EXISTS cortex_analyst_wh;
Détruire la base de données supprime automatiquement toutes les objets de base de données liés, par exemple les tables.
Prochaines étapes¶
Félicitations ! Vous avez réussi à construire un simple application Cortex Analyst pour « parler à vos données » dans Snowflake.
Ressources supplémentaires¶
Poursuivez l’entraînement en utilisant les ressources suivantes :