{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## What is linear classification?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Linear classification** is the task of finding a linear function that best separates a series of differently classified points in euclidean space. The linear function is called a **linear separator**. Each point can be interpreted as an **example**, and each dimension can be interpreted as a **feature**. If the space has 2 dimensions, the linear regression is **univariate** and the linear separator is a **straight line**. If the space has more than 2 dimensions, the linear regression is **multivariate** and the linear separator is a **hyperplane**. If the linear classification classifies examples into two different classes, the classification is **binary**. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Linear classification vs. linear regression."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Linear classification and linear regression are similar in their approach and data\n",
"representation. However, they solve two different problems. **Linear regression** is the task of finding a linear function that *best approximates* a series of points. The example classification is nothing more than another dimension to a linear regressor. In contrast, a linear classifier treats the example classification not as a dimension, but in a special way that the following code demonstrates."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Implementing and using linear classification."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Classifying the survival chances of Titanic passengers."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following code uses multivariate linear binary classification to classify the survival of passengers of the ship Titanic. The input data is taken from the [Kaggle Titanic](https://www.kaggle.com/c/titanic) competition."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As a first step, we import `os.path` to locate our dataset, `pandas` to manipulate the dataset as tabular data, `numpy` to efficiently process our data arrays and `matplotlib.pyplot` to display the results of the linear classification in a graph. We disable warnings to keep the output tidy."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"hide_input": false
},
"outputs": [],
"source": [
"from os import path\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import pandas as pd\n",
"import warnings\n",
"warnings.filterwarnings('ignore')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Reading the input data."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"datadir = path.abspath(path.expanduser('~/datasets/titanic'))\n",
"rawexamples = pd.read_csv(path.join(datadir, 'train.csv'))"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" PassengerId | \n",
" Survived | \n",
" Pclass | \n",
" Name | \n",
" Sex | \n",
" Age | \n",
" SibSp | \n",
" Parch | \n",
" Ticket | \n",
" Fare | \n",
" Cabin | \n",
" Embarked | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
" 3 | \n",
" Braund, Mr. Owen Harris | \n",
" male | \n",
" 22.0 | \n",
" 1 | \n",
" 0 | \n",
" A/5 21171 | \n",
" 7.2500 | \n",
" NaN | \n",
" S | \n",
"
\n",
" \n",
" 1 | \n",
" 2 | \n",
" 1 | \n",
" 1 | \n",
" Cumings, Mrs. John Bradley (Florence Briggs Th... | \n",
" female | \n",
" 38.0 | \n",
" 1 | \n",
" 0 | \n",
" PC 17599 | \n",
" 71.2833 | \n",
" C85 | \n",
" C | \n",
"
\n",
" \n",
" 2 | \n",
" 3 | \n",
" 1 | \n",
" 3 | \n",
" Heikkinen, Miss. Laina | \n",
" female | \n",
" 26.0 | \n",
" 0 | \n",
" 0 | \n",
" STON/O2. 3101282 | \n",
" 7.9250 | \n",
" NaN | \n",
" S | \n",
"
\n",
" \n",
" 3 | \n",
" 4 | \n",
" 1 | \n",
" 1 | \n",
" Futrelle, Mrs. Jacques Heath (Lily May Peel) | \n",
" female | \n",
" 35.0 | \n",
" 1 | \n",
" 0 | \n",
" 113803 | \n",
" 53.1000 | \n",
" C123 | \n",
" S | \n",
"
\n",
" \n",
" 4 | \n",
" 5 | \n",
" 0 | \n",
" 3 | \n",
" Allen, Mr. William Henry | \n",
" male | \n",
" 35.0 | \n",
" 0 | \n",
" 0 | \n",
" 373450 | \n",
" 8.0500 | \n",
" NaN | \n",
" S | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" PassengerId Survived Pclass \\\n",
"0 1 0 3 \n",
"1 2 1 1 \n",
"2 3 1 3 \n",
"3 4 1 1 \n",
"4 5 0 3 \n",
"\n",
" Name Sex Age SibSp \\\n",
"0 Braund, Mr. Owen Harris male 22.0 1 \n",
"1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 \n",
"2 Heikkinen, Miss. Laina female 26.0 0 \n",
"3 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 \n",
"4 Allen, Mr. William Henry male 35.0 0 \n",
"\n",
" Parch Ticket Fare Cabin Embarked \n",
"0 0 A/5 21171 7.2500 NaN S \n",
"1 0 PC 17599 71.2833 C85 C \n",
"2 0 STON/O2. 3101282 7.9250 NaN S \n",
"3 0 113803 53.1000 C123 S \n",
"4 0 373450 8.0500 NaN S "
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rawexamples.head()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"891"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(rawexamples)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Our input data `rawexamples` consists of 891 rows. Each row consists of 11 columns that contain information about a passenger. We interpret each row as an *example* and each column as a *feature*. The feature *Survived* classifies each example as either *survived* (1) or *died* (0) and is thus a binary classification. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Cleaning the input data."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Our input data has many features of presumably low importance. To simplify and speed up the binary classifier, we limit our examples to the three presumably most important features: *Pclass* (the passenger's class), *Sex* and *Age*."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Pclass | \n",
" Sex | \n",
" Age | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 3 | \n",
" male | \n",
" 22.0 | \n",
"
\n",
" \n",
" 1 | \n",
" 1 | \n",
" female | \n",
" 38.0 | \n",
"
\n",
" \n",
" 2 | \n",
" 3 | \n",
" female | \n",
" 26.0 | \n",
"
\n",
" \n",
" 3 | \n",
" 1 | \n",
" female | \n",
" 35.0 | \n",
"
\n",
" \n",
" 4 | \n",
" 3 | \n",
" male | \n",
" 35.0 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Pclass Sex Age\n",
"0 3 male 22.0\n",
"1 1 female 38.0\n",
"2 3 female 26.0\n",
"3 1 female 35.0\n",
"4 3 male 35.0"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"examples = rawexamples[['Pclass', 'Sex', 'Age']]\n",
"examples.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, we assign a neutral value to all missing values in the input data."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"examples = examples.fillna(0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Additionally, we convert the `Sex` feature to a numerical scale, because our linear classifier takes only numerical input."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"examples['Sex'] = examples['Sex'].map({'male': 0, 'female': 1})"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" Then, we obtain the classifications."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"classifications = rawexamples[['Survived']]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, we split our examples into a training set and a validation set and convert them to arrays."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"training_examples = examples.values[:800]\n",
"training_classifications = classifications.values[:800]\n",
"\n",
"validation_examples = examples.values[801:]\n",
"validation_classifications = classifications.values[801:]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Implementing the linear classifier."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"class LinearBinaryClassifier:\n",
" def __init__(self, features):\n",
" self.weights = np.zeros(features)\n",
" self.time = 0\n",
" def train(self, examples, classifications):\n",
" for example, classification in zip(examples, classifications):\n",
" self.time += 1\n",
" prediction = self.classify(example)\n",
" for idx, value in enumerate(example):\n",
" weight = self.weights[idx]\n",
" annealing = 1000/(1000 + self.time*10) # Values chosen by experience.\n",
" self.weights[idx] += annealing * (classification - prediction) * value\n",
" def classify(self, example):\n",
" if np.dot(example, self.weights) > 0:\n",
" return 1\n",
" else:\n",
" return 0"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The above linear binary classifier supports two actions, `train()` and `classify()`. `train()` takes a list of examples and their classifications. It then approximates a linear function $$classify(example) = w_1 example_1 + w_2 example_2 + ... + w_n example_n$$ where $example_n$ refers to the value of $example$ for the n-th feature. $\\textbf{w}$ is a vector of weights that defines the function $classify$. The output of $classify$ is interpreted in this way:\n",
"* value less than 0: classify as 0.\n",
"* value greater than 0 : classify as 1.\n",
"* value equal to 0: undefined (the algorithm is \"uncertain\").\n",
"\n",
"The approximation is done by iterating over all examples and updating the weights if an example is misclassified. Specifically, each weight is increased or decreased so that the numerical output of `classify` gets closer to the the correct output range. \n",
"\n",
"To ensure that the algorithm converges at an approximately optimal solution, we use [simulated annealing](https://en.wikipedia.org/wiki/Simulated_annealing) to gradually lower the learning rate."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Using the linear classifier."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To test and use our linear classifier, we need to train it on the example set and than validate it with the validation set. The validation step tells us the accuracy of the linear classifier.\n",
"\n",
"Since our example set has only 800 examples, it is small for machine learning standards. Therefore, we will train our linear classifier multiple times with the same examples. After each training iteration, we test our classifier by classifying all examples from the validation set and comparing the output with the expected result. It is important for the validation step that *no* data of the validation data is used for improving the classifier, since this would invalidate subsequent accuracy reports. "
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"classifier = LinearBinaryClassifier(features = len(training_examples[0]))\n",
"training_iterations = 100\n",
"accuracy = np.zeros(training_iterations)\n",
"for i in range(0,training_iterations):\n",
" classifier.train(training_examples, training_classifications)\n",
" correct = 0\n",
" for example, classification in zip(validation_examples, validation_classifications):\n",
" prediction = classifier.classify(example)\n",
" correct += 1 if prediction == classification else 0\n",
" accuracy[i] = correct/len(validation_examples)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, we plot the reported accuracy of our linear classifier after each iteration."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"Text(0.5,0,'Iterations')"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.plot(accuracy)\n",
"plt.ylabel(\"Accuracy\")\n",
"plt.xlabel(\"Iterations\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The graph shows that our linear classifier has an accuracy of $≈78\\%$. This means that when asked to predict the odds of survival of a Titanic passenger, it is correct $≈78\\%$ of the time."
]
}
],
"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.2"
},
"nikola": {
"category": "",
"date": "2018-03-28 07:42:40 UTC+02:00",
"description": "",
"link": "",
"slug": "multivariate_linear_binary_classification",
"tags": "",
"title": "Multivariate linear binary classification.",
"type": "text"
}
},
"nbformat": 4,
"nbformat_minor": 2
}