TL;DR
If your labels are part of your feature matrix, you need to convert them to numerals using OneHotEncoding
(docs). However, if your labels are just your targets, you can leave them as is.
1) Is it necessary to convert the strings to integers?
You did not specify if your string labels are one of your features in your feature matrix X
, or if they are your target y
. So, here is some data to cover both cases:
X = [
['sunny'],
['rainy'],
['rainy'],
['cloudy'],
['very rainy'],
['sunny'],
['partially cloudy']
]
y = [
'no umbrella',
'umbrella',
'umbrella',
'no umbrella',
'umbrella',
'no umbrella',
'no umbrella'
]
If you try to fit a DecisionTreeClassifier
with this, like this:
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier()
clf.fit(X, y)
You get an error:
ValueError: could not convert string to float: 'sunny'
So definitely, you need to convert them to integers, for example:
from sklearn.preprocessing import OrdinalEncoder
encoder = OrdinalEncoder()
encoder.fit(X)
X_encoded = encoder.transform(X)
>> [[3.] # sunny
>> [2.] # rainy
>> [2.] # rainy
>> [0.] # cloudy
>> [4.] # very rainy
>> [3.] # sunny
>> [1.]] # partially cloudy
This transforms your labels into integers. And now you are able to .fit()
your model.
This means that features in X
must be transformed to integers, however, target labels in y
can remain as strings.
2) Will the algorithms work less effectively?
If you don't convert your targets y
into integers, there will be no decrease in your algorithms performance.
Now, given that you need to convert your string features X
into numerals, the way that you convert will affect the algorithm.
In Sklearn you can use the OrdinalEncoder
(docs) or the OneHotEncoder
(docs). The way in which they encode X
is different, observe:
OrdinalEncoder
from sklearn.preprocessing import OrdinalEncoder
encoder = OrdinalEncoder()
encoder.fit(X)
X_encoded = encoder.transform(X)
>> [[3.] # sunny
>> [2.] # rainy
>> [2.] # rainy
>> [0.] # cloudy
>> [4.] # very rainy
>> [3.] # sunny
>> [1.]] # partially cloudy
OneHotEncoder
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder()
encoder.fit(X)
X_encoded = encoder.transform(X)
[[0. 0. 0. 1. 0.] # sunny
[0. 0. 1. 0. 0.] # rainy
[0. 0. 1. 0. 0.] # rainy
[1. 0. 0. 0. 0.] # cloudy
[0. 0. 0. 0. 1.] # very rainy
[0. 0. 0. 1. 0.] # sunny
[0. 1. 0. 0. 0.]] # partially cloudy
For algorithms like DecisionTreeClassifier
s, the second option, namely OneHotEncoder
is better because there are more dimensions to finding boundary lines. So you can have a shallower trees. Where as, if you encode with a simple LabelEncoder
, you will need to have deeper tree.
Have a look at the tree generated given the two types of input:
LabelEncoder
, notice how 3 decisions nodes are needed.

OneHotEncoder
, notice how only 2 decisions nodes are needed.
