<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Python on Max Halford</title><link>https://maxhalford.github.io/tags/python/</link><description>Recent content in Python on Max Halford</description><generator>Hugo</generator><language>en-US</language><managingEditor>maxhalford25@gmail.com (Max Halford)</managingEditor><webMaster>maxhalford25@gmail.com (Max Halford)</webMaster><lastBuildDate>Tue, 21 Jul 2026 21:18:41 +0200</lastBuildDate><atom:link href="https://maxhalford.github.io/tags/python/index.xml" rel="self" type="application/rss+xml"/><item><title>Text classification with Python 3.14's zstd module</title><link>https://maxhalford.github.io/blog/text-classification-zstd/</link><pubDate>Fri, 06 Feb 2026 00:00:00 +0000</pubDate><author>maxhalford25@gmail.com (Max Halford)</author><guid>https://maxhalford.github.io/blog/text-classification-zstd/</guid><description>&lt;p&gt;Python 3.14 &lt;a href="https://docs.python.org/3/whatsnew/3.14.html#whatsnew314-zstandard"&gt;introduced&lt;/a&gt; the &lt;a href="https://docs.python.org/3/library/compression.zstd.html"&gt;&lt;code&gt;compression.zstd&lt;/code&gt;&lt;/a&gt; module. It is a standard library implementation of Facebook&amp;rsquo;s &lt;a href="https://en.wikipedia.org/wiki/Zstd"&gt;Zstandard (Zstd)&lt;/a&gt; compression algorithm. It was developed a decade ago by Yann Collet, who holds a &lt;a href="https://fastcompression.blogspot.com/"&gt;blog&lt;/a&gt; devoted to compression algorithms.&lt;/p&gt;
&lt;p&gt;I am not a compression expert, but Zstd caught my eye because it supports incremental compression. You can feed it data to compress in chunks, and it will maintain an internal state. It&amp;rsquo;s particularly well &lt;a href="https://facebook.github.io/zstd/"&gt;suited&lt;/a&gt; for compressing small data. It&amp;rsquo;s perfect for the classify text via compression trick, which I described in &lt;a href="https://maxhalford.github.io/blog/text-classification-by-compression/"&gt;a previous blog post&lt;/a&gt; 5 years ago.&lt;/p&gt;</description></item><item><title>Row level lineage at Carbonfact</title><link>https://maxhalford.github.io/blog/row-level-lineage/</link><pubDate>Fri, 09 Jan 2026 00:00:00 +0000</pubDate><author>maxhalford25@gmail.com (Max Halford)</author><guid>https://maxhalford.github.io/blog/row-level-lineage/</guid><description/></item><item><title>Scraping Google Calendar events</title><link>https://maxhalford.github.io/blog/google-calendar-scraping/</link><pubDate>Sun, 12 Oct 2025 00:00:00 +0000</pubDate><author>maxhalford25@gmail.com (Max Halford)</author><guid>https://maxhalford.github.io/blog/google-calendar-scraping/</guid><description>&lt;p&gt;At my day job we deal with enterprise customers. They pay us a subscription fee, and in return we help them in various ways to reduce their carbon footprint. To keep the boat afloat, we need to make some money. We shouldn&amp;rsquo;t spend more money than we make. So we need to keep track of our revenue and costs. Our gross margin is &lt;code&gt;(revenue - cost) / revenue&lt;/code&gt;, where the cost is mostly the salaries of our employees.&lt;/p&gt;</description></item><item><title>Minimizing the runtime of a SQL DAG</title><link>https://maxhalford.github.io/blog/minimizing-sql-dag-runtime/</link><pubDate>Sat, 08 Feb 2025 00:00:00 +0000</pubDate><author>maxhalford25@gmail.com (Max Halford)</author><guid>https://maxhalford.github.io/blog/minimizing-sql-dag-runtime/</guid><description>&lt;p&gt;I recently looked into reducing the runtime of &lt;a href="https://www.carbonfact.com/"&gt;Carbonfact&lt;/a&gt;&amp;rsquo;s SQL DAG. Our DAG is made up of roughly 160 SQL queries. It takes about 10 minutes to run with BigQuery, using on-demand pricing. It&amp;rsquo;s decent. However, the results of our DAG feed customer dashboards, and we have the (bad) habit of refreshing the DAG several times a day. Reducing the runtime by a few minutes can be a nice quality-of-life improvement.&lt;/p&gt;</description></item><item><title>Introducing icanexplain @ PyData Paris 2024</title><link>https://maxhalford.github.io/blog/icanexplain-pydata/</link><pubDate>Thu, 26 Sep 2024 00:00:00 +0000</pubDate><author>maxhalford25@gmail.com (Max Halford)</author><guid>https://maxhalford.github.io/blog/icanexplain-pydata/</guid><description/></item><item><title>@daily_cache implementation in Python</title><link>https://maxhalford.github.io/blog/python-daily-cache/</link><pubDate>Tue, 27 Aug 2024 00:00:00 +0000</pubDate><author>maxhalford25@gmail.com (Max Halford)</author><guid>https://maxhalford.github.io/blog/python-daily-cache/</guid><description>&lt;p&gt;I spend a lot of time at Carbonfact working on datasets shared by our customers. We typically set things up so that our customers can export data automatically. They usually deposit files to a GCP bucket, with a script, once a day. We then have an ETL script for each customer that runs afterwards to fetch their latest data and process it.&lt;/p&gt;
&lt;p&gt;During development, I load customer data to my laptop and work on it. The datasets can be quite heavy, and it takes time to fetch them, so I cache them to save some time. Python has &lt;a href="https://docs.python.org/3/library/functools.html"&gt;something&lt;/a&gt; for this in its standard library:&lt;/p&gt;</description></item><item><title>LCA software: exit the matrix</title><link>https://maxhalford.github.io/blog/lca-exit-the-matrix/</link><pubDate>Sun, 09 Jun 2024 00:00:00 +0000</pubDate><author>maxhalford25@gmail.com (Max Halford)</author><guid>https://maxhalford.github.io/blog/lca-exit-the-matrix/</guid><description>&lt;p&gt;Measuring the environmental impact of a product is done using &lt;a href="https://en.wikipedia.org/wiki/Life-cycle_assessment"&gt;life cycle assessment&lt;/a&gt; (LCA). This is a methodology that breaks down a product&amp;rsquo;s life cycle into stages (&lt;a href="https://en.wikipedia.org/wiki/Life-cycle_assessment#Life_cycle_inventory_(LCI)"&gt;LCI&lt;/a&gt;), and measures the impact of each stage on the environment (&lt;a href="https://en.wikipedia.org/wiki/Life-cycle_assessment#Life_cycle_impact_assessment_(LCIA)"&gt;LCIA&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;There are a few pieces of LCA software to choose from. The leading ones are &lt;a href="https://simapro.com/"&gt;SimaPro&lt;/a&gt;, &lt;a href="https://sphera.com/life-cycle-assessment-lca-software/"&gt;GaBi&lt;/a&gt;, &lt;a href="https://www.openlca.org/"&gt;openLCA&lt;/a&gt;, and &lt;a href="https://www.ifu.com/umberto/"&gt;Umberto&lt;/a&gt;. These are all proprietary software, and they&amp;rsquo;re expensive. But there&amp;rsquo;s a free and open source alternative: &lt;a href="https://docs.brightway.dev/en/latest/"&gt;Brightway&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Fast Poetry and pre-commit with GitHub Actions</title><link>https://maxhalford.github.io/blog/fast-poetry-pre-commit-github-actions/</link><pubDate>Tue, 27 Feb 2024 00:00:00 +0000</pubDate><author>maxhalford25@gmail.com (Max Halford)</author><guid>https://maxhalford.github.io/blog/fast-poetry-pre-commit-github-actions/</guid><description>&lt;p&gt;This is a short post to share a GitHub Actions pattern I use to setup &lt;a href="https://python-poetry.org/"&gt;Poetry&lt;/a&gt; and &lt;a href="https://pre-commit.com/"&gt;pre-commit&lt;/a&gt;. These two tools cover most of my Python development needs. I use Poetry to manage dependencies and pre-commit to run code checks and formatting. The setup is fast because it caches the virtual environment and the &lt;code&gt;.local&lt;/code&gt; directory.&lt;/p&gt;
&lt;p&gt;I like to use &lt;a href="https://docs.github.com/en/actions/creating-actions/about-custom-actions"&gt;custom actions&lt;/a&gt; for this type of stuff. These are base actions that can be re-used in multiple workflows. I have a custom action to install the Python environment. Here&amp;rsquo;s the action file:&lt;/p&gt;</description></item><item><title>Measuring the carbon footprint of pizzas</title><link>https://maxhalford.github.io/blog/carbon-footprint-pizzas/</link><pubDate>Sun, 25 Jun 2023 00:00:00 +0000</pubDate><author>maxhalford25@gmail.com (Max Halford)</author><guid>https://maxhalford.github.io/blog/carbon-footprint-pizzas/</guid><description>&lt;p&gt;Making environmentally friendly decisions can only be done with the right information. At Carbonfact, we&amp;rsquo;ve realized a big challenge is the lack of information about industrial processes. We tackle that slowly but surely by gathering data from various sources, and making it available to our customers.&lt;/p&gt;
&lt;p&gt;Regarding food, the French government has a great initiative called &lt;a href="https://agribalyse.ademe.fr/"&gt;Agribalyse&lt;/a&gt;. It&amp;rsquo;s a free database of environmental footprints for various food products. It includes raw ingredients straight out from the farm, as well as ready to eat dishes from the supermarket. It&amp;rsquo;s a great initiative, as it allows anyone to do their own research and make informed decisions.&lt;/p&gt;</description></item><item><title>Using SymPy in Python doctests</title><link>https://maxhalford.github.io/blog/sympy-doctests/</link><pubDate>Wed, 15 Feb 2023 00:00:00 +0000</pubDate><author>maxhalford25@gmail.com (Max Halford)</author><guid>https://maxhalford.github.io/blog/sympy-doctests/</guid><description>&lt;p&gt;A program which compiles and runs without errors isn&amp;rsquo;t necessarily correct. I find this to be especially true for statistical software, both as a developer and as a user. Small but nasty bugs creep up on me every week. I keep sane in the membrane by writing many unit tests 🐛🔨&lt;/p&gt;
&lt;p&gt;I make heavy use of &lt;a href="https://docs.python.org/3/library/doctest.html"&gt;doctests&lt;/a&gt;. These are unit tests which you write as Python &lt;a href="https://realpython.com/documenting-python-code/#documenting-your-python-code-base-using-docstrings"&gt;docstrings&lt;/a&gt;. They&amp;rsquo;re really handy because they kill two birds with one stone: the unit tests you write for a function also act as documentation.&lt;/p&gt;</description></item><item><title>Fuzzy regex matching in Python</title><link>https://maxhalford.github.io/blog/fuzzy-regex-matching-in-python/</link><pubDate>Mon, 04 Apr 2022 00:00:00 +0000</pubDate><author>maxhalford25@gmail.com (Max Halford)</author><guid>https://maxhalford.github.io/blog/fuzzy-regex-matching-in-python/</guid><description>&lt;h2 id="fuzzy-string-matching-in-a-nutshell"&gt;Fuzzy string matching in a nutshell&lt;/h2&gt;
&lt;p&gt;Say we&amp;rsquo;re looking for a pattern in a blob of text. If you know the text has no typos, then determining whether it contains a pattern is trivial. In Python you can use the &lt;code&gt;in&lt;/code&gt; function. You can also write a regex pattern with the &lt;code&gt;re&lt;/code&gt; module from the standard library. But what about if the text contains typos? For instance, this might be the case with user inputs on a website, or with OCR outputs. This is a much harder problem.&lt;/p&gt;</description></item><item><title>Comic book panel segmentation</title><link>https://maxhalford.github.io/blog/comic-book-panel-segmentation/</link><pubDate>Sat, 05 Mar 2022 00:00:00 +0000</pubDate><author>maxhalford25@gmail.com (Max Halford)</author><guid>https://maxhalford.github.io/blog/comic-book-panel-segmentation/</guid><description>&lt;p&gt;&lt;strong&gt;Edit (2023-05-26)&lt;/strong&gt; &amp;ndash; &lt;em&gt;I&amp;rsquo;ve learnt about the &lt;a href="https://github.com/njean42/kumiko"&gt;Kumiko project&lt;/a&gt;, which is exactly devoted to slicing comic book panels. There&amp;rsquo;s even a live &lt;a href="https://kumiko.njean.me/demo"&gt;tool&lt;/a&gt;. I discovered it thanks to being pinged on &lt;a href="https://github.com/njean42/kumiko/issues/12"&gt;this&lt;/a&gt; issue.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve recently been reading some comic books I used to devour as a kid. Especially those from the golden era of francophone comics: Thorgal, Lanfeust, XIII, Tintin, Largo Winch, Blacksad, Aldebaran, etc.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s not easy to get my hands on many of them. Luckily enough I found a website called &lt;a href="https://readcomiconline.li/"&gt;ReadComicOnline&lt;/a&gt; which is delightfully profuse. It gives access to comics for free under the murky &amp;ldquo;fair use&amp;rdquo; copyright doctrine. I&amp;rsquo;m very doubtful about the legality of the website, but I&amp;rsquo;m still using it for lack of a better option.&lt;/p&gt;</description></item><item><title>Weighted sampling without replacement in pure Python</title><link>https://maxhalford.github.io/blog/weighted-sampling-without-replacement/</link><pubDate>Fri, 24 Dec 2021 00:00:00 +0000</pubDate><author>maxhalford25@gmail.com (Max Halford)</author><guid>https://maxhalford.github.io/blog/weighted-sampling-without-replacement/</guid><description>&lt;p&gt;I&amp;rsquo;m working on a problem where I need to sample &lt;code&gt;k&lt;/code&gt; items from a list without replacement. The sampling has to be weighted. In Python, &lt;code&gt;numpy&lt;/code&gt; has &lt;code&gt;random.choice&lt;/code&gt; method which allows doing this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;np&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;population&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;weights&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirichlet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ones_like&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;population&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;population&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;weights&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;m always wary of using &lt;code&gt;numpy&lt;/code&gt; without thinking because I know it incurs some overhead. This overhead is usually meaningful when small amounts of data are involved. In such a case, a pure Python implementation may be faster.&lt;/p&gt;</description></item><item><title>Focal loss implementation for LightGBM</title><link>https://maxhalford.github.io/blog/lightgbm-focal-loss/</link><pubDate>Sun, 20 Sep 2020 00:00:00 +0000</pubDate><author>maxhalford25@gmail.com (Max Halford)</author><guid>https://maxhalford.github.io/blog/lightgbm-focal-loss/</guid><description>&lt;p&gt;&lt;strong&gt;Edit (2021-01-26)&lt;/strong&gt; &amp;ndash; &lt;em&gt;I initially wrote this blog post using version 2.3.1 of LightGBM. I&amp;rsquo;ve now updated it to use version 3.1.1. There are a couple of subtle but important differences between version 2.x.y and 3.x.y. If you&amp;rsquo;re using version 2.x.y, then I strongly recommend you to upgrade to version 3.x.y.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re reading this blog post, then you&amp;rsquo;re likely to be aware of &lt;a href="https://github.com/microsoft/LightGBM"&gt;LightGBM&lt;/a&gt;. The latter is a best of breed &lt;a href="https://explained.ai/gradient-boosting/"&gt;gradient boosting&lt;/a&gt; library. As of 2020, it&amp;rsquo;s still the go-to machine learning model for tabular data. It&amp;rsquo;s also ubiquitous in competitive machine learning.&lt;/p&gt;</description></item><item><title>Server-sent events in Flask without extra dependencies</title><link>https://maxhalford.github.io/blog/flask-sse-no-deps/</link><pubDate>Mon, 04 May 2020 00:00:00 +0000</pubDate><author>maxhalford25@gmail.com (Max Halford)</author><guid>https://maxhalford.github.io/blog/flask-sse-no-deps/</guid><description>&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Server-sent_events"&gt;Server-sent events (SSE)&lt;/a&gt; is a mechanism for sending updates from a server to a client. The fundamental difference with &lt;a href="https://en.wikipedia.org/wiki/WebSocket"&gt;WebSockets&lt;/a&gt; is that the communication only goes in one direction. In other words, the client cannot send information to the server. For many usecases this is all you might need. Indeed, if you just want to receive notifications/updates/messages, then using a WebSocket is overkill. Once you&amp;rsquo;ve implemented the SSE functionality on your server, then all you need on a JavaScript client is an &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/EventSource"&gt;&lt;code&gt;EventSource&lt;/code&gt;&lt;/a&gt;. Trust me, it&amp;rsquo;s very straightforward.&lt;/p&gt;</description></item><item><title>Target encoding done the right way</title><link>https://maxhalford.github.io/blog/target-encoding/</link><pubDate>Sat, 13 Oct 2018 00:00:00 +0000</pubDate><author>maxhalford25@gmail.com (Max Halford)</author><guid>https://maxhalford.github.io/blog/target-encoding/</guid><description>&lt;p&gt;When you&amp;rsquo;re doing supervised learning, you often have to deal with categorical variables. That is, variables which don&amp;rsquo;t have a natural numerical representation. The problem is that most machine learning algorithms require the input data to be numerical. At some point or another a data science pipeline will require converting categorical variables to numerical variables.&lt;/p&gt;
&lt;p&gt;There are many ways to do so:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html"&gt;Label encoding&lt;/a&gt; where you choose an arbitrary number for each category&lt;/li&gt;
&lt;li&gt;&lt;a href="http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html"&gt;One-hot encoding&lt;/a&gt; where you create one binary column per category&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.tensorflow.org/tutorials/representation/word2vec"&gt;Vector representation&lt;/a&gt; a.k.a. word2vec where you find a low dimensional subspace that fits your data&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Microsoft/LightGBM/blob/master/docs/Advanced-Topics.rst#categorical-feature-support"&gt;Optimal binning&lt;/a&gt; where you rely on tree-learners such as LightGBM or CatBoost&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.saedsayad.com/encoding.htm"&gt;Target encoding&lt;/a&gt; where you average the target value by category&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each and every one of these method has its own pros and cons. The best approach typically depends on your data and your requirements. If a variable has a lot of categories, then a one-hot encoding scheme will produce many columns, which can cause memory issues. In my experience, relying on LightGBM/CatBoost is the best out-of-the-box method. Label encoding is useless and you should never use it. However if your categorical variable happens to be ordinal then you can and should represent it with increasing numbers (for example &amp;ldquo;cold&amp;rdquo; becomes 0, &amp;ldquo;mild&amp;rdquo; becomes 1, and &amp;ldquo;hot&amp;rdquo; becomes 2). &lt;a href="https://en.wikipedia.org/wiki/Word2vec"&gt;Word2vec&lt;/a&gt; and others such methods are cool and good but they require some fine-tuning and don&amp;rsquo;t always work out of the box.&lt;/p&gt;</description></item></channel></rss>