【问题标题】:TensorForestEstimator with feature_column throws TypeError带有 feature_column 的 TensorForestEstimator 抛出 TypeError
【发布时间】:2019-02-25 01:35:03
【问题描述】:

我计划在更大的数据集上使用TensorForestEstimator,该数据集将通过对 Pandas 对象进行操作的input_fn 提供数据。

为了验证我对 API 的理解,我整理了一个较小的示例,该示例使用来自 UC Irvine Machine Learning Repository 的数据集。该数据集有七个特征(六个int32s 和一个float32)和一个标签(int32)。

当数据集通过xy 参数直接作为numpy 数组输入时,我可以运行fit()evaluate()

当我尝试对来自tf.estimator.inputs.pandas_input_fninput_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 问题记录中进行了大量搜索,但尚未找到根本原因。

提前致谢!

TensorForestEstimatorpandas_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]

Instatntiate 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')
)

【问题讨论】:

    标签: python csv numpy classification tflearn


    【解决方案1】:

    经过进一步测试,我认为这是TensorForestEstimator 中的一个错误。更多细节可以在这个 URL 的 GitHub 问题中找到:

    https://github.com/tensorflow/tensorflow/issues/26082

    【讨论】:

      猜你喜欢
      • 2018-07-12
      • 2022-08-15
      • 1970-01-01
      • 2017-12-18
      • 2011-10-03
      • 2016-11-18
      • 1970-01-01
      • 1970-01-01
      • 2013-12-28
      相关资源
      最近更新 更多