بناء نموذج خطي باستخدام المقدرين

عرض على TensorFlow.org تشغيل في Google Colab عرض المصدر على جيثب تحميل دفتر

ملخص

تدرب هذه الإرشادات الشاملة على نموذج الانحدار اللوجستي باستخدام tf.estimator API. غالبًا ما يستخدم النموذج كخط أساس لخوارزميات أخرى أكثر تعقيدًا.

يثبت

pip install sklearn
import os
import sys

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from IPython.display import clear_output
from six.moves import urllib

قم بتحميل مجموعة البيانات العملاقة

ستستخدم مجموعة بيانات تايتانيك مع الهدف (المهووس إلى حد ما) للتنبؤ ببقاء الركاب على قيد الحياة ، نظرًا لخصائص مثل الجنس والعمر والفئة وما إلى ذلك.

import tensorflow.compat.v2.feature_column as fc

import tensorflow as tf
# Load dataset.
dftrain = pd.read_csv('https://storage.googleapis.com/tf-datasets/titanic/train.csv')
dfeval = pd.read_csv('https://storage.googleapis.com/tf-datasets/titanic/eval.csv')
y_train = dftrain.pop('survived')
y_eval = dfeval.pop('survived')

استكشف البيانات

تحتوي مجموعة البيانات على الميزات التالية

dftrain.head()
dftrain.describe()

يوجد 627 و 264 مثالًا في مجموعات التدريب والتقييم ، على التوالي.

dftrain.shape[0], dfeval.shape[0]
(627, 264)

غالبية الركاب في العشرينات والثلاثينات من العمر.

dftrain.age.hist(bins=20)
<AxesSubplot:>

بي إن جي

ويبلغ عدد الركاب الذكور ما يقرب من ضعف عدد الركاب على متن الطائرة.

dftrain.sex.value_counts().plot(kind='barh')
<AxesSubplot:>

بي إن جي

وكان غالبية الركاب في الدرجة "الثالثة".

dftrain['class'].value_counts().plot(kind='barh')
<AxesSubplot:>

بي إن جي

تتمتع الإناث بفرصة أعلى للبقاء على قيد الحياة مقارنة بالذكور. من الواضح أن هذه ميزة تنبؤية للنموذج.

pd.concat([dftrain, y_train], axis=1).groupby('sex').survived.mean().plot(kind='barh').set_xlabel('% survive')
Text(0.5, 0, '% survive')

بي إن جي

هندسة الخصائص للنموذج

يستخدم المقدرون نظامًا يسمى أعمدة الميزات لوصف كيفية تفسير النموذج لكل ميزة من ميزات الإدخال الأولية. يتوقع "المقدر" متجهًا للمدخلات الرقمية ، وتصف أعمدة الميزة كيفية تحويل النموذج لكل ميزة.

يعد تحديد وصياغة المجموعة الصحيحة من أعمدة الميزات أمرًا أساسيًا لتعلم نموذج فعال. يمكن أن يكون عمود المعلم إما أحد المدخلات الأولية في dict الميزات الأصلية ( عمود المعلم الأساسي ) ، أو أي أعمدة جديدة تم إنشاؤها باستخدام تحويلات محددة عبر عمود واحد أو عدة أعمدة أساسية (أعمدة معلم مشتقة ).

يستخدم المقدر الخطي كلاً من السمات الرقمية والفئوية. تعمل أعمدة المعالم مع جميع مقدرات TensorFlow والغرض منها هو تحديد الميزات المستخدمة في النمذجة. بالإضافة إلى ذلك ، فإنها توفر بعض القدرات الهندسية المميزة مثل الترميز الساخن ، والتطبيع ، والجرافة.

أعمدة الميزة الأساسية

CATEGORICAL_COLUMNS = ['sex', 'n_siblings_spouses', 'parch', 'class', 'deck',
                       'embark_town', 'alone']
NUMERIC_COLUMNS = ['age', 'fare']

feature_columns = []
for feature_name in CATEGORICAL_COLUMNS:
  vocabulary = dftrain[feature_name].unique()
  feature_columns.append(tf.feature_column.categorical_column_with_vocabulary_list(feature_name, vocabulary))

for feature_name in NUMERIC_COLUMNS:
  feature_columns.append(tf.feature_column.numeric_column(feature_name, dtype=tf.float32))

تحدد input_function كيفية تحويل البيانات إلى tf.data.Dataset الذي يغذي خط أنابيب الإدخال بطريقة متدفقة. يمكن أن تأخذ tf.data.Dataset مصادر متعددة مثل إطار البيانات وملف بتنسيق csv والمزيد.

def make_input_fn(data_df, label_df, num_epochs=10, shuffle=True, batch_size=32):
  def input_function():
    ds = tf.data.Dataset.from_tensor_slices((dict(data_df), label_df))
    if shuffle:
      ds = ds.shuffle(1000)
    ds = ds.batch(batch_size).repeat(num_epochs)
    return ds
  return input_function

train_input_fn = make_input_fn(dftrain, y_train)
eval_input_fn = make_input_fn(dfeval, y_eval, num_epochs=1, shuffle=False)

يمكنك فحص مجموعة البيانات:

ds = make_input_fn(dftrain, y_train, batch_size=10)()
for feature_batch, label_batch in ds.take(1):
  print('Some feature keys:', list(feature_batch.keys()))
  print()
  print('A batch of class:', feature_batch['class'].numpy())
  print()
  print('A batch of Labels:', label_batch.numpy())
Some feature keys: ['sex', 'age', 'n_siblings_spouses', 'parch', 'fare', 'class', 'deck', 'embark_town', 'alone']

A batch of class: [b'Third' b'Third' b'Third' b'Third' b'Third' b'First' b'Second' b'First'
 b'First' b'Third']

A batch of Labels: [0 1 1 0 0 1 0 1 1 0]

يمكنك أيضًا فحص نتيجة عمود معلم معين باستخدام طبقة tf.keras.layers.DenseFeatures :

age_column = feature_columns[7]
tf.keras.layers.DenseFeatures([age_column])(feature_batch).numpy()
array([[35.],
       [14.],
       [28.],
       [19.],
       [28.],
       [35.],
       [60.],
       [63.],
       [45.],
       [21.]], dtype=float32)

لا تقبل DenseFeatures إلا الموترات الكثيفة ، لفحص عمود فئوي تحتاج إلى تحويله إلى عمود مؤشر أولاً:

gender_column = feature_columns[0]
tf.keras.layers.DenseFeatures([tf.feature_column.indicator_column(gender_column)])(feature_batch).numpy()
array([[1., 0.],
       [0., 1.],
       [0., 1.],
       [1., 0.],
       [1., 0.],
       [1., 0.],
       [1., 0.],
       [0., 1.],
       [0., 1.],
       [0., 1.]], dtype=float32)

بعد إضافة جميع الميزات الأساسية إلى النموذج ، دعنا ندرب النموذج. يعد تدريب النموذج أمرًا واحدًا فقط باستخدام tf.estimator API:

linear_est = tf.estimator.LinearClassifier(feature_columns=feature_columns)
linear_est.train(train_input_fn)
result = linear_est.evaluate(eval_input_fn)

clear_output()
print(result)
{'accuracy': 0.7537879, 'accuracy_baseline': 0.625, 'auc': 0.8060607, 'auc_precision_recall': 0.7480768, 'average_loss': 0.5639972, 'label/mean': 0.375, 'loss': 0.5542658, 'precision': 0.7741935, 'prediction/mean': 0.25232768, 'recall': 0.4848485, 'global_step': 200}

أعمدة السمات المشتقة

الآن وصلت إلى دقة 75٪. قد لا يكون استخدام كل عمود ميزة أساسية على حدة كافياً لشرح البيانات. على سبيل المثال ، قد يختلف الارتباط بين العمر والتسمية باختلاف الجنس. لذلك ، إذا تعلمت فقط وزن نموذج واحد gender="Male" gender="Female" ، فلن تلتقط كل مجموعة عمرية وجنس (مثل التمييز بين gender="Male" age="30" gender="Male" age="40" ).

لمعرفة الاختلافات بين مجموعات الميزات المختلفة ، يمكنك إضافة أعمدة معالم متقاطعة إلى النموذج (يمكنك أيضًا تجميع عمود العمر قبل العمود المتقاطع):

age_x_gender = tf.feature_column.crossed_column(['age', 'sex'], hash_bucket_size=100)

بعد إضافة ميزة المجموعة إلى النموذج ، دعنا ندرب النموذج مرة أخرى:

derived_feature_columns = [age_x_gender]
linear_est = tf.estimator.LinearClassifier(feature_columns=feature_columns+derived_feature_columns)
linear_est.train(train_input_fn)
result = linear_est.evaluate(eval_input_fn)

clear_output()
print(result)
{'accuracy': 0.7462121, 'accuracy_baseline': 0.625, 'auc': 0.845577, 'auc_precision_recall': 0.7873878, 'average_loss': 0.47313985, 'label/mean': 0.375, 'loss': 0.46722567, 'precision': 0.6509434, 'prediction/mean': 0.41550797, 'recall': 0.6969697, 'global_step': 200}

يحقق الآن دقة تصل إلى 77.6٪ ، وهو أفضل قليلاً من التدريب على الميزات الأساسية فقط. يمكنك محاولة استخدام المزيد من الميزات والتحولات لمعرفة ما إذا كان يمكنك القيام بعمل أفضل!

يمكنك الآن استخدام نموذج القطار لعمل تنبؤات بشأن أحد الركاب من مجموعة التقييم. تم تحسين نماذج TensorFlow لعمل تنبؤات حول مجموعة أو مجموعة من الأمثلة في وقت واحد. في وقت سابق ، تم تعريف eval_input_fn باستخدام مجموعة التقييم بأكملها.

pred_dicts = list(linear_est.predict(eval_input_fn))
probs = pd.Series([pred['probabilities'][1] for pred in pred_dicts])

probs.plot(kind='hist', bins=20, title='predicted probabilities')
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmpe5vngw46/model.ckpt-200
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
<AxesSubplot:title={'center':'predicted probabilities'}, ylabel='Frequency'>

بي إن جي

أخيرًا ، انظر إلى خاصية تشغيل جهاز الاستقبال (ROC) للنتائج ، والتي ستعطينا فكرة أفضل عن المقايضة بين المعدل الإيجابي الحقيقي والمعدل الإيجابي الخاطئ.

from sklearn.metrics import roc_curve
from matplotlib import pyplot as plt

fpr, tpr, _ = roc_curve(y_eval, probs)
plt.plot(fpr, tpr)
plt.title('ROC curve')
plt.xlabel('false positive rate')
plt.ylabel('true positive rate')
plt.xlim(0,)
plt.ylim(0,)
(0.0, 1.05)

بي إن جي