آپ کی ٹیم نے ہفتہ 20 میں 1 ورک اسپیس کو لہرانے کے لیے LLM پر مبنی سمری فیچر شروع کیا ہے، اور پوسٹ لانچ دستاویز اب بند ہے۔ شماریات دانوں کو وجہ اثر کے ٹھوس، قابل دفاع تخمینوں کی ضرورت ہے۔
مسئلہ یہ ہے کہ Wave 2 ورک اسپیس اب بھی انتظار کر رہی ہے، اسی منگل کو پروڈکٹ وائڈ آن بورڈنگ ری ڈیزائن جاری کیا گیا، اور ہفتہ 20 میں بھی مصروفیت میں سہ ماہی اضافہ دیکھا گیا۔ ہفتہ 20 کے بعد دو گروپوں کا موازنہ خصوصیات کے کارآمد اثرات اور دوبارہ ڈیزائن، موسمی اور انتخاب کے معیار کو ملا دیتا ہے جو یہ طے کرتا ہے کہ کون سی ورک اسپیس ابتدائی طور پر لہر ون تک پہنچتی ہے۔
اس طرح زیادہ تر انٹرپرائز SaaS ٹیمیں 2026 میں AI صلاحیتوں کا آغاز کریں گی۔ اس کا مطلب ہے ایک وقت میں ایک ورک اسپیس کی فراہمی، ترتیب وار اور ریلیز کے شیڈول پر۔ کوئی بے ترتیب نہیں ہے، اور چونکہ کوئی بے ترتیب نہیں ہوتا ہے، A/B ٹیسٹنگ واضح وجہ اثر نہیں دے سکتی۔ نتیجہ ڈیش بورڈ پر ایک نمبر ہے جس کے بارے میں ہر کوئی بحث کر رہا ہے۔
یہ رول آؤٹ کیلنڈر ٹریپ: آپ کے پاس حقیقی ڈیٹا، حقیقی تجرباتی ڈھانچے، اور مکمل طور پر غلط موازنہ ہیں۔ اعداد و شمار کے سائنسدانوں کے لیے جو کہ بڑی تعداد میں AI صلاحیتیں فراہم کرتے ہیں، یہ غلط وجہ کے دعووں کا ایک بڑا ذریعہ ہے۔
تخلیقی AI خصوصیات کے ساتھ پروڈکٹ کے تجربات ایک درست نمونہ کی پیروی کرتے ہیں۔ مفروضہ یہ ہے کہ AI خصوصیات زیادہ مصروفیت کو آگے بڑھائیں گی اور لہر کی ساخت کو اس کی جانچ کرنی چاہئے۔
لہر کیلنڈر نے سکے کے پلٹنے کی جگہ لے لی، اور اس تبدیلی نے ریاضی کو توڑ دیا۔ ایک سادہ A/B موازنہ رول آؤٹ پیدا کیے بغیر بے ترتیب اسائنمنٹ کو فرض کرتا ہے، لہذا پیمائش کا آلہ ناکام ہوجاتا ہے چاہے تجرباتی ڈیزائن درست ہو۔
فرق میں فرق causal inference کا طریقہ ہے جو اسے حل کرتا ہے۔ ہر گروپ میں وقت کے ساتھ نتائج کیسے بدلتے ہیں اس کا موازنہ کرتے ہوئے اور وقت کے رجحانات کو گھٹا کر، ہم بے ترتیب ہونے کے بغیر وجہ کے قابل دفاع تخمینے فراہم کرتے ہیں۔
اس ٹیوٹوریل میں، آپ اسے مصنوعی SaaS پروڈکٹ ڈیٹاسیٹ پر Python کوڈ کو چلانے کے لیے استعمال کریں گے تاکہ انٹرپرائز ورک اسپیس میں تعینات AI صلاحیتوں کے حقیقی دنیا کے کارگر اثر کی پیمائش کی جا سکے۔
آخر تک، آپ کو معلوم ہو جائے گا کہ DiD تخمینہ کیسے چلانا ہے، متوازی رجحانات کے مفروضے کو کیسے جانچنا ہے، اور اگر یہ مفروضہ ناکام ہو جاتا ہے تو کیا کرنا ہے۔
انڈیکس
اسٹیجڈ رول آؤٹس میں A/B ٹیسٹنگ کیوں رک جاتی ہے۔
رینڈم اسائنمنٹ وہ انجن ہے جو A/B ٹیسٹنگ کو ایک درست کازل طریقہ بناتا ہے۔ اگر آپ یہ فیصلہ کرنے کے لیے ایک سکے کو پلٹتے ہیں کہ کن صارفین کو خصوصیت ملے گی، تو علاج اور کنٹرول گروپس تمام صارفین کی یکساں تقسیم کے ساتھ ختم ہوتے ہیں۔ الجھا ہوا شخص (کوئی بھی متغیر جو علاج حاصل کرنے والے اور ناپے جانے والے نتائج دونوں پر اثر انداز ہوتا ہے) تفویض کے بعد نتائج میں فرق علاج کا سبب اثر ہے۔ مکمل سٹاپ
انٹرپرائز ورک اسپیس میں ایک مرحلہ وار رول آؤٹ اس انجن کو تین طریقوں سے توڑتا ہے:
1. لہر کی تقسیم بے ترتیب نہیں ہے۔
پروڈکٹ ٹیمیں مختلف وجوہات کی بنا پر Wave 1 ورک اسپیس کا انتخاب کرتی ہیں۔ اس کا مطلب ہے سب سے زیادہ مصروف مینیجرز، سب سے زیادہ نشستیں، کسٹمر کی کامیابی کے ساتھ بہترین تعلقات، اور بہت کچھ۔ ان وجوہات کا براہ راست تعلق نتائج سے ہے۔ Wave 1 ورک اسپیسز زیادہ مصروفیت دیکھیں گے، قطع نظر اس کے کہ ان میں خصوصیات ہیں یا نہیں۔
2. کیلنڈر وقت کے رجحانات کو متعارف کراتا ہے۔
ہفتہ 20 (پہلی لانچ) اور ہفتہ 30 (دوسری لانچ) کے درمیان، آپ کا پروڈکٹ بہتر ہو جاتا ہے، آن بورڈنگ بہتر ہوتی ہے، اور آپ کی سیلز ٹیم زیادہ سے زیادہ صارفین کو راغب کرتی ہے۔ ایک سادہ "20 ہفتوں کے بعد مشغولیت مائنس 20 ہفتوں سے پہلے شرکت” کا موازنہ فیچر کے اثر کے ساتھ ساتھ ہر چیز کو اپنی گرفت میں لے لیتا ہے۔
3. پروسیس شدہ ورک اسپیس کے اندر اپنانا اپنے آپ میں اختیاری ہے۔
یہاں تک کہ ورک اسپیس کے اندر بھی جو خصوصیت حاصل کرتے ہیں، تمام صارفین اسے فعال نہیں کریں گے۔ اعلی درجے کے صارفین کے لیے، ہاں۔ کم مصروف صارفین اکثر مہینوں انتظار کرتے ہیں۔ وہ صارفین جنہوں نے فیچر کو اپنایا ان کے مقابلے میں جنہوں نے نہیں کیا۔ انتخاب کا تعصبغیر بے ترتیب ورک اسپیس تفویض کے علاوہ، نتائج کی پیمائش کرنے سے پہلے گروپس منظم طریقے سے مختلف تھے۔
A/B ٹیسٹنگ مانتی ہے کہ ان تینوں میں سے کوئی بھی مسئلہ موجود نہیں ہے۔ مرحلہ وار رول آؤٹ تینوں کو یقینی بناتا ہے۔ سادہ موازنہ نمبر فراہم کرتا ہے، اور وہ نمبر شریک تھیئٹرز کی پیمائش کرتے ہیں۔
فرق میں فرق کیا ہوتا ہے۔
کے درمیان اختلافات کا موازنہ کریں: تبدیلی علاج اور کنٹرول گروپوں کے درمیان وقت کے ساتھ نتائج۔ ایک تبدیلی کو دوسرے سے گھٹانے سے مشترکہ وقت کے رجحانات (مصنوعات میں بہتری، موسمی، آن بورڈنگ تبدیلیاں) منسوخ ہو جاتے ہیں۔ دونوں گروہوں کا ایک ہی تجربہ ہے، لہذا صرف علاج کا اثر باقی رہتا ہے۔
یہاں ایک ٹھوس مثال ہے: دو محلوں میں کافی شاپس کی سہ ماہی آمدنی کو ٹریک کرنے کا تصور کریں۔ ایک محلے کو تیسری سہ ماہی میں ایک نیا مدمقابل ملتا ہے، لیکن دوسرے محلے کو نہیں ملتا۔
دونوں خطوں میں مارکیٹ کے یکساں بنیادی رجحانات، مقامی اقتصادی تیزی اور چھٹیوں کے موسم کا تجربہ ہوتا ہے۔ DiD دونوں خطوں سے آمدنی میں تبدیلی کو گھٹا کر حریفوں کے اثرات کو الگ کرتا ہے۔
ایک مرحلہ وار رول آؤٹ بالکل وہی ڈھانچہ ترتیب دیتا ہے۔ Wave 1 ورک اسپیس ایک پڑوس ہے جس میں نئے داخلے ہیں اور Wave 2 ایک موازنہ ہے۔
ریاضی اسے 2×2 ٹیبل کے طور پر باضابطہ بناتا ہے۔ یہاں، قطاریں گروپس ہیں (علاج، کنٹرول)، کالم پیریڈز ہیں (پری، پوسٹ)، اور ہر سیل اس گروپ کے لیے اس مدت کے لیے اوسط نتیجہ رکھتا ہے۔
-
کوئی راستہ نہیں = ویو 1 کے صارفین کے ذریعہ مکمل کیا گیا اوسط کام پہلے ہفتہ 20 (کافی شاپ: دوسری سہ ماہی کی فروخت، حریف والے علاقے)
-
بارش = ویو 1 کے صارفین کے ذریعہ مکمل کیا گیا اوسط کام ~ بعد ہفتہ 20 (کافی شاپ: تیسری سہ ماہی کی فروخت، وہی پڑوس)
-
aspirate = ویو 2 کے صارفین کی طرف سے ہفتہ 20 سے پہلے مکمل کیے گئے اوسط کام (کافی شاپ: Q2 آمدنی، غیر متاثرہ پڑوس)
-
d = ہفتہ 20 کے بعد ویو 2 صارفین کے ذریعہ مکمل کیا گیا اوسط کام (کافی شاپ: Q3 آمدنی، وہی)
Pre Post
Treated (wave 1): A B
Control (wave 2): C D
Naive post-period gap: B - D (contaminated by group differences)
Naive treated change: B - A (contaminated by time trend)
DiD: (B - A) - (D - C) ← the causal effect
B - A یہ لہر 1 سے تبدیلی ہے، لیکن اس میں علاج کا اثر اور وقت کا رجحان دونوں شامل ہیں جس نے ہر کسی کو حرکت میں لایا۔ D - C یہ ایک ہی ونڈو، ایک ہی وقت کے رجحان پر لہر 2 میں تبدیلی ہے، اور کوئی پروسیسنگ نہیں ہے۔ اگر آپ ایک کو دوسرے سے گھٹاتے ہیں تو صرف علاج کا اثر باقی رہتا ہے۔
کہ متضاد علاج کے بغیر پہلی لہر ایسی ہی نظر آتی۔ DiD کو پہنچایا جاتا ہے اور لہر 1 کی متضاد رفتار کی تشکیل کرتا ہے = لہر 1 کی پری پیریڈ لیول، لہر 2 کے بعد کی مدت کا رجحان۔ اصل Wave 1 کی رفتار اور جوابی رفتار کے درمیان فرق DiD تخمینہ ہے۔
شکل 1: فرق میں فرق کا استعمال کرتے ہوئے وجہ کا اندازہ۔ بلیو ٹھوس: لہر 1 کی اصل رفتار۔ اورنج ڈاٹڈ لائن: لہر 2 (کنٹرول، اس مدت کے دوران علاج نہیں کیا گیا)۔ بلیو ڈاٹڈ لائن: جوابی، جہاں پہلی لہر دوسری لہر کی مدت کے بعد رجحان کی بنیاد پر چلی ہوگی۔ سبز تیر ڈی آئی ڈی کا تخمینہ ہے، یعنی علاج کے بعد کی مدت میں اصل لہر 1 کی رفتار اور جوابی رفتار کے درمیان فرق۔ A, B, C, D اوپر دیے گئے جدول کے چار خلیات سے مماثل ہیں۔
ہفتہ 20 سے پہلے، لہریں 1 اور 2 ایک دوسرے کو قریب سے ٹریک کرتی ہیں۔ یہ کام پر متوازی رجحان کی ضرورت ہے۔ ہفتہ 20 میں، لہر 1 لہر 2 سے آگے ہے اور کاؤنٹر فیکچوئل (ڈاٹڈ لائن)۔ علاج کے بعد کی تبدیلی ڈی آئی ڈی کا تخمینہ ہے۔
DiD تخمینہ بیک وقت دونوں قسم کے تعصب کو سنبھالتا ہے۔ علاج شدہ اور کنٹرول گروپس کے درمیان مستقل اختلافات (بنیادی ورک اسپیس ہمیشہ زیادہ مشغول رہتی ہے) کو پورا کیا جاتا ہے کیونکہ DiD توجہ مرکوز کرتا ہے: تبدیلی وقت کے ساتھ نتائج۔ وقت کے رجحانات جو دونوں گروپوں کو متاثر کرتے ہیں (مصنوعات میں بہتری، مارکیٹ کی موسمی حالت) کو پورا کیا جاتا ہے کیونکہ دونوں گروپ ان کا تجربہ کرتے ہیں۔
DiD بدلے میں ایک چیز پوچھتا ہے: دوسرے لفظوں میں، متوازی پری پروسیسنگ کا رجحان ہے۔ علاج شروع ہونے سے پہلے علاج اور کنٹرول گروپس کو ایک ہی سمت اور ایک ہی رفتار سے حرکت کرنا چاہیے۔ ایک بار یہ قائم ہونے کے بعد، مشترکہ رجحانات کا اندازہ لگایا جا سکتا ہے اور علاج کے بعد کے فرق کو علاج سے منسوب کیا جا سکتا ہے۔ اگر علاج سے پہلے ہی رجحان بدل گیا ہے، تو DiD متعصب ہے اور اس کے لیے کوئی ہوشیار رجعت کا طریقہ درست نہیں کر سکتا۔
متوازی رجحانات وہ مفروضہ ہیں جن کا مرحلہ 3 میں تجربہ کیا جائے گا۔
ساتھ والا لیپ ٹاپ
اس ٹیوٹوریل کے تمام کوڈ، بشمول مصنوعی ڈیٹاسیٹس، ڈی ڈی ریگریشن، متوازی ٹرینڈ پلاٹ، اور پلیسبو پری ٹرینڈ ٹیسٹنگ، GitHub ریپوزٹری میں اس سیریز کے لیے GenAI اور LLM ایپلی کیشنز کے لیے کارآمد نتائج کے لیے ایک قابل عمل Jupyter نوٹ بک میں ہے۔
آپ اسے کلون کر کے چلا سکتے ہیں۔ generate_data.py اس مضمون سے تمام آؤٹ پٹ بالکل اس پر دوبارہ تیار کیا گیا ہے: github.com/RudrenduPaul/product-experimentation-causal-inference-genai-llm
شرطیں
آپ کو Python 3.11 یا اس سے زیادہ کی ضرورت ہوگی اور آپ پانڈوں اور بنیادی رجعت سے واقف ہوں گے۔ مضمون پہلی بار ظاہر ہونے پر کنفاؤنڈرز اور سلیکشن تعصب کی ان لائن وضاحت کرتا ہے، اس لیے آپ بغیر کسی پیشگی وجہ کے تجربے کے ان کی پیروی کر سکتے ہیں۔ مرحلہ 2 میں، ہمیں کلسٹرڈ معیاری خامیاں اور ایڈجسٹ شدہ اثرات کا سامنا کرنا پڑتا ہے۔ یہ مضمون وضاحت کرے گا کہ یہ غلطی کیا کرتی ہے اور یہ کیوں اہم ہے، لیکن یہ شروع سے اخذ نہیں کی جائے گی۔
اس ٹیوٹوریل کے لیے پیکجز انسٹال کریں۔
pip install numpy pandas statsmodels linearmodels matplotlib
مصنوعی ڈیٹاسیٹ حاصل کرنے کے لیے، ساتھی ریپوزٹری کو کلون کریں۔
git clone https://github.com/RudrenduPaul/product-experimentation-causal-inference-genai-llm.git
cd product-experimentation-causal-inference-genai-llm
python data/generate_data.py --seed 42 --n-users 50000 --out data/synthetic_llm_logs.csv
ورکنگ مثال سیٹ اپ
ڈیٹا سیٹ دو لہروں میں جاری کردہ AI خلاصہ خصوصیات کا استعمال کرتے ہوئے SaaS مصنوعات کی نقل کرتا ہے۔ ویو 1 ورک اسپیس ہفتہ 20 میں دستیاب ہوگا اور ویو 2 ہفتہ 30 میں دستیاب ہوگا، ہر لہر میں کل 50,000 صارفین اور ایک ٹیلی میٹری قطار کے ساتھ۔
ڈیٹا جنریٹر ورک اسپیس کی پوسٹ پروسیسنگ مدت کے دوران صارف کے کام کی تکمیل پر +5 فیصد پوائنٹ کازل اثر کا اطلاق کرتا ہے۔ چونکہ ہم سچائی کو پہلے سے جانتے ہیں، اس لیے ہم اس بات کی تصدیق کر سکتے ہیں کہ DiD کا تخمینہ لگانے والا حقیقت میں سچائی کو بازیافت کرتا ہے۔
ڈیٹا لوڈ کریں اور اس کی ساخت چیک کریں۔
import pandas as pd
df = pd.read_csv("data/synthetic_llm_logs.csv")
print(df.shape)
print(df[["wave", "signup_week", "workspace_id", "task_completed"]].head())
print("nWave sizes:", df.wave.value_counts().to_dict())
print("Treatment weeks per wave:",
df.groupby("wave").treatment_week.first().to_dict())
متوقع پیداوار:
(50000, 16)
wave signup_week workspace_id task_completed
0 2 10 36 0
1 2 51 44 1
2 2 2 28 1
3 1 15 20 1
4 1 29 0 1
Wave sizes: {2: 25063, 1: 24937}
Treatment weeks per wave: {1: 20, 2: 30}
یہاں کیا ہو رہا ہے: 50,000 قطاریں لوڈ کریں، فی صارف ایک۔ ویو 1 کے 25 ورک اسپیس میں تقریباً 24,937 صارفین ہیں۔ ویو 2 کے 25 مختلف ورک اسپیس میں تقریباً 25,063 صارفین ہیں۔ کہ treatment_week کالم ریکارڈ کرتا ہے جب ہر صارف کے ورک اسپیس نے AI سمری کی صلاحیتیں حاصل کیں (ویو 1 کے لیے ہفتہ 20 اور لہر 2 کے لیے ہفتہ 30)۔ کہ task_completed گرمی کا نتیجہ ہے۔ آیا AI نے صارف کا کام کامیابی کے ساتھ مکمل کیا۔
ایک اہم تفصیل: signup_week اس ڈیٹاسیٹ میں، ہم اس ہفتے کو ریکارڈ کرتے ہیں جب کسی صارف نے پروڈکٹ کے ساتھ پہلی بار مشغول کیا تھا اور اسے وقت کے اشارے کے طور پر استعمال کرتے ہیں تاکہ صارفین کو علاج سے پہلے یا علاج کے بعد کے گروپ کو تفویض کیا جا سکے۔
وہ صارفین جنہوں نے ہفتہ 22 میں سائن اپ کیا تھا فیچر لانچ ہونے کے بعد سائن اپ کیا، اس لیے ان کا تجربہ "پوسٹ ٹریٹمنٹ” ہے۔ وہ صارفین جنہوں نے ہفتہ 14 میں سائن اپ کیا تھا، لانچ سے پہلے سائن اپ کیا، اس لیے ان کا تجربہ ‘پری پروسیسڈ’ ہے۔
یہ یہاں کام کرتا ہے کیونکہ ہر صارف کے پاس ان کے ابتدائی پروڈکٹ کے تجربے سے منسلک ایک ٹیلی میٹری قطار ہوتی ہے۔ وقت کے ساتھ ساتھ فی صارف متعدد مشاہدات کے ساتھ پینل ڈیٹاسیٹس ایک مشاہداتی ٹائم اسٹیمپ کالم کا استعمال کرتے ہیں جو ہر قطار کو ریکارڈ کرنے کے وقت سے وابستہ ہوتا ہے۔
اپنے تجزیہ کو صاف رکھنے کے لیے، اسے ان صارفین تک محدود رکھیں جنہوں نے Wave 2 کے آغاز سے پہلے سائن اپ کیا تھا (signup_week < 30)۔ ویو 2 نے ایک مناسب کنٹرول گروپ کے طور پر کام کیا کیونکہ انہیں ابھی تک علاج نہیں ملا تھا، جبکہ ویو 1 نے 10 ہفتوں تک علاج حاصل کیا تھا۔
analysis = df[df.signup_week < 30].copy()
analysis["post"] = (analysis.signup_week >= 20).astype(int)
analysis["treated"] = (analysis.wave == 1).astype(int)
print(analysis.groupby(["treated", "post"])
.agg(n=("user_id", "count"),
mean_completion=("task_completed", "mean"))
.round(3))
متوقع پیداوار:
n mean_completion
treated post
0 0 9590 0.556
1 4878 0.555
1 0 9633 0.592
1 4738 0.643
یہاں کیا ہو رہا ہے: تجزیہ ونڈو (ہفتے 0 سے 29) کے ذریعہ ڈیٹا کو فلٹر کریں اور دو ڈسپلے متغیرات بنائیں۔ post 1 ہفتہ 20 یا اس کے بعد کے صارفین کے لیے، بصورت دیگر 0۔ treated لہر 1 صارفین کے لیے 1 اور لہر 2 صارفین کے لیے 0 ہے۔ گروپ بائی DiD 2x2 ٹیبل میں چار سیل دکھاتا ہے: (Process=0, Post=0), (Process=0, Post=1), (Process=1, Post=0), (Process=1, Post=1)۔ یہ چار ذرائع ہیں جو آپ کو پہلے DiD تخمینہ کے لیے درکار ہیں۔
مرحلہ 1: سادہ 2x2 DiD
صاف ترین ورژن کے ساتھ شروع کریں۔ 4 خلیات کی اوسط کا براہ راست حساب لگائیں اور پھر فرق کا فرق معلوم کریں۔
cells = analysis.groupby(["treated", "post"]).task_completed.mean()
wave2_pre = cells.loc[(0, 0)] # control, pre
wave2_post = cells.loc[(0, 1)] # control, post
wave1_pre = cells.loc[(1, 0)] # treated, pre
wave1_post = cells.loc[(1, 1)] # treated, post
did_effect = (wave1_post - wave1_pre) - (wave2_post - wave2_pre)
print(f"Wave 1 change: {wave1_post - wave1_pre:+.4f}")
print(f"Wave 2 change: {wave2_post - wave2_pre:+.4f}")
print(f"DiD effect: {did_effect:+.4f}")
متوقع پیداوار:
Wave 1 change: +0.0515
Wave 2 change: -0.0013
DiD effect: +0.0527 (ground truth = +0.05)
یہاں کیا ہو رہا ہے: 4 سیلز کی اوسط لیں، پہلے سے پوسٹ تک کام کی تکمیل کے لیے لہر 1 میں تبدیلی کا حساب لگائیں، اسی کیلنڈر ونڈو کے لیے لہر 2 میں تبدیلی کا حساب لگائیں (ویو 2 پر ابھی عمل نہیں ہوا ہے) اور فرق لیں۔ ڈی ڈی کا تخمینہ لہر 1 میں تبدیلی کا وہ حصہ ہے جس کی وضاحت کسی بھی وقت کے رجحان سے نہیں کی جا سکتی جس کے ساتھ لہر 2 بھی منتقل ہوئی۔
اس ڈیٹاسیٹ میں، ایک سادہ 2x2 تخمینہ +0.053 تک پہنچتا ہے، جو کہ اصل +0.05 کے بہت قریب ہے۔ تاہم، آپ اس نمبر کو پروڈکٹ کے جائزوں کے لیے استعمال نہیں کر سکتے۔ کوئی معیاری غلطیاں نہیں ہیں۔ اس کا مطلب ہے کہ ہم یہ نہیں بتا سکتے کہ آیا +0.053 اصل سگنل ہے یا سیمپلنگ شور کے اندر۔ کوئی کوواریٹ ایڈجسٹمنٹ نہیں ہے، لہذا کچھ +0.053 شرکت کی سطح بندی کی وجہ سے ہو سکتے ہیں اگر لہر 1 میں اس گروہ میں زیادہ بھاری صارفین تھے۔ اور ڈیٹا میں ورک اسپیس سطح کے ارتباط کو سنبھالنے کا کوئی طریقہ نہیں ہے۔ مرحلہ 2 تینوں کو ٹھیک کرتا ہے۔
مرحلہ 2: مقررہ اثرات کے ساتھ ریگریشن ڈی ڈی
DiD کا ریگریشن فارمولہ covariates کی غیر موجودگی میں 2x2 ٹیبل کے برابر پوائنٹ تخمینہ تیار کرتا ہے۔ لیکن یہ تین چیزیں بھی خریدتا ہے:
-
معیاری خرابی اور پی ویلیو صحیح حساب لگایا
-
Covariate ایڈجسٹمنٹ فرق کو کم کرنے اور تخمینوں کو تیز کرنے کے لیے
-
کلسٹر میں مضبوط ناکامی۔ مرحلہ وار رول آؤٹ ہمیشہ ورک اسپیس کے اندر باہمی تعلق کو ہینڈل کرتے ہیں۔
رجعت یہ ہے: outcome ~ treated + post + treated:post + controls. گتانک ہے۔ treated:post تعاملات ڈی ڈی تخمینہ ہیں۔
import statsmodels.formula.api as smf
did_model = smf.ols(
"task_completed ~ treated * post + C(engagement_tier)",
data=analysis
).fit(
cov_type="cluster",
cov_kwds={"groups": analysis.workspace_id}
)
print(did_model.summary().tables[1])
متوقع پیداوار:
================================================================================================
coef std err z P>|z| [0.025 0.975]
------------------------------------------------------------------------------------------------
Intercept 0.8301 0.007 126.538 0.000 0.817 0.843
C(engagement_tier)[T.light] -0.4027 0.006 -63.168 0.000 -0.415 -0.390
C(engagement_tier)[T.medium] -0.1766 0.007 -25.931 0.000 -0.190 -0.163
treated 0.0367 0.005 6.885 0.000 0.026 0.047
post -0.0056 0.008 -0.684 0.494 -0.022 0.011
treated:post 0.0541 0.011 4.981 0.000 0.033 0.075
================================================================================================
یہ ہے کیا ہو رہا ہے: کام کی تکمیل کے لیے عام کم از کم مربع رجعت treated خصوصیت post میٹرکس، تعاملات، اور مشغولیت کی تہوں پر واضح کنٹرول۔
کہ treated:post گتانک DiD تخمینہ ہیں۔ ایک ہی ورک اسپیس کے استعمال کنندگان ایک مشترکہ جذبے کا اشتراک کرتے ہیں، نتائج کو مربوط کرتے ہیں۔ کی طرف سے گروپ workspace_id میں اس پر آپ کو درست کرنا چاہتا ہوں۔
اس ڈیٹا سیٹ میں treated:post گتانک <0.001 کی کلسٹرڈ p- ویلیو کے ساتھ +0.054 معلوم ہوتا ہے۔ اصل قیمت +0.050 ہے۔ کام کی جگہ کی سطح کے ارتباط کے حساب سے معیاری غلطیوں کے ساتھ، حقیقی اثر سے 0.4 فیصد پوائنٹس ایک ایسی تعداد ہے جسے پروڈکٹ کے جائزے میں شامل کیا جا سکتا ہے۔
اس رجعت کے بارے میں چند عملی نوٹ:
-
کنٹرول کو وقت کے ساتھ تبدیل نہیں ہونا چاہئے۔ (شرکت کی کلاس، سبسکرپشن گروپ)۔ علاج سے متاثر ہونے والے وقت کے مختلف کنٹرول تخمینوں کی طرفداری کریں گے۔
-
صرف تعاملات کی وجہ کی تشریح ہوتی ہے۔ مداخلت اور سطح کی شرائط گروپوں کے درمیان بنیادی فرق کو بیان کرتی ہیں۔
-
کلسٹرڈ غلطیاں درکار ہیں۔ اگر آپ کلسٹرنگ کو چھوڑ دیتے ہیں، تو آپ کی معیاری غلطیاں 3 سے 10 گنا بہت چھوٹی ہوں گی اور آپ کے ٹیسٹ کے اعدادوشمار مصنوعی طور پر بڑھائے جائیں گے، جس سے آپ کے نتائج واقعی ان سے کہیں زیادہ اہم معلوم ہوتے ہیں۔
مرحلہ 3: متوازی رجحان کے مفروضوں کو چیک کریں۔
DiD صرف اس صورت میں درست ہے جب لہر 1 اور لہر 2 ایک ہی سمت اور ایک ہی رفتار سے حرکت کریں۔ پہلے علاج شروع ہو گیا ہے۔ پری پروسیسنگ ونڈو پر دونوں لہروں کے لئے ہفتہ وار اوسط کو پلاٹ (یا ٹیبلٹنگ) کرکے اسے چیک کریں۔
import matplotlib.pyplot as plt
import numpy as np
df_plot = df[df.signup_week < 30].copy()
weekly = (df_plot.groupby(["signup_week", "wave"])
.task_completed.mean()
.reset_index()
.pivot(index="signup_week", columns="wave", values="task_completed"))
# 3-week rolling average to smooth week-to-week sampling noise
smoothed = weekly.rolling(3, center=True, min_periods=2).mean()
TREATMENT_WEEK = 20
pre_idx = smoothed.index[smoothed.index < TREATMENT_WEEK]
post_idx = smoothed.index[smoothed.index >= TREATMENT_WEEK]
# DiD counterfactual: wave 1 pre-period mean + wave 2's post-period change
wave1_pre_mean = smoothed.loc[pre_idx, 1].mean()
wave2_pre_mean = smoothed.loc[pre_idx, 2].mean()
counterfactual = wave1_pre_mean + (smoothed.loc[post_idx, 2].values - wave2_pre_mean)
fig, ax = plt.subplots(figsize=(10, 5.5))
ax.axvspan(-0.5, TREATMENT_WEEK, alpha=0.04, color="#94A3B8", zorder=0)
ax.axvspan(TREATMENT_WEEK, 29.5, alpha=0.06, color="#3B82F6", zorder=0)
ax.plot(smoothed.index, smoothed[2], "s--", color="#F59E0B", linewidth=2,
markersize=4, label="Wave 2 — control (untreated during this window)", zorder=3)
ax.plot(smoothed.index, smoothed[1], "o-", color="#2563EB", linewidth=2.2,
markersize=4, label="Wave 1 — treated (AI feature on at week 20)", zorder=4)
ax.plot(post_idx, counterfactual, ":", color="#2563EB", linewidth=2.2,
label="Wave 1 counterfactual (projected without treatment)", zorder=4)
ax.axvline(TREATMENT_WEEK, color="#DC2626", linestyle="--", linewidth=1.8,
label="AI feature launched (week 20)")
ax.text(9.5, 0.508, "Pre-treatment periodn(parallel trends required)",
fontsize=9, ha="center", color="#64748B", style="italic")
ax.text(24, 0.508, "Post-treatment",
fontsize=9, ha="center", color="#64748B", style="italic")
ax.set_xlabel("Week", fontsize=11)
ax.set_ylabel("Mean task completion rate", fontsize=11)
ax.set_title("Figure 2: Data-Driven Parallel-Trends Checkn(3-week rolling average, 50k users)",
fontsize=12, fontweight="bold", pad=14)
ax.legend(loc="upper left", fontsize=9, framealpha=0.92)
ax.set_xlim(-0.5, 29.5)
ax.set_ylim(0.50, 0.72)
ax.grid(True, alpha=0.18, linestyle=":")
ax.tick_params(labelsize=10)
plt.tight_layout()
plt.savefig("parallel_trends.png", dpi=150, bbox_inches="tight")
print("Saved parallel_trends.png")
متوقع نتائج (شکل 2، ڈیٹا سے چلنے والی توثیق):
Saved parallel_trends.png

شکل 2 حقیقی ڈیٹا سیٹ کا ڈیٹا سے چلنے والا متوازی ٹرینڈ چیک ہے، جو ہفتہ وار نمونے لینے کے شور کو ہموار کرنے کے لیے تین ہفتے کی متحرک اوسط کے طور پر پیش کیا جاتا ہے۔ دونوں لہریں 20 ہفتے پہلے ایک دوسرے کو قریب سے ٹریک کرتی ہیں، پچھلے دور کے چھوٹے جھٹکوں کے ساتھ ایک ہی وقت میں دونوں گروہوں کو متاثر کرتے ہیں، جسے ہم متوازی رجحانات کے طور پر دیکھتے ہیں۔ ہفتہ 20 کے بعد، لہر 1 نقطے والی لائن کے مخالف ٹھوس لائن کے اوپر صاف طور پر الگ ہو جاتی ہے۔ پوسٹ پروسیسنگ ونڈو میں نیلی ٹھوس اور ڈیشڈ لائنوں کے درمیان فرق حقیقی ڈیٹا سے دوبارہ تیار کردہ ڈی ڈی تخمینہ ہے۔
یہاں کیا ہو رہا ہے: سائن اپ ہفتہ اور لہر کے لحاظ سے گروپ بنائیں، فی سیل کام کی اوسط تکمیل کا حساب لگائیں، پیوٹ کریں تاکہ ہر لہر ایک کالم ہو، اور دونوں ٹائم سیریز کو ایک ساتھ دکھائیں۔
عمودی ڈیشڈ لائن ہفتہ 20 کو نشان زد کرتی ہے، جب پہلی لہر کا علاج ہوا۔ علاج سے پہلے کی مدت (0-19 ہفتوں) میں، دونوں سیریز کو ایک دوسرے کو قریب سے ٹریک کرنا چاہیے۔ ہفتہ 20 کے بعد، Wave 1 کو Wave 2 کی تقریباً علاج کے اثر سے رہنمائی کرنی چاہیے۔
اگر آپ نمبروں کو کم کرنا چاہتے ہیں، تو صرف علاج سے پہلے کی مدت کے لیے پلیسبو ریگریشن چلائیں۔ ہم پروسیس شدہ اشارے کے ساتھ تعامل کرنے والے لکیری وقت کے رجحان کے خلاف نتائج کو پیچھے چھوڑتے ہیں۔ اگر تعامل کا گتانک 0 کے قریب تھا اور اہم نہیں تھا، تو دونوں گروپ علاج سے پہلے متوازی طور پر منتقل ہو گئے تھے۔
pre_only = analysis[analysis.post == 0].copy()
pre_only["weeks_since_start"] = pre_only.signup_week - 10 # center
placebo_model = smf.ols(
"task_completed ~ treated * weeks_since_start + C(engagement_tier)",
data=pre_only
).fit(
cov_type="cluster",
cov_kwds={"groups": pre_only.workspace_id}
)
print("Pre-trend slope difference:",
placebo_model.params["treated:weeks_since_start"])
print("p-value:",
placebo_model.pvalues["treated:weeks_since_start"])
متوقع پیداوار:
Pre-trend slope difference: -0.00095...
p-value: 0.4435...
یہاں کیا ہو رہا ہے: اپنے آپ کو علاج سے پہلے کے مشاہدات تک محدود رکھتے ہوئے، ہم ایک رجعت کو فٹ کرتے ہیں کہ لہر 1 اور لہر 2 علاج سے پہلے کی مدت میں مختلف لکیری رجحانات کی پیروی کرتے ہیں اور تعامل کے قابلیت کو پڑھتے ہیں۔
0 کے قریب ایک عدد، p > 0.05 کے ساتھ، کا مطلب ہے کہ علاج سے پہلے دونوں لہریں متوازی حرکت کرتی ہیں۔ اگر گتانک بڑا اور شماریاتی لحاظ سے اہم ہے تو متوازی رجحانات کا مفروضہ ٹوٹ جاتا ہے۔ یعنی، ڈی آئی ڈی کا تخمینہ ان تمام تفریق رجحانات کو جذب کرتا ہے جنہوں نے 20 ہفتے قبل گروپوں کو الگ کیا تھا۔
اگر پلیسبو ٹیسٹ ناکام ہو جاتا ہے تو رکیں اور دوبارہ سوچیں۔ اختیارات یہ ہیں: متوازی رجحانات کے ساتھ ایک تنگ پرانی ونڈو تک محدود رکھیں، کنٹرولز کا ایک بہتر گروپ تلاش کریں، یا مصنوعی کنٹرولز پر سوئچ کریں جو متعدد خام اکائیوں سے وزنی جوابی حقائق بناتے ہیں۔
اس مصنوعی ڈیٹاسیٹ پر پلیسبو ٹیسٹ پاس ہو گیا۔ پری ٹرینڈ ڈھلوان کا فرق -0.00095 (p = 0.44) ہے، اس لیے متوازی رجحانات کا قیاس ہے اور مرحلہ 2 سے +0.054 کا تخمینہ قابل اعتماد ہے۔
جب فرق کا فرق ناکام ہوجاتا ہے۔
DiD اکاؤنٹنگ کا ایک درست طریقہ ہے، اور تمام درست طریقوں میں کچھ ناکامی کے طریقے ہوتے ہیں جن کے بارے میں آپ کو نتائج پر بھروسہ کرنے سے پہلے آگاہ ہونا ضروری ہے۔ یہاں چار عام ہیں:
1. غیر متوازی پری رجحان
اگر علاج اور کنٹرول گروپ علاج شروع ہونے سے پہلے ہی مختلف ہو رہے ہیں، تو DiD علاج کے اثر کے لیے موجودہ بہاؤ کو غلط سمجھتا ہے۔
تین مراحل کا پلیسبو ٹیسٹ محفوظ ہے۔ اسے ہر بار چلانے کی کوشش کریں۔ اگر آپ ناکام ہو جاتے ہیں، تو آپ کے پاس تین اختیارات ہیں:
-
اپنے تجزیے کو پہلے کی مختصر مدت تک محدود رکھیں جہاں رجحانات ایک جیسے ہوں اور پلیسبو کو دوبارہ چلائیں۔
-
ایک بہتر کنٹرول گروپ تلاش کریں جس کے سابقہ رجحانات علاج کے گروپ سے مماثل ہوں۔
-
ہم متعدد غیر پروسیس شدہ اکائیوں سے وزنی جوابی حقائق بناتے ہیں اور مصنوعی کنٹرول پر سوئچ کرتے ہیں، جو ایسے وزن کا انتخاب کرتا ہے جو علاج شدہ گروپوں کی پری پروسیسنگ رفتار سے میل کھاتا ہے۔
2. لڑکھڑا کر اپنانا
تین یا زیادہ لہروں کے ساتھ مرحلہ وار رول آؤٹ کے لیے صاف 2x2 سے مختلف نقطہ نظر کی ضرورت ہوتی ہے۔ ویو 1 ہفتہ 20 پر، ویو 2 پر ہفتہ 30 پر اور ویو 3 پر ہفتہ 40 پر کارروائی کی جاتی ہے۔ ایک بار ویو 2 پر کارروائی ہو جانے کے بعد، یہ 30 اور اس کے بعد کے ویو 1 کے موازنہ کے لیے درست کنٹرول نہیں رہتا ہے۔ پہلے پروسیس شدہ یونٹس بعد میں پروسیس شدہ یونٹس کے لیے کنٹرول کے طور پر کام کرنا شروع کر دیتے ہیں، اندازوں کو آلودہ کرتے ہیں۔
یہ گڈمین بیکن سڑنے کا مسئلہ ہے، اور اسٹیج 2 میں معیاری دو طرفہ فکسڈ اثرات کا تخمینہ لگانے والا اسے خود بخود جذب کر لیتا ہے۔ Callaway-Sant'Anna کا تخمینہ لگانے والا (2021 پیپر دیکھیں) اس مسئلے کو صرف صاف 2x2 موازنہ کی اوسط سے حل کرتا ہے اور آلودہ موازنہ کو مسترد کرتا ہے۔ کہ differences ازگر میں ایک پیکیج اس کو نافذ کرتا ہے۔
3. وقت کے لحاظ سے مختلف الجھنے والے عوامل جو صرف علاج شدہ گروپ کو متاثر کرتے ہیں۔
اگر آپ کی مارکیٹنگ ٹیم ہفتہ 22 میں آپ کے بنیادی ورک اسپیس میں ایک ٹارگٹڈ مہم چلاتی ہے، تو آپ کو علاج سے متعلق ایک جھٹکا لگے گا جسے DiD برداشت نہیں کر سکتا۔
متوازی رجحانات علاج سے پہلے کی مدت کی تصدیق کرتے ہیں، لیکن علاج کے بعد کی مدت آڈیٹنگ کے لیے ذمہ دار ہے۔
تجزیہ ونڈو کے اندر تمام مصنوعات یا مارکیٹنگ کے واقعات کو چیک کریں۔ ایک بار مل جانے کے بعد، صرف ایک ہی اختیارات ہیں کہ مطالعہ کو دوبارہ ڈیزائن کریں، تجزیے کو پری شاک ونڈو تک محدود کریں، یا جھٹکے کو دوسرے علاج کے متغیر کے طور پر واضح طور پر ماڈل کریں۔
4. متوقع اثرات
اگر Wave 1 کے صارفین کو ہفتہ 18 میں معلوم ہوتا کہ یہ خصوصیت ہفتہ 20 میں دستیاب ہو گی، تو ہو سکتا ہے کہ کچھ نے مختلف طریقے سے کام کرنا شروع کر دیا ہو، مزید سائن اپ کرنا، ترتیبات کو پہلے سے ترتیب دینا، اور تکنیکی طور پر علاج شروع ہونے سے پہلے سپورٹ سے رابطہ کرنا۔ یہ "پری" مدت کو آلودہ کرتا ہے۔ ایونٹ اسٹڈی پلاٹ میں ہفتہ 20 سے پہلے کے ہفتوں میں لہر 1 کے عروج یا زوال کی نمائندگی کرتا ہے۔
حل یہ ہے کہ پری پیریڈ کٹ آف کو پیچھے دھکیل دیا جائے۔ تجزیہ کے مقاصد کے لیے، ہفتہ 18 کو "علاج" کا آغاز سمجھا جاتا ہے، جس سے قبل از ماہواری کی بنیاد سے تخمینی مدت کو ہٹا دیا جاتا ہے۔
ناکامی کے ان طریقوں میں سے ہر ایک کی تشخیص اور مخصوص کام ہوتا ہے۔ اپنے تجزیہ کو نام دینے سے شکی جائزہ لینے والوں کے ساتھ اس کی ساکھ بڑھ جاتی ہے۔ DiD ایک محتاط اکاؤنٹنگ ID ہے۔ جب تک ان پٹ صاف ہے، یہ درست اور قابل اعتماد تخمینہ پیدا کرتا ہے۔
آگے کیا کرنا ہے۔
مندرجہ بالا رجعت DiD دو مرحلے کے رول آؤٹ کے لیے موزوں ٹول ہے۔ اگر آپ کے رول آؤٹ میں تین سے زیادہ لہریں ہیں، تو Callaway-Sant'Anna تخمینہ لگانے والے پر جائیں۔ اگر آپ کا رول آؤٹ جان بوجھ کر طے شدہ پروسیسنگ تھریشولڈز (اعتماد کا سکور، استفسار کی پیچیدگی) سے تجاوز کرتا ہے، تو رجعت کے وقفے کی چھان بین کریں۔ اگر آپ کسی ایک پراسیس شدہ یونٹ کا ایک تعمیر شدہ کاؤنٹر فیکچوئل سے موازنہ کرنا چاہتے ہیں تو جامع کنٹرول صحیح انتخاب ہے۔
اس ٹیوٹوریل کے لیے ساتھی نوٹ بک یہاں ہے۔ ریپوزٹری کو کلون کریں اور اس کا استعمال کرتے ہوئے ایک مصنوعی ڈیٹاسیٹ بنائیں: generate_data.pyاور کھولیں did_demo.ipynb پہلے سے محفوظ شدہ آؤٹ پٹ کے ساتھ کسی کوڈ بلاک کو دوبارہ تیار کریں۔
اگر آپ AI خصوصیات کو ترتیب وار رول آؤٹ کر رہے ہیں، تو آپ کا ریلیز شیڈول پہلے سے ہی ایک DiD مطالعہ ہے۔ صرف سوال یہ ہے کہ آیا آپ تجزیہ چلاتے ہیں یا نہیں۔