CloudWave datasets¶
Synthetic SaaS data, checked into data/. One company all the way through the ML course.
| Dataset | Records | Grain | Format |
|---|---|---|---|
subscriptions.csv |
48,991 | one row per customer | CSV |
user_events.csv |
220,000 | one row per event | CSV |
feature_usage.csv |
160,000 | one row per user × feature × day | CSV |
feedback.json |
10,000 | one object per comment | JSON Lines |
product_catalog.csv |
300 | one row per product/feature | CSV |
subscriptions.csv¶
Customer lifecycle.
user_id— unique customerplan_type—free,starter,pro,enterprisemrr— monthly recurring revenue in dollars (0for free)signup_date/churn_date—churn_dateempty if still activeis_churned—1or0tenure_days— signup → churn, or signup → 2024-11-30 if still active. That date is the observation end of this fixture.
user_events.csv¶
Telemetry.
event_id,user_id,event_type(login,page_view,click,feature_use,payment,support_message,signup,upgrade,downgrade,cancel),timestampdevice—web,ios,androidregion—NA,EMEA,APAC,LATAMsession_duration— seconds
feature_usage.csv¶
Adoption.
user_id,feature_name,usage_count,avg_session_seconds,date
feedback.json¶
JSON Lines (one object per line), not a JSON array.
user_id,category,sentiment_score,feedback_text
How lessons load it¶
from lib.course_data import find_data_dir, load_customer_360
DATA = find_data_dir()
customers = load_customer_360() # ~8k rows, laptop default
everyone = load_customer_360(n=None) # all ~49k
load_customer_360 is the Week 2 idea as a function: aggregate usage, events, and feedback to one row per user, then left-join onto subscriptions. Usage and events stop at 2024-11-30. Billing rows after that date are not in the fixture.
Grain
Do not join subscriptions to raw feature_usage and then sum(mrr). That number is a lie. Collapse the many-side first. Week 2 exists so you feel this once, on purpose.