target encoding что это
Заметки, идеи и скрипты
Как сделать мир лучше с помощью компьютера
Две функции повышения точности классификатора с помощью target encoding / mean encoding
Раз Вы смогли нагуглить эту статью, значит скорее всего знаете что такое target encoding, а тажке ознакомлены со всеми прелестями этого мощного метода и знаете все опасности переобучения, которые могут возникнуть при неправильном использовании подхода.
Поэтому здесь я приведу лишь две функции, которые можно быстро использовать для Ваших задач.
Если же не знакомы c mean encoding, то вкратце так:
На основе знаний о target, и его распределения по какой-нибудь категориальной фичи можно добавить новую переменную, показывающую характеристику встречаемости чисто внутри какой-то категории. Для примера пусть есть датасет с разными характеристиками автомобиля, необходимо предсказать город, где был куплен автомобиль. Можно подсчитать среднее кол-во каждой марки в каждом городе и добавить это как дополнительную фичу. Так скажем для тойоты это число будет больше во Владивостоке, чем для Москвы и наоборот, какой-нибудь мерседес явно будет более встречаемый в Москве, нежели рядом с Японией. Как видим, разделяемость по новой фиче будет очень хорошая. Но в этом и есть большой риск переобучения (например какая-нибудь редкая марка, которая в датасете встретится всего пару раз и в одном городе) поэтому напрямую считать среднее не рекомендуется, а правильнее будет использовать регуляризации. Ниже приведены две функции для корректного использования mean-encoding:
Функция 1: CV loop регуляризация
Достаточно интуитивный и устойчивый метод для mean encoding. Данные разбиваются на фолды и значение для каждого фолда вычисляется на основе оставшихся фолдов. Таким образом не будет переобучения на текущем куске данных, т.к. вычисляемое среднее значение будет браться на остальном подмножестве данных. Обычно 4-5 фолдов достаточно.
Функция 2: Регуляризация на основе размытия
Суть данной регуляризации в том, что мы доверяем большим категориям, с большим кол-вом значений и устанавливаем коэффициент недоверия к небольшим, слабопредставленным категориям. По сути говоря коэффициент alpha это размер группы, начиная с которой мы доверяем среднему значению
Некоторые библиотеки градиентного бустинга из коробки умеют делать mean-encoding, например catboost. Делает котяра эту вещь отменно, достаточно просто указать категориальные фичи, и мне даже когда-то не хотелось лезть в эту тему, но в один момент надо было работать с очень большим датасетом, и оказалась что эта фича библиотеки ужасно прожорлива на используемую память, а если использовать ещё и обучение на видеокарте, то терабайтов оперативной памяти не хватит. Поэтому иногда полезно самим прикрутить фичи на основе mean-енкодинга, кроме того, за основу не обязательно брать таргет, можно поэкспериментировать и с другими величинами из датасета.
Мульти-классовое целе-вероятностное кодирование переменных (Multi-Class Target Encoding)
Что не так с TargetEncoder из библиотеки category_encoders?
Эта статья является продолжением предыдущей статьи, в которой объяснялось, как на самом деле работает целе-вероятностное кодирование, и теперь мы посмотрим в каких случаях стандартное решение библиотеки category_encoders дает неверный результат, а кроме того, изучим теорию и пример кода для корректного мульти-классового целе-вероятностного кодирования. Поехали!
1. Когда ошибается TargetEncoder?
Давайте сделаем для этого обычную целе-вероятностную кодировку.
Хмм… выглядит не очень, не так ли? Все цвета были заменены на 1. Почему? Так происходит потому, что TargetEncoder принимает среднее значение всех целевых значений для каждого цвета, а не вероятность.
Хотя TargetEncoder корректно работает в случае, когда у вас есть двоичная цель, имеющая 0 и 1, он будет давать сбой в двух случаях:
Когда цель двоичная, но не 0/1 (хотя бы, например 1 и 2).
Теория
В оригинальном документе Daniele Micci-Barreca, который вводит средне-целевую кодировку говориться про мульти-классовые целевые переменные.
Допустим, мы имеем n классов. Теория гласит, что первым делом нужно закодировать значения класса в бинарные переменные. Это даст n двоичных столбцов, по одному на каждый класс цели. Однако только n-1 двоичных столбцов будут линейно независимы, так что в принципе, любой из них можно отбросить. После чего применим обычное целе-вероятностное кодирование для наших новых категорий, используя каждую из двоичных меток, по одной за раз.
Давайте разберемся на примере.
Пример
Продолжим с предыдущими данными.
Шаг 1: Бинарное кодирование мульти-классовой категории.
Обратите внимание, что столбец Target_1 показывает наличие либо отсутствие значения 0 в исходном столбце Target. Он принимает значение 1 если в Target есть 0, либо 0 в противном случае. Точно так же столбец Target_2 показывает наличие или отсутствие 1 в Target.
Шаг 2: Кодируем цвет, используя каждую из бинарных категорий.
Шаг 3: Если есть другие категории, кроме цвета, повторяем шаги 1 и 2 для них.
Таким образом, на выходе получаем такой набор данных:
Обратите внимание, что для ясности я закодировал здесь все три столбца Color_Target. Если вы знаете бинарное кодирование, то слышали, что один из столбцов можно удалить без потери информации. Следовательно, здесь мы можем безопасно удалить, например, столбец Color_Target_3 (либо какой-то другой) без потери информации.
Практика
Вы здесь за кодом, не так ли?!
Ниже представлена функция, которая принимает на вход таблицу данных и объект целевой метки типа Series. Функция df может иметь как числовые, так и категориальные переменные.
Резюме
В этой статье я показал, что не так с TargetEncoder из библиотеки category_encoder, объяснил, что говорится в оригинальной статье о целевом кодировании мультиклассовых переменных, продемонстрировал всё это на примере и предоставил рабочий модульный код, который вы можете подключить к своему приложению.
Target Encoding Vs. One-hot Encoding with Simple Examples
For machine learning algorithms, categorical data can be extremely useful. However, in its original form, it is unrecognizable to most models. In order to solve this problem, we can use different “encoding” techniques to make our categorical data legible.
In this post, we will cover two common encoding techniques used in data science models — Target Encoding and One-hot Encoding.
Target Encoding
From the documentation linked above, Target Encoding is defined as the process in which
“features are replaced with a blend of posterior probability of the target given particular categorical value and the prior probability of the target over all the training data.”
Example — Target Encoding
To better understand what this means, let’s look at an example. In Table 1, we have categorical data in the ‘Animal’ column, and we have our binary target in the ‘Target’ column. In the final column, we have the encoded animal values. So how did we get there?
3. Finally, add back in the new column, which gives the probability value of each Animal Group. This is shown in the first dataframe (Table 1). Now you have a numerical value that represents the ‘Animal’ feature that can be recognized by machine learning algorithms.
Note that when you do target encoding in sklearn, your values may be slightly different than what you get with the above methodology. This is because we have only taken into account the posterior probability so far. Sklearn also looks at the prior probability, which in this case would be the probability of the target being 1. In this case, this probability is 0.5 since we have the target equal to 1 half of the time. Sklearn then uses this metric to help smooth out the encoded value so as to not give too much weight to the target encoded feature which is dependent on the target.
What This Looks Like in Code
In the below code, the ‘category_encoders’ library is used to do the target encoding the fast way (not manually, as explained above).
2. Target Encode & Clean DataFrame
This will output the dataframe found in Table 1. This can also be iterable among multiple categorical features.
Benefits of Target Encoding
Target encoding is a simple and quick encoding method that doesn’t add to the dimensionality of the dataset. Therefore it may be used as a good first try encoding method.
Limitations of Target Encoding
Target encoding is dependent on the distribution of the target which means target encoding requires careful validation as it can be prone to overfitting. This method is also dataset-specific and will only show significant improvements some of the time.
One-hot Encoding
One-hot encoding is easier to conceptually understand. This type of encoding simply “produces one feature per category, each binary.” Or for the example above, creating a new feature for cat, dog, and hamster. In the column cat, for example, we show that a cat exists with a 1, and it doesn’t exist with a 0. Let’s look at the same example to make more sense of this:
Example — One-hot Encoding
Using the same data as above when we one-hot encode, our data will look like:
Notice now we have three new columns: ‘isCat’, ‘isDog’, and ‘isHamster.’ Each ‘1′ signifies that the feature contains the animal in the feature title. If there is a 0, then we don’t have that animal. Once again, we now have new features that a machine learning algorithm can interpret.
Let’s look at the steps to get here.
This will output the full dataframe shown in Table 3. Now you have 3 new features that can be understood by a machine learning algorithm.
Benefits of One-hot Encoding
One-hot encoding works well with nominal data and eliminates any issue of higher categorical values influencing data, since we are creating each column in the binary 1 or 0.
Limitations of One-hot Encoding
One-hot encoding can create very high dimensionality depending on the number of categorical features you have and the number of categories per feature. This can become problematic not only in smaller datasets but also potentially in larger datasets as well. Combining PCA with one-hot encoding can help reduce that dimensionality when running models. One-hot encoding can also be problematic in tree-based models. See here for further discussion.
Conclusion
There are many different types of encoding. I recommend exploring other options as you dive into specific datasets. With that said, these two are common approaches that can help you make use of the categorical features that exist within datasets.
You can access the code I used for this blog on my GitHub.
Вводная статья по реализации целе-вероятностного кодирования переменных (Feature Target Encoding)
В этой статье я дам обзор документа, в котором описана кодировка по целевому признаку, и покажу на примере, как целевая кодировка работает для двоичных проблем.
Теория
Итак: если вас спрашивают «0 / 1», «кликнули / не кликнули» или «кошка / собака», то ваша проблема классификации бинарная; если вы хотите ответить «красный либо зеленый или синий, но может быть желтый» или «седан против хэчбэка и все против внедорожника», тогда проблема в нескольких классах.
Вот что вкратце говорится в упомянутой выше статье о категориальной цели:
Результат любого наблюдения можно отобразить через оценку вероятности целевой переменной.
При классификации, числовое представление будет соответствовать вероятности выпадения целевой переменной, обусловленной значением категориальной переменной.
Это эффективнее простого числового кодирования.
Для избежания переобучения при небольшом количестве наблюдений, может применяться сглаживание средних значений.
Давайте посмотрим на это практически. В бинарной задаче целью является либо 0, либо 1. В таком случае оценка вероятности для категориальной переменной может быть задана эмпирической бейесовской вероятностью P (Y = 1 | X = Xi), т.е.:
Введение весового коэффициента имеет смысл, когда размер выборки большой, и мы должны уделять больше внимания оценке вероятности, определяемой в левой части выражения. Однако, если размер выборки невелик, то мы должны заменить оценку вероятности нулевой гипотезой, заданной первоначальной вероятностью зависимого атрибута (т. е. средним значением от всех Y). С помощью такого преобразования пропущенные значения обрабатываются подобно остальным переменным.
В документе та же концепция распространяется и на мультиклассовые целевые признаки. У нас есть по одной новой функции для каждого целевого класса. Таким образом, каждая функция фактически является числовым представлением ожидаемого значения ровно одного целевого класса с учетом значения категориального признака. Конечно, количество входов может значительно увеличиться, если цель имеет очень большое количество классов, однако на практике количество значений обычно невелико. Подробнее об этом будет другая статья.
А теперь, давайте рассмотрим ситуацию с двоичной классификацией на примере.
Практика
Давайте посмотрим на пример двоичной целевой переменной.
Теперь, если вы замените все значения «Female» на 0,25, вы рискуете так называемым переобучением. Это происходит потому, что общая вероятность единицы равна 4/9 = 0,4.
Чтобы учесть этот факт, мы добавляем вес к этой «предварительной» информации, используя формулу, из предыдущего раздела.
Установка min_sample_leaf, k = 1 и сглаживание, f = 1,
У нас есть две строки со значением «Male», поэтому n = 2;
Аналогично, для «Female» у нас четыре строки, поэтому n = 4;
Если приглядеться, можно заметить, что λ увеличивает значимость тех категорий, для которых количество строк больше. В нашем примере было 4 строки с полем «Female», и только 2 строки с полем «Male». Соответствующие весовые коэффициенты составили 0,95 и 0,73.
Поздравляю! Вы только что реализовали вероятностную кодировку через целевой признак!
Убедитесь сами, запустив этот код, который делает то же самое с использованием библиотеки category_encoders:
Вывод
В этой статье я описал недостаток класса TargetEncoder библиотеки category_encoders, объяснил и резюмировал статью, в которой было введено целевое кодирование, объяснил на примере, как категории можно заменить числовыми значениями.
Следующая статья полностью посвящена тому, как мы можем сделать то же самое для мультиклассовых целевых признаков.
All About Target Encoding For Classification Tasks
Setting Context To Implement Target Encoding For Multi-Class Classification
Jul 6, 2020 · 6 min read
Background
Recently I did a project wherein the target was multi-class. It was a simple prediction task and the dataset involved both categorical as well as numerical features.
For those of you who are wondering what multi-class classification is: If you want to answer in ‘0 vs 1’, ‘clicked vs not-clicked’ or ‘cat vs dog’, your classification problem is binary; if you want to answer in ‘red vs green vs blue vs yellow’ or ‘sedan vs hatch vs SUV’, then the problem is multi-class.
Therefore, I was r esearching suitable ways to encode the categorical features. No points for guessing, I was taken to medium articles enumerating benefits of mean target encoding and how it outperforms other methods and how you can use category_encoders library to do the task in just 2 lines of code. However, to my surprise, I found that no article demonstrated this on multi-class target. I went to the documentation of category_encoders and found that it does not say anything about supporting multi-class targets. I dug deeper, scouring through the source code and realized that the library only works for binary or continuous targets.
So I thought: “Inside of every problem lies an opportunity.” — Robert Kiposaki
Going deep, I went straight for the original paper by Daniele Micci-Barreca that introduced mean target encoding. Not only for regression problem, the paper gives the solution for both binary classification as well as multi-class classification. This is the same paper that category_encoders cites for target encoding as well.
While there are several articles explaining target encoding for regression and binary classification problems, my aim is to implement target encoding for multi-class variables. However, before that, we need to understand how it’s done for binary targets. In this article, I cover an overview of the paper that introduced target encoding, and show by example how target encoding works for binary problems.
The Theory
Here is what the paper says for categorical target, in a nutshell:
(Skip this section if you wish to understand through an example)
One can map every occurrence of a category to the probability estimate of the target attribute. In a classification scenario, the numerical representation corresponds to the posterior probability of the target, conditioned by the value of the categorical attribute. This is effectively a numerical representation of the expected value of the target, given the value of the categorical attribute. In order to avoid overfitting due to a small number of observations in a category, smoothing of the means is also applied.
Let’s look at this practically. In binary problem the target is either 0 or 1. Then, the probability estimate for a category within a categorical variable can be given by Empirical Bayesian probability, P(Y=1|X=Xi), i.e.
If you have used TargetEncoder from category_encoders library, k is the ‘min_sample_leaf’ parameter, and f is the ‘smoothing’ parameter.
Introducing the weighting factor makes sense because when the sample size is large, we should assign more credit to the posterior probability estimate provided by the first term above. However, if the sample size is small, then we replace the probability estimate with the null hypothesis given by the prior probability of the dependent attribute (i.e. mean of all Ys). With this transformation, missing values are handled by treating them as just another variable.
The paper extends the same concept to multi-class target as well. We have one new feature for each class of target. Each feature is then effectively a numerical representation of the expected value of exactly one class of target, given the value of the categorical attribute. Of course, the number of inputs can increase significantly if the target has a very high number of classes. However, practically the number of classes is usually small. Read more on this in my next article.
In the next section, we look at binary classification situation, with an example.
An Example
Let’s look at a binary target example.
What is the probability of Target being 1 if the category of feature Gender is ‘Male’?
Similarly, what is the probability of Target being 1 if the category of feature Gender is ‘Female’?
Wait, now if you replace all occurrences of ‘Female’ with 0.25, you risk what is called overfitting. This is because you did not consider that overall probability of 1’s is not 0.5. It’s 4/9=0.4.
To account for this fact, we add a weight to this ‘prior’ information, using the formula shown in the previous section.
Setting min_sample_leaf, k=1 and smoothing, f=1,
for ‘Male’, we have two rows, so n=2;
Similarly, for ‘Female’, we have four rows, so n=4;
If you look closer, you may notice that λ helps giving importance to those categories for which number of rows are more. In our example, there were 4 rows of Gender ‘Female’, as opposed to only 2 rows of Gender ‘Male’. The corresponding Weight Factor were 0.95 and 0.73.
Thus, replace all occurrences of ‘Male’ with 0.485 and ‘Female’ with 0.259. Value for ‘Other’ can be calculated in a similar fashion.
Congratulations! You just implemented target encoding.
Check for yourself by running this code, which does the same using your favorite category_encoders library:
Conclusion
In this article, I introduced a shortcoming of the TargetEncoder class of category_encoders library. I explained and summarized the paper that introduced target encoding. I explained through an example how the categories can be replaced with a numerical value.
My next article will focus completely on how we can do the same for multi-class targets. Stay tuned!
Edit: Published the next one, demonstrating and implementing multi-class target encoding here.
Connect with me on LinkedIn
Check out some of my interesting projects on GitHub