# TypeError: Expected binary or unicode string, got [

ERROR SUMMARY:

I'm getting the following error:

TypeError: Expected binary or unicode string, got [


BACKGROUND:

I have several features that are histories of user activity. I am trying to predict whether a given user will take an action (represented by a 0 or 1 in my y_train list below) based off of their histories of different types of actions. For example, one feature might be button_A_click_per_day and the history for a given user would be a vector of button A clicks per day over the past 365 days.

The relevant snippets of my code is as follow:

import tensorflow as tf

# Build feature columns for classifier
feature_columns = []
for key in X_train:
col = tf.feature_column.numeric_column(
key=key,
shape=max_width,
)
feature_columns.append(col)

# Build classifier
classifier = tf.estimator.DNNClassifier(
feature_columns=my_feature_columns,
hidden_units=[10, 10],
n_classes=2,
)


And X_train is structured as follows:

>>> X_train['<feature_name>']
129     [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
...
1294    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
860     [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
Name: <feature_name>, Length: 1377, dtype: object


My train input function is as follows:

def train_input_fn(features, labels, batch_size):
dataset = tf.data.Dataset.from_tensor_slices((dict(features), labels))
dataset = dataset.shuffle(buffer_size=1000).repeat(count=None).batch(batch_size)
return dataset.make_one_shot_iterator().get_next()


Finally, when issuing the following command...

classifier.train(
# input_fn is a fn that takes not arguments and returns an iterator.
input_fn=lambda: train_input_fn(X_train, y_train, batch_size=100),
steps=1000,
)


I get the error:

~/.pyenv/versions/anaconda3-5.0.1/lib/python3.6/site-packages/tensorflow/python/util/compat.py in as_bytes(bytes_or_text, encoding)
63   else:
64     raise TypeError('Expected binary or unicode string, got %r' %
---> 65                     (bytes_or_text,))
66
67

TypeError: Expected binary or unicode string, got [0.0, 0.0, 0...


MY QUESTIONS:

1. Do you know what I'm doing wrong to get this error?
2. Is there a better way to model features that are histories?
• have you tried to specify the data type explicitly? – Media Feb 19 '18 at 15:40
• I figured the default data type of tf.float32 would be correct since each item in the list is a float and since I used an integer max_width for shape. – Paul Feb 22 '18 at 0:14
• So now your dtype is tf.float32 and still getting the same error? – Media Feb 22 '18 at 14:04
• Correct. Still getting error. – Paul Feb 22 '18 at 20:46
• did you get any solution.. I am also facing exactly the same issue. – maswadkar Jun 5 '18 at 7:50

You should use a built-in function for train_input_fn instead of writing your own. For example:

train_input_fn = tf.estimator.inputs.numpy_input_fn(
x={"x": np.array(training_set.data)},
y=np.array(training_set.target),
num_epochs=None,
shuffle=True)


There is a complete example in the TensorFlow documentation here.

For me, the cause was incorrect type decimal for some column; fixed by using instead float

I have similar experience, solved by calling pd.Series#tolist() apparently. Here is a whole example.

import tensorflow as tf
import pandas as pd
def get_dataset():
data = [['Tom', 'M', 95], ['Jerry', 'M', 96], ['Tonny', 'M', 97], ['Lisa', 'F', 98]]
dataframe = pd.DataFrame(data=data, columns=['name', 'gender', 'score'])
labels = dataframe.pop('score')
features = dict()
# call pd.Series#tolist() apparently
for col_name in dataframe.columns:
features[col_name] = dataframe[col_name].tolist()
dataset = tf.data.Dataset.from_tensor_slices((features, labels))
dataset=dataset.batch(2)
return dataset

dataset=get_dataset()
features,labels = dataset.make_one_shot_iterator().get_next()

with tf.Session() as sess:
print(sess.run([features,labels]))
print(sess.run([features,labels]))
"""
[({'name': array([b'Tom', b'Jerry'], dtype=object), 'gender': array([b'M', b'M'], dtype=object)}, array([95, 96], dtype=int64))]
[({'name': array([b'Tonny', b'Lisa'], dtype=object), 'gender': array([b'M', b'F'], dtype=object)}, array([97, 98], dtype=int64))]
"""