יצירת תהליך עבודה של איכות נתונים כמדיניות בקוד

ליצור תהליך עבודה של איכות נתונים והעשרת מטא-נתונים לפי מדיניות-כקוד. במדריך הזה נסביר איך להגדיר ציפיות לגבי איכות הנתונים בקבצים הצהרתיים עם ניהול גרסאות, כדי לעבור מתהליכים ידניים לתהליכים אוטומטיים.

כשמגדירים כללים אוטומטיים ליצירת פרופילים ולאיכות הנתונים, המטא-נתונים מועשרים באותות אמינות ובהקשר עסקי.

בעזרת גישת Human-in-the-Loop, שבה ה-AI מנסח את הכללים הראשוניים ואתם בודקים, משפרים ומאמתים אותם, אתם יכולים לתרגם במהירות את הנתונים הסטטיסטיים של הפרופיל למסגרת של איכות נתונים.

מטרות

  • השטחת נתונים בתצוגות מהותיות ב-BigQuery כדי לאפשר יצירת פרופילים ב-Knowledge Catalog.
  • להריץ סריקות פרופיל של Knowledge Catalog באמצעות ספריית הלקוח של Python.
  • אתם יכולים להשתמש ב-Antigravity CLI כדי ליצור כללים לאיכות הנתונים על סמך נתונים סטטיסטיים של פרופילים.
  • איך מאמתים ופורסים כללים שנוצרו על ידי AI כסריקות איכות של Knowledge Catalog באמצעות תהליך בדיקה של האדם שבתהליך.

לפני שמתחילים

לפני שמתחילים, צריך לוודא שיש לכם פרויקט ב- Google Cloud שהחיוב מופעל בו.

הכנת הסביבה

בשלבים הבאים משתמשים ב-Cloud Shell, סביבה של שורת פקודה שפועלת בענן.

  1. במסוף Google Cloud , לוחצים על Activate Cloud Shell בסרגל הכלים שבפינה הימנית העליונה. ההקצאה והחיבור של הסביבה נמשכים כמה רגעים.

  2. ב-Cloud Shell, מגדירים את מזהה הפרויקט ואת משתני הסביבה:

    export PROJECT_ID=$(gcloud config get-value project)
    gcloud config set project $PROJECT_ID
    export LOCATION="us-central1"
    export BQ_LOCATION="us"
    export DATASET_ID="kc_dq_codelab"
    export TABLE_ID="ga4_transactions"
    

    משתמשים ב-us (מספר אזורים) בתור המיקום, כי נתוני הדוגמה הציבוריים נמצאים גם ב-us (מספר אזורים). בשאילתות של BigQuery, נתוני המקור וטבלת היעד צריכים להיות באותו מיקום.

  3. מפעילים את השירותים הנדרשים:

    gcloud services enable dataplex.googleapis.com \
                           bigquery.googleapis.com \
                           serviceusage.googleapis.com \
                           aiplatform.googleapis.com
    
  4. יוצרים מערך נתונים ב-BigQuery כדי לאחסן את הנתונים לדוגמה ואת התוצאות:

    bq --location=us mk --dataset $PROJECT_ID:$DATASET_ID
    
  5. מכינים את הנתונים לדוגמה, שמגיעים ממערך נתונים ציבורי של מסחר אלקטרוני מ-Google Merchandise Store.

    הפקודה הבאה של bq יוצרת טבלה חדשה, ga4_transactions, במערך הנתונים kc_dq_codelab. כדי לוודא שהסריקות יפעלו במהירות, הוא מעתיק נתונים רק מיום אחד (31-01-2021).

    bq query \
    --use_legacy_sql=false \
    --destination_table=$PROJECT_ID:$DATASET_ID.$TABLE_ID \
    --replace=true \
    'SELECT * FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_20210131`'
    
  6. משכפלים את המאגר ב-GitHub שמכיל את מבנה התיקיות והקבצים התומכים של המדריך הזה:

    # Perform a shallow clone to get only the latest repository structure without the full history
    git clone --depth 1 --filter=blob:none --sparse https://github.com/GoogleCloudPlatform/devrel-demos.git
    cd devrel-demos
    
    # Specify and download only the folder we need for this lab
    git sparse-checkout set data-analytics/programmatic-dq
    cd data-analytics/programmatic-dq
    

    הספרייה הזו היא אזור העבודה הפעיל שלכם.

נתונים שמוצבים בתוך נתונים אחרים בפרופיל

בעזרת יצירת פרופיל נתונים, Knowledge Catalog מוצא נתונים סטטיסטיים של עמודות ברמה העליונה, כמו אחוזי ערכי null, ייחודיות והתפלגויות ערכים בנתונים, כדי לעזור לכם להבין אותם.

כדי לקבל נתונים סטטיסטיים של שדות בתצוגת עץ, אפשר לשטח את הנתונים באמצעות קבוצה של תצוגות מהותיות. כך כל שדה בתצוגת עץ הופך לעמודה ברמה העליונה, ש-Knowledge Catalog יכול ליצור לה פרופיל.

קבלת הסכימה המקוננת

מורידים את הסכימה המלאה של טבלת המקור, כולל כל המבנים בתצוגת עץ, ושומרים את הפלט כקובץ JSON:

bq show --schema --format=json $PROJECT_ID:$DATASET_ID.$TABLE_ID > bq_schema.json

הצגת הסכימה:

jq < bq_schema.json

הקובץ bq_schema.json חושף מבנים מורכבים.

השטחת נתונים באמצעות תצוגה מהותית

כשמבצעים שיטוח של נתונים בתצוגת עץ, חשוב לא לבטל את ההיררכיה של כמה מערכים בלתי תלויים באותה תצוגה. פעולה כזו מבצעת שאילתת איחוד (cross join) מרומזת (מכפלה קרטזית) בין המערכים, שמכפילה שורות באופן שגוי ומשחיתה את הנתונים.

במקום זאת, מומלץ ליצור כמה תצוגות מפורטות, שכל אחת מהן מיועדת למטרה ספציפית. כל תצוגה צריכה לשמור על רמת פירוט אחת וברורה. בשלב הזה יוצרים את התצוגות המהותיות הבאות:

  • תצוגה שטוחה של סשן (mv_ga4_user_session_flat.sql): שורה אחת לכל אירוע.
  • תצוגת עסקאות (mv_ga4_ecommerce_transactions.sql): שורה אחת לכל עסקה.
  • תצוגת פריטים (mv_ga4_ecommerce_items.sql): שורה אחת לכל פריט.

במאגר הפרויקט יש שלושה קובצי SQL בספרייה devrel-demos/data-analytics/programmatic-dq שמגדירים את התצוגות האלה.

מריצים את הקבצים האלה מ-Cloud Shell באמצעות הפקודות הבאות של BigQuery.

envsubst < mv_ga4_user_session_flat.sql | bq query --use_legacy_sql=false
envsubst < mv_ga4_ecommerce_transactions.sql | bq query --use_legacy_sql=false
envsubst < mv_ga4_ecommerce_items.sql | bq query --use_legacy_sql=false

הרצת סריקות פרופיל באמצעות לקוח Python

עכשיו אתם יכולים ליצור ולהריץ סריקות של פרופיל נתונים ב-Knowledge Catalog לכל תצוגה מהותית. הסקריפט הבא ב-Python משתמש בספריית הלקוח google-cloud-dataplex כדי להפוך את התהליך הזה לאוטומטי.

לפני שמריצים את הסקריפט, צריך ליצור סביבה וירטואלית מבודדת של Python בספריית הפרויקט.

# Create the virtual environment
python3 -m venv dq_venv

# Activate the environment
source dq_venv/bin/activate

מתקינים את ספריית הלקוח של Knowledge Catalog בסביבה הווירטואלית.

# Install the Knowledge Catalog client library
pip install google-cloud-dataplex

אחרי שהגדרתם את הסביבה והתקנתם את הספרייה, אתם יכולים להשתמש בסקריפט 1_run_scan.py. הסקריפט הזה יוצר ומריץ סריקה לכל אחת משלוש התצוגות המהותיות כדי ליצור להן פרופיל. בסיום, המערכת מפיקה סיכום סטטיסטי עשיר שמשמש בשלב הבא ליצירת כללים מבוססי-AI לאיכות הנתונים.

מריצים את הסקריפט מהטרמינל של Cloud Shell.

python3 1_run_scan.py

בדיקת סריקות הפרופילים

אפשר לראות את סריקות הפרופיל החדשות במסוף Google Cloud .

  1. בתפריט הניווט, עוברים אל Knowledge Catalog ואל Data profiling & quality בקטע Govern.
  2. מוצאים את שלוש סריקות הפרופיל ברשימה, יחד עם סטטוס המשימה האחרון שלהן. לוחצים על סריקה כדי לראות את התוצאות המפורטות שלה.

ייצוא תוצאות הפרופיל ל-JSON

כדי ש-Antigravity CLI יוכל לקרוא את סריקות הפרופילים, צריך לחלץ את התוכן שלהן לקובץ מקומי.

משתמשים בסקריפט 2_dq_profile_save.py כדי למצוא את הסריקה המוצלחת האחרונה של התצוגה mv_ga4_user_session_flat, מורידים את נתוני הפרופיל ושומרים אותם בקובץ בשם dq_profile_results.json.

python3 2_dq_profile_save.py

כשהסקריפט מסתיים, הוא יוצר קובץ dq_profile_results.json בספרייה. הקובץ הזה מכיל את המטא-נתונים הסטטיסטיים המפורטים שדרושים כדי ליצור כללים לאיכות הנתונים. כדי לראות את התוכן שלו, מריצים את הפקודה הבאה:

cat dq_profile_results.json

יצירת כללים לאיכות הנתונים באמצעות Antigravity CLI

עכשיו אתם יכולים להשתמש ב-Antigravity CLI כדי לקרוא את תוצאות הסריקה של הפרופיל המקומי.

כתיבה ידנית של מפרטים לאיכות הנתונים של מערכי נתונים מורכבים היא תהליך ארוך ומועד לטעויות. שימוש בסוכן AI גנרטיבי מאיץ את תהליך העבודה הזה, כי הוא מנסח הגדרה הצהרתית ראשונית תוך שניות. כך צוותי הנתונים יכולים לעבור מניסוח ידני של תחביר לפיקוח ברמה גבוהה, שמותאם לעסק, באמצעות האדם שבתהליך (HITL).

כדי להפעיל את Antigravity CLI, משתמשים בפקודה הבאה:

agy

עכשיו אתם מוכנים ליצור כללי איכות. מכיוון שה-CLI יכול לקרוא קבצים בספרייה הנוכחית, הוא יכול להשתמש ישירות בנתוני סריקת הפרופיל החדשים.

מבקשים מהסוכן ליצור תוכנית

קודם, בקשו מה-Agent לנתח את הפרופיל הסטטיסטי ולהציע תוכנית פעולה. הנחו אותו לא לכתוב עדיין את קובץ ה-YAML, כדי שיתמקד בניתוח ובהצדקה.

בסשן האינטראקטיבי של Antigravity CLI, מזינים את ההנחיה המובנית הבאה:

# Context
You are preparing a data quality rule configuration plan for Google Cloud Knowledge Catalog based on data profile statistics.

# Input
- File Path: `./dq_profile_results.json` (contains metrics like null percentage, distinct counts, and distributions)

# Task
Analyze the input statistics and propose a step-by-step plan for establishing automated data quality rules. 
*Do not write any YAML code in this step.* Focus only on analytical planning.

# Rule Mapping Strategy
For candidate columns, match the statistical metrics to the most appropriate expectations:
- `nonNullExpectation`: Propose for columns with 0% null values in the profile.
- `setExpectation`: Propose for columns with a highly limited, stable set of categorical values.
- `rangeExpectation`: Propose for numeric columns with consistent and predictable value boundaries.

# Guidelines
- Provide a metric-based justification for each proposed rule (for example, "Recommend nonNullExpectation for column 'user_pseudo_id' because its null percentage is 0%").
- Flag volatile metrics such as hardcoded row counts that could cause false-positive alerts in production.

# Output Format
Provide your analysis and proposed rules as a structured, step-by-step markdown plan with clear headings.

הסוכן ינתח את קובץ ה-JSON ויחזיר תוכנית מובנית כמו זו:

Automated Data Quality Rule Configuration Plan

  Google Cloud Knowledge Catalog (Dataplex Data Quality)
  ──────
  ## Executive Summary
  This analytical planning document outlines a step-by-step strategy for
  configuring automated data quality (DQ) rules in Google Cloud
  Knowledge Catalog (formerly Dataplex Data Quality) based on profiling
  statistics.
  The dataset contains 26,489 rows representing GA4 event logs. Based on
  statistical metrics (null ratios, distinct value distributions, and data
  types), candidate columns are mapped to appropriate expectation rules.
  ──────
  ## 1. Data Profile Overview & Statistical Highlights

   Column Name     │ Data Type │ Null Ratio     │ Distinct Count │ Key Value Range / Categories
  ─────────────────┼───────────┼────────────────┼────────────────┼──────────────────────────────────────────────────
   event_date      │ STRING    │ 0.0% (0)       │ 1 (3.78e-05)   │ "20210131" (100%)
   event_timestamp │ INTEGER   │ 0.0% (0)       │ ~16,539 (0.62) │ Min: 1612051200657906, Max: 1612137595412363
   event_name      │ STRING    │ 0.0% (0)       │ 16 (0.0006)    │ page_view (35.8%), user_engagement (18.9%), etc.
   user_pseudo_id  │ STRING    │ 0.0% (0)       │ ~2,545 (0.09)  │ 18-21 characters string identifiers
   user_id         │ STRING    │ 100.0% (1.0)   │ 0 (0.0)        │ Entirely NULL
   device_category │ STRING    │ 0.0% (0)       │ 3 (0.0001)     │ desktop (57.5%), mobile (40.1%), tablet (2.4%)
   ...             │ ...       │ ...            │ ...            │ ...
  ──────
  ## 2. Rule Mapping Strategy & Analytical Justifications

  ### Step 1: Nullability Rules (nonNullExpectation)
  Propose nonNullExpectation for mandatory columns where the data profile
  demonstrates 0% null values.
  • user_pseudo_id, event_timestamp, event_name, event_date, stream_id,
    platform, device_category (Metric Justification: nullRatio is 0.0%)

  │ [!NOTE] Exclusions:
  │ • user_id: Has a nullRatio of 100.0% (unauthenticated traffic).
  │ • device_language: Has a nullRatio of 37.53%.
  ──────
  ### Step 2: Categorical Value Set Validation (setExpectation)
  Propose setExpectation for columns with a highly limited, stable set of
  categorical domain values.
  • device_category: Distinct count is exactly 3. Allowed set:
    ['desktop', 'mobile', 'tablet']
  • platform: Distinct count is 1. Allowed set expanded to:
    ['WEB', 'ANDROID', 'IOS'] to avoid over-fitting.
  • geo_continent: Distinct count is 6. Allowed set:
    ['Americas', 'Asia', 'Europe', 'Africa', 'Oceania', 'Antarctica', '(not set)']

  ──────
  ### Step 3: Numeric & Timestamp Boundary Validation (rangeExpectation)
  Propose rangeExpectation for numeric columns with consistent and predictable
  value boundaries.
  • event_timestamp: rangeExpectation requiring event_timestamp > 0 (avoid
    dynamic microsecond range hardcoding)
  • stream_id: rangeExpectation requiring positive integer stream IDs
    (stream_id > 0)

  ──────
  ## 3. Risk Warning: Volatile Metrics & Production False Positives
  │ [!WARNING] Volatile Metrics Flagged for Risk Mitigation:
  1. Hardcoded Total Row Count (rowCount = 26,489) -> Daily event volume
     fluctuates. Use dynamic volume thresholds.
  2. Hardcoded Partition Date (event_date = '20210131') -> Breaks on future
     runs. Validate against YYYYMMDD regex patterns.
  3. Exact Timestamp Range Bounds -> Enforcing these microsecond limits on
     incoming live pipelines will reject all future data.
  4. Single-Value Domain Restrictions -> Single profile sample might lack
     active streams. Set sets according to enterprise schema.

  ──────
  ## Summary Table of Proposed Rules
  
   Target Column   │ Rule Type          │ Metric-Based Justification │ Operational Considerations
  ─────────────────┼────────────────────┼────────────────────────────┼──────────────────────────────────────────────────
   user_pseudo_id  │ nonNullExpectation │ Null Ratio: 0.0%           │ Core identifier, strictly required
   event_timestamp │ nonNullExpectation │ Null Ratio: 0.0%           │ Temporal key, strictly required
   event_timestamp │ rangeExpectation   │ Min: > 0 (Microseconds)    │ Avoid hardcoding epoch min/max
   event_name      │ nonNullExpectation │ Null Ratio: 0.0%           │ Required event taxonomy key
   event_name      │ setExpectation     │ Categorical distribution   │ Map to standard GA4 event taxonomy
   device_category │ nonNullExpectation │ Null Ratio: 0.0%           │ Required form-factor dimension
   device_category │ setExpectation     │ Distinct Count: 3 values   │ ['desktop', 'mobile', 'tablet']
   ...             │ ...                │ ...                        │ ...

יצירת כללים לאיכות הנתונים

זה השלב הכי חשוב בתהליך העבודה כולו: בדיקה של האדם שבתהליך (HITL). התוכנית שהסוכן יצר מבוססת אך ורק על דפוסים סטטיסטיים בנתונים. הנציג לא מבין את ההקשר העסקי, שינויים עתידיים בנתונים או את הכוונה הספציפית מאחורי הנתונים. התפקיד שלכם כמומחים אנושיים הוא לאמת, לתקן ולאשר את התוכנית הזו לפני שהיא הופכת לקוד.

מה צריך לאמת במהלך בדיקת HITL

בודקים את התוכנית שהסוכן הציע לפי הקריטריונים העסקיים הבאים:

  • חריגות סטטיסטיות לעומת המציאות העסקית:
    • למה: סוכן AI עשוי להניח שעמודה עם 0% ערכים ריקים בדגימה של יום אחד לא צריכה להכיל ערכים ריקים אף פעם, או להגדיר טווח מספרי קפדני על סמך התפלגויות היסטוריות מוגבלות.
    • פעולה: בודקים אם הגבולות המוצעים (כמו rangeExpectation או nonNullExpectation) משקפים אילוצים עסקיים אמיתיים או רק פריטים של קבוצת דוגמאות.
  • מדדים תנודתיים (כמו מספר השורות):
    • למה: מדדים כמו rowCount או גידול בטבלה משתנים מדי יום בסביבות ארגוניות פעילות. כלל סטטי יגרום להתראות חיוביות כוזבות.
    • פעולה: דוחים או משנים כללים שאוכפים ספי נתונים סטטיים בטבלאות של עסקאות דינמיות.
  • שלמות קטגורית (setExpectation):
    • למה: נתוני הפרופיל חושפים רק ערכים שקיימים בחלון הדגימה שנסרק. הוא לא יכול לחזות קטגוריות תקינות שלא התרחשו במסגרת הזמן הזו.
    • פעולה: בודקים את הרשימות של הקטגוריות מול מילון המונחים הארגוני הרשמי או נתוני העזר, ומוסיפים ערכים תקינים שהושמטו מהדגימה (לדוגמה, מוסיפים קודי אזור או קטגוריות מוצרים חסרים).

שיפור התוכנית באמצעות משוב על ההנחיה

נותנים משוב לנציג ונותנים לו את הפקודה הסופית ליצירת הקוד. אתם יכולים להתאים את ההנחיה הבאה לפי התוכנית שקיבלתם והתיקונים שאתם רוצים לעשות.

ההנחיה היא רק תבנית. בשורה הראשונה מוסיפים את התיקונים הספציפיים.

ההנחיה הזו דורשת התאמה למפרט של DataQualityRule כי Knowledge Catalog דורש מבנה YAML מדויק, כדי למנוע שגיאות תחביר או גרסאות סכימה מיושנות.

# Feedback & Approvals
[YOUR CORRECTIONS AND APPROVAL GO HERE. Examples:
- "The plan looks good. Please proceed."
- "The rowCount rule is not necessary, as the table size changes daily. The rest of the plan is approved. Please proceed."
- "For the setExpectation on the geo_continent column, please also include 'Antarctica'."]

# Objective
Based on the approved analysis plan and the provided feedback, generate the final `dq_rules.yaml` file conforming to the standard `DataQualityRule` schema.

# Instructions
1. **Rule Justifications**: For every generated rule, add a YAML comment (`#`) on the line directly above it, briefly explaining the justification established in the plan.
2. **Schema Alignment**: Ensure the structure strictly adheres to the required Knowledge Catalog data quality scan specification. Refer to the `sample_rule.yaml` file in the current directory and the `DataQualityRule` class definition as the schema authority. Search for the `data_quality.py` file inside the `./dq_venv/lib/` directory to read this class definition.
3. **Data-Driven Values**: Derive all rule parameters, such as thresholds or expected values, directly from the statistical metrics in `dq_profile_results.json`.

# Constraints
- **Output Purity**: Return ONLY the raw, valid, and properly formatted YAML code block.
- Do not include conversational preambles, introductory sentences, explanations, or markdown blocks around the YAML.

הנציג יוצר קובץ YAML בשם dq_rules.yaml בספריית העבודה, על סמך ההוראות המאומתות.

יצירה והפעלה של סריקה לבדיקת איכות הנתונים

עכשיו יש לכם קבוצה של כללים לאיכות הנתונים שנוצרו על ידי נציג ועברו אימות על ידי אדם, ואתם יכולים לרשום ולפרוס אותם כסריקה.

  1. כדי לצאת מ-Antigravity CLI, מקלידים /quit או לוחצים על Ctrl+C פעמיים.

  2. אחר כך יוצרים סריקת נתונים ב-Knowledge Catalog:

    export DQ_SCAN="dq-scan"
    gcloud dataplex datascans create data-quality $DQ_SCAN \
        --project=$PROJECT_ID \
        --location=$LOCATION \
        --data-quality-spec-file=dq_rules.yaml \
        --data-source-resource="//bigquery.googleapis.com/projects/$PROJECT_ID/datasets/$DATASET_ID/tables/mv_ga4_user_session_flat"
    
  3. מפעילים את הסריקה:

    gcloud dataplex datascans run $DQ_SCAN --location=$LOCATION --project=$PROJECT_ID
    

    הפקודה הזו יוצרת סריקה של איכות הנתונים בשם dq-scan.

  4. אפשר לבדוק את התקדמות הסריקה בקטע Knowledge Catalog במסוף Google Cloud .

    1. בתפריט הניווט, עוברים אל Knowledge Catalog ואל Data profiling & quality בקטע Govern.
    2. מוצאים את dq-scan. בסיום הסריקה, לוחצים עליה כדי לראות את התוצאות.

הסרת המשאבים

כדי להימנע מחיובים קבועים על המשאבים שיצרתם במדריך הזה, אתם צריכים למחוק אותם.

מחיקת הסריקות של Knowledge Catalog

מוחקים את הפרופיל ואת הסריקות האיכותיות באמצעות שמות הסריקות הספציפיים מ-Codelab הזה:

# Delete the Data Quality Scan
gcloud dataplex datascans delete dq-scan \
    --location=us-central1 \
    --project=$PROJECT_ID --quiet

# Delete the Data Profile Scans
gcloud dataplex datascans delete profile-scan-mv-ga4-user-session-flat \
    --location=us-central1 \
    --project=$PROJECT_ID --quiet

gcloud dataplex datascans delete profile-scan-mv-ga4-ecommerce-transactions \
    --location=us-central1 \
    --project=$PROJECT_ID --quiet

gcloud dataplex datascans delete profile-scan-mv-ga4-ecommerce-items \
    --location=us-central1 \
    --project=$PROJECT_ID --quiet

מחיקת מערך הנתונים לדוגמה

מוחקים את מערך הנתונים הזמני ב-BigQuery ואת הטבלאות שלו.

bq rm -r -f --dataset $PROJECT_ID:kc_dq_codelab

מחיקת קבצים מקומיים

משביתים את הסביבה הווירטואלית של Python ומסירים את המאגר המשוכפל ואת התוכן שלו:

deactivate
cd ../../..
rm -rf devrel-demos

סיכום

כל הכבוד, יצרתם תהליך עבודה פרוגרמטי מקצה לקצה של בקרת איכות והעשרת מטא-נתונים.

כשמשלבים סוכן Antigravity CLI עם Knowledge Catalog, יוצרים בסיס שניתן לאימות להעשרת מטא-נתונים בעזרת AI. הגישה הזו מאיצה את היצירה של כללים הצהרתיים, כך שמנהלי הנתונים יכולים להתמקד באימות של האדם שבתהליך (HITL) ובשיפור הכללים בהתאם ללוגיקה העסקית – וכך לוודא שקטלוג הנתונים פועל כמנוע תלוי הקשר מהימן לצריכת AI בארגון.

המאמרים הבאים