Я планирую использовать TensorForestEstimator
для большого набора данных, который будет передаваться через input_fn
, который работает с объектами Pandas.
Чтобы проверить мое понимание API, я собрал меньшийпример, который использует набор данных из UC Irvine Machine Learning Repository .Набор данных имеет семь функций (шесть int32
с и float32
) и метку (int32
).
Я могу запустить fit()
и evaluate()
очень хорошо, когда набор данныхнапрямую передается в виде массивов numpy
с аргументами x
и y
.
Когда я пытаюсь выполнить ту же операцию с данными, полученными из input_fn
, в которых используется оператор from tf.estimator.inputs.pandas_input_fn
, иtf.contrib.layers
особенность столбцов аргумента feature_columns
, я наблюдаю ошибку значения в tensorflow/contrib/tensor_forest/python/ops/data_ops.py
:
TypeError: '<' not supported between instances of '_RealValuedColumn' and 'str'
Это потому, что sorted()
вызывается из спискаключи словаря, которые являются одновременно str
и объектами TensorFlow.
Код, экспортированный из записной книжки Jupyter, приведен в конце этого поста.
Любая информация о том, почему это может происходитьбудет оценено.Я проделал немалый поиск в документах, StackOverflow и записях о проблемах GitHub, и мне еще не удалось найти основную причину.
Заранее спасибо!
Пример кода дляTensorForestEstimator
с pandas_input_fn
Импорт стандартной библиотеки Python
import csv
import numpy as np
import pandas as pd
import random
Импорт библиотеки TensorFlow
import tensorflow as tf
import tensorflow.contrib.layers as layers
import tensorflow.contrib.tensor_forest as tforest
Импорт библиотеки TensorFlow с псевдонимом
from tensorflow.estimator.inputs import pandas_input_fn
from tensorflow.python.platform import tf_logging as logging
Метаданные для столбцов CSV
COLUMN_PROPS = {
'sex' : {
'is_feature' : True,
'is_label' : False,
'dtype' : tf.int32,
'default' : -1,
'feature_column' : layers.real_valued_column(
'sex',
dtype=tf.int32
)
},
'age' : {
'is_feature' : True,
'is_label' : False,
'dtype' : tf.int32,
'default' : -1,
'feature_column' : layers.real_valued_column(
'age',
dtype=tf.int32
)
},
'Time' : {
'is_feature' : True,
'is_label' : False,
'dtype' : tf.float32,
'default' : -1.0,
'feature_column' : layers.real_valued_column(
'Time',
dtype=tf.float32
)
},
'Number_of_Warts' : {
'is_feature' : True,
'is_label' : False,
'dtype' : tf.int32,
'default' : -1,
'feature_column' : layers.real_valued_column(
'Number_of_Warts',
dtype=tf.int32
),
},
'Type' : {
'is_feature' : True,
'is_label' : False,
'dtype' : tf.int32,
'default' : -1,
'feature_column' : layers.real_valued_column(
'Type',
dtype=tf.int32
)
},
'Area' : {
'is_feature' : True,
'is_label' : False,
'dtype' : tf.int32,
'default' : -1,
'feature_column' : layers.real_valued_column(
'Area',
dtype=tf.int32
)
},
'induration_diameter' : {
'is_feature' : True,
'is_label' : False,
'dtype': tf.int32,
'default': -1,
'feature_column' : layers.real_valued_column(
'induration_diameter',
dtype=tf.int32
)
},
'Result_of_Treatment': {
'is_feature' : False,
'is_label' : True,
'dtype': tf.int32,
'default': -1,
'feature_column' : None
}
}
Упорядочение столбцов CSV
CSV_COLUMNS = [
'sex',
'age',
'Time',
'Number_of_Warts',
'Type',
'Area',
'induration_diameter',
'Result_of_Treatment'
]
Создание списков объектов и меток из метаданных
FEATURE_COLUMNS = []
LABEL_COLUMN = None
for k in CSV_COLUMNS:
if COLUMN_PROPS[k]['is_feature']:
FEATURE_COLUMNS.append(k)
elif COLUMN_PROPS[k]['is_label']:
LABEL_COLUMN = k
Вспомогательная функция для перетасовки и экспортаПодмножества
Эта функция используется для экспорта наборов обучающих, оценочных и тестовых данных в виде CSV, перетасовывающих строки.
def generate_sets(datasets):
for k, v in datasets.items():
random.shuffle(v)
with open(k + '.csv', 'w') as fobj:
wrtr = csv.writer(fobj)
wrtr.writerow(header)
for rec in v:
wrtr.writerow(rec)
Разделенные наборы данных для обучения, оценки и тестирования
trn = []
evl = []
tst = []
with open('Immunotherapy - ImmunoDataset.csv', 'r') as fobj:
rdr = csv.reader(fobj)
header = next(rdr)
label_key = header[-1]
feature_keys = header[:-1]
for rec in rdr:
# Output of random number generator determines
# which set the record will be placed.
rn = random.random()
if rn < 0.6:
trn.append(rec)
elif rn < 0.8:
evl.append(rec)
else:
tst.append(rec)
datasets = {
'train' : trn,
'eval' : evl,
'test' : tst
}
generate_sets(datasets)
Настройка TensorForest
Гиперпараметры
fhp = tforest.tensor_forest.ForestHParams(
num_classes=2,
num_features=7,
regression=False
)
Выбор столбцов объектов из словаря метаданных
fcs = [COLUMN_PROPS[k]['feature_column'] for k in FEATURE_COLUMNS]
Создание экземпляра TensorForestEstimator
Объект
tfe = tforest.random_forest.TensorForestEstimator(
fhp,
feature_columns=fcs,
report_feature_importances=True
)
ОпределениеОбертка для pandas_input_fn
def get_input_fn(csv_file):
df = pd.read_csv(csv_file)
features = df.loc[:,'sex':'induration_diameter']
# Workaround for this issue:
#
# https://stackoverflow.com/questions/48577372/tensorflowusing-pandas-input-fn-with-tensorforestestimator
# https://github.com/tensorflow/tensorflow/issues/16692
labels = pd.DataFrame(
np.expand_dims(
df.loc[:,'Result_of_Treatment'].values, axis=1
)
)
return pandas_input_fn(x=features, y=labels, shuffle=False)
Поезд по данным
tfe.fit(
input_fn=get_input_fn('train.csv')
)