บทช่วยสอน: สร้าง ฝึก และประเมินแบบจําลองยกกําลัง
บทช่วยสอนนี้แสดงตัวอย่างแบบ end-to-end ของเวิร์กโฟลว์ Synapse Data Science ใน Microsoft Fabric คุณเรียนรู้วิธีการสร้าง ฝึก และประเมินแบบจําลองยกระดับและใช้เทคนิคการสร้างแบบจําลองที่ยกระดับ
ข้อกำหนดเบื้องต้น
รับการสมัครใช้งาน Microsoft Fabric หรือลงทะเบียนเพื่อทดลองใช้งาน Microsoft Fabric ฟรี
ลงชื่อเข้าใช้ Microsoft Fabric
ใช้ตัวสลับประสบการณ์ทางด้านซ้ายของโฮมเพจของคุณเพื่อสลับไปยังประสบการณ์วิทยาศาสตร์ข้อมูล Synapse
- ความคุ้นเคยกับ สมุดบันทึก Microsoft Fabric
- เลคเฮ้าส์สําหรับสมุดบันทึกนี้ เพื่อจัดเก็บข้อมูลสําหรับตัวอย่างนี้ สําหรับข้อมูลเพิ่มเติม โปรดเยี่ยมชม เพิ่มเลคเฮาส์ลงในสมุดบันทึกของคุณ
ติดตามในสมุดบันทึก
คุณสามารถทําตามในสมุดบันทึกได้หนึ่งในสองวิธี:
- เปิดและเรียกใช้สมุดบันทึกที่มีอยู่ภายในในประสบการณ์วิทยาศาสตร์ข้อมูล Synapse
- อัปโหลดสมุดบันทึกของคุณจาก GitHub ไปยังประสบการณ์วิทยาศาสตร์ข้อมูล Synapse
เปิดสมุดบันทึกที่มีอยู่แล้วภายใน
ตัวอย่าง สมุดบันทึกการสร้าง แบบจําลอง Uplift มาพร้อมกับบทช่วยสอนนี้ เยี่ยมชมเพื่อเปิดสมุดบันทึกตัวอย่างที่มีอยู่แล้วภายในของบทช่วยสอนในประสบการณ์ Synapse Data Science:1 ไปที่หน้าแรกของ Synapse Data Science 1. เลือกใช้ตัวอย่าง 1. เลือกตัวอย่างที่เกี่ยวข้อง:* จาก ค่าเริ่มต้น แท็บเวิร์กโฟลว์แบบ End-to-end (Python) ถ้าตัวอย่างใช้สําหรับบทช่วยสอน Python * จากแท็บ เวิร์กโฟลว์แบบ end-to-end (R) ถ้าตัวอย่างสําหรับบทช่วยสอน R * จากแท็บ บทช่วยสอน ด่วน ถ้าตัวอย่างมีไว้สําหรับบทช่วยสอนด่วน 1 แนบเลคเฮ้าส์ลงในสมุดบันทึก ก่อนที่คุณจะเริ่มเรียกใช้โค้ด สําหรับข้อมูลเพิ่มเติมเกี่ยวกับการเข้าถึงสมุดบันทึกตัวอย่างที่มีอยู่แล้วภายในสําหรับบทช่วยสอน
เมื่อต้องการเปิดสมุดบันทึกตัวอย่างที่มีอยู่แล้วภายในของบทช่วยสอนในประสบการณ์ Synapse Data Science:
ไปที่หน้าแรกของ Synapse Data Science
เลือกใช้ตัวอย่าง
เลือกตัวอย่างที่สอดคล้องกัน:
- จากแท็บเวิร์กโฟลว์แบบปลายทาง-ต่อ-ปลายทาง (Python) เริ่มต้น ถ้าตัวอย่างมีไว้สําหรับบทช่วยสอน Python
- จากแท็บ เวิร์กโฟลว์แบบ End-to-end (R) ถ้าตัวอย่างมีไว้สําหรับบทช่วยสอน R
- จากแท็บ บทช่วยสอนด่วน ถ้าตัวอย่างมีไว้สําหรับบทช่วยสอนด่วน
แนบเลคเฮ้าส์ลงในสมุดบันทึก ก่อนที่คุณจะเริ่มเรียกใช้โค้ด
นําเข้าสมุดบันทึกจาก GitHub
AIsample - Uplift Modeling.ipynb notebook มาพร้อมกับบทช่วยสอนนี้
เมื่อต้องการเปิดสมุดบันทึกที่มาพร้อมกับบทช่วยสอนนี้ ให้ทําตามคําแนะนําใน เตรียมระบบของคุณสําหรับบทช่วยสอนวิทยาศาสตร์ข้อมูล เพื่อนําเข้าสมุดบันทึกไปยังพื้นที่ทํางานของคุณ
คุณสามารถสร้าง สมุดบันทึก ใหม่ได้ถ้าคุณต้องการคัดลอกและวางรหัสจากหน้านี้
ตรวจสอบให้แน่ใจว่าแนบ lakehouse เข้ากับสมุดบันทึก ก่อนที่คุณจะเริ่มเรียกใช้รหัส
ขั้นตอนที่ 1: โหลดข้อมูล
ชุดข้อมูล
แล็บ AI ของ Criteo สร้างชุดข้อมูลขึ้น ชุดข้อมูลมีแถว 13 ล้านแถว แต่ละแถวแสดงผู้ใช้หนึ่งราย แต่ละแถวมี 12 คุณสมบัติ ตัวบ่งชี้การรักษา และป้ายชื่อไบนารีสองป้ายที่มีการเยี่ยมชมและการแปลง
- f0 - f11: ค่าคุณลักษณะ (หนาแน่น ค่าเลขทศนิยม)
- ทรีต: ผู้ใช้เป็นเป้าหมายแบบสุ่มในการรักษา (ตัวอย่างเช่น การโฆษณา) (1 = การรักษา, 0 = การควบคุม)
- การแปลง: ไม่ว่าจะมีการแปลงเกิดขึ้นหรือไม่ (ตัวอย่างเช่น ทําการซื้อ) สําหรับผู้ใช้ (ไบนารี ป้ายชื่อ) หรือไม่
- เยี่ยมชม: การแปลงเกิดขึ้นหรือไม่ (ตัวอย่างเช่น ทําการซื้อ) สําหรับผู้ใช้ (ไบนารี ป้ายชื่อ) หรือไม่
อ้าง อิง
- โฮมเพจชุดข้อมูล: https://ailab.criteo.com/criteo-uplift-prediction-dataset/
ชุดข้อมูลที่ใช้สําหรับสมุดบันทึกนี้จําเป็นต้องมีข้อมูลอ้างอิง BIbTex นี้:
@inproceedings{Diemert2018,
author = {{Diemert Eustache, Betlei Artem} and Renaudin, Christophe and Massih-Reza, Amini},
title={A Large Scale Benchmark for Uplift Modeling},
publisher = {ACM},
booktitle = {Proceedings of the AdKDD and TargetAd Workshop, KDD, London,United Kingdom, August, 20, 2018},
year = {2018}
}
เคล็ดลับ
เมื่อกําหนดพารามิเตอร์ต่อไปนี้ คุณจะสามารถใช้สมุดบันทึกนี้กับชุดข้อมูลที่แตกต่างกันได้อย่างง่ายดาย
IS_CUSTOM_DATA = False # If True, the user must upload the dataset manually
DATA_FOLDER = "Files/uplift-modelling"
DATA_FILE = "criteo-research-uplift-v2.1.csv"
# Data schema
FEATURE_COLUMNS = [f"f{i}" for i in range(12)]
TREATMENT_COLUMN = "treatment"
LABEL_COLUMN = "visit"
EXPERIMENT_NAME = "aisample-upliftmodelling" # MLflow experiment name
นําเข้าไลบรารี
ก่อนการประมวลผล คุณต้องนําเข้าไลบรารี Spark และ SynapseML ที่จําเป็น นอกจากนี้คุณยังต้องนําเข้าไลบรารีการแสดงภาพข้อมูล - ตัวอย่างเช่น Seaborn, ไลบรารีการแสดงภาพข้อมูล Python ไลบรารีการแสดงภาพข้อมูลมีอินเทอร์เฟซระดับสูงเพื่อสร้างทรัพยากรวิชวลบน DataFrames และอาร์เรย์ เรียนรู้เพิ่มเติมเกี่ยวกับ Spark, SynapseML และ Seaborn
import os
import gzip
import pyspark.sql.functions as F
from pyspark.sql.window import Window
from pyspark.sql.types import *
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.style as style
import seaborn as sns
%matplotlib inline
from synapse.ml.featurize import Featurize
from synapse.ml.core.spark import FluentAPI
from synapse.ml.lightgbm import *
from synapse.ml.train import ComputeModelStatistics
import mlflow
ดาวน์โหลดชุดข้อมูลและอัปโหลดไปยัง lakehouse
รหัสนี้จะดาวน์โหลดเวอร์ชันสาธารณะของชุดข้อมูล และจากนั้นจะจัดเก็บทรัพยากรข้อมูลนั้นในแฟบริคเลคเฮ้าส์
สำคัญ
ตรวจสอบให้แน่ใจว่าคุณ ได้เพิ่มเลคเฮาส์ ลงในสมุดบันทึกก่อนที่คุณจะเรียกใช้ ความล้มเหลวในการทําเช่นนั้นจะส่งผลให้เกิดข้อผิดพลาด
if not IS_CUSTOM_DATA:
# Download demo data files into lakehouse if not exist
import os, requests
remote_url = "http://go.criteo.net/criteo-research-uplift-v2.1.csv.gz"
download_file = "criteo-research-uplift-v2.1.csv.gz"
download_path = f"/lakehouse/default/{DATA_FOLDER}/raw"
if not os.path.exists("/lakehouse/default"):
raise FileNotFoundError("Default lakehouse not found, please add a lakehouse and restart the session.")
os.makedirs(download_path, exist_ok=True)
if not os.path.exists(f"{download_path}/{DATA_FILE}"):
r = requests.get(f"{remote_url}", timeout=30)
with open(f"{download_path}/{download_file}", "wb") as f:
f.write(r.content)
with gzip.open(f"{download_path}/{download_file}", "rb") as fin:
with open(f"{download_path}/{DATA_FILE}", "wb") as fout:
fout.write(fin.read())
print("Downloaded demo data files into lakehouse.")
เริ่มการบันทึกรันไทม์ของสมุดบันทึกนี้
# Record the notebook running time
import time
ts = time.time()
ตั้งค่าการติดตามการทดสอบ MLflow
เพื่อขยายความสามารถในการบันทึกกระแส ML การล็อกอัตโนมัติจะจับค่าของพารามิเตอร์อินพุตและเมตริกเอาท์พุตของแบบจําลองการเรียนรู้ของเครื่องในระหว่างการฝึกโดยอัตโนมัติ ข้อมูลนี้จะถูกบันทึกไปยังพื้นที่ทํางานที่ MLflow API หรือการทดลองที่สอดคล้องกันในพื้นที่ทํางานสามารถเข้าถึงและแสดงภาพได้ เยี่ยมชมแหล่งข้อมูลนี้สําหรับข้อมูลเพิ่มเติมเกี่ยวกับการล็อกอัตโนมัติ
# Set up the MLflow experiment
import mlflow
mlflow.set_experiment(EXPERIMENT_NAME)
mlflow.autolog(disable=True) # Disable MLflow autologging
หมายเหตุ
เพื่อปิดใช้งาน Microsoft Fabric autologging ในเซสชันสมุดบันทึก เรียกใช้ mlflow.autolog()
และตั้งค่าdisable=True
อ่านข้อมูลจากเลคเฮ้าส์
อ่านข้อมูลดิบจากส่วนไฟล์ของ lakehouse และเพิ่มคอลัมน์เพิ่มเติมสําหรับส่วนวันที่ที่แตกต่างกัน ข้อมูลเดียวกันถูกใช้เพื่อสร้างตารางส่วนที่แตกต่างที่มีการแบ่งพาร์ติชัน
raw_df = spark.read.csv(f"{DATA_FOLDER}/raw/{DATA_FILE}", header=True, inferSchema=True).cache()
ขั้นตอนที่ 2: การวิเคราะห์ข้อมูลเชิงสํารวจ
display
ใช้คําสั่ง เพื่อดูสถิติระดับสูงเกี่ยวกับชุดข้อมูล คุณยังสามารถแสดงมุมมองแผนภูมิเพื่อแสดงชุดย่อยของชุดข้อมูลได้อย่างง่ายดาย
display(raw_df.limit(20))
ตรวจสอบเปอร์เซ็นต์ของผู้ใช้ที่เยี่ยมชม เปอร์เซ็นต์ของผู้ใช้ที่แปลง และเปอร์เซ็นต์ของผู้เข้าชมที่แปลง
raw_df.select(
F.mean("visit").alias("Percentage of users that visit"),
F.mean("conversion").alias("Percentage of users that convert"),
(F.sum("conversion") / F.sum("visit")).alias("Percentage of visitors that convert"),
).show()
การวิเคราะห์แสดงให้เห็นว่า ผู้ใช้ 4.9% จากกลุ่มการรักษา - ผู้ใช้ที่ได้รับการรักษาหรือการโฆษณา - เยี่ยมชมร้านค้าออนไลน์ มีผู้ใช้เพียง 3.8% จากกลุ่มควบคุม - ผู้ใช้ที่ไม่เคยได้รับการรักษาหรือไม่เคยนําเสนอหรือเปิดเผยในการโฆษณา เช่นเดียวกัน นอกจากนี้ ผู้ใช้ทั้งหมด 0.31% จากกลุ่มการรักษาถูกแปลงหรือทําการซื้อ - ในขณะที่ผู้ใช้เพียง 0.19% จากกลุ่มตัวควบคุมทําเช่นนั้น ดังนั้นอัตราการแปลงของผู้เยี่ยมชมที่ทําการซื้อซึ่งเป็นสมาชิกของกลุ่มการรักษาคือ 6.36% เมื่อเทียบกับเพียง 5.07%** สําหรับผู้ใช้ของกลุ่มควบคุม จากผลการรักษาเหล่านี้การรักษาอาจปรับปรุงอัตราการเยี่ยมชมประมาณ 1% และอัตราการแปลงของผู้เข้าชมประมาณ 1.3% การรักษานําไปสู่การปรับปรุงที่สําคัญ
ขั้นตอนที่ 3: กําหนดแบบจําลองสําหรับการฝึก
เตรียมการฝึกอบรมและทดสอบชุดข้อมูล
ที่นี่คุณพอดีกับตัวแปลง Featureize กับ raw_df
DataFrame เพื่อแยกคุณลักษณะจากคอลัมน์อินพุตที่ระบุและส่งออกคุณลักษณะเหล่านั้นไปยังคอลัมน์ใหม่ที่ชื่อว่าfeatures
DataFrame ที่เกิดขึ้นจะถูกเก็บไว้ใน DataFrame ใหม่ที่ชื่อว่าdf
transformer = Featurize().setOutputCol("features").setInputCols(FEATURE_COLUMNS).fit(raw_df)
df = transformer.transform(raw_df)
# Split the DataFrame into training and test sets, with a 80/20 ratio and a seed of 42
train_df, test_df = df.randomSplit([0.8, 0.2], seed=42)
# Print the training and test dataset sizes
print("Size of train dataset: %d" % train_df.count())
print("Size of test dataset: %d" % test_df.count())
# Group the training dataset by the treatment column, and count the number of occurrences of each value
train_df.groupby(TREATMENT_COLUMN).count().show()
เตรียมการรักษาและควบคุมชุดข้อมูล
หลังจากที่คุณสร้างชุดข้อมูลการฝึกอบรมและการทดสอบแล้ว คุณต้องสร้างชุดข้อมูลการรักษาและควบคุมเพื่อฝึกแบบจําลองการเรียนรู้ของเครื่องเพื่อวัดการเพิ่มขนาด
# Extract the treatment and control DataFrames
treatment_train_df = train_df.where(f"{TREATMENT_COLUMN} > 0")
control_train_df = train_df.where(f"{TREATMENT_COLUMN} = 0")
หลังจากที่คุณเตรียมข้อมูลของคุณแล้ว คุณสามารถดําเนินการฝึกแบบจําลองด้วย LightGBM ได้
การสร้างแบบจําลองยกระดับ: T-Learner พร้อม LightGBM
Meta-learners คือชุดของอัลกอริทึม ที่สร้างขึ้นจากอัลกอริทึมการเรียนรู้ของเครื่อง เช่น LightGBM, Xgboost เป็นต้น ซึ่งช่วยประมาณผลการรักษาโดยเฉลี่ยตามเงื่อนไขหรือ CATE T-learner เป็นผู้เรียนที่ไม่ใช้แบบจําลองเดี่ยว แต่ T-learner จะใช้หนึ่งแบบจําลองต่อตัวแปรการรักษา ดังนั้นสองแบบจําลองได้รับการพัฒนาและเราอ้างถึง meta-learner ในฐานะผู้เรียน T-learner T-learner ใช้แบบจําลองการเรียนรู้ของเครื่องหลายแบบเพื่อเอาชนะปัญหาของการละทิ้งการรักษาโดยบังคับให้ผู้เรียนแยกออกจากกันก่อน
mlflow.autolog(exclusive=False)
classifier = (
LightGBMClassifier(dataTransferMode="bulk")
.setFeaturesCol("features") # Set the column name for features
.setNumLeaves(10) # Set the number of leaves in each decision tree
.setNumIterations(100) # Set the number of boosting iterations
.setObjective("binary") # Set the objective function for binary classification
.setLabelCol(LABEL_COLUMN) # Set the column name for the label
)
# Start a new MLflow run with the name "uplift"
active_run = mlflow.start_run(run_name="uplift")
# Start a new nested MLflow run with the name "treatment"
with mlflow.start_run(run_name="treatment", nested=True) as treatment_run:
treatment_run_id = treatment_run.info.run_id # Get the ID of the treatment run
treatment_model = classifier.fit(treatment_train_df) # Fit the classifier on the treatment training data
# Start a new nested MLflow run with the name "control"
with mlflow.start_run(run_name="control", nested=True) as control_run:
control_run_id = control_run.info.run_id # Get the ID of the control run
control_model = classifier.fit(control_train_df) # Fit the classifier on the control training data
ใช้ชุดข้อมูลทดสอบสําหรับการคาดการณ์
ที่นี่ คุณใช้ treatment_model
และ control_model
ที่กําหนดไว้ก่อนหน้านี้เพื่อแปลง test_df
ชุดข้อมูลทดสอบ จากนั้นคุณคํานวณยกกําลังที่คาดการณ์ไว้ คุณกําหนด Uplift ที่คาดการณ์ไว้เป็นความแตกต่างระหว่างผลลัพธ์ของการรักษาที่คาดการณ์ไว้และผลลัพธ์ของการควบคุมที่คาดการณ์ไว้ ยิ่งความแตกต่างของ Uplift ที่ทํานายนี้มีประสิทธิภาพในการรักษามากขึ้นเท่านั้น (ตัวอย่างเช่น การโฆษณา) ในแต่ละบุคคลหรือกลุ่มย่อย
getPred = F.udf(lambda v: float(v[1]), FloatType())
# Cache the resulting DataFrame for easier access
test_pred_df = (
test_df.mlTransform(treatment_model)
.withColumn("treatment_pred", getPred("probability"))
.drop("rawPrediction", "probability", "prediction")
.mlTransform(control_model)
.withColumn("control_pred", getPred("probability"))
.drop("rawPrediction", "probability", "prediction")
.withColumn("pred_uplift", F.col("treatment_pred") - F.col("control_pred"))
.select(TREATMENT_COLUMN, LABEL_COLUMN, "treatment_pred", "control_pred", "pred_uplift")
.cache()
)
# Display the first twenty rows of the resulting DataFrame
display(test_pred_df.limit(20))
ดําเนินการประเมินผลแบบจําลอง
เนื่องจากไม่สามารถสังเกตการยกระดับได้สําหรับแต่ละบุคคล คุณจําเป็นต้องวัดการเพิ่มสินค้าในกลุ่มของบุคคล คุณใช้เส้นโค้ง Uplift ที่ลงจุด uplift จริงสะสมทั่วทั้งประชากร
แกน x แสดงอัตราส่วนของประชากรที่เลือกสําหรับการรักษา ค่า 0 ไม่แนะนําให้มีการรักษาแบบกลุ่ม - ไม่มีใครเปิดเผยหรือเสนอการรักษา ค่า 1 หมายถึงกลุ่มการรักษาเต็มรูปแบบ - ทุกคนจะได้รับการรักษาหรือเสนอการรักษา แกน y แสดงหน่วยวัดอัพลิฟต์ จุดมุ่งหมายคือการหาขนาดของกลุ่มการรักษาหรือเปอร์เซ็นต์ของประชากรที่จะเสนอหรือเปิดเผยในการรักษา (ตัวอย่างเช่นการโฆษณา) วิธีการนี้จะปรับการเลือกเป้าหมายให้เหมาะสมเพื่อปรับผลลัพธ์ให้เหมาะสม
ขั้นแรก ให้จัดอันดับคําสั่งซื้อ DataFrame ทดสอบโดยยกระดับที่คาดการณ์ไว้ ยกระดับที่คาดการณ์ไว้คือความแตกต่างระหว่างผลลัพธ์การรักษาที่คาดการณ์ไว้และผลลัพธ์ของการควบคุมที่คาดการณ์ไว้
# Compute the percentage rank of the predicted uplift values in descending order, and display the top twenty rows
test_ranked_df = test_pred_df.withColumn("percent_rank", F.percent_rank().over(Window.orderBy(F.desc("pred_uplift"))))
display(test_ranked_df.limit(20))
ถัดไป คํานวณเปอร์เซ็นต์สะสมของการเยี่ยมชมทั้งในกลุ่มการรักษาและกลุ่มควบคุม
# Calculate the number of control and treatment samples
C = test_ranked_df.where(f"{TREATMENT_COLUMN} == 0").count()
T = test_ranked_df.where(f"{TREATMENT_COLUMN} != 0").count()
# Add columns to the DataFrame to calculate the control and treatment cumulative sum
test_ranked_df = (
test_ranked_df.withColumn(
"control_label",
F.when(F.col(TREATMENT_COLUMN) == 0, F.col(LABEL_COLUMN)).otherwise(0),
)
.withColumn(
"treatment_label",
F.when(F.col(TREATMENT_COLUMN) != 0, F.col(LABEL_COLUMN)).otherwise(0),
)
.withColumn(
"control_cumsum",
F.sum("control_label").over(Window.orderBy("percent_rank")) / C,
)
.withColumn(
"treatment_cumsum",
F.sum("treatment_label").over(Window.orderBy("percent_rank")) / T,
)
)
# Display the first 20 rows of the dataframe
display(test_ranked_df.limit(20))
สุดท้าย ในแต่ละเปอร์เซ็นต์ ให้คํานวณค่ายกระดับของกลุ่มเป็นความแตกต่างระหว่างเปอร์เซ็นต์การเยี่ยมชมระหว่างกลุ่มการรักษาและกลุ่มควบคุม
test_ranked_df = test_ranked_df.withColumn("group_uplift", F.col("treatment_cumsum") - F.col("control_cumsum")).cache()
display(test_ranked_df.limit(20))
ในตอนนี้ ให้ลงจุดเส้นโค้งยกกําลังสําหรับการคาดการณ์ชุดข้อมูลทดสอบ คุณต้องแปลง PySpark DataFrame เป็น Pandas DataFrame ก่อนที่จะลงจุด
def uplift_plot(uplift_df):
"""
Plot the uplift curve
"""
gain_x = uplift_df.percent_rank
gain_y = uplift_df.group_uplift
# Plot the data
fig = plt.figure(figsize=(10, 6))
mpl.rcParams["font.size"] = 8
ax = plt.plot(gain_x, gain_y, color="#2077B4", label="Normalized Uplift Model")
plt.plot(
[0, gain_x.max()],
[0, gain_y.max()],
"--",
color="tab:orange",
label="Random Treatment",
)
plt.legend()
plt.xlabel("Porportion Targeted")
plt.ylabel("Uplift")
plt.grid()
return fig, ax
test_ranked_pd_df = test_ranked_df.select(["pred_uplift", "percent_rank", "group_uplift"]).toPandas()
fig, ax = uplift_plot(test_ranked_pd_df)
mlflow.log_figure(fig, "UpliftCurve.png")
แกน x แสดงอัตราส่วนของประชากรที่เลือกสําหรับการรักษา ค่า 0 ไม่แนะนําให้มีการรักษาแบบกลุ่ม - ไม่มีใครเปิดเผยหรือเสนอการรักษา ค่า 1 หมายถึงกลุ่มการรักษาเต็มรูปแบบ - ทุกคนจะได้รับการรักษาหรือเสนอการรักษา แกน y แสดงหน่วยวัดอัพลิฟต์ จุดมุ่งหมายคือการหาขนาดของกลุ่มการรักษาหรือเปอร์เซ็นต์ของประชากรที่จะเสนอหรือเปิดเผยในการรักษา (ตัวอย่างเช่นการโฆษณา) วิธีการนี้จะปรับการเลือกเป้าหมายให้เหมาะสมเพื่อปรับผลลัพธ์ให้เหมาะสม
ขั้นแรก ให้จัดอันดับคําสั่งซื้อ DataFrame ทดสอบโดยยกระดับที่คาดการณ์ไว้ ยกระดับที่คาดการณ์ไว้คือความแตกต่างระหว่างผลลัพธ์การรักษาที่คาดการณ์ไว้และผลลัพธ์ของการควบคุมที่คาดการณ์ไว้
# Compute the percentage rank of the predicted uplift values in descending order, and display the top twenty rows
test_ranked_df = test_pred_df.withColumn("percent_rank", F.percent_rank().over(Window.orderBy(F.desc("pred_uplift"))))
display(test_ranked_df.limit(20))
ถัดไป คํานวณเปอร์เซ็นต์สะสมของการเยี่ยมชมทั้งในกลุ่มการรักษาและกลุ่มควบคุม
# Calculate the number of control and treatment samples
C = test_ranked_df.where(f"{TREATMENT_COLUMN} == 0").count()
T = test_ranked_df.where(f"{TREATMENT_COLUMN} != 0").count()
# Add columns to the DataFrame to calculate the control and treatment cumulative sum
test_ranked_df = (
test_ranked_df.withColumn(
"control_label",
F.when(F.col(TREATMENT_COLUMN) == 0, F.col(LABEL_COLUMN)).otherwise(0),
)
.withColumn(
"treatment_label",
F.when(F.col(TREATMENT_COLUMN) != 0, F.col(LABEL_COLUMN)).otherwise(0),
)
.withColumn(
"control_cumsum",
F.sum("control_label").over(Window.orderBy("percent_rank")) / C,
)
.withColumn(
"treatment_cumsum",
F.sum("treatment_label").over(Window.orderBy("percent_rank")) / T,
)
)
# Display the first 20 rows of the dataframe
display(test_ranked_df.limit(20))
สุดท้าย ในแต่ละเปอร์เซ็นต์ ให้คํานวณค่ายกระดับของกลุ่มเป็นความแตกต่างระหว่างเปอร์เซ็นต์การเยี่ยมชมระหว่างกลุ่มการรักษาและกลุ่มควบคุม
test_ranked_df = test_ranked_df.withColumn("group_uplift", F.col("treatment_cumsum") - F.col("control_cumsum")).cache()
display(test_ranked_df.limit(20))
ในตอนนี้ ให้ลงจุดเส้นโค้งยกกําลังสําหรับการคาดการณ์ชุดข้อมูลทดสอบ คุณต้องแปลง PySpark DataFrame เป็น Pandas DataFrame ก่อนที่จะลงจุด
def uplift_plot(uplift_df):
"""
Plot the uplift curve
"""
gain_x = uplift_df.percent_rank
gain_y = uplift_df.group_uplift
# Plot the data
fig = plt.figure(figsize=(10, 6))
mpl.rcParams["font.size"] = 8
ax = plt.plot(gain_x, gain_y, color="#2077B4", label="Normalized Uplift Model")
plt.plot(
[0, gain_x.max()],
[0, gain_y.max()],
"--",
color="tab:orange",
label="Random Treatment",
)
plt.legend()
plt.xlabel("Porportion Targeted")
plt.ylabel("Uplift")
plt.grid()
return fig, ax
test_ranked_pd_df = test_ranked_df.select(["pred_uplift", "percent_rank", "group_uplift"]).toPandas()
fig, ax = uplift_plot(test_ranked_pd_df)
mlflow.log_figure(fig, "UpliftCurve.png")
การวิเคราะห์และเส้นโค้งยกระดับแสดงให้เห็นว่าประชากร 20% อันดับต้น ๆ ตามการจัดอันดับโดยการคาดการณ์จะมีกําไรอย่างมากถ้าพวกเขาได้รับการรักษา ซึ่งหมายความว่า 20% ด้านบนของประชากรแสดงถึงกลุ่มโน้มน้าว ดังนั้น คุณสามารถตั้งค่าคะแนน cutoff สําหรับขนาดที่ต้องการของกลุ่มการรักษาที่ 20% เพื่อระบุลูกค้าที่เลือกเป้าหมายเพื่อให้ได้ผลลัพธ์ที่ยิ่งใหญ่ที่สุด
cutoff_percentage = 0.2
cutoff_score = test_ranked_pd_df.iloc[int(len(test_ranked_pd_df) * cutoff_percentage)][
"pred_uplift"
]
print("Uplift scores that exceed {:.4f} map to Persuadables.".format(cutoff_score))
mlflow.log_metrics(
{"cutoff_score": cutoff_score, "cutoff_percentage": cutoff_percentage}
)
ขั้นตอนที่ 4: ลงทะเบียนแบบจําลอง ML ขั้นสุดท้าย
คุณใช้ MLflow เพื่อติดตามและบันทึกการทดลองทั้งหมดสําหรับทั้งกลุ่มการรักษาและการควบคุม การติดตามและการบันทึกนี้ประกอบด้วยพารามิเตอร์ เมตริก และแบบจําลองที่เกี่ยวข้อง ข้อมูลนี้จะถูกบันทึกไว้ใต้ชื่อการทดลองในพื้นที่ทํางานสําหรับการใช้งานในภายหลัง
# Register the model
treatment_model_uri = "runs:/{}/model".format(treatment_run_id)
mlflow.register_model(treatment_model_uri, f"{EXPERIMENT_NAME}-treatmentmodel")
control_model_uri = "runs:/{}/model".format(control_run_id)
mlflow.register_model(control_model_uri, f"{EXPERIMENT_NAME}-controlmodel")
mlflow.end_run()
วิธีดูการทดลองของคุณ:
- บนแผงด้านซ้าย ให้เลือกพื้นที่ทํางานของคุณ
- ค้นหาและเลือกชื่อการทดลอง ในกรณีนี้คือ aisample-upliftmodelling
ขั้นตอนที่ 5: บันทึกผลลัพธ์การคาดการณ์
Microsoft Fabric เสนอ PREDICT - ฟังก์ชันที่ปรับขนาดได้ที่สนับสนุนการให้คะแนนแบบกลุ่มในกลไกการคํานวณใด ๆ ซึ่งช่วยให้ลูกค้าสามารถดําเนินการแบบจําลองการเรียนรู้ของเครื่องได้ ผู้ใช้สามารถสร้างการคาดการณ์แบบกลุ่มได้โดยตรงจากสมุดบันทึกหรือหน้ารายการสําหรับแบบจําลองเฉพาะ เยี่ยมชมแหล่งข้อมูลนี้เพื่อเรียนรู้เพิ่มเติมเกี่ยวกับการทํานาย และเพื่อเรียนรู้วิธีใช้การทํานายใน Microsoft Fabric
# Load the model back
loaded_treatmentmodel = mlflow.spark.load_model(treatment_model_uri, dfs_tmpdir="Files/spark")
loaded_controlmodel = mlflow.spark.load_model(control_model_uri, dfs_tmpdir="Files/spark")
# Make predictions
batch_predictions_treatment = loaded_treatmentmodel.transform(test_df)
batch_predictions_control = loaded_controlmodel.transform(test_df)
batch_predictions_treatment.show(5)
# Save the predictions in the lakehouse
batch_predictions_treatment.write.format("delta").mode("overwrite").save(
f"{DATA_FOLDER}/predictions/batch_predictions_treatment"
)
batch_predictions_control.write.format("delta").mode("overwrite").save(
f"{DATA_FOLDER}/predictions/batch_predictions_control"
)
# Determine the entire runtime
print(f"Full run cost {int(time.time() - ts)} seconds.")