1
$\begingroup$

On using fit() method on sklearn.ensemble.RandomForestClassifier I am getting a value error that says.

ValueError: could not convert string to float: 'male'

The data-set used is the one in Titanic:Machine Learning from Disaster competition on Kaggle. Here is the link- https://www.kaggle.com/c/titanic Can someone please help me how to deal with this, why is it occurring and how to prevent it in future.

Note-There are no NaN in my DataFrame for train_X, i.e I have replaced all NaN with df.fillna(df.mean()), also I cross-checked that no NaN values exist by using

train_X.isnull().sum()

where, train_X is the training data for features. Please Help!!

$\endgroup$
3
  • $\begingroup$ It seems the model wants to interpret your sex variable as a float, have you specified it as a factor? $\endgroup$ Sep 25 '18 at 9:13
  • $\begingroup$ It is a column in the dataframe, but it is supposed to be a classification as only male and female are possible. How can I change this? $\endgroup$ Sep 25 '18 at 11:02
  • $\begingroup$ Don't know Python, but there should be a factor() function. $\endgroup$ Sep 25 '18 at 11:06
2
$\begingroup$

As an extension to @marco_gorelli's answer, another option apart from one-hot encoding is to use LabelEncoder from sklearn.

from sklearn.preprocessing import LabelEncoder

le = LabelEncoder()
df['sex_enc'] = le.fit_transform(df['sex'])
df['sex_enc'] = df['sex_enc'].astype('category')
$\endgroup$
0
3
$\begingroup$

You can't pass a categorical variable as it is to one of sklearn's classifiers. One approach for dealing with this is to dummy-encode the column in question.

I realise that it's not a strict requirement to post minimal, complete, verifiable code on this site, but it will help if you provide code that can be run by others so that they can go straight to the solution without having to guess what's happening from your error message.

Here's some code which reproduces your error:

import pandas as pd
from sklearn.ensemble import RandomForestClassifier

df = pd.DataFrame({'sex': ['male', 'female', 'female', 'male', 'female'], 'survived': [0, 1, 1, 0, 1]})
rf = RandomForestClassifier()
rf.fit(df.drop('survived', axis=1), df['survived'])

We can fix the error by using the get_dummies function from pandas. The following code gives no errors:

df_dummies = pd.get_dummies(df)
rf.fit(df_dummies.drop('survived', axis=1), df_dummies['survived'])
$\endgroup$
7
  • $\begingroup$ I am not able to get that. Why is this error being produced at the first placed. I am passing it test_y variable (i.e survived columns of pandas DataFrame) so why can't I set categorical data. Has it got to do anything with how it works or is it because of how columns are arranged in the DataFrame? $\endgroup$ Sep 28 '18 at 14:34
  • $\begingroup$ The error is being produced because you are passing a string to the classifier. Sklearn's classifiers don't deal with them automatically, so you need to dummy-encode them (or find some other way of transforming the column's values to floats). $\endgroup$ Sep 28 '18 at 14:54
  • $\begingroup$ I've re-read your sentence " I am passing it test_y variable (i.e survived columns of pandas DataFrame) so why can't I set categorical data" three times, and don't understand what you mean. Could you try rewording it, please? $\endgroup$ Sep 28 '18 at 14:55
  • $\begingroup$ I may be wrong somewhere and feel free to correct me whenever that happens. RandomForest creates an a Forest of Trees at Random, so in a tree, It classifies the instances based on entropy, such that Information Gain with respect to the classification (i.e Survived or not) at each split is maximum. Then why is the algorithm not able to split the the test instances with 'Sex' as one of the attributes when required, why it requires to convert the attribute 'Sex' into float to build a model. Because the classification is to be done on val_y (i.e Survived or not) variable and not on Sex.Plz tell me $\endgroup$ Sep 28 '18 at 15:14
  • $\begingroup$ Ok, so you're asking why sklearn's implementation of the random forest algorithm doesn't allow you to pass categorical variables directly? It's just the way they've implemented it. If you use R, then as @user2974951 suggested, all you need to do is specify that it's a categorical variable by writing asfactor(). $\endgroup$ Sep 28 '18 at 15:22

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.