├── .gitignore ├── GAN ├── GAN_1.ipynb ├── GAN_1.py └── readme.md ├── LICENSE ├── Perceptron Linear Algorithm ├── PLA.ipynb ├── PLA.py ├── Pocket_PLA.py ├── data │ ├── data1.csv │ ├── data2.csv │ └── iris.data.csv ├── images │ ├── 1.jpg │ ├── 2.jpg │ └── 3.jpg └── readme.md ├── README.md ├── SVM ├── README.md ├── SVM.ipynb └── data │ └── README.md ├── Softmax ├── Softmax.ipynb ├── data │ └── readme.md └── readme.md └── kNN ├── README.md ├── data └── iris.data.csv ├── images ├── 1.jpg └── 2.png └── kNN.ipynb /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | -------------------------------------------------------------------------------- /GAN/GAN_1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## 使用 GAN 生成一个类似二次曲线" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 2, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import torch\n", 19 | "import torch.nn as nn\n", 20 | "import numpy as np\n", 21 | "import matplotlib.pyplot as plt" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 3, 27 | "metadata": { 28 | "collapsed": true 29 | }, 30 | "outputs": [], 31 | "source": [ 32 | "# torch.manual_seed(1) # reproducible\n", 33 | "# np.random.seed(1)\n", 34 | "\n", 35 | "# Hyper Parameters\n", 36 | "BATCH_SIZE = 64\n", 37 | "LR_G = 0.0001 # learning rate for generator\n", 38 | "LR_D = 0.0001 # learning rate for discriminator\n", 39 | "N_IDEAS = 5 # think of this as number of ideas for generating an art work(Generator)\n", 40 | "ART_COMPONENTS = 15 # it could be total point G can drew in the canvas\n", 41 | "PAINT_POINTS = np.vstack([np.linspace(-1, 1, ART_COMPONENTS) for _ in range(BATCH_SIZE)])" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 59, 47 | "metadata": { 48 | "scrolled": true 49 | }, 50 | "outputs": [ 51 | { 52 | "data": { 53 | "image/png": "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\nrkJggg==\n", 54 | "text/plain": [ 55 | "" 56 | ] 57 | }, 58 | "metadata": {}, 59 | "output_type": "display_data" 60 | } 61 | ], 62 | "source": [ 63 | "# show our beautiful painting range\n", 64 | "plt.plot(PAINT_POINTS[0], np.sin(PAINT_POINTS[0] * np.pi), c='#74BCFF', lw=3, label='standard curve')\n", 65 | "plt.legend(loc='best')\n", 66 | "plt.show()" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 60, 72 | "metadata": { 73 | "collapsed": true 74 | }, 75 | "outputs": [], 76 | "source": [ 77 | "def artist_works(): # painting from the famous artist (real target)\n", 78 | " #a = np.random.uniform(1, 2, size=BATCH_SIZE)[:, np.newaxis]\n", 79 | " r = 0.02 * np.random.randn(1, ART_COMPONENTS)\n", 80 | " paintings = np.sin(PAINT_POINTS * np.pi) + r\n", 81 | " paintings = torch.from_numpy(paintings).float()\n", 82 | " return paintings" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 61, 88 | "metadata": {}, 89 | "outputs": [ 90 | { 91 | "data": { 92 | "image/png": "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\n", 93 | "text/plain": [ 94 | "" 95 | ] 96 | }, 97 | "metadata": {}, 98 | "output_type": "display_data" 99 | } 100 | ], 101 | "source": [ 102 | "r = 0.02 * np.random.randn(1, ART_COMPONENTS)\n", 103 | "paintings = np.sin(PAINT_POINTS * np.pi) + r\n", 104 | "plt.plot(PAINT_POINTS[0],paintings[0])\n", 105 | "plt.show()" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": 65, 111 | "metadata": { 112 | "collapsed": true 113 | }, 114 | "outputs": [], 115 | "source": [ 116 | "G = nn.Sequential( # Generator\n", 117 | " nn.Linear(N_IDEAS, 128), # random ideas (could from normal distribution)\n", 118 | " nn.ReLU(),\n", 119 | " nn.Linear(128, ART_COMPONENTS), # making a painting from these random ideas\n", 120 | ")\n", 121 | "\n", 122 | "D = nn.Sequential( # Discriminator\n", 123 | " nn.Linear(ART_COMPONENTS, 128), # receive art work either from the famous artist or a newbie like G\n", 124 | " nn.ReLU(),\n", 125 | " nn.Linear(128, 1),\n", 126 | " nn.Sigmoid(), # tell the probability that the art work is made by artist\n", 127 | ")" 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": 71, 133 | "metadata": {}, 134 | "outputs": [ 135 | { 136 | "data": { 137 | "image/png": "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\nefdyqsXzLMv8hDtbnn2/rjmpjUtJVwJHpJTxUkoLsBg414wdU4EGcce3uLiY119/nQkTJlRY/+KL\nL7J69WqWL1/ufLMOCQnh0CFtjAC73U7Xrl3ZunWrs42UEn9/f06dOkV6enqFs5CyfXz++edce+21\nxMXFMXjwYKSUFfZTdo36hhtuYMmSJSQnJzvPBq6//nrnJZGyr7S0NAYOHOi8Vl12ucZV2Rt7enq6\n8zJXWRubzcauXbucb5xlzGZtmEpvb2+KiorIz8/n999/p3v37hXqud4U3rx5Mx07Vv0oo91uJzc3\nl9zc3ApnHmWvTVUWLVrkfCN3ja9sHx07dmTHDm2u3+3bt58Vw5m/t6rqV5bUY2JieOaZZ5yX87p2\n7cqjjz5KXFwcW7dudV4OLPsZ2rZty19/aZ+H9uzZA0BwcDA9e/Zk3bp1xMXFsXv3boQQxMfHn/W6\n14cDGXDI8ZFMABM6gxCwLmclG3PXOOvNCnualubweo+vPpkMML788xItCq/FvbQzKzOXkGXN0C+w\nBqA2Pg5EAC5PQJMI9K+sohDCCxgN3OeyWgJrhRA24D0p5YJaiOmcFi1axJYtW7DZbMTGxtK7d+8K\n28eNG8eQIUO48sornZ+mX3jhBe6++26EEFx33XU88MADtG3blsGDB+Pu7s7XX39NbGws48ePZ9Cg\nQYSEhJx13OHDh3Pbbbfx7bffOtdNmDCB7777jiFDhuDj48OqVavw8/PDw8PD+SkTqj5jCAkJwcPD\ng+joaHr37s2VV14JwKxZs3jrrbd45JFH2Lt3L3a7nXnztCt8M2bM4Oabb+att94iNjYWN7eKc/T2\n79+fP//8k549e/Lkk08yatQoPDw8+PjjjwGYN28e06ZNY/fu3Tz99NO4u7sTHR1N//6V/toB+Oc/\n/+m8F/Lss89WWQ8gLS2NYcOGYTAY6Nq1K//3f/9XYXuPHj14/PHHmTx5MkuWLOGjjz4iOjoaX19f\nPv/88wp1K/u9nVn/zEtpZSZNmkSvXr2cb/axsbHcfffd/Pe//0VKedbN+LCwMHr37k10dDTdu3fH\nbDZjMBh46KGHGDFiBEIIunfvzjvvvMP69esZN27cOV+H2ma1a53YyvSPgHBfSCo5zrsp5Vd/r25x\nHdF+o+o1Nr10C4IugVqyFBhplfMwx4PuYVnGx8wIfUjv8HQjanpaK4SYBIyWUs5wlKcB/aWU91VS\n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\n", 138 | "text/plain": [ 139 | "" 140 | ] 141 | }, 142 | "metadata": {}, 143 | "output_type": "display_data" 144 | } 145 | ], 146 | "source": [ 147 | "opt_D = torch.optim.Adam(D.parameters(), lr=LR_D)\n", 148 | "opt_G = torch.optim.Adam(G.parameters(), lr=LR_G)\n", 149 | "\n", 150 | "plt.ion() # something about continuous plotting\n", 151 | "\n", 152 | "D_loss_history = []\n", 153 | "G_loss_history = []\n", 154 | "for step in range(10000):\n", 155 | " artist_paintings = artist_works() # real painting from artist\n", 156 | " G_ideas = torch.randn(BATCH_SIZE, N_IDEAS) # random ideas\n", 157 | " G_paintings = G(G_ideas) # fake painting from G (random ideas)\n", 158 | " \n", 159 | " prob_artist0 = D(artist_paintings) # D try to increase this prob\n", 160 | " prob_artist1 = D(G_paintings) # D try to reduce this prob\n", 161 | " \n", 162 | " D_loss = - torch.mean(torch.log(prob_artist0) + torch.log(1. - prob_artist1))\n", 163 | " G_loss = torch.mean(torch.log(1. - prob_artist1))\n", 164 | " \n", 165 | " D_loss_history.append(D_loss)\n", 166 | " G_loss_history.append(G_loss)\n", 167 | " \n", 168 | " opt_D.zero_grad()\n", 169 | " D_loss.backward(retain_graph=True) # reusing computational graph\n", 170 | " opt_D.step()\n", 171 | " \n", 172 | " opt_G.zero_grad()\n", 173 | " G_loss.backward()\n", 174 | " opt_G.step()\n", 175 | " \n", 176 | " if step % 50 == 0: # plotting\n", 177 | " plt.cla()\n", 178 | " plt.plot(PAINT_POINTS[0], G_paintings.data.numpy()[0], c='#4AD631', lw=3, label='Generated painting',)\n", 179 | " plt.plot(PAINT_POINTS[0], np.sin(PAINT_POINTS[0] * np.pi), c='#74BCFF', lw=3, label='standard curve')\n", 180 | " plt.text(-1, 0.75, 'D accuracy=%.2f (0.5 for D to converge)' % prob_artist0.data.numpy().mean(), fontdict={'size': 8})\n", 181 | " plt.text(-1, 0.5, 'D score= %.2f (-1.38 for G to converge)' % -D_loss.data.numpy(), fontdict={'size': 8})\n", 182 | " plt.ylim((-1, 1));plt.legend(loc='lower right', fontsize=10);plt.draw();plt.pause(0.01)\n", 183 | "\n", 184 | "plt.ioff()\n", 185 | "plt.show()" 186 | ] 187 | }, 188 | { 189 | "cell_type": "code", 190 | "execution_count": null, 191 | "metadata": { 192 | "collapsed": true 193 | }, 194 | "outputs": [], 195 | "source": [] 196 | } 197 | ], 198 | "metadata": { 199 | "kernelspec": { 200 | "display_name": "Python 3", 201 | "language": "python", 202 | "name": "python3" 203 | }, 204 | "language_info": { 205 | "codemirror_mode": { 206 | "name": "ipython", 207 | "version": 3 208 | }, 209 | "file_extension": ".py", 210 | "mimetype": "text/x-python", 211 | "name": "python", 212 | "nbconvert_exporter": "python", 213 | "pygments_lexer": "ipython3", 214 | "version": "3.6.3" 215 | } 216 | }, 217 | "nbformat": 4, 218 | "nbformat_minor": 2 219 | } 220 | -------------------------------------------------------------------------------- /GAN/GAN_1.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torch.nn as nn 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | 6 | # torch.manual_seed(1) # reproducible 7 | # np.random.seed(1) 8 | 9 | # Hyper Parameters 10 | BATCH_SIZE = 64 11 | LR_G = 0.0001 # learning rate for generator 12 | LR_D = 0.0001 # learning rate for discriminator 13 | N_IDEAS = 5 # think of this as number of ideas for generating an art work(Generator) 14 | ART_COMPONENTS = 15 # it could be total point G can drew in the canvas 15 | PAINT_POINTS = np.vstack([np.linspace(-1, 1, ART_COMPONENTS) for _ in range(BATCH_SIZE)]) 16 | 17 | 18 | def artist_works(): # painting from the famous artist (real target) 19 | #a = np.random.uniform(1, 2, size=BATCH_SIZE)[:, np.newaxis] 20 | r = 0.02 * np.random.randn(1, ART_COMPONENTS) 21 | paintings = np.sin(PAINT_POINTS * np.pi) + r 22 | paintings = torch.from_numpy(paintings).float() 23 | return paintings 24 | 25 | 26 | G = nn.Sequential( # Generator 27 | nn.Linear(N_IDEAS, 128), # random ideas (could from normal distribution) 28 | nn.ReLU(), 29 | nn.Linear(128, ART_COMPONENTS), # making a painting from these random ideas 30 | ) 31 | 32 | D = nn.Sequential( # Discriminator 33 | nn.Linear(ART_COMPONENTS, 128), # receive art work either from the famous artist or a newbie like G 34 | nn.ReLU(), 35 | nn.Linear(128, 1), 36 | nn.Sigmoid(), # tell the probability that the art work is made by artist 37 | ) 38 | 39 | 40 | opt_D = torch.optim.Adam(D.parameters(), lr=LR_D) 41 | opt_G = torch.optim.Adam(G.parameters(), lr=LR_G) 42 | 43 | plt.ion() # something about continuous plotting 44 | 45 | D_loss_history = [] 46 | G_loss_history = [] 47 | for step in range(10000): 48 | artist_paintings = artist_works() # real painting from artist 49 | G_ideas = torch.randn(BATCH_SIZE, N_IDEAS) # random ideas 50 | G_paintings = G(G_ideas) # fake painting from G (random ideas) 51 | 52 | prob_artist0 = D(artist_paintings) # D try to increase this prob 53 | prob_artist1 = D(G_paintings) # D try to reduce this prob 54 | 55 | D_loss = - torch.mean(torch.log(prob_artist0) + torch.log(1. - prob_artist1)) 56 | G_loss = torch.mean(torch.log(1. - prob_artist1)) 57 | 58 | D_loss_history.append(D_loss) 59 | G_loss_history.append(G_loss) 60 | 61 | opt_D.zero_grad() 62 | D_loss.backward(retain_graph=True) # reusing computational graph 63 | opt_D.step() 64 | 65 | opt_G.zero_grad() 66 | G_loss.backward() 67 | opt_G.step() 68 | 69 | if step % 50 == 0: # plotting 70 | plt.cla() 71 | plt.plot(PAINT_POINTS[0], G_paintings.data.numpy()[0], c='#4AD631', lw=3, label='Generated painting',) 72 | plt.plot(PAINT_POINTS[0], np.sin(PAINT_POINTS[0] * np.pi), c='#74BCFF', lw=3, label='upper bound') 73 | plt.text(-1, 0.75, 'D accuracy=%.2f (0.5 for D to converge)' % prob_artist0.data.numpy().mean(), fontdict={'size': 13}) 74 | plt.text(-1, 0.5, 'D score= %.2f (-1.38 for G to converge)' % -D_loss.data.numpy(), fontdict={'size': 13}) 75 | plt.ylim((-1, 1));plt.legend(loc='upper right', fontsize=10);plt.draw();plt.pause(0.01) 76 | 77 | plt.ioff() 78 | plt.show() -------------------------------------------------------------------------------- /GAN/readme.md: -------------------------------------------------------------------------------- 1 | # First GAN Program by PyTorch 2 | 3 | - GAN_1.py 4 | 5 | - GAN_1.ipynb 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Perceptron Linear Algorithm/PLA.py: -------------------------------------------------------------------------------- 1 | # PLA算法 2 | 3 | import numpy as np 4 | import pandas as pd 5 | import matplotlib.pyplot as plt 6 | 7 | data = pd.read_csv('./data/data1.csv', header=None) 8 | # 样本输入,维度(100,2) 9 | X = data.iloc[:,:2].values 10 | # 样本输出,维度(100,) 11 | y = data.iloc[:,2].values 12 | 13 | plt.scatter(X[:50, 0], X[:50, 1], color='blue', marker='o', label='Positive') 14 | plt.scatter(X[50:, 0], X[50:, 1], color='red', marker='x', label='Negative') 15 | plt.xlabel('Feature 1') 16 | plt.ylabel('Feature 2') 17 | plt.legend(loc = 'upper left') 18 | plt.title('Original Data') 19 | plt.show() 20 | 21 | # 均值 22 | u = np.mean(X, axis=0) 23 | # 方差 24 | v = np.std(X, axis=0) 25 | X = (X - u) / v 26 | 27 | # 作图 28 | plt.scatter(X[:50, 0], X[:50, 1], color='blue', marker='o', label='Positive') 29 | plt.scatter(X[50:, 0], X[50:, 1], color='red', marker='x', label='Negative') 30 | plt.xlabel('Feature 1') 31 | plt.ylabel('Feature 2') 32 | plt.legend(loc = 'upper left') 33 | plt.title('Normalization data') 34 | plt.show() 35 | 36 | # 直线初始化 37 | # X加上偏置项 38 | X = np.hstack((np.ones((X.shape[0],1)), X)) 39 | # 权重初始化 40 | w = np.random.randn(3,1) 41 | 42 | for i in range(100): 43 | s = np.dot(X, w) 44 | y_pred = np.ones_like(y) 45 | loc_n = np.where(s < 0)[0] 46 | y_pred[loc_n] = -1 47 | num_fault = len(np.where(y != y_pred)[0]) 48 | print('第%2d次更新,分类错误的点个数:%2d' % (i, num_fault)) 49 | if num_fault == 0: 50 | break 51 | else: 52 | t = np.where(y != y_pred)[0][0] 53 | w += y[t] * X[t, :].reshape((3,1)) 54 | 55 | # 直线第一个坐标(x1,y1) 56 | x1 = -2 57 | y1 = -1 / w[2] * (w[0] * 1 + w[1] * x1) 58 | # 直线第二个坐标(x2,y2) 59 | x2 = 2 60 | y2 = -1 / w[2] * (w[0] * 1 + w[1] * x2) 61 | # 作图 62 | plt.scatter(X[:50, 1], X[:50, 2], color='blue', marker='o', label='Positive') 63 | plt.scatter(X[50:, 1], X[50:, 2], color='red', marker='x', label='Negative') 64 | plt.plot([x1,x2], [y1,y2],'r') 65 | plt.xlabel('Feature 1') 66 | plt.ylabel('Feature 2') 67 | plt.legend(loc = 'upper left') 68 | plt.show() -------------------------------------------------------------------------------- /Perceptron Linear Algorithm/Pocket_PLA.py: -------------------------------------------------------------------------------- 1 | # Pocket PLA算法 2 | 3 | import numpy as np 4 | import pandas as pd 5 | import matplotlib.pyplot as plt 6 | 7 | data = pd.read_csv('./data/data2.csv', header=None) 8 | # 样本输入,维度(100,2) 9 | X = data.iloc[:,:2].values 10 | # 样本输出,维度(100,) 11 | y = data.iloc[:,2].values 12 | 13 | # 在二维平面上绘出正负样本的分布情况 14 | import matplotlib.pyplot as plt 15 | 16 | plt.scatter(X[:50, 0], X[:50, 1], color='blue', marker='o', label='Positive') 17 | plt.scatter(X[50:, 0], X[50:, 1], color='red', marker='x', label='Negative') 18 | plt.xlabel('Feature 1') 19 | plt.ylabel('Feature 2') 20 | plt.legend(loc = 'upper left') 21 | plt.title('Original Data') 22 | plt.show() 23 | 24 | # 特征归一化 25 | # 均值 26 | u = np.mean(X, axis=0) 27 | # 方差 28 | v = np.std(X, axis=0) 29 | 30 | X = (X - u) / v 31 | 32 | # 作图 33 | plt.scatter(X[:50, 0], X[:50, 1], color='blue', marker='o', label='Positive') 34 | plt.scatter(X[50:, 0], X[50:, 1], color='red', marker='x', label='Negative') 35 | plt.xlabel('Feature 1') 36 | plt.ylabel('Feature 2') 37 | plt.legend(loc = 'upper left') 38 | plt.title('Normalization data') 39 | plt.show() 40 | 41 | # 初始化 42 | # X加上偏置项 43 | X = np.hstack((np.ones((X.shape[0],1)), X)) 44 | # 权重初始化 45 | w = np.random.randn(3,1) 46 | 47 | # 显示初始化直线位置 48 | # 直线第一个坐标(x1,y1) 49 | x1 = -2 50 | y1 = -1 / w[2] * (w[0] * 1 + w[1] * x1) 51 | # 直线第二个坐标(x2,y2) 52 | x2 = 2 53 | y2 = -1 / w[2] * (w[0] * 1 + w[1] * x2) 54 | # 作图 55 | plt.scatter(X[:50, 1], X[:50, 2], color='blue', marker='o', label='Positive') 56 | plt.scatter(X[50:, 1], X[50:, 2], color='red', marker='x', label='Negative') 57 | plt.plot([x1,x2], [y1,y2],'r') 58 | plt.xlabel('Feature 1') 59 | plt.ylabel('Feature 2') 60 | plt.legend(loc = 'upper left') 61 | plt.show() 62 | 63 | # 迭代更新训练 64 | for i in range(100): 65 | s = np.dot(X, w) 66 | y_pred = np.ones_like(y) 67 | loc_n = np.where(s < 0)[0] 68 | y_pred[loc_n] = -1 69 | num_fault = len(np.where(y != y_pred)[0]) 70 | 71 | if num_fault == 0: 72 | break 73 | else: 74 | r = np.random.choice(num_fault) # 随机选择一个错误分类点 75 | t = np.where(y != y_pred)[0][r] 76 | w2 = w + y[t] * X[t, :].reshape((3,1)) 77 | 78 | s = np.dot(X, w2) 79 | y_pred = np.ones_like(y) 80 | loc_n = np.where(s < 0)[0] 81 | y_pred[loc_n] = -1 82 | num_fault2 = len(np.where(y != y_pred)[0]) 83 | if num_fault2 " 172 | ] 173 | }, 174 | "metadata": {}, 175 | "output_type": "display_data" 176 | } 177 | ], 178 | "source": [ 179 | "import matplotlib.pyplot as plt\n", 180 | "\n", 181 | "plt.scatter(X_setosa[:, 0], X_setosa[:, 2], color='red', marker='o', label='setosa')\n", 182 | "plt.scatter(X_versicolor[:, 0], X_versicolor[:, 2], color='blue', marker='^', label='versicolor')\n", 183 | "plt.scatter(X_virginica[:, 0], X_virginica[:, 2], color='green', marker='s', label='virginica')\n", 184 | "plt.xlabel('sepal length')\n", 185 | "plt.ylabel('petal length')\n", 186 | "plt.legend(loc = 'upper left')\n", 187 | "plt.show()" 188 | ] 189 | }, 190 | { 191 | "cell_type": "markdown", 192 | "metadata": {}, 193 | "source": [ 194 | "由上图可见,三个类别之间是有较明显区别的。" 195 | ] 196 | }, 197 | { 198 | "cell_type": "markdown", 199 | "metadata": {}, 200 | "source": [ 201 | "### 训练集、验证集、测试集划分" 202 | ] 203 | }, 204 | { 205 | "cell_type": "markdown", 206 | "metadata": {}, 207 | "source": [ 208 | "接下来,我们要将每个类别的所有样本分成**训练样本**(training set)、**验证集(validation set)**和**测试样本**(test set),各占所有样本的比例分别为60%,20%,20%。" 209 | ] 210 | }, 211 | { 212 | "cell_type": "code", 213 | "execution_count": 66, 214 | "metadata": { 215 | "collapsed": true 216 | }, 217 | "outputs": [], 218 | "source": [ 219 | "# training set\n", 220 | "X_setosa_train = X_setosa[:30, :]\n", 221 | "y_setosa_train = y_setosa[:30]\n", 222 | "X_versicolor_train = X_versicolor[:30, :]\n", 223 | "y_versicolor_train = y_versicolor[:30]\n", 224 | "X_virginica_train = X_virginica[:30, :]\n", 225 | "y_virginica_train = y_virginica[:30]\n", 226 | "X_train = np.vstack([X_setosa_train, X_versicolor_train, X_virginica_train])\n", 227 | "y_train = np.hstack([y_setosa_train, y_versicolor_train, y_virginica_train])\n", 228 | "\n", 229 | "# validation set\n", 230 | "X_setosa_val = X_setosa[30:40, :]\n", 231 | "y_setosa_val = y_setosa[30:40]\n", 232 | "X_versicolor_val = X_versicolor[30:40, :]\n", 233 | "y_versicolor_val = y_versicolor[30:40]\n", 234 | "X_virginica_val = X_virginica[30:40, :]\n", 235 | "y_virginica_val = y_virginica[30:40]\n", 236 | "X_val = np.vstack([X_setosa_val, X_versicolor_val, X_virginica_val])\n", 237 | "y_val = np.hstack([y_setosa_val, y_versicolor_val, y_virginica_val])\n", 238 | "\n", 239 | "# test set\n", 240 | "X_setosa_test = X_setosa[40:50, :]\n", 241 | "y_setosa_test = y_setosa[40:50]\n", 242 | "X_versicolor_test = X_versicolor[40:50, :]\n", 243 | "y_versicolor_test = y_versicolor[40:50]\n", 244 | "X_virginica_test = X_virginica[40:50, :]\n", 245 | "y_virginica_test = y_virginica[40:50]\n", 246 | "X_test = np.vstack([X_setosa_test, X_versicolor_test, X_virginica_test])\n", 247 | "y_test = np.hstack([y_setosa_test, y_versicolor_test, y_virginica_test])" 248 | ] 249 | }, 250 | { 251 | "cell_type": "markdown", 252 | "metadata": {}, 253 | "source": [ 254 | "## 4. KNN训练函数和预测函数" 255 | ] 256 | }, 257 | { 258 | "cell_type": "markdown", 259 | "metadata": {}, 260 | "source": [ 261 | "KNN的训练过程实际上是一种数据标类、数据存储的过程,不包含机器学习算法。首先我们需要定义一个**类**(class)来实现KNN算法模块。该类的初始化定义为:" 262 | ] 263 | }, 264 | { 265 | "cell_type": "markdown", 266 | "metadata": {}, 267 | "source": [ 268 | "```python\n", 269 | "class KNearestNeighbor(object):\n", 270 | " def __init__(self):\n", 271 | " pass\n", 272 | "```" 273 | ] 274 | }, 275 | { 276 | "cell_type": "markdown", 277 | "metadata": {}, 278 | "source": [ 279 | "然后,在KNearestNeighbor类中定义训练函数,训练函数保存所有训练样本。" 280 | ] 281 | }, 282 | { 283 | "cell_type": "markdown", 284 | "metadata": {}, 285 | "source": [ 286 | "```python\n", 287 | "def train(self, X, y):\n", 288 | " self.X_train = X\n", 289 | " self.y_train = y\n", 290 | " \n", 291 | "```" 292 | ] 293 | }, 294 | { 295 | "cell_type": "markdown", 296 | "metadata": {}, 297 | "source": [ 298 | "KNN的测试过程是核心部分。其中,有两点需要注意:\n", 299 | "\n", 300 | "* 衡量距离的方式\n", 301 | "\n", 302 | "* K值的选择" 303 | ] 304 | }, 305 | { 306 | "cell_type": "markdown", 307 | "metadata": {}, 308 | "source": [ 309 | "### 衡量距离的方式" 310 | ] 311 | }, 312 | { 313 | "cell_type": "markdown", 314 | "metadata": {}, 315 | "source": [ 316 | "KNN距离衡量一般有两种方式:**L1距离**和**L2距离**。" 317 | ] 318 | }, 319 | { 320 | "cell_type": "markdown", 321 | "metadata": {}, 322 | "source": [ 323 | "L1距离的计算公式为:" 324 | ] 325 | }, 326 | { 327 | "cell_type": "markdown", 328 | "metadata": {}, 329 | "source": [ 330 | "$$d1(I_1,I_2)=\\sum_p|I_1^p-I_2^p|$$" 331 | ] 332 | }, 333 | { 334 | "cell_type": "markdown", 335 | "metadata": {}, 336 | "source": [ 337 | "其中,$I_1$和$I_2$分别表示两个样本,$p$表示特征维度。" 338 | ] 339 | }, 340 | { 341 | "cell_type": "markdown", 342 | "metadata": {}, 343 | "source": [ 344 | "L2距离的计算公式为:" 345 | ] 346 | }, 347 | { 348 | "cell_type": "markdown", 349 | "metadata": {}, 350 | "source": [ 351 | "$$d2(I_1,I_2)=\\sqrt{\\sum_p(I_1^p-I_2^p)^2}$$" 352 | ] 353 | }, 354 | { 355 | "cell_type": "markdown", 356 | "metadata": {}, 357 | "source": [ 358 | "一般来说,L1距离和L2距离都比较常用。需要注意的是,如果两个样本距离越大,那么使用L2会继续扩大距离,即对距离大的情况**惩罚性越大**。反过来说,如果两个样本距离较小,那么使用L2会缩小距离,减小惩罚。这里,我们使用最常用的L2距离。" 359 | ] 360 | }, 361 | { 362 | "cell_type": "markdown", 363 | "metadata": {}, 364 | "source": [ 365 | "### K值的选择" 366 | ] 367 | }, 368 | { 369 | "cell_type": "markdown", 370 | "metadata": {}, 371 | "source": [ 372 | "KNN中K值的选择至关重要,K值太小会使模型过于复杂,造成**过拟合**(overfitting);K值太大会使模型分类模糊,造成**欠拟合**(underfitting)。实际应用中,我们可以选择不同的K值,通过验证来决定K值大小。代码中,我们将K设定为可调参数。" 373 | ] 374 | }, 375 | { 376 | "cell_type": "markdown", 377 | "metadata": {}, 378 | "source": [ 379 | "在KNearestNeighbor类中定义预测函数:" 380 | ] 381 | }, 382 | { 383 | "cell_type": "markdown", 384 | "metadata": {}, 385 | "source": [ 386 | "```python\n", 387 | "def predict(self, X, k=1)\n", 388 | " # 计算L2距离\n", 389 | " num_test = X.shape[0]\n", 390 | " num_train = self.X_train.shape[0]\n", 391 | " dists = np.zeros((num_test, num_train)) # 初始化距离函数\n", 392 | " # because(X - X_train)*(X - X_train) = -2X*X_train + X*X + X_train*X_train, so\n", 393 | " d1 = -2 * np.dot(X, self.X_train.T) # shape (num_test, num_train)\n", 394 | " d2 = np.sum(np.square(X), axis=1, keepdims=True) # shape (num_test, 1)\n", 395 | " d3 = np.sum(np.square(self.X_train), axis=1) # shape (1, num_train)\n", 396 | " dist = np.sqrt(d1 + d2 + d3)\n", 397 | " # 根据K值,选择最可能属于的类别\n", 398 | " y_pred = np.zeros(num_test)\n", 399 | " for i in range(num_test):\n", 400 | " dist_k_min = np.argsort(dist[i])[:k] # 最近邻k个实例位置\n", 401 | " y_kclose = self.y_train[dist_k_min] # 最近邻k个实例对应的标签\n", 402 | " y_pred[i] = np.argmax(np.bincount(y_kclose)) # 找出k个标签中从属类别最多的作为预测类别\n", 403 | " \n", 404 | " return y_pred\n", 405 | "```" 406 | ] 407 | }, 408 | { 409 | "cell_type": "markdown", 410 | "metadata": {}, 411 | "source": [ 412 | "KNearestNeighbor类的完整定义代码如下:" 413 | ] 414 | }, 415 | { 416 | "cell_type": "code", 417 | "execution_count": 154, 418 | "metadata": { 419 | "collapsed": true 420 | }, 421 | "outputs": [], 422 | "source": [ 423 | "class KNearestNeighbor(object):\n", 424 | " def __init__(self):\n", 425 | " pass\n", 426 | "\n", 427 | " # 训练函数\n", 428 | " def train(self, X, y):\n", 429 | " self.X_train = X\n", 430 | " self.y_train = y\n", 431 | " \n", 432 | " # 预测函数\n", 433 | " def predict(self, X, k=1):\n", 434 | " # 计算L2距离\n", 435 | " num_test = X.shape[0]\n", 436 | " num_train = self.X_train.shape[0]\n", 437 | " dists = np.zeros((num_test, num_train)) # 初始化距离函数\n", 438 | " # because(X - X_train)*(X - X_train) = -2X*X_train + X*X + X_train*X_train, so\n", 439 | " d1 = -2 * np.dot(X, self.X_train.T) # shape (num_test, num_train)\n", 440 | " d2 = np.sum(np.square(X), axis=1, keepdims=True) # shape (num_test, 1)\n", 441 | " d3 = np.sum(np.square(self.X_train), axis=1) # shape (1, num_train)\n", 442 | " dist = np.sqrt(d1 + d2 + d3)\n", 443 | " # 根据K值,选择最可能属于的类别\n", 444 | " y_pred = np.zeros(num_test)\n", 445 | " for i in range(num_test):\n", 446 | " dist_k_min = np.argsort(dist[i])[:k] # 最近邻k个实例位置\n", 447 | " y_kclose = self.y_train[dist_k_min] # 最近邻k个实例对应的标签\n", 448 | " y_pred[i] = np.argmax(np.bincount(y_kclose.tolist())) # 找出k个标签中从属类别最多的作为预测类别\n", 449 | "\n", 450 | " return y_pred\n" 451 | ] 452 | }, 453 | { 454 | "cell_type": "markdown", 455 | "metadata": {}, 456 | "source": [ 457 | "## 5. 训练和预测" 458 | ] 459 | }, 460 | { 461 | "cell_type": "markdown", 462 | "metadata": {}, 463 | "source": [ 464 | "### 选择合适的K值 " 465 | ] 466 | }, 467 | { 468 | "cell_type": "markdown", 469 | "metadata": {}, 470 | "source": [ 471 | "首先,创建一个KnearestNeighbor实例对象。" 472 | ] 473 | }, 474 | { 475 | "cell_type": "code", 476 | "execution_count": 155, 477 | "metadata": { 478 | "collapsed": true 479 | }, 480 | "outputs": [], 481 | "source": [ 482 | "KNN = KNearestNeighbor()" 483 | ] 484 | }, 485 | { 486 | "cell_type": "markdown", 487 | "metadata": {}, 488 | "source": [ 489 | "然后,在验证集上进行k-fold交叉验证。选择不同的K值,根据验证结果,选择最佳的K值。" 490 | ] 491 | }, 492 | { 493 | "cell_type": "code", 494 | "execution_count": 176, 495 | "metadata": {}, 496 | "outputs": [ 497 | { 498 | "name": "stdout", 499 | "output_type": "stream", 500 | "text": [ 501 | "k = 3, accuracy: 0.888889\n", 502 | "k = 5, accuracy: 0.877778\n", 503 | "k = 7, accuracy: 0.888889\n", 504 | "k = 9, accuracy: 0.888889\n", 505 | "k = 11, accuracy: 0.866667\n", 506 | "k = 13, accuracy: 0.855556\n", 507 | "k = 15, accuracy: 0.877778\n", 508 | "Best K is: 3\n", 509 | "\n" 510 | ] 511 | } 512 | ], 513 | "source": [ 514 | "num_folds = 5 # 训练数据分为5 folds\n", 515 | "K_classes = [3, 5, 7, 9, 11, 13, 15] # 所有K值\n", 516 | "\n", 517 | "# 把训练数据分成5份\n", 518 | "X_train_folds = []\n", 519 | "y_train_folds = []\n", 520 | "X_train_folds = np.split(X_train, num_folds)\n", 521 | "y_train_folds = np.split(y_train, num_folds)\n", 522 | "\n", 523 | "# 字典用来存储不同K值对应的准确率\n", 524 | "K_accuracy = []\n", 525 | "k_best = K_classes[0]\n", 526 | "\n", 527 | "for k in K_classes:\n", 528 | " accuracies = []\n", 529 | " for i in range(num_folds):\n", 530 | " Xtr = np.concatenate(X_train_folds[:i] + X_train_folds[i+1:])\n", 531 | " ytr = np.concatenate(y_train_folds[:i] + y_train_folds[i+1:])\n", 532 | " Xcv = X_train_folds[i]\n", 533 | " ycv = y_train_folds[i]\n", 534 | " KNN.train(Xtr, ytr)\n", 535 | " ycv_pred = KNN.predict(Xcv, k=k)\n", 536 | " accuracy = np.mean(ycv_pred == ycv)\n", 537 | " accuracies.append(accuracy)\n", 538 | " accuracies_avg = np.mean(accuracies)\n", 539 | " K_accuracy.append(accuracies_avg)\n", 540 | " if accuracies_avg > k_best:\n", 541 | " k_best = accuracies_avg\n", 542 | "\n", 543 | "# 打印出验证结果\n", 544 | "for k in range(len(K_classes)):\n", 545 | " print('k = %d, accuracy: %f' % (K_classes[k], K_accuracy[k]))\n", 546 | "print('Best K is: %d\\n' % k_best)" 547 | ] 548 | }, 549 | { 550 | "cell_type": "markdown", 551 | "metadata": {}, 552 | "source": [ 553 | "作图,查看验证结果。" 554 | ] 555 | }, 556 | { 557 | "cell_type": "code", 558 | "execution_count": 180, 559 | "metadata": {}, 560 | "outputs": [ 561 | { 562 | "data": { 563 | "image/png": "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\nYII=\n", 564 | "text/plain": [ 565 | "" 566 | ] 567 | }, 568 | "metadata": {}, 569 | "output_type": "display_data" 570 | } 571 | ], 572 | "source": [ 573 | "# Plot the cross validation\n", 574 | "plt.plot(K_classes, K_accuracy, 'ro-')\n", 575 | "plt.title('Cross-validation on k')\n", 576 | "plt.xlabel('K')\n", 577 | "plt.ylabel('Cross-validation accuracy')\n", 578 | "plt.show()" 579 | ] 580 | }, 581 | { 582 | "cell_type": "markdown", 583 | "metadata": {}, 584 | "source": [ 585 | "可见,K值取3的时候,验证集的准确率最高。此例中,由于总体样本数据量不够多,所以验证结果并不明显。但是使用k-fold交叉验证来选择最佳K值是最常用的方法之一。" 586 | ] 587 | }, 588 | { 589 | "cell_type": "markdown", 590 | "metadata": {}, 591 | "source": [ 592 | "### 对测试集进行预测" 593 | ] 594 | }, 595 | { 596 | "cell_type": "markdown", 597 | "metadata": {}, 598 | "source": [ 599 | "选择完合适的K值之后,就可以对测试集进行预测分析了。" 600 | ] 601 | }, 602 | { 603 | "cell_type": "code", 604 | "execution_count": 194, 605 | "metadata": {}, 606 | "outputs": [ 607 | { 608 | "name": "stdout", 609 | "output_type": "stream", 610 | "text": [ 611 | "测试集预测准确率:1.000000\n" 612 | ] 613 | } 614 | ], 615 | "source": [ 616 | "KNN.train(X_train, y_train)\n", 617 | "y_pred = KNN.predict(X_test, k=6)\n", 618 | "accuracy = np.mean(y_pred == y_test)\n", 619 | "print('测试集预测准确率:%f' % accuracy)" 620 | ] 621 | }, 622 | { 623 | "cell_type": "markdown", 624 | "metadata": {}, 625 | "source": [ 626 | "最终结果显示,测试集预测准确率为100%。" 627 | ] 628 | }, 629 | { 630 | "cell_type": "markdown", 631 | "metadata": {}, 632 | "source": [ 633 | "最后,我们把预测结果绘图表示。仍然只选择sepal length和petal length两个特征,在二维平面上作图。" 634 | ] 635 | }, 636 | { 637 | "cell_type": "code", 638 | "execution_count": 204, 639 | "metadata": {}, 640 | "outputs": [ 641 | { 642 | "data": { 643 | "image/png": "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\nY2LE/wcLCmK1wPtUPgAAAABJRU5ErkJggg==\n", 644 | "text/plain": [ 645 | "" 646 | ] 647 | }, 648 | "metadata": {}, 649 | "output_type": "display_data" 650 | } 651 | ], 652 | "source": [ 653 | "# 训练集\n", 654 | "plt.scatter(X_setosa_train[:, 0], X_setosa_train[:, 2], color='red', marker='o', label='setosa_train')\n", 655 | "plt.scatter(X_versicolor_train[:, 0], X_versicolor_train[:, 2], color='blue', marker='^', label='versicolor_train')\n", 656 | "plt.scatter(X_virginica_train[:, 0], X_virginica_train[:, 2], color='green', marker='s', label='virginica_train')\n", 657 | "# 测试集\n", 658 | "plt.scatter(X_setosa_test[:, 0], X_setosa_test[:, 2], color='y', marker='o', label='setosa_test')\n", 659 | "plt.scatter(X_versicolor_test[:, 0], X_versicolor_test[:, 2], color='y', marker='^', label='versicolor_test')\n", 660 | "plt.scatter(X_virginica_test[:, 0], X_virginica_test[:, 2], color='y', marker='s', label='virginica_test')\n", 661 | "\n", 662 | "plt.xlabel('sepal length')\n", 663 | "plt.ylabel('petal length')\n", 664 | "plt.legend(loc = 4)\n", 665 | "plt.show()" 666 | ] 667 | }, 668 | { 669 | "cell_type": "markdown", 670 | "metadata": {}, 671 | "source": [ 672 | "## 6. KNN算法总结 " 673 | ] 674 | }, 675 | { 676 | "cell_type": "markdown", 677 | "metadata": {}, 678 | "source": [ 679 | "KNN算法是一种最简单最直观的分类算法。它的训练过程保留了所有样本的所有特征,把所有信息都记下来,没有经过处理和提取。而其它机器学习算法包括神经网络则是在训练过程中提取最重要、最有代表性的特征。在这一点上,KNN算法还非常不够“智能”。但是,KNN算法作为机器学习的第一个算法,还是值得我们了解一下的。" 680 | ] 681 | }, 682 | { 683 | "cell_type": "code", 684 | "execution_count": null, 685 | "metadata": { 686 | "collapsed": true 687 | }, 688 | "outputs": [], 689 | "source": [] 690 | } 691 | ], 692 | "metadata": { 693 | "kernelspec": { 694 | "display_name": "Python 3", 695 | "language": "python", 696 | "name": "python3" 697 | }, 698 | "language_info": { 699 | "codemirror_mode": { 700 | "name": "ipython", 701 | "version": 3 702 | }, 703 | "file_extension": ".py", 704 | "mimetype": "text/x-python", 705 | "name": "python", 706 | "nbconvert_exporter": "python", 707 | "pygments_lexer": "ipython3", 708 | "version": "3.6.3" 709 | } 710 | }, 711 | "nbformat": 4, 712 | "nbformat_minor": 2 713 | } 714 | --------------------------------------------------------------------------------