{
"nbformat": 4,
"nbformat_minor": 0,
"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.7.3"
},
"colab": {
"name": "ML - Concepts - Part 1.ipynb",
"provenance": [],
"collapsed_sections": [
"pB2IzJHL526B"
]
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "tj8Q-p2B525N",
"colab_type": "text"
},
"source": [
"[ML Terminologies](#mlt)\n",
"\n",
"[Knowing the data](#kda)\n",
"\n",
"[Train and Test Sets](#tts)\n",
"\n",
"[KNN - From scratch and Sklearn](#kn)\n",
"\n",
"[Neural networks - From scratch](#nn)\n",
"\n",
"[Backpropagation](#bpp)\n",
"\n",
"[MNIST - From scratch](#mn)\n",
"\n",
"[Dropout](#drt)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "hLnEEb3s525P",
"colab_type": "text"
},
"source": [
"\n",
"\n",
"### Terminologies"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "WiOquggH525Q",
"colab_type": "text"
},
"source": [
"#### Classifier\n",
"\n",
"A program or a function which maps from unlabeled instances to classes is called a classifier.\n",
"\n",
"#### Confusion Matrix\n",
"\n",
"A confusion matrix, also called a contingeny table or error matrix, is used to visualize the performance of a classifier.\n",
"The columns of the matrix represent the instances of the predicted classes and the rows represent the instances of the actual class. (Note: It can be the other way around as well.)\n",
"In the case of binary classification the table has 2 rows and 2 columns.\n",
"\n",
"\n",
"#### Accuracy (error rate)\n",
"\n",
"Accuracy is a statistical measure which is defined as the quotient of correct predictions made by a classifier divided by the sum of predictions made by the classifier.\n",
"\n",
"The classifier in our previous example predicted correctly predicted 42 male instances and 32 female instance.\n",
"\n",
"Therefore, the accuracy can be calculated by:\n",
"\n",
"accuracy = (42+32)/(42+8+18+32)\n",
"\n",
"\n",
"#### Precision and Recall\n",
"\n",
"\n",
"Accuracy: (TN+TP)/(TN+TP+FN+FP)\n",
"Precision: TP/(TP+FP)\n",
"Recall: TP/(TP+FN)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "oMy0WDAl525Q",
"colab_type": "text"
},
"source": [
"\n",
"\n",
"### Knowing the data"
]
},
{
"cell_type": "code",
"metadata": {
"id": "nrHLwb2D525R",
"colab_type": "code",
"colab": {}
},
"source": [
"from sklearn.datasets import load_iris\n",
"\n",
"iris = load_iris()"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "265tGTVY525T",
"colab_type": "code",
"colab": {},
"outputId": "c3a76a44-d759-46f5-ba6f-ca64f0832e27"
},
"source": [
"# The features of each sample flower are stored in the data attribute of the dataset:\n",
"\n",
"n_samples, n_features = iris.data.shape\n",
"print('Number of samples:', n_samples)\n",
"print('Number of features:', n_features)\n",
"# the sepal length, sepal width, petal length and petal width of the first sample (first flower)\n",
"print(iris.data[0])"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"Number of samples: 150\n",
"Number of features: 4\n",
"[5.1 3.5 1.4 0.2]\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "ObEkk_8O525W",
"colab_type": "code",
"colab": {},
"outputId": "31729ff7-d422-492f-9d7b-1c5c9d5c3b48"
},
"source": [
"print(iris.target)"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n",
" 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n",
" 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2\n",
" 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n",
" 2 2]\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "z6YzTNXj525Y",
"colab_type": "code",
"colab": {},
"outputId": "e23f32c3-eec8-4877-f18b-ed8613b3a159"
},
"source": [
"### Visualising the Features of the Iris Data Set\n",
"\n",
"## The feature data is four dimensional, but we can visualize one or two of the dimensions at a time using a simple histogram or scatter-plot.\n",
"\n",
"from sklearn.datasets import load_iris\n",
"iris = load_iris()\n",
"\n",
"print(iris.data[iris.target==1][:5])\n",
"\n",
"print(iris.data[iris.target==1, 0][:5])"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"[[7. 3.2 4.7 1.4]\n",
" [6.4 3.2 4.5 1.5]\n",
" [6.9 3.1 4.9 1.5]\n",
" [5.5 2.3 4. 1.3]\n",
" [6.5 2.8 4.6 1.5]]\n",
"[7. 6.4 6.9 5.5 6.5]\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "PTnQX-ET525a",
"colab_type": "code",
"colab": {},
"outputId": "5fcb0d48-9260-482e-f832-089fb3dd3e4e"
},
"source": [
"import matplotlib.pyplot as plt\n",
"%matplotlib inline\n",
"\n",
"fig, ax = plt.subplots()\n",
"x_index = 3\n",
"\n",
"colors = ['blue', 'red', 'green']\n",
"\n",
"for label, color in zip(range(len(iris.target_names)), colors):\n",
" ax.hist(iris.data[iris.target==label, x_index], \n",
" label=iris.target_names[label],\n",
" color=color)\n",
"\n",
"ax.set_xlabel(iris.feature_names[x_index])\n",
"ax.legend(loc='upper right')\n",
"fig.show()"
],
"execution_count": null,
"outputs": [
{
"output_type": "display_data",
"data": {
"image/png": "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\n",
"text/plain": [
"