Preparing and using data for analysis · Topic 2 of 3
Preparing Data for ML, Embeddings and RAG
Feature engineering, training and serving with BigQuery ML, avoiding leakage and skew, and preparing unstructured data for embeddings, vector search, RAG.
- 5 min
- Avoid leakage: features must exist at prediction time; split by time for time series.
- The TRANSFORM clause keeps training and prediction preprocessing identical.
- BigQuery ML trains and predicts in SQL; export models for online serving.
What it is
Machine learning models are only as good as the data that feeds them. A data engineer prepares features for training and serving, often with BigQuery ML so models are built where the data lives. For generative AI, the engineer turns unstructured documents into chunks and embeddings so a model can retrieve relevant facts: retrieval-augmented generation (RAG).
How it works
Preparing data for feature engineering
| Task | Why |
|---|---|
| Handle missing values (impute or flag) | Many algorithms fail or bias on NULLs |
| Encode categories (one-hot, labels) | Models need numbers |
| Scale numeric features | Keeps large-range features from dominating |
| Bucketize skewed values | Captures non-linear effects simply |
| Build time-aware features (last 30 days) | Uses only data known at prediction time |
| Split train, evaluation and test sets | Measures performance on unseen data; split by time for forecasting |
Data leakage happens when a feature contains information that would not exist at prediction time, such as a "cancellation date" used to predict churn. Leaky models look excellent in evaluation and fail in production.
Training and serving with BigQuery ML
The TRANSFORM clause stores preprocessing with the model. ML.PREDICT then applies the same steps automatically, which prevents training-serving skew.
CREATE OR REPLACE MODEL `ml.churn_model`
TRANSFORM (
ML.STANDARD_SCALER(tenure_months) OVER () AS tenure_scaled,
ML.QUANTILE_BUCKETIZE(monthly_spend, 4) OVER () AS spend_bucket,
plan_type,
churned
)
OPTIONS (model_type = 'LOGISTIC_REG', input_label_cols = ['churned']) AS
SELECT tenure_months, monthly_spend, plan_type, churned
FROM ml.customer_features
WHERE snapshot_date < '2026-07-01';
SELECT * FROM ML.EVALUATE(MODEL `ml.churn_model`);
SELECT customer_id, predicted_churned
FROM ML.PREDICT(MODEL `ml.churn_model`,
(SELECT * FROM ml.customer_features WHERE snapshot_date = '2026-10-01'));
| Need | BigQuery ML option |
|---|---|
| Predict a number or a class | LINEAR_REG, LOGISTIC_REG, BOOSTED_TREE_CLASSIFIER and others |
| Group customers without labels | KMEANS |
| Forecast time series | ARIMA_PLUS |
| Recommendations | MATRIX_FACTORIZATION |
| Batch scoring | ML.PREDICT in a scheduled query |
| Low-latency online predictions | Export the model with EXPORT MODEL and serve it from an online endpoint |
"Analysts know SQL, data is in BigQuery, minimal data movement" points to BigQuery ML. Exporting data to train elsewhere is rarely the best answer in that case.
Preparing unstructured data for embeddings
| Step | How |
|---|---|
| Make files queryable | Object tables over Cloud Storage files |
| Extract text | Document parsing (for example with Document AI through BigQuery) or OCR |
| Chunk | Split long text into passages of a few hundred words, with overlap, keeping titles and IDs |
| Embed | ML.GENERATE_EMBEDDING with a remote embedding model |
| Index | CREATE VECTOR INDEX for fast approximate search |
| Retrieve | VECTOR_SEARCH with the embedded question |
| Generate | Pass the top chunks to an LLM in the prompt |
CREATE MODEL `rag.embedder`
REMOTE WITH CONNECTION `prod-ai.us.ai-conn`
OPTIONS (ENDPOINT = 'text-embedding-005');
CREATE TABLE rag.chunk_vectors AS
SELECT * FROM ML.GENERATE_EMBEDDING(
MODEL `rag.embedder`,
(SELECT chunk_id, chunk_text AS content FROM rag.chunks),
STRUCT(TRUE AS flatten_json_output));
SELECT base.chunk_id, base.content, distance
FROM VECTOR_SEARCH(
TABLE rag.chunk_vectors, 'ml_generate_embedding_result',
(SELECT ml_generate_embedding_result
FROM ML.GENERATE_EMBEDDING(MODEL `rag.embedder`,
(SELECT 'How do I reset the router?' AS content))),
top_k => 5, distance_type => 'COSINE');
Use the same embedding model for documents and questions; vectors from different models are not comparable. Re-embed chunks when source documents change, and keep metadata such as product and date to filter results.
A worked example
A telecom company wants a support assistant that answers from 20,000 PDF manuals and cites the source. The engineer creates an object table over the PDFs and extracts text. Text is split into overlapping chunks tagged with manual ID and section, and embeddings go into a BigQuery table with a vector index.
At question time, the question is embedded, VECTOR_SEARCH returns the closest chunks, and the LLM answers using only those chunks with their IDs as citations.
How the exam asks about this
- "Preprocessing in training differs from what the application sends at prediction time." Put preprocessing in the BigQuery ML TRANSFORM clause so ML.PREDICT applies it automatically.
- "A churn model scores 99% in evaluation but fails in production." Check for data leakage from features unknown at prediction time.
- "An LLM answers questions about internal documents incorrectly." Implement RAG: chunk and embed the documents, retrieve with vector search, ground the prompt.
What to remember for the exam
- Avoid leakage: features must exist at prediction time; split by time for time series.
- The TRANSFORM clause keeps training and prediction preprocessing identical.
- BigQuery ML trains and predicts in SQL; export models for online serving.
- RAG pipeline: extract, chunk, embed, index, retrieve, generate.
- Embed documents and queries with the same model and refresh when sources change.
A random train and test split on time-series data leaks future information into training. Split by date so the model is tested on a later period.
Common mistakes
Duplicating preprocessing in application code. The two versions drift; keep it in TRANSFORM.
Embedding whole documents. Long texts dilute meaning; chunk them first.
Mixing embedding models. Old vectors and new query vectors from different models do not match.
Check yourself
What does the BigQuery ML TRANSFORM clause prevent?
Training-serving skew, because the same preprocessing is stored with the model and applied automatically by ML.PREDICT.
Why are documents chunked before embedding?
Smaller passages give focused vectors, so vector search returns the specific relevant text that fits in the prompt.
Which BigQuery function finds the nearest embeddings to a query vector?
VECTOR_SEARCH, optionally accelerated by a vector index.
Topic 2 of 3 in Preparing and using data for analysis
Test yourself on Preparing and using data for analysis
The full Google Cloud Professional Data Engineer question bank has 733 questions, with timed practice exams and an explanation for every answer.
This study guide is independent and is not affiliated with, endorsed by, or sponsored by Google Cloud. Vendor names, certification names and exam codes are trademarks of their respective owners and are used for identification only.