title: sklearn.LabelEncoder with never seen before values
body: <p>If a <code>sklearn.LabelEncoder</code> has been fitted on a training set, it might break if it encounters new values when used on a test set.</p>
  
  <p>The only solution I could come up with for this is to map everything new in the test set (i.e. not belonging to any existing class) to <code>"&lt;unknown&gt;"</code>, and then explicitly add a corresponding class to the <code>LabelEncoder</code> afterward:</p>
  
  <pre class="lang-python prettyprint-override"><code># train and test are pandas.DataFrame's and c is whatever column
  le = LabelEncoder()
  le.fit(train[c])
  test[c] = test[c].map(lambda s: '&lt;unknown&gt;' if s not in le.classes_ else s)
  le.classes_ = np.append(le.classes_, '&lt;unknown&gt;')
  train[c] = le.transform(train[c])
  test[c] = le.transform(test[c])
  </code></pre>
  
  <p>This works, but is there a better solution?</p>
  
  <p><strong>Update</strong></p>
  
  <p>As @sapo_cosmico points out in a comment, it seems that the above doesn't work anymore, given what I assume is an implementation change in <code>LabelEncoder.transform</code>, which now seems to use <code>np.searchsorted</code> (I don't know if it was the case before). So instead of appending the <code>&lt;unknown&gt;</code> class to the <code>LabelEncoder</code>'s list of already extracted classes, it needs to be inserted in sorted order:</p>
  
  <pre class="lang-python prettyprint-override"><code>import bisect
  le_classes = le.classes_.tolist()
  bisect.insort_left(le_classes, '&lt;unknown&gt;')
  le.classes_ = le_classes
  </code></pre>
  
  <p>However, as this feels pretty clunky all in all, I'm certain there is a better approach for this.</p>