'Cast string to float is not supported in Linear Model

I keep getting this error in my linear model:

Cast string to float is not supported

Specifically, the error is on this line:

results = m.evaluate(input_fn=lambda: input_fn(df_test), steps=1)

If it helps, here's the stack trace:

 File "tensorflowtest.py", line 164, in <module>
    m.fit(input_fn=lambda: input_fn(df_train), steps=int(100))
  File "/home/computer/.local/lib/python2.7/site-packages/tensorflow/contrib/learn/python/learn/estimators/linear.py", line 475, in fit
    max_steps=max_steps)
  File "/home/computer/.local/lib/python2.7/site-packages/tensorflow/contrib/learn/python/learn/estimators/estimator.py", line 333, in fit
    max_steps=max_steps)
  File "/home/computer/.local/lib/python2.7/site-packages/tensorflow/contrib/learn/python/learn/estimators/estimator.py", line 662, in _train_model
    train_op, loss_op = self._get_train_ops(features, targets)
  File "/home/computer/.local/lib/python2.7/site-packages/tensorflow/contrib/learn/python/learn/estimators/estimator.py", line 963, in _get_train_ops
    _, loss, train_op = self._call_model_fn(features, targets, ModeKeys.TRAIN)
  File "/home/computer/.local/lib/python2.7/site-packages/tensorflow/contrib/learn/python/learn/estimators/estimator.py", line 944, in _call_model_fn
    return self._model_fn(features, targets, mode=mode, params=self.params)
  File "/home/computer/.local/lib/python2.7/site-packages/tensorflow/contrib/learn/python/learn/estimators/linear.py", line 220, in _linear_classifier_model_fn
    loss = loss_fn(logits, targets)
  File "/home/computer/.local/lib/python2.7/site-packages/tensorflow/contrib/learn/python/learn/estimators/linear.py", line 141, in _log_loss_with_two_classes
    logits, math_ops.to_float(target))
  File "/home/computer/.local/lib/python2.7/site-packages/tensorflow/python/ops/math_ops.py", line 661, in to_float
    return cast(x, dtypes.float32, name=name)
  File "/home/computer/.local/lib/python2.7/site-packages/tensorflow/python/ops/math_ops.py", line 616, in cast
    return gen_math_ops.cast(x, base_type, name=name)
  File "/home/computer/.local/lib/python2.7/site-packages/tensorflow/python/ops/gen_math_ops.py", line 419, in cast
    result = _op_def_lib.apply_op("Cast", x=x, DstT=DstT, name=name)
  File "/home/computer/.local/lib/python2.7/site-packages/tensorflow/python/framework/op_def_library.py", line 749, in apply_op
    op_def=op_def)
  File "/home/computer/.local/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 2380, in create_op
    original_op=self._default_original_op, op_def=op_def)
  File "/home/computer/.local/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 1298, in __init__
    self._traceback = _extract_stack()

UnimplementedError (see above for traceback): Cast string to float is not supported
         [[Node: ToFloat = Cast[DstT=DT_FLOAT, SrcT=DT_STRING, _device="/job:localhost/replica:0/task:0/cpu:0"](Reshape_1)]]

The model is an adaptation of the tutorial from here and here. The tutorial code does run, so it's not a problem with my TensorFlow installation.

The input CSV is data in the form of many binary categorical columns (yes/no). Initially, I represented the data in each column as 0's and 1's, but I get the same error when I change it to ys and ns.

How do I fix this?



Solution 1:[1]

I had the exact same problem, you need to make sure that the input data you are feeding the model is in the right format. ( not just the features but also the label column)

My problem was that i was not skipping the first row in the data file, so i was trying to convert the titles to float format.Something as simple as adding

skiprows=1

When reading the csv:

df_test = pd.read_csv(test_file, names=COLUMNS_TEST, skipinitialspace=True, skiprows=1, engine="python")

I would recommend you to check:

df_test.dtypes

You should get something like

Feature1      int64
Feature2      int64
Feature3      int64
Feature4      object
Feature5      object
Feature6      float64
dtype: object

If you are not getting the correct dtype then the model.fit is going to fail

Solution 2:[2]

The problem is that you probably had indicated the feature like a real type but in your data frame is still string or when set in tf.constant you didn't cast to correct type.

Confirm the types of your columns. You can check just type (df is your dataframe):

df.info()

And you can see all columns and types, some like that:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 178932 entries, 0 to 178931
Data columns (total 64 columns):
d_prcp                      178932 non-null float64
d_stn                       178932 non-null int64
ws_lat                      178932 non-null float64
ws_lon                      178932 non-null float64
d_year                      178932 non-null int64
d_temp                      178932 non-null float64
...

You can use this bellow function in order to convert your data in correct type in tensorflow. (this code is from a repo google/training-data-analyst: link here)

def make_input_fn(df):
  def pandas_to_tf(pdcol):
    # convert the pandas column values to float
    t = tf.constant(pdcol.astype('float32').values)
    # take the column which is of shape (N) and make it (N, 1)
    return tf.expand_dims(t, -1)

  def input_fn():
    # create features, columns
    features = {k: pandas_to_tf(df[k]) for k in FEATURES}
    labels = tf.constant(df[TARGET].values)
    return features, labels
  return input_fn

def make_feature_cols():
  input_columns = [tf.contrib.layers.real_valued_column(k) for k in FEATURES]
  return input_columns

Solution 3:[3]

You can't literally cast a string to a number, particularly "y","n" to 1.0/0.0.

If you have numeric strings (e.g. "0") you could try tf.string_to_number(..)

Solution 4:[4]

I faced the same issue when I tried replicating the steps on a different data-set for practice.

SIMPLE TO FIX, just use the following code to change the data type of your TARGET COLUMN to int,

df["target_column_name"] = df["target_column_name"].astype(str).astype(int)

Also, you need to do it at the starting, when the target column is inside your data-file initially.

Solution 5:[5]

I am using W10, Python3 and Tensorflow 1.9

The source of the error in my code was in the feature definition. I had a boolean feature with a default_value of -1 like this:

tf.feature_column.categorical_column_with_vocabulary_list( 
    key='partial_funding_indicator', vocabulary_list=['True', 'False'],
    dtype=tf.string, **default_value=-1**, num_oov_buckets=None)

The issue did not arise when the default_value was changed to 0:

tf.feature_column.categorical_column_with_vocabulary_list(
    key='partial_funding_indicator', vocabulary_list=['True', 'False'],
    dtype=tf.string, **default_value=0**, num_oov_buckets=None)

default_value is the integer ID value to return for out-of-vocabulary feature values. For example, in a list/file of value like ['True', 'False'] to make default_value == True, it would be default_value=0; the list index.

Solution 6:[6]

Your classes are probably in string forms and they need to be numeric (1 and 0 only for this specific tutorial)

Solution 7:[7]

Normally this error is because m.evaluate is somehow empty.

Since you load your data from csv file, it is very likely that your data was stored as string instead of float or int inside the array. I suggest you check it manually to make sure.

Solution 8:[8]

Somewhere in your code you're using tf.cast() to convert a string to number, but you cannot do this. Replace it with tf.strings.to_number():

tf.strings.to_number(x, out_type=tf.float32)

Solution 9:[9]

The problem is that there's a header on the file you've imported to work on. The header is of the type string and the rest of the rows are int64 or float64. While the types are variant in a column they are typed as object . You can check and make sure the this is the problem with this code:

df_test.dtypes

To solve this you can simply delete the header row from your CSV before importing it to pyhton. Just remember that if you drop that row after importing it will not work and the data types won't change!

Solution 10:[10]

The other way is using

df = df.astype({'COL1': 'float64', 'COL2': 'float64'})

for a dataframe

Solution 11:[11]

Some times the reason is that your feeding data is not in the string format and that is example of WRONGE data

,0
' or x = 1 , 1, 0,1
SELECT * FROM USERS WHERE(1 = 1, 1, 0 = 0,0),1

Try to clean your dataset first and honestly this worked with me in my graduation project dataset

Solution 12:[12]

The immediate answer is, that you need to change your df_test's format to the same format as your df_train at the very beginning.

For example,

df_train.replace({'yes':1,'no':0}, inplace = True)
    
df_test.replace({'yes':1,'no':0}, inplace = True)