TensorFlow Transform으로 데이터 전처리

TensorFlow Extended(TFX)의 기능 엔지니어링 구성요소

이 예제 colab 노트북은 TensorFlow Transform( tf.Transform ) 을 사용하여 프로덕션에서 모델을 훈련하고 추론을 제공하는 데 정확히 동일한 코드를 사용하여 데이터를 사전 처리하는 방법에 대한 매우 간단한 예를 제공합니다.

TensorFlow Transform은 훈련 데이터 세트에 대한 전체 전달이 필요한 기능 생성을 포함하여 TensorFlow용 입력 데이터를 사전 처리하기 위한 라이브러리입니다. 예를 들어 TensorFlow Transform을 사용하여 다음을 수행할 수 있습니다.

  • 평균과 표준편차를 이용하여 입력값 정규화
  • 모든 입력 값에 대해 어휘를 생성하여 문자열을 정수로 변환
  • 관찰된 데이터 분포를 기반으로 부동 소수점을 버킷에 할당하여 정수로 변환

TensorFlow에는 단일 예제 또는 예제 배치에 대한 조작 지원이 내장되어 있습니다. tf.Transform 은 이러한 기능을 확장하여 전체 교육 데이터 세트에 대한 전체 패스를 지원합니다.

tf.Transform 의 출력은 훈련과 제공 모두에 사용할 수 있는 TensorFlow 그래프로 내보내집니다. 훈련과 제공 모두에 동일한 그래프를 사용하면 두 단계에 동일한 변환이 적용되므로 왜곡을 방지할 수 있습니다.

핍 업그레이드

로컬에서 실행할 때 시스템에서 Pip를 업그레이드하지 않으려면 Colab에서 실행 중인지 확인하세요. 물론 로컬 시스템은 별도로 업그레이드할 수 있습니다.

try:
  import colab
  !pip install --upgrade pip
except:
  pass

TensorFlow 변환 설치

pip install -q -U tensorflow_transform

런타임을 다시 시작했습니까?

Google Colab을 사용하는 경우 위의 셀을 처음 실행할 때 런타임을 다시 시작해야 합니다(런타임 > 런타임 다시 시작...). Colab이 패키지를 로드하는 방식 때문입니다.

수입품

import pprint
import tempfile

import tensorflow as tf
import tensorflow_transform as tft

import tensorflow_transform.beam as tft_beam
from tensorflow_transform.tf_metadata import dataset_metadata
from tensorflow_transform.tf_metadata import schema_utils

데이터: 더미 데이터 생성

간단한 예제를 위해 몇 가지 간단한 더미 데이터를 만들 것입니다.

  • raw_data 는 전처리할 초기 원시 데이터입니다.
  • raw_data_metadata 에는 raw_data 의 각 열 유형을 알려주는 스키마가 포함되어 있습니다. 이 경우 매우 간단합니다.
raw_data = [
      {'x': 1, 'y': 1, 's': 'hello'},
      {'x': 2, 'y': 2, 's': 'world'},
      {'x': 3, 'y': 3, 's': 'hello'}
  ]

raw_data_metadata = dataset_metadata.DatasetMetadata(
    schema_utils.schema_from_feature_spec({
        'y': tf.io.FixedLenFeature([], tf.float32),
        'x': tf.io.FixedLenFeature([], tf.float32),
        's': tf.io.FixedLenFeature([], tf.string),
    }))

변환: 전처리 함수 생성

전처리 기능 은 tf.Transform의 가장 중요한 개념입니다. 전처리 기능은 데이터 세트의 변환이 실제로 일어나는 곳입니다. 텐서 사전을 수락하고 반환합니다. 여기서 텐서는 Tensor 또는SparseTensor 를 의미합니다. 일반적으로 전처리 기능의 핵심을 형성하는 두 가지 주요 API 호출 그룹이 있습니다.

  1. TensorFlow Ops: 일반적으로 TensorFlow 작업을 의미하는 텐서를 수락하고 반환하는 모든 함수입니다. 이것은 원시 데이터를 변환된 데이터로 한 번에 하나의 특성 벡터로 변환하는 TensorFlow 작업을 그래프에 추가합니다. 이는 교육 및 봉사 중 모든 예에 대해 실행됩니다.
  2. Tensorflow 변환 분석기/매퍼: tf.Transform에서 제공하는 분석기/매퍼 중 하나입니다. 이들은 또한 텐서를 수락하고 반환하며 일반적으로 Tensorflow 작업과 Beam 계산의 조합을 포함하지만 TensorFlow 작업과 달리 전체 교육 데이터 세트에 대한 전체 패스가 필요한 분석 중에 Beam 파이프라인에서만 실행됩니다. Beam 계산은 훈련 중에 한 번만 실행되며 일반적으로 전체 훈련 데이터 세트를 완전히 통과합니다. 그들은 그래프에 추가되는 텐서 상수를 생성합니다. 예를 들어 tft.min은 훈련 데이터 세트에 대해 텐서의 최소값을 계산하는 반면 tft.scale_by_min_max는 먼저 훈련 데이터 세트에 대해 텐서의 최소값과 최대값을 계산한 다음 사용자 지정 범위 [output_min, output_max]. tf.Transform은 이러한 분석기/매퍼의 고정 세트를 제공하지만 향후 버전에서 확장될 예정입니다.
def preprocessing_fn(inputs):
    """Preprocess input columns into transformed columns."""
    x = inputs['x']
    y = inputs['y']
    s = inputs['s']
    x_centered = x - tft.mean(x)
    y_normalized = tft.scale_to_0_1(y)
    s_integerized = tft.compute_and_apply_vocabulary(s)
    x_centered_times_y_normalized = (x_centered * y_normalized)
    return {
        'x_centered': x_centered,
        'y_normalized': y_normalized,
        's_integerized': s_integerized,
        'x_centered_times_y_normalized': x_centered_times_y_normalized,
    }

함께 모아서

이제 데이터를 변환할 준비가 되었습니다. 직접 실행기와 함께 Apache Beam을 사용하고 다음 세 가지 입력을 제공합니다.

  1. raw_data - 위에서 생성한 원시 입력 데이터
  2. raw_data_metadata - 원시 데이터의 스키마
  3. preprocessing_fn - 변환을 수행하기 위해 만든 함수
def main():
  # Ignore the warnings
  with tft_beam.Context(temp_dir=tempfile.mkdtemp()):
    transformed_dataset, transform_fn = (  # pylint: disable=unused-variable
        (raw_data, raw_data_metadata) | tft_beam.AnalyzeAndTransformDataset(
            preprocessing_fn))

  transformed_data, transformed_metadata = transformed_dataset  # pylint: disable=unused-variable

  print('\nRaw data:\n{}\n'.format(pprint.pformat(raw_data)))
  print('Transformed data:\n{}'.format(pprint.pformat(transformed_data)))

if __name__ == '__main__':
  main()
WARNING:apache_beam.runners.interactive.interactive_environment:Dependencies required for Interactive Beam PCollection visualization are not available, please use: `pip install apache-beam[interactive]` to install necessary dependencies to enable all data visualization features.
WARNING:tensorflow:You are passing instance dicts and DatasetMetadata to TFT which will not provide optimal performance. Consider following the TFT guide to upgrade to the TFXIO format (Apache Arrow RecordBatch).
WARNING:tensorflow:You are passing instance dicts and DatasetMetadata to TFT which will not provide optimal performance. Consider following the TFT guide to upgrade to the TFXIO format (Apache Arrow RecordBatch).
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow_transform/tf_utils.py:289: Tensor.experimental_ref (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use ref() instead.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow_transform/tf_utils.py:289: Tensor.experimental_ref (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use ref() instead.
WARNING:tensorflow:You are passing instance dicts and DatasetMetadata to TFT which will not provide optimal performance. Consider following the TFT guide to upgrade to the TFXIO format (Apache Arrow RecordBatch).
WARNING:tensorflow:You are passing instance dicts and DatasetMetadata to TFT which will not provide optimal performance. Consider following the TFT guide to upgrade to the TFXIO format (Apache Arrow RecordBatch).
WARNING:apache_beam.options.pipeline_options:Discarding unparseable args: ['/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py', '-f', '/tmp/tmp8aif_7w8.json', '--HistoryManager.hist_file=:memory:']
WARNING:root:Make sure that locally built Python SDK docker image has Python 3.7 interpreter.
INFO:tensorflow:Assets written to: /tmp/tmpfvgb9_2h/tftransform_tmp/319450c9d7da4ab08741bc79e129ac38/assets
2022-02-03 10:18:41.378629: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
INFO:tensorflow:Assets written to: /tmp/tmpfvgb9_2h/tftransform_tmp/319450c9d7da4ab08741bc79e129ac38/assets
INFO:tensorflow:tensorflow_text is not available.
INFO:tensorflow:tensorflow_text is not available.
INFO:tensorflow:tensorflow_decision_forests is not available.
INFO:tensorflow:tensorflow_decision_forests is not available.
INFO:tensorflow:struct2tensor is not available.
INFO:tensorflow:struct2tensor is not available.
INFO:tensorflow:Assets written to: /tmp/tmpfvgb9_2h/tftransform_tmp/1f79865adbdd4ede9a3768fcac29949c/assets
INFO:tensorflow:Assets written to: /tmp/tmpfvgb9_2h/tftransform_tmp/1f79865adbdd4ede9a3768fcac29949c/assets
INFO:tensorflow:tensorflow_text is not available.
INFO:tensorflow:tensorflow_text is not available.
INFO:tensorflow:tensorflow_decision_forests is not available.
INFO:tensorflow:tensorflow_decision_forests is not available.
INFO:tensorflow:struct2tensor is not available.
INFO:tensorflow:struct2tensor is not available.
Raw data:
[{'s': 'hello', 'x': 1, 'y': 1},
 {'s': 'world', 'x': 2, 'y': 2},
 {'s': 'hello', 'x': 3, 'y': 3}]

Transformed data:
[{'s_integerized': 0,
  'x_centered': -1.0,
  'x_centered_times_y_normalized': -0.0,
  'y_normalized': 0.0},
 {'s_integerized': 1,
  'x_centered': 0.0,
  'x_centered_times_y_normalized': 0.0,
  'y_normalized': 0.5},
 {'s_integerized': 0,
  'x_centered': 1.0,
  'x_centered_times_y_normalized': 1.0,
  'y_normalized': 1.0}]

이게 정답인가요?

이전에는 tf.Transform 을 사용하여 다음을 수행했습니다.

x_centered = x - tft.mean(x)
y_normalized = tft.scale_to_0_1(y)
s_integerized = tft.compute_and_apply_vocabulary(s)
x_centered_times_y_normalized = (x_centered * y_normalized)

x_중심

[1, 2, 3] 을 입력하면 x의 평균은 2이고 x 값을 0에 중앙에 맞추기 위해 x에서 뺍니다. 따라서 [-1.0, 0.0, 1.0] 의 결과는 정확합니다.

y_정규화

우리는 0과 1 사이에서 y 값을 조정하고 싶었습니다. 입력은 [1, 2, 3] 이므로 [0.0, 0.5, 1.0] 의 결과가 정확합니다.

s_integerized

우리는 문자열을 어휘의 색인에 매핑하고 싶었고 어휘에는 2개의 단어("hello"와 "world")만 있었습니다. 따라서 ["hello", "world", "hello"] 를 입력하면 [0, 1, 0] 의 결과가 정확합니다. "hello"는 이 데이터에서 가장 자주 발생하므로 어휘의 첫 번째 항목이 됩니다.

x_center_times_y_정규화

곱셈을 사용하여 x_centeredy_normalized 를 교차하여 새로운 기능을 만들고 싶었습니다. 이것은 원래 값이 아니라 결과를 곱하며 [-0.0, 0.0, 1.0] 의 새 결과가 정확합니다.