1
$\begingroup$

I'm brand new to machine learning (having just completed the google machine learning crash course) and thought it would be good to try my hand at a Kaggle competition as a good starter to some real problem solving. I'm using tensorflow and Python 3, all up to date (the kaggle online jupyter notebook)

The data is formatted in a dataframe like below

|Identity | Cuisine | Ingredients                |
|---------|---------|----------------------------|
|1        | italian | [beans, milk,..., tomatoes]|
|2        | indian  | [chicken, curry leaf,...]  |

I have made a vocabulary list generator to create a vocabulary set, and replace instances of those words in the ingredients array with the index of the ingredient in the vocabulary set, so my original data looks like below.

|Identity | Cuisine | Ingredients |
|---------|---------|-------------|
|1        | italian |[0, 1,..., 4]|
|2        | indian  |[5, 6,...]   |

I seperate the labels (cuisine) and the features (ingredients) into 2 seperate dataframes for ease, and I am using a tf.feature_column.categorical_column_with_vocabulary_list and subsequent tf.feature_column.indicator_column for the ingredients array.

I now however have an issue with my model not being able to read the ingredients column, and get the error

TypeError: Expected binary or unicode string, got [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

my input function is as follows

def input_fn(features,labels,batch_size,num_epochs=None,shuffle=True):
    ds = Dataset.from_tensor_slices((features,labels))
    ds = ds.batch(batch_size).repeat(num_epochs)

    if shuffle:
        ds = ds.shuffle(10000)

    feature_batch, label_batch = ds.make_one_shot_iterator().get_next()
    return feature_batch, label_batch

which is fed into a simple function as below

training_func = lambda: input_fn(training_example,training_target,batch_size)
validati_func = lambda: input_fn(validation_example,validation_target,batch_size)

optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
optimizer = tf.contrib.estimator.clip_gradients_by_norm(optimizer, 5.0)

classifier.train(
    input_fn=training_func,
    steps=steps_per_period
)

My urgent question is how do I fix this TypeError

In addition I also want to know if there a best practice for handling this format of data? (and if there is any built-in functionality to handle this)

$\endgroup$
  • 1
    $\begingroup$ Since this might be a code heavy question, I added my entire code to an online Pastebin paste so you can check out the code. The dataset I am using is from the kaggle Whats Cooking competition $\endgroup$ – Byren Higgin Aug 9 '18 at 3:07
0
$\begingroup$

I'm not completely familiar with TF API, but here's what I think is happening.

The library tells you that it can handle a binary column or a string. But you have all the ingredients listed in a single column. So the integer conversion of ingredient label is not helping.

You can instead create one column per possible list of ingredient and setting it to 1 if that ingredient is present or absent. For example, Italian cuisine will have column for tomatoes or garlic set to 1 for many records.

You can read more about get_dummies function in pandas library. If the original ingredient list comes in form of text, you can read up more about text feature extraction / bag of words APIs in scikit-learn libary.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.