![]() | ![]() | ![]() | ![]() |
بررسی اجمالی
این آموزش مروری است بر محدودیت ها و تنظیم کننده های ارائه شده توسط کتابخانه TensorFlow Lattice (TFL). در اینجا ما از برآوردگرهای کنسرو شده TFL در مجموعه داده های مصنوعی استفاده می کنیم ، اما توجه داشته باشید که همه چیز در این آموزش با مدل های ساخته شده از لایه های TFL Keras نیز قابل انجام است.
قبل از ادامه ، اطمینان حاصل کنید که در زمان اجرا تمام بسته های مورد نیاز نصب شده است (همانطور که در سلول های کد زیر وارد شده است).
برپایی
نصب بسته TF Lattice:
pip install -q tensorflow-lattice
وارد کردن بسته های مورد نیاز:
import tensorflow as tf
from IPython.core.pylabtools import figsize
import itertools
import logging
import matplotlib
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
import sys
import tensorflow_lattice as tfl
logging.disable(sys.maxsize)
مقادیر پیش فرض مورد استفاده در این راهنما:
NUM_EPOCHS = 1000
BATCH_SIZE = 64
LEARNING_RATE=0.01
مجموعه آموزش داده ها برای رتبه بندی رستوران ها
یک سناریوی ساده را تصور کنید که در آن می خواهیم تعیین کنیم آیا کاربران روی نتیجه جستجوی رستوران کلیک می کنند یا خیر. وظیفه پیش بینی نرخ کلیک (CTR) با توجه به ویژگی های ورودی است:
- میانگین امتیاز (
avg_rating
): یک ویژگی عددی با مقادیر در محدوده [1،5]. - تعداد بازبینی ها (
num_reviews
): یک ویژگی عددی با مقادیرnum_reviews
200 که از آن برای اندازه گیری روند روز استفاده می کنیم. - رتبه بندی دلار (
dollar_rating
): یک ویژگی طبقه بندی شده با مقادیر رشته در مجموعه {"D" ، "DD" ، "DDD" ، "DDDD"}.
در اینجا ما یک مجموعه داده مصنوعی ایجاد می کنیم که CTR واقعی با فرمول داده می شود:
جایی که $ b (\ cdot) $ هر dollar_rating
به مقدار پایه ترجمه می کند:
این فرمول الگوهای معمولی کاربر را منعکس می کند. به عنوان مثال با توجه به سایر موارد ثابت ، کاربران رستوران هایی با رتبه بندی ستاره بالاتر را ترجیح می دهند و رستوران های "\ $ \ $" کلیک بیشتری نسبت به "\ $" دریافت می کنند و به دنبال آن "\ $ \ $ \ $" و "\ $ \ $ \ $" \ $ ".
def click_through_rate(avg_ratings, num_reviews, dollar_ratings):
dollar_rating_baseline = {"D": 3, "DD": 2, "DDD": 4, "DDDD": 4.5}
return 1 / (1 + np.exp(
np.array([dollar_rating_baseline[d] for d in dollar_ratings]) -
avg_ratings * np.log1p(num_reviews) / 4))
بیایید نگاهی به نمودارهای کانتور این عملکرد CTR بیندازیم.
def color_bar():
bar = matplotlib.cm.ScalarMappable(
norm=matplotlib.colors.Normalize(0, 1, True),
cmap="viridis",
)
bar.set_array([0, 1])
return bar
def plot_fns(fns, split_by_dollar=False, res=25):
"""Generates contour plots for a list of (name, fn) functions."""
num_reviews, avg_ratings = np.meshgrid(
np.linspace(0, 200, num=res),
np.linspace(1, 5, num=res),
)
if split_by_dollar:
dollar_rating_splits = ["D", "DD", "DDD", "DDDD"]
else:
dollar_rating_splits = [None]
if len(fns) == 1:
fig, axes = plt.subplots(2, 2, sharey=True, tight_layout=False)
else:
fig, axes = plt.subplots(
len(dollar_rating_splits), len(fns), sharey=True, tight_layout=False)
axes = axes.flatten()
axes_index = 0
for dollar_rating_split in dollar_rating_splits:
for title, fn in fns:
if dollar_rating_split is not None:
dollar_ratings = np.repeat(dollar_rating_split, res**2)
values = fn(avg_ratings.flatten(), num_reviews.flatten(),
dollar_ratings)
title = "{}: dollar_rating={}".format(title, dollar_rating_split)
else:
values = fn(avg_ratings.flatten(), num_reviews.flatten())
subplot = axes[axes_index]
axes_index += 1
subplot.contourf(
avg_ratings,
num_reviews,
np.reshape(values, (res, res)),
vmin=0,
vmax=1)
subplot.title.set_text(title)
subplot.set(xlabel="Average Rating")
subplot.set(ylabel="Number of Reviews")
subplot.set(xlim=(1, 5))
_ = fig.colorbar(color_bar(), cax=fig.add_axes([0.95, 0.2, 0.01, 0.6]))
figsize(11, 11)
plot_fns([("CTR", click_through_rate)], split_by_dollar=True)
آماده سازی داده ها
اکنون باید مجموعه داده های مصنوعی خود را ایجاد کنیم. ما با تولید یک مجموعه داده شبیه سازی شده از رستوران ها و ویژگی های آنها شروع می کنیم.
def sample_restaurants(n):
avg_ratings = np.random.uniform(1.0, 5.0, n)
num_reviews = np.round(np.exp(np.random.uniform(0.0, np.log(200), n)))
dollar_ratings = np.random.choice(["D", "DD", "DDD", "DDDD"], n)
ctr_labels = click_through_rate(avg_ratings, num_reviews, dollar_ratings)
return avg_ratings, num_reviews, dollar_ratings, ctr_labels
np.random.seed(42)
avg_ratings, num_reviews, dollar_ratings, ctr_labels = sample_restaurants(2000)
figsize(5, 5)
fig, axs = plt.subplots(1, 1, sharey=False, tight_layout=False)
for rating, marker in [("D", "o"), ("DD", "^"), ("DDD", "+"), ("DDDD", "x")]:
plt.scatter(
x=avg_ratings[np.where(dollar_ratings == rating)],
y=num_reviews[np.where(dollar_ratings == rating)],
c=ctr_labels[np.where(dollar_ratings == rating)],
vmin=0,
vmax=1,
marker=marker,
label=rating)
plt.xlabel("Average Rating")
plt.ylabel("Number of Reviews")
plt.legend()
plt.xlim((1, 5))
plt.title("Distribution of restaurants")
_ = fig.colorbar(color_bar(), cax=fig.add_axes([0.95, 0.2, 0.01, 0.6]))
بیایید مجموعه داده های آموزش ، اعتبار سنجی و آزمایش را تولید کنیم. وقتی یک رستوران در نتایج جستجو مشاهده می شود ، می توانیم تعامل کاربر (کلیک یا بدون کلیک) را به عنوان یک نمونه از نمونه ثبت کنیم.
در عمل ، کاربران اغلب همه نتایج جستجو را انجام نمی دهند. این بدان معناست که کاربران احتمالاً فقط رستورانهایی را می بینند که قبلاً توسط مدل رتبه بندی فعلی "خوب" در نظر گرفته شده است. در نتیجه ، رستوران های "خوب" بیشتر تحت تأثیر قرار می گیرند و در مجموعه داده های آموزشی بیش از حد نمایان می شوند. هنگام استفاده از ویژگی های بیشتر ، مجموعه داده های آموزشی می توانند در قسمت های "بد" فضای ویژگی ها ، شکاف زیادی داشته باشند.
هنگامی که از این مدل برای رتبه بندی استفاده می شود ، اغلب در تمام نتایج مربوطه با توزیع یکنواخت تری که توسط مجموعه داده های آموزشی به خوبی نشان داده نمی شود ، ارزیابی می شود. یک مدل انعطاف پذیر و پیچیده ممکن است در این مورد به دلیل نصب بیش از حد نقاط داده ای که بیش از حد نشان داده شده است ، از کار بیفتد و بنابراین قابلیت تعمیم ندارد. این مسئله را با استفاده از دانش دامنه برای افزودن محدودیت های شکلی که مدل را برای پیش بینی معقول هدایت می کند ، وقتی نمی تواند آنها را از مجموعه داده های آموزشی انتخاب کند ، حل می کنیم.
در این مثال ، مجموعه داده های آموزشی بیشتر شامل تعاملات کاربر با رستوران های خوب و محبوب است. مجموعه داده آزمایش دارای توزیع یکنواختی برای شبیه سازی تنظیمات ارزیابی شده در بالا است. توجه داشته باشید که چنین مجموعه داده آزمایشی در یک مشکل واقعی موجود نخواهد بود.
def sample_dataset(n, testing_set):
(avg_ratings, num_reviews, dollar_ratings, ctr_labels) = sample_restaurants(n)
if testing_set:
# Testing has a more uniform distribution over all restaurants.
num_views = np.random.poisson(lam=3, size=n)
else:
# Training/validation datasets have more views on popular restaurants.
num_views = np.random.poisson(lam=ctr_labels * num_reviews / 50.0, size=n)
return pd.DataFrame({
"avg_rating": np.repeat(avg_ratings, num_views),
"num_reviews": np.repeat(num_reviews, num_views),
"dollar_rating": np.repeat(dollar_ratings, num_views),
"clicked": np.random.binomial(n=1, p=np.repeat(ctr_labels, num_views))
})
# Generate datasets.
np.random.seed(42)
data_train = sample_dataset(500, testing_set=False)
data_val = sample_dataset(500, testing_set=False)
data_test = sample_dataset(500, testing_set=True)
# Plotting dataset densities.
figsize(12, 5)
fig, axs = plt.subplots(1, 2, sharey=False, tight_layout=False)
for ax, data, title in [(axs[0], data_train, "training"),
(axs[1], data_test, "testing")]:
_, _, _, density = ax.hist2d(
x=data["avg_rating"],
y=data["num_reviews"],
bins=(np.linspace(1, 5, num=21), np.linspace(0, 200, num=21)),
density=True,
cmap="Blues",
)
ax.set(xlim=(1, 5))
ax.set(ylim=(0, 200))
ax.set(xlabel="Average Rating")
ax.set(ylabel="Number of Reviews")
ax.title.set_text("Density of {} examples".format(title))
_ = fig.colorbar(density, ax=ax)
تعریف input_fns مورد استفاده برای آموزش و ارزیابی:
train_input_fn = tf.compat.v1.estimator.inputs.pandas_input_fn(
x=data_train,
y=data_train["clicked"],
batch_size=BATCH_SIZE,
num_epochs=NUM_EPOCHS,
shuffle=False,
)
# feature_analysis_input_fn is used for TF Lattice estimators.
feature_analysis_input_fn = tf.compat.v1.estimator.inputs.pandas_input_fn(
x=data_train,
y=data_train["clicked"],
batch_size=BATCH_SIZE,
num_epochs=1,
shuffle=False,
)
val_input_fn = tf.compat.v1.estimator.inputs.pandas_input_fn(
x=data_val,
y=data_val["clicked"],
batch_size=BATCH_SIZE,
num_epochs=1,
shuffle=False,
)
test_input_fn = tf.compat.v1.estimator.inputs.pandas_input_fn(
x=data_test,
y=data_test["clicked"],
batch_size=BATCH_SIZE,
num_epochs=1,
shuffle=False,
)
نصب درختان تقویت شده شیب دار
بیایید فقط با دو ویژگی شروع کنیم: avg_rating
و num_reviews
.
ما چند توابع کمکی برای رسم و محاسبه اعتبار سنجی و معیارهای آزمون ایجاد می کنیم.
def analyze_two_d_estimator(estimator, name):
# Extract validation metrics.
metric = estimator.evaluate(input_fn=val_input_fn)
print("Validation AUC: {}".format(metric["auc"]))
metric = estimator.evaluate(input_fn=test_input_fn)
print("Testing AUC: {}".format(metric["auc"]))
def two_d_pred(avg_ratings, num_reviews):
results = estimator.predict(
tf.compat.v1.estimator.inputs.pandas_input_fn(
x=pd.DataFrame({
"avg_rating": avg_ratings,
"num_reviews": num_reviews,
}),
shuffle=False,
))
return [x["logistic"][0] for x in results]
def two_d_click_through_rate(avg_ratings, num_reviews):
return np.mean([
click_through_rate(avg_ratings, num_reviews,
np.repeat(d, len(avg_ratings)))
for d in ["D", "DD", "DDD", "DDDD"]
],
axis=0)
figsize(11, 5)
plot_fns([("{} Estimated CTR".format(name), two_d_pred),
("CTR", two_d_click_through_rate)],
split_by_dollar=False)
ما می توانیم TensorFlow درختان تصمیم تقویت شده را در مجموعه داده جای دهیم:
feature_columns = [
tf.feature_column.numeric_column("num_reviews"),
tf.feature_column.numeric_column("avg_rating"),
]
gbt_estimator = tf.estimator.BoostedTreesClassifier(
feature_columns=feature_columns,
# Hyper-params optimized on validation set.
n_batches_per_layer=1,
max_depth=2,
n_trees=50,
learning_rate=0.05,
config=tf.estimator.RunConfig(tf_random_seed=42),
)
gbt_estimator.train(input_fn=train_input_fn)
analyze_two_d_estimator(gbt_estimator, "GBT")
Validation AUC: 0.6333084106445312 Testing AUC: 0.774649977684021
حتی اگر این مدل شکل کلی CTR واقعی را به دست آورده و دارای معیارهای اعتبار سنجی مناسبی باشد ، در چندین قسمت از فضای ورودی رفتار ضد شهودی دارد: با افزایش میانگین رتبه یا تعداد بررسی ها ، CTR تخمین زده شده کاهش می یابد. این به دلیل کمبود نقاط نمونه در مناطقی است که به خوبی تحت مجموعه داده های آموزشی قرار ندارند. این مدل به سادگی راهی برای استنباط رفتار صحیح فقط از داده ها ندارد.
برای حل این مسئله ، ما محدودیت شکل را اعمال می کنیم که مدل باید مقادیر خروجی را افزایش دهد که با توجه به رتبه بندی متوسط و تعداد بررسی ها به صورت یکنواخت افزایش می یابد. بعداً خواهیم دید که چگونه این مورد را در TFL پیاده سازی کنیم.
نصب یک DNN
می توانیم همان مراحل را با طبقه بندی DNN تکرار کنیم. ما می توانیم الگوی مشابهی را مشاهده کنیم: نداشتن امتیاز کافی با تعداد کمی بررسی منجر به برون یابی پوچ می شود. توجه داشته باشید که حتی اگر معیار سنجش از محلول درخت بهتر باشد ، معیار سنجش بسیار بدتر است.
feature_columns = [
tf.feature_column.numeric_column("num_reviews"),
tf.feature_column.numeric_column("avg_rating"),
]
dnn_estimator = tf.estimator.DNNClassifier(
feature_columns=feature_columns,
# Hyper-params optimized on validation set.
hidden_units=[16, 8, 8],
optimizer=tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE),
config=tf.estimator.RunConfig(tf_random_seed=42),
)
dnn_estimator.train(input_fn=train_input_fn)
analyze_two_d_estimator(dnn_estimator, "DNN")
Validation AUC: 0.6696228981018066 Testing AUC: 0.750156044960022
محدودیت های شکل
شبکه TensorFlow (TFL) بر اعمال محدودیت های شکل برای حفاظت از رفتار مدل فراتر از داده های آموزش متمرکز شده است. این محدودیت های شکل بر روی لایه های TFL Keras اعمال می شود. جزئیات آنها را می توان در مقاله JMLR ما یافت .
در این آموزش ما از برآوردگرهای کنسرو شده TF برای پوشش دادن محدودیت های مختلف شکل استفاده می کنیم ، اما توجه داشته باشید که تمام این مراحل را می توان با مدل های ایجاد شده از لایه های TFL Keras انجام داد.
همانند سایر برآوردگرهای TensorFlow ، برآوردگرهای کنسرو شده TFL از ستونهای ویژگی برای تعریف قالب ورودی و استفاده از آموزش input_fn برای انتقال داده استفاده می کنند. استفاده از برآورد کنسرو TFL همچنین به موارد زیر احتیاج دارد:
- یک پیکربندی مدل : تعریف معماری مدل و محدودیت های شکل و قاعده آور شکل هر ویژگی.
- یک تجزیه و تحلیل ویژگی input_fn : ورودی TF_FN برای انتقال مقادیر اولیه برای TFL.
برای توضیحات کامل تر ، لطفاً به آموزش برآورد کنسرو شده یا اسناد API مراجعه کنید.
یکنواختی
ما ابتدا با افزودن محدودیت های شکل یکنواختی به هر دو ویژگی ، نگرانی های یکنواختی را برطرف می کنیم.
برای آموزش TFL برای اجرای محدودیت های شکل ، محدودیت ها را در پیکربندی های ویژگی مشخص می کنیم. کد زیر نشان می دهد که چگونه می توان با تنظیم monotonicity="increasing"
به یکنواختی خروجی با توجه به num_reviews
و avg_rating
نیاز داشت.
feature_columns = [
tf.feature_column.numeric_column("num_reviews"),
tf.feature_column.numeric_column("avg_rating"),
]
model_config = tfl.configs.CalibratedLatticeConfig(
feature_configs=[
tfl.configs.FeatureConfig(
name="num_reviews",
lattice_size=2,
monotonicity="increasing",
pwl_calibration_num_keypoints=20,
),
tfl.configs.FeatureConfig(
name="avg_rating",
lattice_size=2,
monotonicity="increasing",
pwl_calibration_num_keypoints=20,
)
])
tfl_estimator = tfl.estimators.CannedClassifier(
feature_columns=feature_columns,
model_config=model_config,
feature_analysis_input_fn=feature_analysis_input_fn,
optimizer=tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE),
config=tf.estimator.RunConfig(tf_random_seed=42),
)
tfl_estimator.train(input_fn=train_input_fn)
analyze_two_d_estimator(tfl_estimator, "TF Lattice")
Validation AUC: 0.6565533876419067 Testing AUC: 0.7784258723258972
با استفاده از CalibratedLatticeConfig
یک طبقه بندی کنسرو شده ایجاد می شود که ابتدا یک کالیبراتور را برای هر ورودی اعمال می کند (یک تابع خطی قطعه ای برای ویژگی های عددی) و سپس یک لایه شبکه برای فیوز نکردن غیر خطی ویژگی های کالیبره شده اعمال می کند. برای تجسم مدل می توانیم از tfl.visualization
استفاده tfl.visualization
. به طور خاص ، نمودار زیر دو کالیبراتور آموزش دیده را در طبقه بندی کنسرو نشان می دهد.
def save_and_visualize_lattice(tfl_estimator):
saved_model_path = tfl_estimator.export_saved_model(
"/tmp/TensorFlow_Lattice_101/",
tf.estimator.export.build_parsing_serving_input_receiver_fn(
feature_spec=tf.feature_column.make_parse_example_spec(
feature_columns)))
model_graph = tfl.estimators.get_model_graph(saved_model_path)
figsize(8, 8)
tfl.visualization.draw_model_graph(model_graph)
return model_graph
_ = save_and_visualize_lattice(tfl_estimator)
با محدودیت های اضافه شده ، CTR تخمینی با افزایش میانگین امتیاز یا افزایش تعداد بازبینی ها همیشه افزایش می یابد. این کار با اطمینان از یکنواخت بودن کالیبراتورها و شبکه انجام می شود.
کاهش بازده
کاهش بازده به این معنی است که با افزایش مقدار ، سود حاشیه ای افزایش مقدار مشخصی کاهش می یابد. در مورد ما انتظار داریم که ویژگی num_reviews
از این الگو پیروی کند ، بنابراین می توانیم کالیبراتور آن را بر اساس آن پیکربندی کنیم. توجه داشته باشید که می توان بازدهی کاهنده را به دو شرط کافی تجزیه کرد:
- کالیبراتور بصورت یکنواخت در حال افزایش است ، و
- کالیبراتور مقعر است.
feature_columns = [
tf.feature_column.numeric_column("num_reviews"),
tf.feature_column.numeric_column("avg_rating"),
]
model_config = tfl.configs.CalibratedLatticeConfig(
feature_configs=[
tfl.configs.FeatureConfig(
name="num_reviews",
lattice_size=2,
monotonicity="increasing",
pwl_calibration_convexity="concave",
pwl_calibration_num_keypoints=20,
),
tfl.configs.FeatureConfig(
name="avg_rating",
lattice_size=2,
monotonicity="increasing",
pwl_calibration_num_keypoints=20,
)
])
tfl_estimator = tfl.estimators.CannedClassifier(
feature_columns=feature_columns,
model_config=model_config,
feature_analysis_input_fn=feature_analysis_input_fn,
optimizer=tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE),
config=tf.estimator.RunConfig(tf_random_seed=42),
)
tfl_estimator.train(input_fn=train_input_fn)
analyze_two_d_estimator(tfl_estimator, "TF Lattice")
_ = save_and_visualize_lattice(tfl_estimator)
Validation AUC: 0.6409633755683899 Testing AUC: 0.7891247272491455
توجه کنید که چگونه معیار آزمایش با افزودن محدودیت تقعر بهبود می یابد. طرح پیش بینی نیز بهتر با حقیقت زمین شباهت دارد.
محدودیت شکل 2D: اعتماد
رتبه بندی 5 ستاره برای یک رستوران که فقط یک یا دو بررسی دارد احتمالاً یک امتیاز غیر قابل اعتماد است (ممکن است رستوران در واقع خوب نباشد) ، در حالی که رتبه بندی 4 ستاره برای یک رستوران با صدها نظر بسیار قابل اعتماد تر است (رستوران در این مورد احتمالاً خوب است). می توانیم ببینیم که تعداد بازبینی های یک رستوران بر میزان اعتماد ما به رتبه بندی متوسط آن تأثیر دارد.
ما می توانیم از محدودیت های اعتماد TFL استفاده کنیم تا به مدل اطلاع دهیم که مقدار بزرگتر (یا کوچکتر) یک ویژگی نشانگر اتکای بیشتر یا اعتماد به ویژگی دیگر است. این کار با تنظیم پیکربندی reflects_trust_in
در پیکربندی ویژگی انجام می شود.
feature_columns = [
tf.feature_column.numeric_column("num_reviews"),
tf.feature_column.numeric_column("avg_rating"),
]
model_config = tfl.configs.CalibratedLatticeConfig(
feature_configs=[
tfl.configs.FeatureConfig(
name="num_reviews",
lattice_size=2,
monotonicity="increasing",
pwl_calibration_convexity="concave",
pwl_calibration_num_keypoints=20,
# Larger num_reviews indicating more trust in avg_rating.
reflects_trust_in=[
tfl.configs.TrustConfig(
feature_name="avg_rating", trust_type="edgeworth"),
],
),
tfl.configs.FeatureConfig(
name="avg_rating",
lattice_size=2,
monotonicity="increasing",
pwl_calibration_num_keypoints=20,
)
])
tfl_estimator = tfl.estimators.CannedClassifier(
feature_columns=feature_columns,
model_config=model_config,
feature_analysis_input_fn=feature_analysis_input_fn,
optimizer=tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE),
config=tf.estimator.RunConfig(tf_random_seed=42),
)
tfl_estimator.train(input_fn=train_input_fn)
analyze_two_d_estimator(tfl_estimator, "TF Lattice")
model_graph = save_and_visualize_lattice(tfl_estimator)
Validation AUC: 0.6409633755683899 Testing AUC: 0.7891043424606323
نمودار زیر عملکرد شبکه آموزش دیده را نشان می دهد. با توجه به محدودیت اعتماد ، ما انتظار داریم که مقادیر بزرگتر تعداد num_reviews
درجه بندی شده شیب بیشتری را با توجه به avg_rating
بندی کالیبره شده avg_rating
، و در نتیجه حرکت قابل توجهی در خروجی شبکه ایجاد شود.
lat_mesh_n = 12
lat_mesh_x, lat_mesh_y = tfl.test_utils.two_dim_mesh_grid(
lat_mesh_n**2, 0, 0, 1, 1)
lat_mesh_fn = tfl.test_utils.get_hypercube_interpolation_fn(
model_graph.output_node.weights.flatten())
lat_mesh_z = [
lat_mesh_fn([lat_mesh_x.flatten()[i],
lat_mesh_y.flatten()[i]]) for i in range(lat_mesh_n**2)
]
trust_plt = tfl.visualization.plot_outputs(
(lat_mesh_x, lat_mesh_y),
{"Lattice Lookup": lat_mesh_z},
figsize=(6, 6),
)
trust_plt.title("Trust")
trust_plt.xlabel("Calibrated avg_rating")
trust_plt.ylabel("Calibrated num_reviews")
trust_plt.show()
کالیبراتورهای صاف کننده
بیایید اکنون نگاهی به کالیبراتور avg_rating
. اگرچه به صورت یکنواخت در حال افزایش است ، اما تغییرات در دامنه های آن ناگهانی است و تفسیر آن دشوار است. این نشان می دهد که ممکن است بخواهیم این کالیبراتور را با استفاده از تنظیم تنظیم کننده در regularizer_configs
.
در اینجا از تنظیم کننده wrinkle
می کنیم تا تغییرات انحنا را کاهش دهد. شما همچنین می توانید با استفاده از laplacian
تنظیم کننده به پهن کردن کالیبراتور و hessian
تنظیم کننده، آن را به خطی تر است.
feature_columns = [
tf.feature_column.numeric_column("num_reviews"),
tf.feature_column.numeric_column("avg_rating"),
]
model_config = tfl.configs.CalibratedLatticeConfig(
feature_configs=[
tfl.configs.FeatureConfig(
name="num_reviews",
lattice_size=2,
monotonicity="increasing",
pwl_calibration_convexity="concave",
pwl_calibration_num_keypoints=20,
regularizer_configs=[
tfl.configs.RegularizerConfig(name="calib_wrinkle", l2=1.0),
],
reflects_trust_in=[
tfl.configs.TrustConfig(
feature_name="avg_rating", trust_type="edgeworth"),
],
),
tfl.configs.FeatureConfig(
name="avg_rating",
lattice_size=2,
monotonicity="increasing",
pwl_calibration_num_keypoints=20,
regularizer_configs=[
tfl.configs.RegularizerConfig(name="calib_wrinkle", l2=1.0),
],
)
])
tfl_estimator = tfl.estimators.CannedClassifier(
feature_columns=feature_columns,
model_config=model_config,
feature_analysis_input_fn=feature_analysis_input_fn,
optimizer=tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE),
config=tf.estimator.RunConfig(tf_random_seed=42),
)
tfl_estimator.train(input_fn=train_input_fn)
analyze_two_d_estimator(tfl_estimator, "TF Lattice")
_ = save_and_visualize_lattice(tfl_estimator)
Validation AUC: 0.6465646028518677 Testing AUC: 0.7948372960090637
اکنون کالیبراتورها صاف هستند و CTR کلی تخمین زده شده با حقیقت زمین مطابقت بیشتری دارد. این امر هم در معیار آزمون و هم در نمودارهای کانتور منعکس می شود.
یکنواختی جزئی برای کالیبراسیون دسته ای
تاکنون ما فقط از دو ویژگی عددی در مدل استفاده کرده ایم. در اینجا ما با استفاده از یک لایه طبقه بندی طبقه ای ، ویژگی سوم را اضافه خواهیم کرد. باز هم ما با تنظیم توابع کمکی برای رسم نمودار و محاسبه معیار شروع می کنیم.
def analyze_three_d_estimator(estimator, name):
# Extract validation metrics.
metric = estimator.evaluate(input_fn=val_input_fn)
print("Validation AUC: {}".format(metric["auc"]))
metric = estimator.evaluate(input_fn=test_input_fn)
print("Testing AUC: {}".format(metric["auc"]))
def three_d_pred(avg_ratings, num_reviews, dollar_rating):
results = estimator.predict(
tf.compat.v1.estimator.inputs.pandas_input_fn(
x=pd.DataFrame({
"avg_rating": avg_ratings,
"num_reviews": num_reviews,
"dollar_rating": dollar_rating,
}),
shuffle=False,
))
return [x["logistic"][0] for x in results]
figsize(11, 22)
plot_fns([("{} Estimated CTR".format(name), three_d_pred),
("CTR", click_through_rate)],
split_by_dollar=True)
برای درگیر کردن ویژگی سوم ، dollar_rating
، باید به یاد بیاوریم که ویژگی های طبقه بندی نیاز به برخورد کمی متفاوت در TFL دارند ، هم به عنوان ستون ویژگی و هم به عنوان پیکربندی ویژگی. در اینجا ما محدودیت یکنواختی جزئی را اعمال می کنیم که خروجی رستوران های "DD" باید بزرگتر از رستوران های "D" باشد ، وقتی همه ورودی های دیگر ثابت شوند. این کار با استفاده از تنظیم monotonicity
در پیکربندی ویژگی انجام می شود.
feature_columns = [
tf.feature_column.numeric_column("num_reviews"),
tf.feature_column.numeric_column("avg_rating"),
tf.feature_column.categorical_column_with_vocabulary_list(
"dollar_rating",
vocabulary_list=["D", "DD", "DDD", "DDDD"],
dtype=tf.string,
default_value=0),
]
model_config = tfl.configs.CalibratedLatticeConfig(
feature_configs=[
tfl.configs.FeatureConfig(
name="num_reviews",
lattice_size=2,
monotonicity="increasing",
pwl_calibration_convexity="concave",
pwl_calibration_num_keypoints=20,
regularizer_configs=[
tfl.configs.RegularizerConfig(name="calib_wrinkle", l2=1.0),
],
reflects_trust_in=[
tfl.configs.TrustConfig(
feature_name="avg_rating", trust_type="edgeworth"),
],
),
tfl.configs.FeatureConfig(
name="avg_rating",
lattice_size=2,
monotonicity="increasing",
pwl_calibration_num_keypoints=20,
regularizer_configs=[
tfl.configs.RegularizerConfig(name="calib_wrinkle", l2=1.0),
],
),
tfl.configs.FeatureConfig(
name="dollar_rating",
lattice_size=2,
pwl_calibration_num_keypoints=4,
# Here we only specify one monotonicity:
# `D` resturants has smaller value than `DD` restaurants
monotonicity=[("D", "DD")],
),
])
tfl_estimator = tfl.estimators.CannedClassifier(
feature_columns=feature_columns,
model_config=model_config,
feature_analysis_input_fn=feature_analysis_input_fn,
optimizer=tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE),
config=tf.estimator.RunConfig(tf_random_seed=42),
)
tfl_estimator.train(input_fn=train_input_fn)
analyze_three_d_estimator(tfl_estimator, "TF Lattice")
_ = save_and_visualize_lattice(tfl_estimator)
Validation AUC: 0.7699775695800781 Testing AUC: 0.8594040274620056
این کالیبراتور طبقه بندی اولویت خروجی مدل را نشان می دهد: DD> D> DDD> DDDD ، که با تنظیمات ما سازگار است. توجه کنید که یک ستون نیز برای مقادیر از دست رفته وجود دارد. اگرچه هیچ ویژگی گمشده ای در داده های آموزش و آزمایش ما وجود ندارد ، اما این مدل درصورتی که در هنگام خدمت مدل پایین دست اتفاق بیفتد ، برای ما مقدار محاسبه شده ای در نظر می گیرد.
در اینجا ما همچنین CTR پیش بینی شده این مدل را با شرط بستگی به dollar_rating
. توجه داشته باشید که تمام محدودیت های مورد نیاز ما در هر یک از برش ها برآورده شده است.
کالیبراسیون خروجی
برای تمام مدلهای TFL که تاکنون آموزش داده ایم ، لایه شبکه (که در نمودار مدل به عنوان "شبکه" نشان داده شده است) مستقیماً پیش بینی مدل را ارائه می دهد. بعضی اوقات مطمئن نیستیم که آیا باید خروجی شبکه برای تولید خروجی مدل مجدداً تغییر یابد:
- ویژگی ها $ log $ counts در حالی که برچسب ها count هستند.
- شبکه به گونه ای پیکربندی شده است که رئوس بسیار کمی دارد اما توزیع برچسب نسبتاً پیچیده است.
در این موارد می توان کالیبراتور دیگری بین خروجی شبکه و خروجی مدل اضافه کرد تا انعطاف پذیری مدل افزایش یابد. در اینجا بیایید یک لایه کالیبراتور با 5 نقطه کلیدی به مدلی که الان ساخته ایم اضافه کنیم. ما همچنین یک تنظیم کننده برای کالیبراتور خروجی اضافه می کنیم تا عملکرد صاف باشد.
feature_columns = [
tf.feature_column.numeric_column("num_reviews"),
tf.feature_column.numeric_column("avg_rating"),
tf.feature_column.categorical_column_with_vocabulary_list(
"dollar_rating",
vocabulary_list=["D", "DD", "DDD", "DDDD"],
dtype=tf.string,
default_value=0),
]
model_config = tfl.configs.CalibratedLatticeConfig(
output_calibration=True,
output_calibration_num_keypoints=5,
regularizer_configs=[
tfl.configs.RegularizerConfig(name="output_calib_wrinkle", l2=0.1),
],
feature_configs=[
tfl.configs.FeatureConfig(
name="num_reviews",
lattice_size=2,
monotonicity="increasing",
pwl_calibration_convexity="concave",
pwl_calibration_num_keypoints=20,
regularizer_configs=[
tfl.configs.RegularizerConfig(name="calib_wrinkle", l2=1.0),
],
reflects_trust_in=[
tfl.configs.TrustConfig(
feature_name="avg_rating", trust_type="edgeworth"),
],
),
tfl.configs.FeatureConfig(
name="avg_rating",
lattice_size=2,
monotonicity="increasing",
pwl_calibration_num_keypoints=20,
regularizer_configs=[
tfl.configs.RegularizerConfig(name="calib_wrinkle", l2=1.0),
],
),
tfl.configs.FeatureConfig(
name="dollar_rating",
lattice_size=2,
pwl_calibration_num_keypoints=4,
# Here we only specify one monotonicity:
# `D` resturants has smaller value than `DD` restaurants
monotonicity=[("D", "DD")],
),
])
tfl_estimator = tfl.estimators.CannedClassifier(
feature_columns=feature_columns,
model_config=model_config,
feature_analysis_input_fn=feature_analysis_input_fn,
optimizer=tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE),
config=tf.estimator.RunConfig(tf_random_seed=42),
)
tfl_estimator.train(input_fn=train_input_fn)
analyze_three_d_estimator(tfl_estimator, "TF Lattice")
_ = save_and_visualize_lattice(tfl_estimator)
Validation AUC: 0.7697908878326416 Testing AUC: 0.861327052116394
آخرین معیار و نمودار آزمایشی نشان می دهد که چگونه استفاده از محدودیت های عقل سلیم می تواند به مدل کمک کند تا از رفتار غیرمنتظره جلوگیری کرده و برتری بیشتری را به کل فضای ورودی وارد کند.