Egy webshop üzemeltetője két, látszólag hasonló kérdést tesz fel a data scientistnek:
A Northstar mesterséges esetben mindkettő tanulóadattal vizsgálható,
de nem ugyanazzal a megfigyelési egységgel. Az első
kérdés megfigyelési egysége a rendelés
(order_id), a másodiké a randomizált
ügyfél (customer_id). Aki a második kérdésre a
rendelési tábla soraiból akar hatást becsülni, összekeverheti a
randomizálási egységet és a megfigyelési egységet. Randomizált
kísérletben a hozzárendelést és az elemzési nevezőt ügyfélszinten kell
megőrizni; megfigyeléses oksági elemzés is lehetséges, de külön
azonosítási feltevéseket és torzításvizsgálatot igényel.
A fejezet célja, hogy az üzleti kérdésből pontos bemenetet, kimenetet és ellenőrzési feltételt adjunk. Nem modellt építünk még, hanem a feladatot írjuk le úgy, hogy egy későbbi modell ne válaszolhasson rossz kérdésre.
1. problémalap: rendeléskori késési kockázat
orders.csv egy
sora, kulcsa order_id.order_ts,
promised_days=7, quantity_sum,
item_rows, basket_minor,
shipping_fee_minor, distance_km,
priority_flag, valamint az ügyfél segment,
region, acquisition_channel és a rendeléskor
már ismert account_age_days.delivery_days, amelyből a célváltozó
delivery_days,
actual_delivery_at, target_late utólagos; a
modell betanításakor címke lehet, de a predikció bemenetében nem. A
tanító és teszt elválasztás időbeli, és a tanítócímke csak akkor
használható, ha a cutoff előtt megérkezett.2. problémalap: randomizált változtatás hatása
assignments.csv minden ügyfelet control vagy
treatment csoportba sorol.outcomes.csv minden ügyfélre ugyanazon 7 napos
ablakban tartalmazza a conversion_7d 0/1 kimenetet.A leírás múltbeli vagy jelenlegi adatot foglal össze: „a múlt hónapi rendelések 22%-a késett”. Az előrejelzés ismeretlen kimenetre ad esélyt vagy várható értéket: „ennek az új rendelésnek 35% az esélye a késésre”. A leírásnak nincs szüksége modellre, az előrejelzésnek igen, mert a célkimenet a döntés pillanatában még nem ismert.
A kísérlet során a kutató maga osztja kezelésre és
kontrollra a megfigyelési egységeket; a Northstar
assignments.csv ügyfélszintű randomizálást rögzít. A
megfigyeléses elemzésben nem avatkozunk be, csak azt
nézzük, ami megtörtént. A rendelési táblából például le lehet írni, hogy
a priority_flag=1 rendelések késnek-e gyakrabban, de ez
önmagában nem bizonyítja, hogy a prioritás okozza a
különbséget, mert a prioritást kapó rendelések szisztematikusan mások is
lehetnek.
Az estimand az a sokasági, ismeretlen mennyiség, amelyre a statisztikai eljárás következtetni akar. A kísérleti problémában az estimand , a hozzárendelés szerinti két potenciális kimenet várható értékének különbsége. A becslés ebből a mintából számított konkrét szám lesz; a becslési céltól különbözik.
A predikciós feladatban az estimand lehet egy új rendelés feltételes késési valószínűsége:
Itt a rendeléskor ismert feature-vektor. Ezt a feltételes várható értéket később modellel közelítjük; a modell által adott a becslés.
A késési kockázatnál a döntési pillanat az order_ts:
amikor a rendelés létrejön, a rendszernek azonnal kockázati becslést
kell adnia. A döntéshozó azonban jellemzően nem a data scientist, hanem
az ügyfélkapcsolati vagy logisztikai folyamat felelőse: ő határoz meg
egy küszöböt, például „30% felett küldjünk kompenzációt tartalmazó
üzenetet”. A data scientist ebben a munkamegosztásban a predikciós
szerződést és az értékelést adja; a küszöb üzleti döntés.
A kísérletnél a döntési pillanat a randomizálás előtti protokollrögzítés; a változtatás bevezetéséről a kísérleti jelentés után dönt a terméktulajdonos. Az ő döntésére a becsült hatás mellett a bizonytalanság és a megvalósítási költség is tartozik. A statisztikus feladata nem az, hogy „szignifikáns?” feliratot adjon, hanem hogy az estimandot, a becslést és annak bizonytalanságát pontosan jelentse.
Egy 0/1 értékű változóval a minta aránya, más néven átlaga:
Egy napi kimenetnél az átlag ugyanilyen szerkezetű, de mértékegysége van:
ahol delivery_days mértékegysége nap, ezért
mértékegysége is nap.
A feltételes arány egy részcsoportra számított ugyanilyen hányad. Ha a csoportot jelöli, akkor:
ahol azoknak a rendeléseknek a száma, amelyekre . A feltétel itt a nevező kiválasztása; a számlálóban továbbra is 0/1 értékeket összegzünk.
Az alábbi nyolc kitalált rendeléssel dolgozunk. A
target_late a 7 napos ígérethez számolt cél; a modell
bemenetébe nem kerülhet be.
| order_id | priority_flag | distance_km | delivery_days | target_late |
|---|---|---|---|---|
| O1 | 1 | 5 | 3 | 0 |
| O2 | 1 | 6 | 8 | 1 |
| O3 | 1 | 7 | 9 | 1 |
| O4 | 0 | 2 | 4 | 0 |
| O5 | 0 | 12 | 11 | 1 |
| O6 | 1 | 1 | 2 | 0 |
| O7 | 0 | 11 | 10 | 1 |
| O8 | 0 | 4 | 6 | 0 |
Kézi kontroll:
priority_flag=1 részcsoportban:
késés,
rendelés, arány
;priority_flag=0 részcsoportban:
késés,
rendelés, arány
.A következő kód ehhez a kézi számpéldához illeszkedik. A közölt kimenet elméletileg várt, automatizált futtatással még nem ellenőrzött eredmény. A kód tiszta Python, semmilyen data science csomagot nem feltételez.
# Szemléltető kód; automatikusan még nem ellenőrzött.
def late_flag(delivery_days: int, promised_days: int = 7) -> int:
"""Célváltozó: 1, ha a kézbesítés késik, 0 különben."""
return int(delivery_days > promised_days)
def late_rate(rows: list[dict], promised_days: int = 7) -> float:
"""Késési arány megfigyelési egységenként."""
if not rows:
return float("nan")
labels = [late_flag(r["delivery_days"], promised_days) for r in rows]
return sum(labels) / len(labels)
def conditional_rate(
rows: list[dict], group_key: str, group_value, promised_days: int = 7
) -> float:
"""Feltételes késési arány egy csoportra."""
group = [r for r in rows if r[group_key] == group_value]
return late_rate(group, promised_days)
rows = [
{"order_id": "O1", "priority_flag": 1, "distance_km": 5, "delivery_days": 3},
{"order_id": "O2", "priority_flag": 1, "distance_km": 6, "delivery_days": 8},
{"order_id": "O3", "priority_flag": 1, "distance_km": 7, "delivery_days": 9},
{"order_id": "O4", "priority_flag": 0, "distance_km": 2, "delivery_days": 4},
{"order_id": "O5", "priority_flag": 0, "distance_km": 12, "delivery_days": 11},
{"order_id": "O6", "priority_flag": 1, "distance_km": 1, "delivery_days": 2},
{"order_id": "O7", "priority_flag": 0, "distance_km": 11, "delivery_days": 10},
{"order_id": "O8", "priority_flag": 0, "distance_km": 4, "delivery_days": 6},
]
overall = late_rate(rows)
priority1 = conditional_rate(rows, "priority_flag", 1)
priority0 = conditional_rate(rows, "priority_flag", 0)
print(f"n={len(rows)}")
print(f"nyers késési arány={overall:.3f}")
print(f"priority=1 késési arány={priority1:.3f}")
print(f"priority=0 késési arány={priority0:.3f}")
# Invariáns ellenőrzés: az arány 0 és 1 közé esik,
# és a 8 elemű mintában pontosan 4 késés van.
assert abs(overall - 0.5) < 1e-12
assert 0.0 <= priority1 <= 1.0
assert 0.0 <= priority0 <= 1.0Elméletileg várt kimenet:
n=8
nyers késési arány=0.500
priority=1 késési arány=0.500
priority=0 késési arány=0.500
A
-ös
érték ebben a mintában a rendelések fele késett; ez nem
állítás a teljes Northstar-populációról. A nyolc sorhoz ismerjük a
teljes eljárást, ezért az eredmény úgy ellenőrizhető, hogy a
delivery_days > 7 egyenlőtlenséget soronként
kiszámoljuk, majd a darabszámot
-nel
osztjuk. A kódba írt assert ugyanezt a levezetett
értéket rögzíti.
A priority_flag szerinti két
azonosnak tűnik, de ez a nyolc elemű példa nem jelenti azt, hogy
a prioritás nem hat. A pillanatnyi mintabeli egyenlőség leíró
eredmény; az oksági hatás azonosításához megfelelő kutatási terv kell:
randomizálás, vagy megfigyeléses vizsgálatban indokolt azonosítási
feltevések és érzékenységvizsgálat.
Ha a bemenetet később a lab/orders.csv 2400 rendelésére
cseréljük, akkor a fájlt a predikciós feladatban úgy kell kezelni, hogy
a rendeléskor ismert feature-listához képest delivery_days,
actual_delivery_at, label_available_at és
target_late csak címkeként jelenhetnek meg. A számítás
akkor is ugyanaz: a nevező a rendelések száma, nem a
rendelési tételek sorainak száma.
Becslési cél és oksági értelmezés. A randomizált kísérletben az elsődleges, előre rögzített becslési cél legyen a hozzárendelés szerinti (intention-to-treat, ITT) átlagos hatás: a randomizálható célpopulációra. A két megfigyelt csoport átlaga közötti különbség ennek becslője randomizálás és konzisztens kimenetmérés mellett; nem azonos automatikusan az egyes ügyfelekre vonatkozó oksági hatással. Külön vizsgálni kell a hiányzó kimenetet és a randomizálás után történt kizárásokat.
A predikciós ezzel szemben egy megadott adatgeneráló eloszlásra és döntési időpontra vonatkozó feltételes mennyiség. Nem ígér oksági hatást és populációváltáskor nem feltétlenül marad azonos. Ellenőrző kérdés: egy ügyfél kétszer rendel; a konverziós kísérletben hány megfigyelésként, a késési modellben hány rendelésként jelenik meg?
Értelmezés. A következő két mondat közül az egyik leírást, a másik kísérleti hatáskérdést tartalmaz:
Implementálás. A fenti függvényekkel számold ki
a késési arányt az alábbi három rendelésre:
{"delivery_days": 8}, {"delivery_days": 7},
{"delivery_days": 12}.
Mi a várt érték, és miért fontos, hogy a 7 napos ígéretnél a
> művelet szerepeljen a >=
helyett?
Hibakeresés. Egy elemző a rendelések helyett az
order_items táblához csatlakoztatott orders
táblát használja, és így számol:
SELECT AVG(1.0 * (o.delivery_days > o.promised_days))
FROM orders o
JOIN order_items oi USING (order_id);Két rendelés van: A rendelés késik és 3 tételsor tartozik hozzá, B rendelés nem késik és 1 tételsor tartozik hozzá. Mekkora a tételsor-alapú arány, mekkora a helyes rendelésalapú arány, és mi okozza az eltérést?
Transzfer megváltoztatott feltételre. Változtasd
az ígéretet 7 napról 5 napra a nyolcrendeléses táblában. Számold ki az
új target_late értékeket és az új késési arányt! Változik-e
a priority_flag=1 és priority_flag=0
feltételes arány, és ha igen, milyen irányba?
Az a) állítás megfigyelési egysége a rendelés:
minden rendelés késő vagy nem késő. Ez leíró összesítés. A b) állítás
megfigyelési egysége az ügyfél: a
conversion_7d ügyfélenként egy 0/1 érték. Ez kísérleti
becslés, mert a két csoport randomizálással jött létre. A b) mondatban
szereplő „3 százalékpont” mintabeli becslés, nem automatikusan a teljes
populációra ismert hatás.
A késési zászlók:
,
,
.
Az összeg
,
a darabszám
,
ezért a késési arány
.
A > kezelésnél a delivery_days = 7 nem
késik, mert a 7 napos ígéretet teljesítette; a >=
viszont későnek számítaná. A szerződés szerint
target_late = 1 akkor, ha
delivery_days > promised_days, ezért a 7 napos
teljesítés kódja
.
A csatlakoztatott táblában az A rendelés 3 sora késik, a B
rendelés 1 sora nem; a tételsor-alapú arány
.
A helyes rendelésalapú arány
.
Az eltérés oka, hogy a JOIN az egy rendeléshez tartozó
tételsorokat többszörözi, ezért a megfigyelési egység nem rendelés,
hanem tételsor. A helyes lekérdezés a rendelési táblán marad:
SELECT AVG(1.0 * target_late) AS rendeles_szintu_arany
FROM orders;A target_late itt ugyanazt a
delivery_days > promised_days definíciót tárolja, de
rendelésenként egy soron.
Az 5 napos küszöbbel a zászlók: O1 0, O2 1, O3 1, O4 0, O5 1, O6
0, O7 1, O8 1, azaz
késés
rendelésből, arány
.
A priority_flag=1 csoport rendelései: O1, O2, O3, O6; ebből
O2 és O3 késik, arány
.
A priority_flag=0 csoport rendelései: O4, O5, O7, O8; ebből
O5, O7, O8 késik, arány
.
Ebben a kitalált mintában a nem prioritásos csoport feltételes aránya
nőtt, a prioritásosé nem változott, de ez ismét mintabeli
leírás.
A leggyakoribb hiba az, hogy a programozó pontosan végrehajt egy hibás statisztikai kérdést. A pontos program nem javítja meg a rosszul megfogalmazott kérdést.
Példa: egy rendeléshez 10 tételsor tartozik, és az a rendelés késik;
egy másik rendelés nem késik, és 1 tételsora van. Ha a fenti
JOIN-t használó kódot lefuttatjuk, 10 késő sort osztunk 11
sorral, az eredmény körülbelül
.
A program szintaktikailag helyes, a csatlakoztatás is technikailag jó,
de a kérdés megfigyelési egysége rossz: a kereskedő azt kérdezte,
mekkora a rendelések késési aránya, nem azt, hogy mekkora a
késő rendeléshez tartozó tételek részaránya.
Önellenőrzés minden feladatkezdés előtt:
Ha ezekre nincs egy mondatos válasz, a kód megírása előtt álljunk meg.
Az üzleti kérdésből akkor lesz statisztikai feladat, ha rögzítjük a megfigyelési egységet, a célváltozót és a döntés pillanatát. A Northstar késési feladatban rendelésenként jelezzük előre a 7 napot meghaladó kézbesítést; bemenete a rendeléskor ismert feature-lista, kimenete 0–1 kockázat. A randomizált kísérletben ügyfélszintű konverziót mérünk, és minden randomizált ügyfél a nevezőben marad. Az arány képlete egyszerű, de a nevező hibája csendesen tönkreteszi a becslést. A következő alfejezet a predikció pillanatát és az adatéletciklus időbeli sorrendjét vizsgálja.