{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "*This notebook contains an excerpt from the book [Machine Learning for OpenCV](https://www.packtpub.com/big-data-and-business-intelligence/machine-learning-opencv) by Michael Beyeler.\n", "The code is released under the [MIT license](https://opensource.org/licenses/MIT),\n", "and is available on [GitHub](https://github.com/mbeyeler/opencv-machine-learning).*\n", "\n", "*Note that this excerpt contains only the raw code - the book is rich with additional explanations and illustrations.\n", "If you find this content useful, please consider supporting the work by\n", "[buying the book](https://www.packtpub.com/big-data-and-business-intelligence/machine-learning-opencv)!*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "< [Reducing the Dimensionality of the Data](04.02-Reducing-the-Dimensionality-of-the-Data.ipynb) | [Contents](../README.md) | [Representing Text Features](04.04-Represening-Text-Features.ipynb) >" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "# Representing Categorical Variables\n", "\n", "One of the most common data types we might encounter while building a machine learning\n", "system are **categorical features** (also known as **discrete features**), such as the color of a fruit\n", "or the name of a company.\n", "\n", "The challenge with categorical features is that they don't change\n", "in a continuous way, which makes it hard to represent them with numbers. For example, a\n", "banana is either green or yellow, but not both. A product belongs either in the clothing\n", "department or in the books department, but rarely in both, and so on.\n", "\n", "How would you go about representing such features?\n", "\n", "Consider the following data containing a list of some of the forefathers of machine learning and artificial intelligence:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "data = [\n", " {'name': 'Alan Turing', 'born': 1912, 'died': 1954},\n", " {'name': 'Herbert A. Simon', 'born': 1916, 'died': 2001},\n", " {'name': 'Jacek Karpinski', 'born': 1927, 'died': 2010},\n", " {'name': 'J.C.R. Licklider', 'born': 1915, 'died': 1990},\n", " {'name': 'Marvin Minsky', 'born': 1927, 'died': 2016},\n", "]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "While the features 'born' and 'died' are already in numeric format, the 'name' feature is\n", "a bit trickier to encode. We might be intrigued to encode them in the following way:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "{'Alan Turing': 1,\n", " 'Herbert A. Simon': 2,\n", " 'Jacek Karpinsky': 3,\n", " 'J.C.R. Licklider': 4,\n", " 'Marvin Minsky': 5};" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Although this seems like a good idea, it does not make much sense from a machine learning\n", "perspective. Why not?\n", "\n", "Refer to the book for the answer (p. 97)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A better way is to use a `DictVectorizer`, also known as a *one-hot encoding*. The way it works is by feeding a\n", "dictionary containing the data to the `fit_transform` function, and the function\n", "automatically determines which features to encode:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1912, 1954, 1, 0, 0, 0, 0],\n", " [1916, 2001, 0, 1, 0, 0, 0],\n", " [1927, 2010, 0, 0, 0, 1, 0],\n", " [1915, 1990, 0, 0, 1, 0, 0],\n", " [1927, 2016, 0, 0, 0, 0, 1]], dtype=int64)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sklearn.feature_extraction import DictVectorizer\n", "vec = DictVectorizer(sparse=False, dtype=int)\n", "vec.fit_transform(data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What happened here? The two year entries are still intact, but the rest of the rows have been\n", "replaced by ones and zeros. We can call `get_feature_names` to find out the listed order of\n", "the features:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['born',\n", " 'died',\n", " 'name=Alan Turing',\n", " 'name=Herbert A. Simon',\n", " 'name=J.C.R. Licklider',\n", " 'name=Jacek Karpinski',\n", " 'name=Marvin Minsky']" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vec.get_feature_names()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first row of our data matrix, which stands for Alan Turing, is now encoded as\n", "`'born'=1912`, `'died'=1954`, `'Alan Turing'=1`, `'Herbert A. Simon'=0`, `'J.C.R Licklider'=0`, `'Jacek Karpinsik'=0`, and `'Marvin Minsky'=0`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If your category has many possible values, it is better to use a sparse matrix:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "<5x7 sparse matrix of type ''\n", "\twith 15 stored elements in Compressed Sparse Row format>" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vec = DictVectorizer(sparse=True, dtype=int)\n", "vec.fit_transform(data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will come back to this technique when we talk about neural networks in [Chapter 9](09.00-Using-Deep-Learning-to-Classify-Handwritten-Digits.ipynb),\n", "*Using Deep Learning to Classify Handwritten Digits*." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "< [Reducing the Dimensionality of the Data](04.02-Reducing-the-Dimensionality-of-the-Data.ipynb) | [Contents](../README.md) | [Representing Text Features](04.04-Represening-Text-Features.ipynb) >" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.3" } }, "nbformat": 4, "nbformat_minor": 1 }