From e48c8d52a000cba8a21932864d88f4df844aeb24 Mon Sep 17 00:00:00 2001 From: Taro Yabuki Date: Tue, 26 Mar 2024 00:58:48 +0900 Subject: [PATCH] =?UTF-8?q?=E5=8B=95=E4=BD=9C=E7=A2=BA=E8=AA=8D2024?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +- code/Python-notebook/README.md | 23 +- code/Python-notebook/ch03/03-colab.ipynb | 1889 ------ code/Python-notebook/ch03/03.01.ipynb | 265 - code/Python-notebook/ch03/03.02.ipynb | 134 - code/Python-notebook/ch03/03.03.ipynb | 379 -- code/Python-notebook/ch03/03.04.ipynb | 626 -- code/Python-notebook/ch03/03.05.ipynb | 158 - code/Python-notebook/ch03/03.06.ipynb | 74 - code/Python-notebook/ch03/03.07.ipynb | 230 - code/Python-notebook/ch03/03.08.ipynb | 90 - code/Python-notebook/ch03/03.ipynb | 1874 ------ code/Python-notebook/ch04/04-colab.ipynb | 1022 ---- code/Python-notebook/ch04/04.01.ipynb | 325 -- code/Python-notebook/ch04/04.02.ipynb | 246 - code/Python-notebook/ch04/04.03.ipynb | 220 - code/Python-notebook/ch04/04.04.ipynb | 270 - code/Python-notebook/ch04/04.ipynb | 1022 ---- code/Python-notebook/ch05/05-colab.ipynb | 435 -- code/Python-notebook/ch05/05.01.ipynb | 284 - code/Python-notebook/ch05/05.02.ipynb | 161 - code/Python-notebook/ch05/05.ipynb | 435 -- code/Python-notebook/ch06/06-colab.ipynb | 93 - code/Python-notebook/ch06/06.01.ipynb | 19 - code/Python-notebook/ch06/06.02.ipynb | 78 - code/Python-notebook/ch06/06.03.ipynb | 23 - code/Python-notebook/ch06/06.ipynb | 93 - code/Python-notebook/ch07/07-colab.ipynb | 881 --- code/Python-notebook/ch07/07.01.ipynb | 19 - code/Python-notebook/ch07/07.02.ipynb | 81 - code/Python-notebook/ch07/07.03.ipynb | 145 - code/Python-notebook/ch07/07.04.ipynb | 206 - code/Python-notebook/ch07/07.05.ipynb | 77 - code/Python-notebook/ch07/07.06.ipynb | 269 - code/Python-notebook/ch07/07.07.ipynb | 159 - code/Python-notebook/ch07/07.ipynb | 881 --- code/Python-notebook/ch08/08-colab.ipynb | 669 --- code/Python-notebook/ch08/08.01.ipynb | 83 - code/Python-notebook/ch08/08.02.ipynb | 125 - code/Python-notebook/ch08/08.03.ipynb | 82 - code/Python-notebook/ch08/08.04.ipynb | 66 - code/Python-notebook/ch08/08.05.ipynb | 68 - code/Python-notebook/ch08/08.06.ipynb | 192 - code/Python-notebook/ch08/08.07.ipynb | 128 - code/Python-notebook/ch08/08.ipynb | 669 --- code/Python-notebook/ch09/09-colab.ipynb | 509 -- code/Python-notebook/ch09/09.01.ipynb | 49 - code/Python-notebook/ch09/09.02.ipynb | 80 - code/Python-notebook/ch09/09.03.ipynb | 162 - code/Python-notebook/ch09/09.04.ipynb | 108 - code/Python-notebook/ch09/09.05.ipynb | 100 - code/Python-notebook/ch09/09.06.ipynb | 68 - code/Python-notebook/ch09/09.ipynb | 509 -- code/Python-notebook/ch10/10-colab.ipynb | 376 -- code/Python-notebook/ch10/10.01.ipynb | 66 - code/Python-notebook/ch10/10.02.ipynb | 102 - code/Python-notebook/ch10/10.03.ipynb | 152 - code/Python-notebook/ch10/10.04.ipynb | 95 - code/Python-notebook/ch10/10.ipynb | 376 -- code/Python-notebook/ch11/11-colab.ipynb | 949 --- code/Python-notebook/ch11/11.01.ipynb | 165 - code/Python-notebook/ch11/11.02.ipynb | 168 - code/Python-notebook/ch11/11.03.ipynb | 436 -- code/Python-notebook/ch11/11.04.ipynb | 199 - code/Python-notebook/ch11/11.ipynb | 934 --- code/Python-notebook/ch12/12-colab.ipynb | 340 -- code/Python-notebook/ch12/12.01.ipynb | 69 - code/Python-notebook/ch12/12.02.ipynb | 266 - code/Python-notebook/ch12/12.ipynb | 325 -- code/Python-notebook/ch13/13-colab.ipynb | 380 -- code/Python-notebook/ch13/13.01.ipynb | 167 - code/Python-notebook/ch13/13.02.ipynb | 208 - code/Python-notebook/ch13/13.ipynb | 365 -- code/Python-notebook/python-03.ipynb | 1494 +++++ code/Python-notebook/python-04.ipynb | 820 +++ code/Python-notebook/python-05.ipynb | 343 ++ code/Python-notebook/python-06.ipynb | 78 + code/Python-notebook/python-07.ipynb | 757 +++ code/Python-notebook/python-08.ipynb | 598 ++ code/Python-notebook/python-09.ipynb | 408 ++ code/Python-notebook/python-10.ipynb | 328 ++ code/Python-notebook/python-11.ipynb | 843 +++ code/Python-notebook/python-12.ipynb | 280 + code/Python-notebook/python-13.ipynb | 316 + code/R-notebook/README.md | 23 +- code/R-notebook/ch03/03-colab.ipynb | 1847 ------ code/R-notebook/ch03/03.01.ipynb | 262 - code/R-notebook/ch03/03.02.ipynb | 163 - code/R-notebook/ch03/03.03.ipynb | 377 -- code/R-notebook/ch03/03.04.ipynb | 626 -- code/R-notebook/ch03/03.05.ipynb | 153 - code/R-notebook/ch03/03.06.ipynb | 37 - code/R-notebook/ch03/03.07.ipynb | 224 - code/R-notebook/ch03/03.08.ipynb | 76 - code/R-notebook/ch03/03.ipynb | 1831 ------ code/R-notebook/ch04/04-colab.ipynb | 1123 ---- code/R-notebook/ch04/04.01.ipynb | 335 -- code/R-notebook/ch04/04.02.ipynb | 336 -- code/R-notebook/ch04/04.03.ipynb | 185 - code/R-notebook/ch04/04.04.ipynb | 285 - code/R-notebook/ch04/04.ipynb | 1107 ---- code/R-notebook/ch05/05-colab.ipynb | 462 -- code/R-notebook/ch05/05.01.ipynb | 311 - code/R-notebook/ch05/05.02.ipynb | 145 - code/R-notebook/ch05/05.ipynb | 446 -- code/R-notebook/ch06/06-colab.ipynb | 60 - code/R-notebook/ch06/06.01.ipynb | 19 - code/R-notebook/ch06/06.02.ipynb | 50 - code/R-notebook/ch06/06.03.ipynb | 23 - code/R-notebook/ch06/06.ipynb | 60 - code/R-notebook/ch07/07-colab.ipynb | 925 --- code/R-notebook/ch07/07.01.ipynb | 19 - code/R-notebook/ch07/07.02.ipynb | 92 - code/R-notebook/ch07/07.03.ipynb | 140 - code/R-notebook/ch07/07.04.ipynb | 200 - code/R-notebook/ch07/07.05.ipynb | 78 - code/R-notebook/ch07/07.06.ipynb | 299 - code/R-notebook/ch07/07.07.ipynb | 156 - code/R-notebook/ch07/07.ipynb | 909 --- code/R-notebook/ch08/08-colab.ipynb | 645 --- code/R-notebook/ch08/08.01.ipynb | 91 - code/R-notebook/ch08/08.02.ipynb | 125 - code/R-notebook/ch08/08.03.ipynb | 83 - code/R-notebook/ch08/08.04.ipynb | 64 - code/R-notebook/ch08/08.05.ipynb | 54 - code/R-notebook/ch08/08.06.ipynb | 174 - code/R-notebook/ch08/08.07.ipynb | 113 - code/R-notebook/ch08/08.ipynb | 629 -- code/R-notebook/ch09/09-colab.ipynb | 516 -- code/R-notebook/ch09/09.01.ipynb | 51 - code/R-notebook/ch09/09.02.ipynb | 71 - code/R-notebook/ch09/09.03.ipynb | 185 - code/R-notebook/ch09/09.04.ipynb | 97 - code/R-notebook/ch09/09.05.ipynb | 89 - code/R-notebook/ch09/09.06.ipynb | 65 - code/R-notebook/ch09/09.ipynb | 500 -- code/R-notebook/ch10/10-colab.ipynb | 436 -- code/R-notebook/ch10/10.01.ipynb | 84 - code/R-notebook/ch10/10.02.ipynb | 105 - code/R-notebook/ch10/10.03.ipynb | 191 - code/R-notebook/ch10/10.04.ipynb | 74 - code/R-notebook/ch10/10.ipynb | 420 -- code/R-notebook/ch11/11-colab.ipynb | 908 --- code/R-notebook/ch11/11.01.ipynb | 145 - code/R-notebook/ch11/11.02.ipynb | 159 - code/R-notebook/ch11/11.03.ipynb | 410 -- code/R-notebook/ch11/11.04.ipynb | 197 - code/R-notebook/ch11/11.ipynb | 877 --- code/R-notebook/ch12/12-colab.ipynb | 339 -- code/R-notebook/ch12/12.01.ipynb | 61 - code/R-notebook/ch12/12.02.ipynb | 271 - code/R-notebook/ch12/12.ipynb | 322 -- code/R-notebook/ch13/13-colab.ipynb | 380 -- code/R-notebook/ch13/13.01.ipynb | 172 - code/R-notebook/ch13/13.02.ipynb | 201 - code/R-notebook/ch13/13.ipynb | 363 -- code/R-notebook/r-03.ipynb | 1434 +++++ code/R-notebook/r-04.ipynb | 878 +++ code/R-notebook/r-05.ipynb | 366 ++ code/R-notebook/r-06.ipynb | 47 + code/R-notebook/r-07.ipynb | 767 +++ code/R-notebook/r-08.ipynb | 553 ++ code/R-notebook/r-09.ipynb | 395 ++ code/R-notebook/r-10.ipynb | 356 ++ code/R-notebook/r-11.ipynb | 827 +++ code/R-notebook/r-12.ipynb | 276 + code/R-notebook/r-13.ipynb | 323 ++ code/R/ch03/03.01.R | 93 - code/R/ch03/03.02.R | 55 - code/R/ch03/03.03.R | 142 - code/R/ch03/03.04.R | 259 - code/R/ch03/03.05.R | 80 - code/R/ch03/03.06.R | 7 - code/R/ch03/03.07.R | 104 - code/R/ch03/03.08.R | 25 - code/R/ch03/03.R | 773 --- code/R/ch04/04.01.R | 164 - code/R/ch04/04.02.R | 150 - code/R/ch04/04.03.R | 84 - code/R/ch04/04.04.R | 151 - code/R/ch04/04.R | 553 -- code/R/ch05/05.01.R | 144 - code/R/ch05/05.02.R | 68 - code/R/ch05/05.R | 214 - code/R/ch06/06.01.R | 1 - code/R/ch06/06.02.R | 20 - code/R/ch06/06.03.R | 5 - code/R/ch06/06.R | 29 - code/R/ch07/07.01.R | 1 - code/R/ch07/07.02.R | 39 - code/R/ch07/07.03.R | 53 - code/R/ch07/07.04.R | 95 - code/R/ch07/07.05.R | 39 - code/R/ch07/07.06.R | 146 - code/R/ch07/07.07.R | 70 - code/R/ch07/07.R | 450 -- code/R/ch08/08.01.R | 38 - code/R/ch08/08.02.R | 60 - code/R/ch08/08.03.R | 37 - code/R/ch08/08.04.R | 32 - code/R/ch08/08.05.R | 22 - code/R/ch08/08.06.R | 80 - code/R/ch08/08.07.R | 43 - code/R/ch08/08.R | 319 - code/R/ch09/09.01.R | 19 - code/R/ch09/09.02.R | 25 - code/R/ch09/09.03.R | 91 - code/R/ch09/09.04.R | 48 - code/R/ch09/09.05.R | 40 - code/R/ch09/09.06.R | 28 - code/R/ch09/09.R | 257 - code/R/ch10/10.01.R | 45 - code/R/ch10/10.02.R | 40 - code/R/ch10/10.03.R | 90 - code/R/ch10/10.04.R | 28 - code/R/ch10/10.R | 207 - code/R/ch11/11.01.R | 50 - code/R/ch11/11.02.R | 66 - code/R/ch11/11.03.R | 199 - code/R/ch11/11.04.R | 87 - code/R/ch11/11.R | 406 -- code/R/ch12/12.01.R | 24 - code/R/ch12/12.02.R | 128 - code/R/ch12/12.R | 154 - code/R/ch13/13.01.R | 88 - code/R/ch13/13.02.R | 93 - code/R/ch13/13.R | 183 - code/Rmd/ch03/03.01.Rmd | 130 - code/Rmd/ch03/03.02.Rmd | 76 - code/Rmd/ch03/03.03.Rmd | 195 - code/Rmd/ch03/03.04.Rmd | 334 -- code/Rmd/ch03/03.05.Rmd | 91 - code/Rmd/ch03/03.06.Rmd | 10 - code/Rmd/ch03/03.07.Rmd | 127 - code/Rmd/ch03/03.08.Rmd | 34 - code/Rmd/ch03/03.Rmd | 1005 ---- code/Rmd/ch04/04.01.Rmd | 203 - code/Rmd/ch04/04.02.Rmd | 189 - code/Rmd/ch04/04.03.Rmd | 103 - code/Rmd/ch04/04.04.Rmd | 178 - code/Rmd/ch04/04.Rmd | 677 --- code/Rmd/ch05/05.01.Rmd | 179 - code/Rmd/ch05/05.02.Rmd | 83 - code/Rmd/ch05/05.Rmd | 264 - code/Rmd/ch06/06.01.Rmd | 2 - code/Rmd/ch06/06.02.Rmd | 23 - code/Rmd/ch06/06.03.Rmd | 6 - code/Rmd/ch06/06.Rmd | 34 - code/Rmd/ch07/07.01.Rmd | 2 - code/Rmd/ch07/07.02.Rmd | 50 - code/Rmd/ch07/07.03.Rmd | 68 - code/Rmd/ch07/07.04.Rmd | 118 - code/Rmd/ch07/07.05.Rmd | 46 - code/Rmd/ch07/07.06.Rmd | 177 - code/Rmd/ch07/07.07.Rmd | 89 - code/Rmd/ch07/07.Rmd | 557 -- code/Rmd/ch08/08.01.Rmd | 49 - code/Rmd/ch08/08.02.Rmd | 73 - code/Rmd/ch08/08.03.Rmd | 46 - code/Rmd/ch08/08.04.Rmd | 37 - code/Rmd/ch08/08.05.Rmd | 27 - code/Rmd/ch08/08.06.Rmd | 97 - code/Rmd/ch08/08.07.Rmd | 56 - code/Rmd/ch08/08.Rmd | 392 -- code/Rmd/ch09/09.01.Rmd | 24 - code/Rmd/ch09/09.02.Rmd | 34 - code/Rmd/ch09/09.03.Rmd | 108 - code/Rmd/ch09/09.04.Rmd | 55 - code/Rmd/ch09/09.05.Rmd | 47 - code/Rmd/ch09/09.06.Rmd | 33 - code/Rmd/ch09/09.Rmd | 307 - code/Rmd/ch10/10.01.Rmd | 52 - code/Rmd/ch10/10.02.Rmd | 53 - code/Rmd/ch10/10.03.Rmd | 109 - code/Rmd/ch10/10.04.Rmd | 37 - code/Rmd/ch10/10.Rmd | 255 - code/Rmd/ch11/11.01.Rmd | 73 - code/Rmd/ch11/11.02.Rmd | 87 - code/Rmd/ch11/11.03.Rmd | 248 - code/Rmd/ch11/11.04.Rmd | 110 - code/Rmd/ch11/11.Rmd | 522 -- code/Rmd/ch12/12.01.Rmd | 29 - code/Rmd/ch12/12.02.Rmd | 159 - code/Rmd/ch12/12.Rmd | 190 - code/Rmd/ch13/13.01.Rmd | 105 - code/Rmd/ch13/13.02.Rmd | 114 - code/Rmd/ch13/13.Rmd | 221 - code/py/ch03/03.01.py | 96 - code/py/ch03/03.02.py | 45 - code/py/ch03/03.03.py | 149 - code/py/ch03/03.04.py | 259 - code/py/ch03/03.05.py | 85 - code/py/ch03/03.06.py | 21 - code/py/ch03/03.07.py | 110 - code/py/ch03/03.08.py | 31 - code/py/ch04/04.01.py | 154 - code/py/ch04/04.02.py | 102 - code/py/ch04/04.03.py | 107 - code/py/ch04/04.04.py | 136 - code/py/ch05/05.01.py | 116 - code/py/ch05/05.02.py | 84 - code/py/ch06/06.01.py | 1 - code/py/ch06/06.02.py | 39 - code/py/ch06/06.03.py | 5 - code/py/ch07/07.01.py | 1 - code/py/ch07/07.02.py | 28 - code/py/ch07/07.03.py | 58 - code/py/ch07/07.04.py | 101 - code/py/ch07/07.05.py | 38 - code/py/ch07/07.06.py | 142 - code/py/ch07/07.07.py | 73 - code/py/ch08/08.01.py | 30 - code/py/ch08/08.02.py | 60 - code/py/ch08/08.03.py | 36 - code/py/ch08/08.04.py | 34 - code/py/ch08/08.05.py | 36 - code/py/ch08/08.06.py | 98 - code/py/ch08/08.07.py | 58 - code/py/ch09/09.01.py | 17 - code/py/ch09/09.02.py | 34 - code/py/ch09/09.03.py | 82 - code/py/ch09/09.04.py | 59 - code/py/ch09/09.05.py | 51 - code/py/ch09/09.06.py | 31 - code/py/ch10/10.01.py | 27 - code/py/ch10/10.02.py | 37 - code/py/ch10/10.03.py | 72 - code/py/ch10/10.04.py | 49 - code/py/ch11/11.01.py | 70 - code/py/ch11/11.02.py | 75 - code/py/ch11/11.03.py | 225 - code/py/ch11/11.04.py | 89 - code/py/ch12/12.01.py | 32 - code/py/ch12/12.02.py | 123 - code/py/ch13/13.01.py | 83 - code/py/ch13/13.02.py | 114 - code/python-results.ipynb | 6352 +++++++++----------- code/python.Rmd | 1 + code/python.ipynb | 1918 +++--- code/r-results.ipynb | 6748 +++++++++++----------- code/r.Rmd | 7 +- code/r.ipynb | 2001 +++---- docker/jupyter.sh | 1 + docker/rstudio-gpu.sh | 10 - docker/rstudio-gpu/Dockerfile | 80 - docker/rstudio-gpu/README.md | 12 - docker/rstudio-mac.sh | 9 - docker/rstudio-mac/Dockerfile | 60 - docker/rstudio-mac/README.md | 9 - docker/rstudio.sh | 1 + 350 files changed, 20824 insertions(+), 74365 deletions(-) delete mode 100644 code/Python-notebook/ch03/03-colab.ipynb delete mode 100644 code/Python-notebook/ch03/03.01.ipynb delete mode 100644 code/Python-notebook/ch03/03.02.ipynb delete mode 100644 code/Python-notebook/ch03/03.03.ipynb delete mode 100644 code/Python-notebook/ch03/03.04.ipynb delete mode 100644 code/Python-notebook/ch03/03.05.ipynb delete mode 100644 code/Python-notebook/ch03/03.06.ipynb delete mode 100644 code/Python-notebook/ch03/03.07.ipynb delete mode 100644 code/Python-notebook/ch03/03.08.ipynb delete mode 100644 code/Python-notebook/ch03/03.ipynb delete mode 100644 code/Python-notebook/ch04/04-colab.ipynb delete mode 100644 code/Python-notebook/ch04/04.01.ipynb delete mode 100644 code/Python-notebook/ch04/04.02.ipynb delete mode 100644 code/Python-notebook/ch04/04.03.ipynb delete mode 100644 code/Python-notebook/ch04/04.04.ipynb delete mode 100644 code/Python-notebook/ch04/04.ipynb delete mode 100644 code/Python-notebook/ch05/05-colab.ipynb delete mode 100644 code/Python-notebook/ch05/05.01.ipynb delete mode 100644 code/Python-notebook/ch05/05.02.ipynb delete mode 100644 code/Python-notebook/ch05/05.ipynb delete mode 100644 code/Python-notebook/ch06/06-colab.ipynb delete mode 100644 code/Python-notebook/ch06/06.01.ipynb delete mode 100644 code/Python-notebook/ch06/06.02.ipynb delete mode 100644 code/Python-notebook/ch06/06.03.ipynb delete mode 100644 code/Python-notebook/ch06/06.ipynb delete mode 100644 code/Python-notebook/ch07/07-colab.ipynb delete mode 100644 code/Python-notebook/ch07/07.01.ipynb delete mode 100644 code/Python-notebook/ch07/07.02.ipynb delete mode 100644 code/Python-notebook/ch07/07.03.ipynb delete mode 100644 code/Python-notebook/ch07/07.04.ipynb delete mode 100644 code/Python-notebook/ch07/07.05.ipynb delete mode 100644 code/Python-notebook/ch07/07.06.ipynb delete mode 100644 code/Python-notebook/ch07/07.07.ipynb delete mode 100644 code/Python-notebook/ch07/07.ipynb delete mode 100644 code/Python-notebook/ch08/08-colab.ipynb delete mode 100644 code/Python-notebook/ch08/08.01.ipynb delete mode 100644 code/Python-notebook/ch08/08.02.ipynb delete mode 100644 code/Python-notebook/ch08/08.03.ipynb delete mode 100644 code/Python-notebook/ch08/08.04.ipynb delete mode 100644 code/Python-notebook/ch08/08.05.ipynb delete mode 100644 code/Python-notebook/ch08/08.06.ipynb delete mode 100644 code/Python-notebook/ch08/08.07.ipynb delete mode 100644 code/Python-notebook/ch08/08.ipynb delete mode 100644 code/Python-notebook/ch09/09-colab.ipynb delete mode 100644 code/Python-notebook/ch09/09.01.ipynb delete mode 100644 code/Python-notebook/ch09/09.02.ipynb delete mode 100644 code/Python-notebook/ch09/09.03.ipynb delete mode 100644 code/Python-notebook/ch09/09.04.ipynb delete mode 100644 code/Python-notebook/ch09/09.05.ipynb delete mode 100644 code/Python-notebook/ch09/09.06.ipynb delete mode 100644 code/Python-notebook/ch09/09.ipynb delete mode 100644 code/Python-notebook/ch10/10-colab.ipynb delete mode 100644 code/Python-notebook/ch10/10.01.ipynb delete mode 100644 code/Python-notebook/ch10/10.02.ipynb delete mode 100644 code/Python-notebook/ch10/10.03.ipynb delete mode 100644 code/Python-notebook/ch10/10.04.ipynb delete mode 100644 code/Python-notebook/ch10/10.ipynb delete mode 100644 code/Python-notebook/ch11/11-colab.ipynb delete mode 100644 code/Python-notebook/ch11/11.01.ipynb delete mode 100644 code/Python-notebook/ch11/11.02.ipynb delete mode 100644 code/Python-notebook/ch11/11.03.ipynb delete mode 100644 code/Python-notebook/ch11/11.04.ipynb delete mode 100644 code/Python-notebook/ch11/11.ipynb delete mode 100644 code/Python-notebook/ch12/12-colab.ipynb delete mode 100644 code/Python-notebook/ch12/12.01.ipynb delete mode 100644 code/Python-notebook/ch12/12.02.ipynb delete mode 100644 code/Python-notebook/ch12/12.ipynb delete mode 100644 code/Python-notebook/ch13/13-colab.ipynb delete mode 100644 code/Python-notebook/ch13/13.01.ipynb delete mode 100644 code/Python-notebook/ch13/13.02.ipynb delete mode 100644 code/Python-notebook/ch13/13.ipynb create mode 100644 code/Python-notebook/python-03.ipynb create mode 100644 code/Python-notebook/python-04.ipynb create mode 100644 code/Python-notebook/python-05.ipynb create mode 100644 code/Python-notebook/python-06.ipynb create mode 100644 code/Python-notebook/python-07.ipynb create mode 100644 code/Python-notebook/python-08.ipynb create mode 100644 code/Python-notebook/python-09.ipynb create mode 100644 code/Python-notebook/python-10.ipynb create mode 100644 code/Python-notebook/python-11.ipynb create mode 100644 code/Python-notebook/python-12.ipynb create mode 100644 code/Python-notebook/python-13.ipynb delete mode 100644 code/R-notebook/ch03/03-colab.ipynb delete mode 100644 code/R-notebook/ch03/03.01.ipynb delete mode 100644 code/R-notebook/ch03/03.02.ipynb delete mode 100644 code/R-notebook/ch03/03.03.ipynb delete mode 100644 code/R-notebook/ch03/03.04.ipynb delete mode 100644 code/R-notebook/ch03/03.05.ipynb delete mode 100644 code/R-notebook/ch03/03.06.ipynb delete mode 100644 code/R-notebook/ch03/03.07.ipynb delete mode 100644 code/R-notebook/ch03/03.08.ipynb delete mode 100644 code/R-notebook/ch03/03.ipynb delete mode 100644 code/R-notebook/ch04/04-colab.ipynb delete mode 100644 code/R-notebook/ch04/04.01.ipynb delete mode 100644 code/R-notebook/ch04/04.02.ipynb delete mode 100644 code/R-notebook/ch04/04.03.ipynb delete mode 100644 code/R-notebook/ch04/04.04.ipynb delete mode 100644 code/R-notebook/ch04/04.ipynb delete mode 100644 code/R-notebook/ch05/05-colab.ipynb delete mode 100644 code/R-notebook/ch05/05.01.ipynb delete mode 100644 code/R-notebook/ch05/05.02.ipynb delete mode 100644 code/R-notebook/ch05/05.ipynb delete mode 100644 code/R-notebook/ch06/06-colab.ipynb delete mode 100644 code/R-notebook/ch06/06.01.ipynb delete mode 100644 code/R-notebook/ch06/06.02.ipynb delete mode 100644 code/R-notebook/ch06/06.03.ipynb delete mode 100644 code/R-notebook/ch06/06.ipynb delete mode 100644 code/R-notebook/ch07/07-colab.ipynb delete mode 100644 code/R-notebook/ch07/07.01.ipynb delete mode 100644 code/R-notebook/ch07/07.02.ipynb delete mode 100644 code/R-notebook/ch07/07.03.ipynb delete mode 100644 code/R-notebook/ch07/07.04.ipynb delete mode 100644 code/R-notebook/ch07/07.05.ipynb delete mode 100644 code/R-notebook/ch07/07.06.ipynb delete mode 100644 code/R-notebook/ch07/07.07.ipynb delete mode 100644 code/R-notebook/ch07/07.ipynb delete mode 100644 code/R-notebook/ch08/08-colab.ipynb delete mode 100644 code/R-notebook/ch08/08.01.ipynb delete mode 100644 code/R-notebook/ch08/08.02.ipynb delete mode 100644 code/R-notebook/ch08/08.03.ipynb delete mode 100644 code/R-notebook/ch08/08.04.ipynb delete mode 100644 code/R-notebook/ch08/08.05.ipynb delete mode 100644 code/R-notebook/ch08/08.06.ipynb delete mode 100644 code/R-notebook/ch08/08.07.ipynb delete mode 100644 code/R-notebook/ch08/08.ipynb delete mode 100644 code/R-notebook/ch09/09-colab.ipynb delete mode 100644 code/R-notebook/ch09/09.01.ipynb delete mode 100644 code/R-notebook/ch09/09.02.ipynb delete mode 100644 code/R-notebook/ch09/09.03.ipynb delete mode 100644 code/R-notebook/ch09/09.04.ipynb delete mode 100644 code/R-notebook/ch09/09.05.ipynb delete mode 100644 code/R-notebook/ch09/09.06.ipynb delete mode 100644 code/R-notebook/ch09/09.ipynb delete mode 100644 code/R-notebook/ch10/10-colab.ipynb delete mode 100644 code/R-notebook/ch10/10.01.ipynb delete mode 100644 code/R-notebook/ch10/10.02.ipynb delete mode 100644 code/R-notebook/ch10/10.03.ipynb delete mode 100644 code/R-notebook/ch10/10.04.ipynb delete mode 100644 code/R-notebook/ch10/10.ipynb delete mode 100644 code/R-notebook/ch11/11-colab.ipynb delete mode 100644 code/R-notebook/ch11/11.01.ipynb delete mode 100644 code/R-notebook/ch11/11.02.ipynb delete mode 100644 code/R-notebook/ch11/11.03.ipynb delete mode 100644 code/R-notebook/ch11/11.04.ipynb delete mode 100644 code/R-notebook/ch11/11.ipynb delete mode 100644 code/R-notebook/ch12/12-colab.ipynb delete mode 100644 code/R-notebook/ch12/12.01.ipynb delete mode 100644 code/R-notebook/ch12/12.02.ipynb delete mode 100644 code/R-notebook/ch12/12.ipynb delete mode 100644 code/R-notebook/ch13/13-colab.ipynb delete mode 100644 code/R-notebook/ch13/13.01.ipynb delete mode 100644 code/R-notebook/ch13/13.02.ipynb delete mode 100644 code/R-notebook/ch13/13.ipynb create mode 100644 code/R-notebook/r-03.ipynb create mode 100644 code/R-notebook/r-04.ipynb create mode 100644 code/R-notebook/r-05.ipynb create mode 100644 code/R-notebook/r-06.ipynb create mode 100644 code/R-notebook/r-07.ipynb create mode 100644 code/R-notebook/r-08.ipynb create mode 100644 code/R-notebook/r-09.ipynb create mode 100644 code/R-notebook/r-10.ipynb create mode 100644 code/R-notebook/r-11.ipynb create mode 100644 code/R-notebook/r-12.ipynb create mode 100644 code/R-notebook/r-13.ipynb delete mode 100644 code/R/ch03/03.01.R delete mode 100644 code/R/ch03/03.02.R delete mode 100644 code/R/ch03/03.03.R delete mode 100644 code/R/ch03/03.04.R delete mode 100644 code/R/ch03/03.05.R delete mode 100644 code/R/ch03/03.06.R delete mode 100644 code/R/ch03/03.07.R delete mode 100644 code/R/ch03/03.08.R delete mode 100644 code/R/ch03/03.R delete mode 100644 code/R/ch04/04.01.R delete mode 100644 code/R/ch04/04.02.R delete mode 100644 code/R/ch04/04.03.R delete mode 100644 code/R/ch04/04.04.R delete mode 100644 code/R/ch04/04.R delete mode 100644 code/R/ch05/05.01.R delete mode 100644 code/R/ch05/05.02.R delete mode 100644 code/R/ch05/05.R delete mode 100644 code/R/ch06/06.01.R delete mode 100644 code/R/ch06/06.02.R delete mode 100644 code/R/ch06/06.03.R delete mode 100644 code/R/ch06/06.R delete mode 100644 code/R/ch07/07.01.R delete mode 100644 code/R/ch07/07.02.R delete mode 100644 code/R/ch07/07.03.R delete mode 100644 code/R/ch07/07.04.R delete mode 100644 code/R/ch07/07.05.R delete mode 100644 code/R/ch07/07.06.R delete mode 100644 code/R/ch07/07.07.R delete mode 100644 code/R/ch07/07.R delete mode 100644 code/R/ch08/08.01.R delete mode 100644 code/R/ch08/08.02.R delete mode 100644 code/R/ch08/08.03.R delete mode 100644 code/R/ch08/08.04.R delete mode 100644 code/R/ch08/08.05.R delete mode 100644 code/R/ch08/08.06.R delete mode 100644 code/R/ch08/08.07.R delete mode 100644 code/R/ch08/08.R delete mode 100644 code/R/ch09/09.01.R delete mode 100644 code/R/ch09/09.02.R delete mode 100644 code/R/ch09/09.03.R delete mode 100644 code/R/ch09/09.04.R delete mode 100644 code/R/ch09/09.05.R delete mode 100644 code/R/ch09/09.06.R delete mode 100644 code/R/ch09/09.R delete mode 100644 code/R/ch10/10.01.R delete mode 100644 code/R/ch10/10.02.R delete mode 100644 code/R/ch10/10.03.R delete mode 100644 code/R/ch10/10.04.R delete mode 100644 code/R/ch10/10.R delete mode 100644 code/R/ch11/11.01.R delete mode 100644 code/R/ch11/11.02.R delete mode 100644 code/R/ch11/11.03.R delete mode 100644 code/R/ch11/11.04.R delete mode 100644 code/R/ch11/11.R delete mode 100644 code/R/ch12/12.01.R delete mode 100644 code/R/ch12/12.02.R delete mode 100644 code/R/ch12/12.R delete mode 100644 code/R/ch13/13.01.R delete mode 100644 code/R/ch13/13.02.R delete mode 100644 code/R/ch13/13.R delete mode 100644 code/Rmd/ch03/03.01.Rmd delete mode 100644 code/Rmd/ch03/03.02.Rmd delete mode 100644 code/Rmd/ch03/03.03.Rmd delete mode 100644 code/Rmd/ch03/03.04.Rmd delete mode 100644 code/Rmd/ch03/03.05.Rmd delete mode 100644 code/Rmd/ch03/03.06.Rmd delete mode 100644 code/Rmd/ch03/03.07.Rmd delete mode 100644 code/Rmd/ch03/03.08.Rmd delete mode 100644 code/Rmd/ch03/03.Rmd delete mode 100644 code/Rmd/ch04/04.01.Rmd delete mode 100644 code/Rmd/ch04/04.02.Rmd delete mode 100644 code/Rmd/ch04/04.03.Rmd delete mode 100644 code/Rmd/ch04/04.04.Rmd delete mode 100644 code/Rmd/ch04/04.Rmd delete mode 100644 code/Rmd/ch05/05.01.Rmd delete mode 100644 code/Rmd/ch05/05.02.Rmd delete mode 100644 code/Rmd/ch05/05.Rmd delete mode 100644 code/Rmd/ch06/06.01.Rmd delete mode 100644 code/Rmd/ch06/06.02.Rmd delete mode 100644 code/Rmd/ch06/06.03.Rmd delete mode 100644 code/Rmd/ch06/06.Rmd delete mode 100644 code/Rmd/ch07/07.01.Rmd delete mode 100644 code/Rmd/ch07/07.02.Rmd delete mode 100644 code/Rmd/ch07/07.03.Rmd delete mode 100644 code/Rmd/ch07/07.04.Rmd delete mode 100644 code/Rmd/ch07/07.05.Rmd delete mode 100644 code/Rmd/ch07/07.06.Rmd delete mode 100644 code/Rmd/ch07/07.07.Rmd delete mode 100644 code/Rmd/ch07/07.Rmd delete mode 100644 code/Rmd/ch08/08.01.Rmd delete mode 100644 code/Rmd/ch08/08.02.Rmd delete mode 100644 code/Rmd/ch08/08.03.Rmd delete mode 100644 code/Rmd/ch08/08.04.Rmd delete mode 100644 code/Rmd/ch08/08.05.Rmd delete mode 100644 code/Rmd/ch08/08.06.Rmd delete mode 100644 code/Rmd/ch08/08.07.Rmd delete mode 100644 code/Rmd/ch08/08.Rmd delete mode 100644 code/Rmd/ch09/09.01.Rmd delete mode 100644 code/Rmd/ch09/09.02.Rmd delete mode 100644 code/Rmd/ch09/09.03.Rmd delete mode 100644 code/Rmd/ch09/09.04.Rmd delete mode 100644 code/Rmd/ch09/09.05.Rmd delete mode 100644 code/Rmd/ch09/09.06.Rmd delete mode 100644 code/Rmd/ch09/09.Rmd delete mode 100644 code/Rmd/ch10/10.01.Rmd delete mode 100644 code/Rmd/ch10/10.02.Rmd delete mode 100644 code/Rmd/ch10/10.03.Rmd delete mode 100644 code/Rmd/ch10/10.04.Rmd delete mode 100644 code/Rmd/ch10/10.Rmd delete mode 100644 code/Rmd/ch11/11.01.Rmd delete mode 100644 code/Rmd/ch11/11.02.Rmd delete mode 100644 code/Rmd/ch11/11.03.Rmd delete mode 100644 code/Rmd/ch11/11.04.Rmd delete mode 100644 code/Rmd/ch11/11.Rmd delete mode 100644 code/Rmd/ch12/12.01.Rmd delete mode 100644 code/Rmd/ch12/12.02.Rmd delete mode 100644 code/Rmd/ch12/12.Rmd delete mode 100644 code/Rmd/ch13/13.01.Rmd delete mode 100644 code/Rmd/ch13/13.02.Rmd delete mode 100644 code/Rmd/ch13/13.Rmd delete mode 100644 code/py/ch03/03.01.py delete mode 100644 code/py/ch03/03.02.py delete mode 100644 code/py/ch03/03.03.py delete mode 100644 code/py/ch03/03.04.py delete mode 100644 code/py/ch03/03.05.py delete mode 100644 code/py/ch03/03.06.py delete mode 100644 code/py/ch03/03.07.py delete mode 100644 code/py/ch03/03.08.py delete mode 100644 code/py/ch04/04.01.py delete mode 100644 code/py/ch04/04.02.py delete mode 100644 code/py/ch04/04.03.py delete mode 100644 code/py/ch04/04.04.py delete mode 100644 code/py/ch05/05.01.py delete mode 100644 code/py/ch05/05.02.py delete mode 100644 code/py/ch06/06.01.py delete mode 100644 code/py/ch06/06.02.py delete mode 100644 code/py/ch06/06.03.py delete mode 100644 code/py/ch07/07.01.py delete mode 100644 code/py/ch07/07.02.py delete mode 100644 code/py/ch07/07.03.py delete mode 100644 code/py/ch07/07.04.py delete mode 100644 code/py/ch07/07.05.py delete mode 100644 code/py/ch07/07.06.py delete mode 100644 code/py/ch07/07.07.py delete mode 100644 code/py/ch08/08.01.py delete mode 100644 code/py/ch08/08.02.py delete mode 100644 code/py/ch08/08.03.py delete mode 100644 code/py/ch08/08.04.py delete mode 100644 code/py/ch08/08.05.py delete mode 100644 code/py/ch08/08.06.py delete mode 100644 code/py/ch08/08.07.py delete mode 100644 code/py/ch09/09.01.py delete mode 100644 code/py/ch09/09.02.py delete mode 100644 code/py/ch09/09.03.py delete mode 100644 code/py/ch09/09.04.py delete mode 100644 code/py/ch09/09.05.py delete mode 100644 code/py/ch09/09.06.py delete mode 100644 code/py/ch10/10.01.py delete mode 100644 code/py/ch10/10.02.py delete mode 100644 code/py/ch10/10.03.py delete mode 100644 code/py/ch10/10.04.py delete mode 100644 code/py/ch11/11.01.py delete mode 100644 code/py/ch11/11.02.py delete mode 100644 code/py/ch11/11.03.py delete mode 100644 code/py/ch11/11.04.py delete mode 100644 code/py/ch12/12.01.py delete mode 100644 code/py/ch12/12.02.py delete mode 100644 code/py/ch13/13.01.py delete mode 100644 code/py/ch13/13.02.py delete mode 100644 docker/rstudio-gpu.sh delete mode 100644 docker/rstudio-gpu/Dockerfile delete mode 100644 docker/rstudio-gpu/README.md delete mode 100644 docker/rstudio-mac.sh delete mode 100644 docker/rstudio-mac/Dockerfile delete mode 100644 docker/rstudio-mac/README.md diff --git a/README.md b/README.md index 81cea08..c2236a5 100644 --- a/README.md +++ b/README.md @@ -48,15 +48,17 @@ RやPythonのコード(具体的なコンピュータプログラム)の読 --|--|--|-- R|Google Colab|[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/r.ipynb)|[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/r-results.ipynb) R|Jupyter|[r.ipynb](code/r.ipynb)|[r-results.ipynb](code/r-results.ipynb) -R|R Markdown|[r.Rmd](code/r.Rmd)|[r.html](https://taroyabuki.github.io/fromzero/r.html) +R|RStudio|[r.Rmd](code/r.Rmd)|[r.html](https://taroyabuki.github.io/fromzero/r.html) Python|Google Colab|[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/python.ipynb)|[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/python-results.ipynb) Python|Jupyter|[python.ipynb](code/python.ipynb)|[python-results.ipynb](code/python-results.ipynb) -Python|R Markdown|[python.Rmd](code/python.Rmd)|[python.html](https://taroyabuki.github.io/fromzero/python.html) +Python|RStudio|[python.Rmd](code/python.Rmd)|[python.html](https://taroyabuki.github.io/fromzero/python.html) -コードの使い方は,2.6節を参照してください[^1]. +コードの使い方は,2.6節を参照してください[^1][^2]. [^1]: [Amazon SageMaker Studio Lab](https://github.com/taroyabuki/fromzero/tree/main/addendum/sagemaker)での動作も確認済みです. +[^2]: Apple Chipでは,JupyterとRStudio上では第11章のコードが動作しません.第11章のコードを試す場合は,Google Colabを利用してください. + ## Docker 環境|言語|説明 diff --git a/code/Python-notebook/README.md b/code/Python-notebook/README.md index 0b008b7..3c12439 100644 --- a/code/Python-notebook/README.md +++ b/code/Python-notebook/README.md @@ -1,14 +1,15 @@ # Jupyter Notebooks for Python + chapter|Open in Colab --|-- -03|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/ch03/03-colab.ipynb) -04|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/ch04/04-colab.ipynb) -05|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/ch05/05-colab.ipynb) -06|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/ch06/06-colab.ipynb) -07|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/ch07/07-colab.ipynb) -08|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/ch08/08-colab.ipynb) -09|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/ch09/09-colab.ipynb) -10|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/ch10/10-colab.ipynb) -11|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/ch11/11-colab.ipynb) -12|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/ch12/12-colab.ipynb) -13|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/ch13/13-colab.ipynb) +03|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/python-03.ipynb) +04|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/python-04.ipynb) +05|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/python-05.ipynb) +06|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/python-06.ipynb) +07|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/python-07.ipynb) +08|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/python-08.ipynb) +09|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/python-09.ipynb) +10|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/python-10.ipynb) +11|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/python-11.ipynb) +12|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/python-12.ipynb) +13|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/Python-notebook/python-13.ipynb) diff --git a/code/Python-notebook/ch03/03-colab.ipynb b/code/Python-notebook/ch03/03-colab.ipynb deleted file mode 100644 index 6a79e09..0000000 --- a/code/Python-notebook/ch03/03-colab.ipynb +++ /dev/null @@ -1,1889 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 03" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Google Colaboratoryの環境設定\n", - "!pip install pandarallel | tail -n 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.1 入門\n", - "\n", - "### 3.1.1 数値" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "0x10\n", - "#> 16" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1.23e5\n", - "#> 123000.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "2 * 3\n", - "#> 6" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "10 / 3\n", - "#> 3.3333333333333335" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "10 // 3 # 商\n", - "#> 3\n", - "\n", - "10 % 3 # 余り\n", - "#> 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.2 変数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = 2\n", - "y = 3\n", - "x * y\n", - "#> 6\n", - "\n", - "x, y = 20, 30 # まとめて名付け\n", - "x * y\n", - "#> 600" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = 1 + 1\n", - "# この段階では結果は表示されない\n", - "\n", - "x # 変数名を評価する.\n", - "#> 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.3 文字列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_s = 'abcde'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "len(my_s)\n", - "#> 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "'This is' ' a' ' pen.'\n", - "# あるいは\n", - "'This is ' + 'a' + ' pen.'\n", - "#> 'This is a pen.'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_s[1:4]\n", - "#> 'bcd'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = \"{} is {}.\"\n", - "tmp.format('This', 'a pen')\n", - "#> 'This is a pen.'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.4 論理値" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1 <= 2\n", - "#> True\n", - "\n", - "1 < 0\n", - "#> False" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "0.1 + 0.1 + 0.1 == 0.3\n", - "#> False\n", - "\n", - "import math\n", - "math.isclose(0.1 + 0.1 + 0.1, 0.3)\n", - "#> True" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "True and False # 論理積(かつ)\n", - "#> False\n", - "\n", - "True or False # 論理和(または)\n", - "#> True\n", - "\n", - "not True # 否定(でない)\n", - "#> False" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.1.4.1 条件演算子" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "0 if 3 < 5 else 10\n", - "#> 0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.5 作業ディレクトリ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "os.getcwd()\n", - "#> '/home/jovyan/work'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "os.chdir('..')\n", - "os.getcwd()\n", - "#> '/home/jovyan'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.2 関数\n", - "\n", - "### 3.2.1 関数の利用" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import math\n", - "math.sqrt(4)\n", - "#> 2.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "math.log(100, 10)\n", - "#> 2.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "math.log(100) # 自然対数\n", - "# あるいは\n", - "math.log(100, math.e) # 省略しない場合\n", - "\n", - "#> 4.605170185988092" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "math.log10(100) # 常用対数\n", - "#> 2.0\n", - "\n", - "math.log2(1024) # 底が2の対数\n", - "#> 10.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.1.1 パイプ(Rのみ)\n", - "\n", - "### 3.2.2 関数の定義" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f(a, b):\n", - " return a - b" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f(3, 5)\n", - "#> -2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.2.1 デフォルト引数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f(a, b=5):\n", - " return a - b\n", - "\n", - "f(3) # f(3, 5)と同じこと\n", - "#> -2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.2.2 無名関数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(lambda a, b: a - b)(3, 5)\n", - "#> -2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.3 コレクション\n", - "\n", - "### 3.3.1 1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = ['foo', 'bar', 'baz']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "len(x)\n", - "#> 3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[1]\n", - "#> 'bar'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[1] = 'BAR'\n", - "x # 結果の確認\n", - "#> ['foo', 'BAR', 'baz']\n", - "\n", - "x[1] = 'bar' # 元に戻す." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[-2]\n", - "#> 'bar'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x + ['qux']\n", - "#> ['foo', 'bar', 'baz', 'qux']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = x + ['qux']\n", - "# あるいは\n", - "#x.append('qux')\n", - "\n", - "x # 結果の確認\n", - "#> ['foo', 'bar', 'baz', 'qux']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.1.1 等間隔の数値からなる1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "list(range(5))\n", - "#> [0, 1, 2, 3, 4]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "list(range(0, 11, 2))\n", - "#> [0, 2, 4, 6, 8, 10]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "np.arange(0, 1.1, 0.5)\n", - "#> array([0. , 0.5, 1. ])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.linspace(0, 100, 5)\n", - "#> array([ 0., 25., 50., 75., 100.])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "[10] * 5\n", - "#> [10, 10, 10, 10, 10]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.1.2 ファクタ(Rのみ)\n", - "\n", - "### 3.3.2 数値計算やデータ解析用の1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "x = np.array([2, 3, 5, 7])\n", - "\n", - "x + 10 # 加算\n", - "#> array([12, 13, 15, 17])\n", - "\n", - "x * 10 # 乗算\n", - "#> array([20, 30, 50, 70])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = [2, 3]\n", - "np.sin(x)\n", - "#> array([0.90929743, 0.14112001])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.array([2, 3, 5, 7])\n", - "y = np.array([1, 10, 100, 1000])\n", - "x + y\n", - "#> array([ 3, 13, 105, 1007])\n", - "\n", - "x * y\n", - "#> array([ 2, 30, 500, 7000])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.dot(x, y)\n", - "# あるいは\n", - "x @ y\n", - "\n", - "#> 7532" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.array([True, False])\n", - "y = np.array([True, True])\n", - "x & y\n", - "#> array([ True, False])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.2.1 1次元データ同士の比較" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "u = np.array([1, 2, 3])\n", - "v = np.array([1, 2, 3])\n", - "w = np.array([1, 2, 4])\n", - "\n", - "all(u == v) # 全体の比較\n", - "#> True\n", - "\n", - "all(u == w) # 全体の比較\n", - "#> False\n", - "\n", - "u == v # 要素ごとの比較\n", - "#> array([ True, True, True])\n", - "\n", - "u == w # 要素ごとの比較\n", - "#> array([ True, True, False])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(u == w).sum() # 同じ要素の数\n", - "#> 2\n", - "\n", - "(u == w).mean() # 同じ要素の割合\n", - "#> [1] 0.6666667" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.3 複数種類のデータをひとまとめにする" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = [1, \"two\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[1]\n", - "#> 'two'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.4 文字列と値のペアのコレクション" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = {'apple' : 'りんご',\n", - " 'orange': 'みかん'}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x['grape'] = 'ぶどう'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x['apple']\n", - "# あるいは\n", - "tmp = 'apple'\n", - "x[tmp]\n", - "\n", - "#> 'りんご'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.5 補足:コピーと参照" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = ['foo', 'bar', 'baz']\n", - "y = x\n", - "y[1] = 'BAR' # yを更新する.\n", - "y\n", - "#> ['foo', 'BAR', 'baz']\n", - "\n", - "x # xも変わる.\n", - "#> ['foo', 'BAR', 'baz']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = ['foo', 'bar', 'baz']\n", - "y = x.copy() # 「y = x」とせずに,コピーする.\n", - "x == y, x is y\n", - "#> (True, False) # xとyは,等価(内容は同じ)だが同一ではない.\n", - "\n", - "y[1] = 'BAR' # yを更新しても,\n", - "x\n", - "#> ['foo', 'bar', 'baz'] # xは変化しない." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.4 データフレーム\n", - "\n", - "### 3.4.1 データフレームの作成" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.1 データを列ごとに記述する方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame({\n", - " 'name': ['A', 'B', 'C', 'D'],\n", - " 'english': [ 60, 90, 70, 90],\n", - " 'math': [ 70, 80, 90, 100],\n", - " 'gender': ['f', 'm', 'm', 'f']})" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.2 データを見た目のとおりに記述する方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame([\n", - " ['A', 60, 70, 'f'],\n", - " ['B', 90, 80, 'm'],\n", - " ['C', 70, 90, 'm'],\n", - " ['D', 90, 100, 'f']],\n", - " columns=['name', 'english',\n", - " 'math', 'gender'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.head()\n", - "# 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.3 データフレームのサイズ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "r, c = my_df.shape # 行数と列数\n", - "r, c\n", - "#> (4, 4)\n", - "\n", - "r # 行数(len(my_df)も可)\n", - "#> 4\n", - "\n", - "c # 列数\n", - "#> 4" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.4 組合せ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from itertools import product\n", - "my_df2 = pd.DataFrame(\n", - " product([1, 2, 3],\n", - " [10, 100]),\n", - " columns=['X', 'Y'])\n", - "my_df2\n", - "#> X Y\n", - "#> 0 1 10\n", - "#> 1 1 100\n", - "#> 2 2 10\n", - "#> 3 2 100\n", - "#> 4 3 10\n", - "#> 5 3 100" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.5 列と行の名前" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2.columns\n", - "#> Index(['X', 'Y'], dtype='object')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2.columns = ['P', 'Q']\n", - "my_df2\n", - "#> P Q\n", - "#> 0 1 10\n", - "#> 1 1 100\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "list(my_df.index)\n", - "#> [0, 1, 2, 3]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2.index = [\n", - " 'a', 'b', 'c', 'd', 'e', 'f']\n", - "my_df2\n", - "#> P Q\n", - "#> a 1 10\n", - "#> b 1 100\n", - "#> c 2 10\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df3 = pd.DataFrame({\n", - " 'english': [ 60, 90, 70, 90],\n", - " 'math': [ 70, 80, 90, 100],\n", - " 'gender': ['f', 'm', 'm', 'f']},\n", - " index= ['A', 'B', 'C', 'D'])\n", - "my_df3\n", - "#> english math gender\n", - "#> A 60 70 f\n", - "#> B 90 80 m\n", - "#> C 70 90 m\n", - "#> D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.2 データの追加\n", - "\n", - "#### 3.4.2.1 行の追加(データフレームの結合)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = pd.DataFrame({\n", - " 'name' : ['E'],\n", - " 'english': [80],\n", - " 'math' : [80],\n", - " 'gender' : ['m']})\n", - "my_df2 = my_df.append(tmp)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.2.2 列の追加" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 = my_df.assign(id=[1, 2, 3, 4])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df3 = my_df.copy() # コピー\n", - "my_df3['id'] = [1, 2, 3, 4] # 更新\n", - "my_df3 # 結果の確認(割愛)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.3 データの取り出し\n", - "\n", - "#### 3.4.3.1 観測値の取り出し" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.iloc[0, 1]\n", - "#> 60" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.2 1列の取り出し(結果は1次元データ)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.iloc[:, 1]\n", - "# あるいは\n", - "x = my_df['english']\n", - "# あるいは\n", - "x = my_df.english\n", - "# あるいは\n", - "tmp = 'english'\n", - "x = my_df[tmp]\n", - "\n", - "x # 結果の確認(割愛)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.3 複数列の取り出し(結果はデータフレーム)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df[['name', 'math']]\n", - "# あるいは\n", - "x = my_df.loc[:, ['name', 'math']]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.take([0, 2], axis=1)\n", - "# あるいは\n", - "x = my_df.iloc[:, [0, 2]]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.drop(\n", - " columns=['english', 'gender'])\n", - "# あるいは\n", - "x = my_df.drop(\n", - " columns=my_df.columns[[1, 3]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.4 複数行の取り出し(結果はデータフレーム)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.take([0, 2])\n", - "# あるいは\n", - "x = my_df.iloc[[0, 2], :]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.drop([1, 3])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.5 検索" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df[my_df['gender'] == 'm']\n", - "# あるいは\n", - "x = my_df.query('gender == \"m\"')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df[(my_df['english'] > 80) & (my_df['gender'] == \"m\")]\n", - "# あるいは\n", - "x = my_df.query('english > 80 and gender == \"m\"')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df[my_df['english'] == my_df['english'].max()]\n", - "# あるいは\n", - "tmp = my_df['english'].max()\n", - "x = my_df.query('english == @tmp')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 = my_df.copy() # コピー\n", - "my_df2.loc[my_df['gender'] == 'm', 'gender'] = 'M'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2\n", - "#> name english math gender\n", - "#> 0 A 60 70 f\n", - "#> 1 B 90 80 M\n", - "#> 2 C 70 90 M\n", - "#> 3 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.6 並べ替え" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.sort_values('english')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.sort_values('english',\n", - " ascending=False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.4 補足:行列\n", - "\n", - "#### 3.4.4.1 行列の生成" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "x = [2, 3, 5, 7, 11, 13, 17, 19, 23,\n", - " 29, 31, 37]\n", - "A = np.array(x).reshape(3, 4)\n", - "A\n", - "#> array([[ 2, 3, 5, 7],\n", - "#> [11, 13, 17, 19],\n", - "#> [23, 29, 31, 37]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.2 データフレームと行列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A = my_df.iloc[:, [1, 2]].values\n", - "A\n", - "#> array([[ 60, 70],\n", - "#> [ 90, 80],\n", - "#> [ 70, 90],\n", - "#> [ 90, 100]])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.DataFrame(A)\n", - "#> 0 1\n", - "#> 0 60 70\n", - "#> 1 90 80\n", - "#> 2 70 90\n", - "#> 3 90 100" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.3 行列の変形" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A.T\n", - "#> array([[ 60, 90, 70, 90],\n", - "#> [ 70, 80, 90, 100]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.4 行列の積" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A.T @ A\n", - "#> array([[24700, 26700],\n", - "#> [26700, 29400]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.5 縦型と横型" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame({\n", - " 'day': [25, 26, 27],\n", - " 'min': [20, 21, 15],\n", - " 'max': [24, 27, 21]})" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_longer = my_df.melt(id_vars='day')\n", - "my_longer\n", - "#> day variable value\n", - "#> 0 25 min 20\n", - "#> 1 26 min 21\n", - "#> 2 27 min 15\n", - "#> 3 25 max 24\n", - "#> 4 26 max 27\n", - "#> 5 27 max 21" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_wider = my_longer.pivot(\n", - " index='day',\n", - " columns='variable',\n", - " values='value')\n", - "my_wider\n", - "#> variable max min\n", - "#> day\n", - "#> 25 24 20\n", - "#> 26 27 21\n", - "#> 27 21 15" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_wider.plot(\n", - " style='o-',\n", - " xticks=my_wider.index, # x軸目盛り\n", - " ylabel='temperature') # y軸ラベル" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.5 1次元データの(非)類似度\n", - "\n", - "### 3.5.1 ユークリッド距離" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from scipy.spatial import distance\n", - "from scipy.stats import pearsonr\n", - "\n", - "A = np.array([3, 4, 5])\n", - "B = np.array([3, 4, 29])\n", - "C = np.array([9, -18, 8])\n", - "\n", - "distance.euclidean(A, B)\n", - "#> 24.0\n", - "\n", - "distance.euclidean(A, C)\n", - "#> 23.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.2 マンハッタン距離" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "distance.cityblock(A, B)\n", - "#> 24\n", - "\n", - "distance.cityblock(A, C)\n", - "#> 31" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.3 コサイン類似度" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1 - distance.cosine(A, B)\n", - "#> 0.8169678632647616\n", - "\n", - "1 - distance.cosine(A, C)\n", - "#> -0.032651157422416865" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.4 相関係数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1 - distance.correlation(A, B)\n", - "# あるいは\n", - "pearsonr(A, B)[0]\n", - "#> 0.8824975032927698\n", - "\n", - "1 - distance.correlation(A, C)\n", - "# あるいは\n", - "pearsonr(A, C)[0]\n", - "#> -0.032662766723200676" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.5.4.1 データフレームを使う方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 小数点以下は3桁表示\n", - "np.set_printoptions(precision=3)\n", - "import pandas as pd\n", - "\n", - "my_df = pd.DataFrame({\n", - " 'x': [3, 3, 9],\n", - " 'y': [4, 4, -18],\n", - " 'z': [5, 29, 8]},\n", - " index=['A', 'B', 'C'])\n", - "\n", - "# ユークリッド距離\n", - "distance.cdist(my_df, my_df,\n", - " metric='euclidean')\n", - "#> array([[ 0., 24., 23.],\n", - "#> [24., 0., 31.],\n", - "#> [23., 31., 0.]])\n", - "\n", - "# マンハッタン距離\n", - "distance.cdist(my_df, my_df,\n", - " metric='cityblock')\n", - "#> array([[ 0., 24., 31.],\n", - "#> [24., 0., 49.],\n", - "#> [31., 49., 0.]])\n", - "\n", - "# コサイン類似度\n", - "1 - distance.cdist(my_df, my_df,\n", - " metric='cosine')\n", - "#> array([[ 1. , 0.817, -0.033],\n", - "#> [ 0.817, 1. , 0.293],\n", - "#> [-0.033, 0.293, 1. ]])\n", - "\n", - "# 相関係数\n", - "1 - distance.cdist(my_df, my_df,\n", - " metric='correlation')\n", - "#> array([[ 1. , 0.882, -0.033],\n", - "#> [ 0.882, 1. , 0.441],\n", - "#> [-0.033, 0.441, 1. ]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.6 Rのパッケージ,Pythonのモジュール\n", - "\n", - "### 3.6.1 Rのパッケージ\n", - "\n", - "### 3.6.2 Pythonのモジュール" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import math\n", - "import numpy as np\n", - "import pandas as pd" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy\n", - "numpy.array([1, 2, 3, 4])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "np.array([1, 2, 3, 4])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from numpy import array\n", - "array([1, 2, 3, 4])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from numpy import *\n", - "array([1, 2, 3, 4])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.7 反復処理" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.1 指定した回数→1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f1(x):\n", - " tmp = np.random.random(x)\n", - " return np.mean(tmp)\n", - "\n", - "f1(10) # 動作確認\n", - "#> 0.5427033207230424 # 結果の例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "[f1(10) for i in range(3)]\n", - "#> [0.4864425069985622,\n", - "#> 0.4290935578857099,\n", - "#> 0.535206509631883]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "[f1(10)] * 3\n", - "#> [0.43725641184595576,\n", - "#> 0.43725641184595576,\n", - "#> 0.43725641184595576]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.2 1次元データ→1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v = [5, 10, 100]\n", - "[f1(x) for x in v] # 方法1\n", - "#> [0.454, 0.419, 0.552]\n", - "\n", - "# あるいは\n", - "\n", - "v = pd.Series([5, 10, 100])\n", - "v.apply(f1) # 方法2\n", - "#> 0 0.394206\n", - "#> 1 0.503949\n", - "#> 2 0.532698\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.Series([10] * 3).apply(f1)\n", - "# 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.3 1次元データ→データフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f2(n):\n", - " tmp = np.random.random(n)\n", - " return pd.Series([\n", - " n,\n", - " tmp.mean(),\n", - " tmp.std(ddof=1)],\n", - " index=['x', 'p', 'q'])\n", - "\n", - "f2(10) # 動作確認\n", - "#> x 10.000000\n", - "#> p 0.405898 (平均の例)\n", - "#> q 0.317374 (標準偏差の例)\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v = pd.Series([5, 10, 100])\n", - "v.apply(f2)\n", - "#> x p q\n", - "#> 0 5.0 0.507798 0.207970\n", - "#> 1 10.0 0.687198 0.264427\n", - "#> 2 100.0 0.487872 0.280743" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.4 データフレーム→データフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f3(x, y):\n", - " tmp = np.random.random(x) * y\n", - " return pd.Series([\n", - " x,\n", - " y,\n", - " tmp.mean(),\n", - " tmp.std(ddof=1)],\n", - " index=['x', 'y', 'p', 'q'])\n", - "\n", - "f3(10, 6) # 動作確認\n", - "#> x 10.000000\n", - "#> y 6.000000\n", - "#> p 2.136413 (平均の例)\n", - "#> q 1.798755 (標準偏差の例)\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame({\n", - " 'x': [5, 10, 100, 5, 10, 100],\n", - " 'y': [6, 6, 6, 12, 12, 12]})\n", - "\n", - "my_df.apply(\n", - " lambda row: f3(row['x'], row['y']),\n", - " axis=1)\n", - "# あるいは\n", - "my_df.apply(lambda row:\n", - " f3(*row), axis=1)\n", - "\n", - "#> x y p q\n", - "#> 0 5.00 6.00 3.37 1.96\n", - "#> 1 10.00 6.00 1.92 0.95\n", - "#> 2 100.00 6.00 2.90 1.73\n", - "#> 3 5.00 12.00 6.82 3.00\n", - "#> 4 10.00 12.00 7.05 2.42\n", - "#> 5 100.00 12.00 5.90 3.54" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.5 補足:反復処理の並列化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from pandarallel import pandarallel\n", - "pandarallel.initialize() # 準備\n", - "\n", - "v = pd.Series([5, 10, 100])\n", - "v.parallel_apply(f1)\n", - "# 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.8 その他\n", - "\n", - "### 3.8.1 よく遭遇するエラーとその対処方法\n", - "\n", - "### 3.8.2 変数や関数についての調査" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = 123\n", - "type(x)\n", - "#> int" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%whos\n", - "#> Variable Type Data/Info\n", - "#> ------------------------------\n", - "#> x int 123" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import math\n", - "?math.log\n", - "# あるいは\n", - "help(math.log)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.8.3 RのNA,Pythonのnan" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "v = [1, np.nan, 3]\n", - "v\n", - "#> [1, nan, 3]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.isnan(v[1])\n", - "#> True\n", - "\n", - "v[1] == np.nan # 誤り\n", - "#> False" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch03/03.01.ipynb b/code/Python-notebook/ch03/03.01.ipynb deleted file mode 100644 index 31b9847..0000000 --- a/code/Python-notebook/ch03/03.01.ipynb +++ /dev/null @@ -1,265 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.1 入門\n", - "\n", - "### 3.1.1 数値" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "0x10\n", - "#> 16" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1.23e5\n", - "#> 123000.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "2 * 3\n", - "#> 6" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "10 / 3\n", - "#> 3.3333333333333335" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "10 // 3 # 商\n", - "#> 3\n", - "\n", - "10 % 3 # 余り\n", - "#> 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.2 変数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = 2\n", - "y = 3\n", - "x * y\n", - "#> 6\n", - "\n", - "x, y = 20, 30 # まとめて名付け\n", - "x * y\n", - "#> 600" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = 1 + 1\n", - "# この段階では結果は表示されない\n", - "\n", - "x # 変数名を評価する.\n", - "#> 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.3 文字列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_s = 'abcde'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "len(my_s)\n", - "#> 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "'This is' ' a' ' pen.'\n", - "# あるいは\n", - "'This is ' + 'a' + ' pen.'\n", - "#> 'This is a pen.'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_s[1:4]\n", - "#> 'bcd'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = \"{} is {}.\"\n", - "tmp.format('This', 'a pen')\n", - "#> 'This is a pen.'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.4 論理値" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1 <= 2\n", - "#> True\n", - "\n", - "1 < 0\n", - "#> False" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "0.1 + 0.1 + 0.1 == 0.3\n", - "#> False\n", - "\n", - "import math\n", - "math.isclose(0.1 + 0.1 + 0.1, 0.3)\n", - "#> True" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "True and False # 論理積(かつ)\n", - "#> False\n", - "\n", - "True or False # 論理和(または)\n", - "#> True\n", - "\n", - "not True # 否定(でない)\n", - "#> False" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.1.4.1 条件演算子" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "0 if 3 < 5 else 10\n", - "#> 0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.5 作業ディレクトリ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "os.getcwd()\n", - "#> '/home/jovyan/work'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "os.chdir('..')\n", - "os.getcwd()\n", - "#> '/home/jovyan'" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch03/03.02.ipynb b/code/Python-notebook/ch03/03.02.ipynb deleted file mode 100644 index 9acc39c..0000000 --- a/code/Python-notebook/ch03/03.02.ipynb +++ /dev/null @@ -1,134 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.2 関数\n", - "\n", - "### 3.2.1 関数の利用" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import math\n", - "math.sqrt(4)\n", - "#> 2.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "math.log(100, 10)\n", - "#> 2.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "math.log(100) # 自然対数\n", - "# あるいは\n", - "math.log(100, math.e) # 省略しない場合\n", - "\n", - "#> 4.605170185988092" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "math.log10(100) # 常用対数\n", - "#> 2.0\n", - "\n", - "math.log2(1024) # 底が2の対数\n", - "#> 10.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.1.1 パイプ(Rのみ)\n", - "\n", - "### 3.2.2 関数の定義" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f(a, b):\n", - " return a - b" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f(3, 5)\n", - "#> -2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.2.1 デフォルト引数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f(a, b=5):\n", - " return a - b\n", - "\n", - "f(3) # f(3, 5)と同じこと\n", - "#> -2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.2.2 無名関数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(lambda a, b: a - b)(3, 5)\n", - "#> -2" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch03/03.03.ipynb b/code/Python-notebook/ch03/03.03.ipynb deleted file mode 100644 index 1f2a7da..0000000 --- a/code/Python-notebook/ch03/03.03.ipynb +++ /dev/null @@ -1,379 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.3 コレクション\n", - "\n", - "### 3.3.1 1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = ['foo', 'bar', 'baz']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "len(x)\n", - "#> 3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[1]\n", - "#> 'bar'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[1] = 'BAR'\n", - "x # 結果の確認\n", - "#> ['foo', 'BAR', 'baz']\n", - "\n", - "x[1] = 'bar' # 元に戻す." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[-2]\n", - "#> 'bar'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x + ['qux']\n", - "#> ['foo', 'bar', 'baz', 'qux']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = x + ['qux']\n", - "# あるいは\n", - "#x.append('qux')\n", - "\n", - "x # 結果の確認\n", - "#> ['foo', 'bar', 'baz', 'qux']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.1.1 等間隔の数値からなる1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "list(range(5))\n", - "#> [0, 1, 2, 3, 4]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "list(range(0, 11, 2))\n", - "#> [0, 2, 4, 6, 8, 10]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "np.arange(0, 1.1, 0.5)\n", - "#> array([0. , 0.5, 1. ])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.linspace(0, 100, 5)\n", - "#> array([ 0., 25., 50., 75., 100.])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "[10] * 5\n", - "#> [10, 10, 10, 10, 10]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.1.2 ファクタ(Rのみ)\n", - "\n", - "### 3.3.2 数値計算やデータ解析用の1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "x = np.array([2, 3, 5, 7])\n", - "\n", - "x + 10 # 加算\n", - "#> array([12, 13, 15, 17])\n", - "\n", - "x * 10 # 乗算\n", - "#> array([20, 30, 50, 70])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = [2, 3]\n", - "np.sin(x)\n", - "#> array([0.90929743, 0.14112001])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.array([2, 3, 5, 7])\n", - "y = np.array([1, 10, 100, 1000])\n", - "x + y\n", - "#> array([ 3, 13, 105, 1007])\n", - "\n", - "x * y\n", - "#> array([ 2, 30, 500, 7000])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.dot(x, y)\n", - "# あるいは\n", - "x @ y\n", - "\n", - "#> 7532" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.array([True, False])\n", - "y = np.array([True, True])\n", - "x & y\n", - "#> array([ True, False])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.2.1 1次元データ同士の比較" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "u = np.array([1, 2, 3])\n", - "v = np.array([1, 2, 3])\n", - "w = np.array([1, 2, 4])\n", - "\n", - "all(u == v) # 全体の比較\n", - "#> True\n", - "\n", - "all(u == w) # 全体の比較\n", - "#> False\n", - "\n", - "u == v # 要素ごとの比較\n", - "#> array([ True, True, True])\n", - "\n", - "u == w # 要素ごとの比較\n", - "#> array([ True, True, False])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(u == w).sum() # 同じ要素の数\n", - "#> 2\n", - "\n", - "(u == w).mean() # 同じ要素の割合\n", - "#> [1] 0.6666667" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.3 複数種類のデータをひとまとめにする" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = [1, \"two\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[1]\n", - "#> 'two'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.4 文字列と値のペアのコレクション" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = {'apple' : 'りんご',\n", - " 'orange': 'みかん'}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x['grape'] = 'ぶどう'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x['apple']\n", - "# あるいは\n", - "tmp = 'apple'\n", - "x[tmp]\n", - "\n", - "#> 'りんご'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.5 補足:コピーと参照" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = ['foo', 'bar', 'baz']\n", - "y = x\n", - "y[1] = 'BAR' # yを更新する.\n", - "y\n", - "#> ['foo', 'BAR', 'baz']\n", - "\n", - "x # xも変わる.\n", - "#> ['foo', 'BAR', 'baz']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = ['foo', 'bar', 'baz']\n", - "y = x.copy() # 「y = x」とせずに,コピーする.\n", - "x == y, x is y\n", - "#> (True, False) # xとyは,等価(内容は同じ)だが同一ではない.\n", - "\n", - "y[1] = 'BAR' # yを更新しても,\n", - "x\n", - "#> ['foo', 'bar', 'baz'] # xは変化しない." - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch03/03.04.ipynb b/code/Python-notebook/ch03/03.04.ipynb deleted file mode 100644 index 6515e71..0000000 --- a/code/Python-notebook/ch03/03.04.ipynb +++ /dev/null @@ -1,626 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.4 データフレーム\n", - "\n", - "### 3.4.1 データフレームの作成" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.1 データを列ごとに記述する方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame({\n", - " 'name': ['A', 'B', 'C', 'D'],\n", - " 'english': [ 60, 90, 70, 90],\n", - " 'math': [ 70, 80, 90, 100],\n", - " 'gender': ['f', 'm', 'm', 'f']})" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.2 データを見た目のとおりに記述する方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame([\n", - " ['A', 60, 70, 'f'],\n", - " ['B', 90, 80, 'm'],\n", - " ['C', 70, 90, 'm'],\n", - " ['D', 90, 100, 'f']],\n", - " columns=['name', 'english',\n", - " 'math', 'gender'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.head()\n", - "# 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.3 データフレームのサイズ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "r, c = my_df.shape # 行数と列数\n", - "r, c\n", - "#> (4, 4)\n", - "\n", - "r # 行数(len(my_df)も可)\n", - "#> 4\n", - "\n", - "c # 列数\n", - "#> 4" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.4 組合せ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from itertools import product\n", - "my_df2 = pd.DataFrame(\n", - " product([1, 2, 3],\n", - " [10, 100]),\n", - " columns=['X', 'Y'])\n", - "my_df2\n", - "#> X Y\n", - "#> 0 1 10\n", - "#> 1 1 100\n", - "#> 2 2 10\n", - "#> 3 2 100\n", - "#> 4 3 10\n", - "#> 5 3 100" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.5 列と行の名前" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2.columns\n", - "#> Index(['X', 'Y'], dtype='object')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2.columns = ['P', 'Q']\n", - "my_df2\n", - "#> P Q\n", - "#> 0 1 10\n", - "#> 1 1 100\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "list(my_df.index)\n", - "#> [0, 1, 2, 3]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2.index = [\n", - " 'a', 'b', 'c', 'd', 'e', 'f']\n", - "my_df2\n", - "#> P Q\n", - "#> a 1 10\n", - "#> b 1 100\n", - "#> c 2 10\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df3 = pd.DataFrame({\n", - " 'english': [ 60, 90, 70, 90],\n", - " 'math': [ 70, 80, 90, 100],\n", - " 'gender': ['f', 'm', 'm', 'f']},\n", - " index= ['A', 'B', 'C', 'D'])\n", - "my_df3\n", - "#> english math gender\n", - "#> A 60 70 f\n", - "#> B 90 80 m\n", - "#> C 70 90 m\n", - "#> D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.2 データの追加\n", - "\n", - "#### 3.4.2.1 行の追加(データフレームの結合)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = pd.DataFrame({\n", - " 'name' : ['E'],\n", - " 'english': [80],\n", - " 'math' : [80],\n", - " 'gender' : ['m']})\n", - "my_df2 = my_df.append(tmp)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.2.2 列の追加" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 = my_df.assign(id=[1, 2, 3, 4])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df3 = my_df.copy() # コピー\n", - "my_df3['id'] = [1, 2, 3, 4] # 更新\n", - "my_df3 # 結果の確認(割愛)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.3 データの取り出し\n", - "\n", - "#### 3.4.3.1 観測値の取り出し" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.iloc[0, 1]\n", - "#> 60" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.2 1列の取り出し(結果は1次元データ)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.iloc[:, 1]\n", - "# あるいは\n", - "x = my_df['english']\n", - "# あるいは\n", - "x = my_df.english\n", - "# あるいは\n", - "tmp = 'english'\n", - "x = my_df[tmp]\n", - "\n", - "x # 結果の確認(割愛)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.3 複数列の取り出し(結果はデータフレーム)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df[['name', 'math']]\n", - "# あるいは\n", - "x = my_df.loc[:, ['name', 'math']]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.take([0, 2], axis=1)\n", - "# あるいは\n", - "x = my_df.iloc[:, [0, 2]]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.drop(\n", - " columns=['english', 'gender'])\n", - "# あるいは\n", - "x = my_df.drop(\n", - " columns=my_df.columns[[1, 3]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.4 複数行の取り出し(結果はデータフレーム)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.take([0, 2])\n", - "# あるいは\n", - "x = my_df.iloc[[0, 2], :]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.drop([1, 3])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.5 検索" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df[my_df['gender'] == 'm']\n", - "# あるいは\n", - "x = my_df.query('gender == \"m\"')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df[(my_df['english'] > 80) & (my_df['gender'] == \"m\")]\n", - "# あるいは\n", - "x = my_df.query('english > 80 and gender == \"m\"')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df[my_df['english'] == my_df['english'].max()]\n", - "# あるいは\n", - "tmp = my_df['english'].max()\n", - "x = my_df.query('english == @tmp')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 = my_df.copy() # コピー\n", - "my_df2.loc[my_df['gender'] == 'm', 'gender'] = 'M'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2\n", - "#> name english math gender\n", - "#> 0 A 60 70 f\n", - "#> 1 B 90 80 M\n", - "#> 2 C 70 90 M\n", - "#> 3 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.6 並べ替え" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.sort_values('english')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.sort_values('english',\n", - " ascending=False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.4 補足:行列\n", - "\n", - "#### 3.4.4.1 行列の生成" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "x = [2, 3, 5, 7, 11, 13, 17, 19, 23,\n", - " 29, 31, 37]\n", - "A = np.array(x).reshape(3, 4)\n", - "A\n", - "#> array([[ 2, 3, 5, 7],\n", - "#> [11, 13, 17, 19],\n", - "#> [23, 29, 31, 37]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.2 データフレームと行列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A = my_df.iloc[:, [1, 2]].values\n", - "A\n", - "#> array([[ 60, 70],\n", - "#> [ 90, 80],\n", - "#> [ 70, 90],\n", - "#> [ 90, 100]])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.DataFrame(A)\n", - "#> 0 1\n", - "#> 0 60 70\n", - "#> 1 90 80\n", - "#> 2 70 90\n", - "#> 3 90 100" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.3 行列の変形" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A.T\n", - "#> array([[ 60, 90, 70, 90],\n", - "#> [ 70, 80, 90, 100]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.4 行列の積" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A.T @ A\n", - "#> array([[24700, 26700],\n", - "#> [26700, 29400]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.5 縦型と横型" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame({\n", - " 'day': [25, 26, 27],\n", - " 'min': [20, 21, 15],\n", - " 'max': [24, 27, 21]})" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_longer = my_df.melt(id_vars='day')\n", - "my_longer\n", - "#> day variable value\n", - "#> 0 25 min 20\n", - "#> 1 26 min 21\n", - "#> 2 27 min 15\n", - "#> 3 25 max 24\n", - "#> 4 26 max 27\n", - "#> 5 27 max 21" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_wider = my_longer.pivot(\n", - " index='day',\n", - " columns='variable',\n", - " values='value')\n", - "my_wider\n", - "#> variable max min\n", - "#> day\n", - "#> 25 24 20\n", - "#> 26 27 21\n", - "#> 27 21 15" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_wider.plot(\n", - " style='o-',\n", - " xticks=my_wider.index, # x軸目盛り\n", - " ylabel='temperature') # y軸ラベル" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch03/03.05.ipynb b/code/Python-notebook/ch03/03.05.ipynb deleted file mode 100644 index 364dc9c..0000000 --- a/code/Python-notebook/ch03/03.05.ipynb +++ /dev/null @@ -1,158 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.5 1次元データの(非)類似度\n", - "\n", - "### 3.5.1 ユークリッド距離" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from scipy.spatial import distance\n", - "from scipy.stats import pearsonr\n", - "\n", - "A = np.array([3, 4, 5])\n", - "B = np.array([3, 4, 29])\n", - "C = np.array([9, -18, 8])\n", - "\n", - "distance.euclidean(A, B)\n", - "#> 24.0\n", - "\n", - "distance.euclidean(A, C)\n", - "#> 23.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.2 マンハッタン距離" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "distance.cityblock(A, B)\n", - "#> 24\n", - "\n", - "distance.cityblock(A, C)\n", - "#> 31" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.3 コサイン類似度" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1 - distance.cosine(A, B)\n", - "#> 0.8169678632647616\n", - "\n", - "1 - distance.cosine(A, C)\n", - "#> -0.032651157422416865" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.4 相関係数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1 - distance.correlation(A, B)\n", - "# あるいは\n", - "pearsonr(A, B)[0]\n", - "#> 0.8824975032927698\n", - "\n", - "1 - distance.correlation(A, C)\n", - "# あるいは\n", - "pearsonr(A, C)[0]\n", - "#> -0.032662766723200676" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.5.4.1 データフレームを使う方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 小数点以下は3桁表示\n", - "np.set_printoptions(precision=3)\n", - "import pandas as pd\n", - "\n", - "my_df = pd.DataFrame({\n", - " 'x': [3, 3, 9],\n", - " 'y': [4, 4, -18],\n", - " 'z': [5, 29, 8]},\n", - " index=['A', 'B', 'C'])\n", - "\n", - "# ユークリッド距離\n", - "distance.cdist(my_df, my_df,\n", - " metric='euclidean')\n", - "#> array([[ 0., 24., 23.],\n", - "#> [24., 0., 31.],\n", - "#> [23., 31., 0.]])\n", - "\n", - "# マンハッタン距離\n", - "distance.cdist(my_df, my_df,\n", - " metric='cityblock')\n", - "#> array([[ 0., 24., 31.],\n", - "#> [24., 0., 49.],\n", - "#> [31., 49., 0.]])\n", - "\n", - "# コサイン類似度\n", - "1 - distance.cdist(my_df, my_df,\n", - " metric='cosine')\n", - "#> array([[ 1. , 0.817, -0.033],\n", - "#> [ 0.817, 1. , 0.293],\n", - "#> [-0.033, 0.293, 1. ]])\n", - "\n", - "# 相関係数\n", - "1 - distance.cdist(my_df, my_df,\n", - " metric='correlation')\n", - "#> array([[ 1. , 0.882, -0.033],\n", - "#> [ 0.882, 1. , 0.441],\n", - "#> [-0.033, 0.441, 1. ]])" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch03/03.06.ipynb b/code/Python-notebook/ch03/03.06.ipynb deleted file mode 100644 index 90223e3..0000000 --- a/code/Python-notebook/ch03/03.06.ipynb +++ /dev/null @@ -1,74 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.6 Rのパッケージ,Pythonのモジュール\n", - "\n", - "### 3.6.1 Rのパッケージ\n", - "\n", - "### 3.6.2 Pythonのモジュール" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import math\n", - "import numpy as np\n", - "import pandas as pd" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy\n", - "numpy.array([1, 2, 3, 4])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "np.array([1, 2, 3, 4])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from numpy import array\n", - "array([1, 2, 3, 4])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from numpy import *\n", - "array([1, 2, 3, 4])" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch03/03.07.ipynb b/code/Python-notebook/ch03/03.07.ipynb deleted file mode 100644 index de9b00b..0000000 --- a/code/Python-notebook/ch03/03.07.ipynb +++ /dev/null @@ -1,230 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.7 反復処理" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.1 指定した回数→1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f1(x):\n", - " tmp = np.random.random(x)\n", - " return np.mean(tmp)\n", - "\n", - "f1(10) # 動作確認\n", - "#> 0.5427033207230424 # 結果の例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "[f1(10) for i in range(3)]\n", - "#> [0.4864425069985622,\n", - "#> 0.4290935578857099,\n", - "#> 0.535206509631883]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "[f1(10)] * 3\n", - "#> [0.43725641184595576,\n", - "#> 0.43725641184595576,\n", - "#> 0.43725641184595576]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.2 1次元データ→1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v = [5, 10, 100]\n", - "[f1(x) for x in v] # 方法1\n", - "#> [0.454, 0.419, 0.552]\n", - "\n", - "# あるいは\n", - "\n", - "v = pd.Series([5, 10, 100])\n", - "v.apply(f1) # 方法2\n", - "#> 0 0.394206\n", - "#> 1 0.503949\n", - "#> 2 0.532698\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.Series([10] * 3).apply(f1)\n", - "# 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.3 1次元データ→データフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f2(n):\n", - " tmp = np.random.random(n)\n", - " return pd.Series([\n", - " n,\n", - " tmp.mean(),\n", - " tmp.std(ddof=1)],\n", - " index=['x', 'p', 'q'])\n", - "\n", - "f2(10) # 動作確認\n", - "#> x 10.000000\n", - "#> p 0.405898 (平均の例)\n", - "#> q 0.317374 (標準偏差の例)\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v = pd.Series([5, 10, 100])\n", - "v.apply(f2)\n", - "#> x p q\n", - "#> 0 5.0 0.507798 0.207970\n", - "#> 1 10.0 0.687198 0.264427\n", - "#> 2 100.0 0.487872 0.280743" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.4 データフレーム→データフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f3(x, y):\n", - " tmp = np.random.random(x) * y\n", - " return pd.Series([\n", - " x,\n", - " y,\n", - " tmp.mean(),\n", - " tmp.std(ddof=1)],\n", - " index=['x', 'y', 'p', 'q'])\n", - "\n", - "f3(10, 6) # 動作確認\n", - "#> x 10.000000\n", - "#> y 6.000000\n", - "#> p 2.136413 (平均の例)\n", - "#> q 1.798755 (標準偏差の例)\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame({\n", - " 'x': [5, 10, 100, 5, 10, 100],\n", - " 'y': [6, 6, 6, 12, 12, 12]})\n", - "\n", - "my_df.apply(\n", - " lambda row: f3(row['x'], row['y']),\n", - " axis=1)\n", - "# あるいは\n", - "my_df.apply(lambda row:\n", - " f3(*row), axis=1)\n", - "\n", - "#> x y p q\n", - "#> 0 5.00 6.00 3.37 1.96\n", - "#> 1 10.00 6.00 1.92 0.95\n", - "#> 2 100.00 6.00 2.90 1.73\n", - "#> 3 5.00 12.00 6.82 3.00\n", - "#> 4 10.00 12.00 7.05 2.42\n", - "#> 5 100.00 12.00 5.90 3.54" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.5 補足:反復処理の並列化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from pandarallel import pandarallel\n", - "pandarallel.initialize() # 準備\n", - "\n", - "v = pd.Series([5, 10, 100])\n", - "v.parallel_apply(f1)\n", - "# 結果は割愛" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch03/03.08.ipynb b/code/Python-notebook/ch03/03.08.ipynb deleted file mode 100644 index 6f5593e..0000000 --- a/code/Python-notebook/ch03/03.08.ipynb +++ /dev/null @@ -1,90 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.8 その他\n", - "\n", - "### 3.8.1 よく遭遇するエラーとその対処方法\n", - "\n", - "### 3.8.2 変数や関数についての調査" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = 123\n", - "type(x)\n", - "#> int" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%whos\n", - "#> Variable Type Data/Info\n", - "#> ------------------------------\n", - "#> x int 123" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import math\n", - "?math.log\n", - "# あるいは\n", - "help(math.log)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.8.3 RのNA,Pythonのnan" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "v = [1, np.nan, 3]\n", - "v\n", - "#> [1, nan, 3]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.isnan(v[1])\n", - "#> True\n", - "\n", - "v[1] == np.nan # 誤り\n", - "#> False" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch03/03.ipynb b/code/Python-notebook/ch03/03.ipynb deleted file mode 100644 index 65c9a6d..0000000 --- a/code/Python-notebook/ch03/03.ipynb +++ /dev/null @@ -1,1874 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 03\n", - "\n", - "## 3.1 入門\n", - "\n", - "### 3.1.1 数値" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "0x10\n", - "#> 16" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1.23e5\n", - "#> 123000.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "2 * 3\n", - "#> 6" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "10 / 3\n", - "#> 3.3333333333333335" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "10 // 3 # 商\n", - "#> 3\n", - "\n", - "10 % 3 # 余り\n", - "#> 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.2 変数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = 2\n", - "y = 3\n", - "x * y\n", - "#> 6\n", - "\n", - "x, y = 20, 30 # まとめて名付け\n", - "x * y\n", - "#> 600" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = 1 + 1\n", - "# この段階では結果は表示されない\n", - "\n", - "x # 変数名を評価する.\n", - "#> 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.3 文字列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_s = 'abcde'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "len(my_s)\n", - "#> 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "'This is' ' a' ' pen.'\n", - "# あるいは\n", - "'This is ' + 'a' + ' pen.'\n", - "#> 'This is a pen.'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_s[1:4]\n", - "#> 'bcd'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = \"{} is {}.\"\n", - "tmp.format('This', 'a pen')\n", - "#> 'This is a pen.'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.4 論理値" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1 <= 2\n", - "#> True\n", - "\n", - "1 < 0\n", - "#> False" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "0.1 + 0.1 + 0.1 == 0.3\n", - "#> False\n", - "\n", - "import math\n", - "math.isclose(0.1 + 0.1 + 0.1, 0.3)\n", - "#> True" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "True and False # 論理積(かつ)\n", - "#> False\n", - "\n", - "True or False # 論理和(または)\n", - "#> True\n", - "\n", - "not True # 否定(でない)\n", - "#> False" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.1.4.1 条件演算子" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "0 if 3 < 5 else 10\n", - "#> 0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.5 作業ディレクトリ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "os.getcwd()\n", - "#> '/home/jovyan/work'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "os.chdir('..')\n", - "os.getcwd()\n", - "#> '/home/jovyan'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.2 関数\n", - "\n", - "### 3.2.1 関数の利用" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import math\n", - "math.sqrt(4)\n", - "#> 2.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "math.log(100, 10)\n", - "#> 2.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "math.log(100) # 自然対数\n", - "# あるいは\n", - "math.log(100, math.e) # 省略しない場合\n", - "\n", - "#> 4.605170185988092" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "math.log10(100) # 常用対数\n", - "#> 2.0\n", - "\n", - "math.log2(1024) # 底が2の対数\n", - "#> 10.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.1.1 パイプ(Rのみ)\n", - "\n", - "### 3.2.2 関数の定義" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f(a, b):\n", - " return a - b" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f(3, 5)\n", - "#> -2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.2.1 デフォルト引数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f(a, b=5):\n", - " return a - b\n", - "\n", - "f(3) # f(3, 5)と同じこと\n", - "#> -2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.2.2 無名関数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(lambda a, b: a - b)(3, 5)\n", - "#> -2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.3 コレクション\n", - "\n", - "### 3.3.1 1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = ['foo', 'bar', 'baz']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "len(x)\n", - "#> 3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[1]\n", - "#> 'bar'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[1] = 'BAR'\n", - "x # 結果の確認\n", - "#> ['foo', 'BAR', 'baz']\n", - "\n", - "x[1] = 'bar' # 元に戻す." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[-2]\n", - "#> 'bar'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x + ['qux']\n", - "#> ['foo', 'bar', 'baz', 'qux']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = x + ['qux']\n", - "# あるいは\n", - "#x.append('qux')\n", - "\n", - "x # 結果の確認\n", - "#> ['foo', 'bar', 'baz', 'qux']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.1.1 等間隔の数値からなる1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "list(range(5))\n", - "#> [0, 1, 2, 3, 4]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "list(range(0, 11, 2))\n", - "#> [0, 2, 4, 6, 8, 10]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "np.arange(0, 1.1, 0.5)\n", - "#> array([0. , 0.5, 1. ])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.linspace(0, 100, 5)\n", - "#> array([ 0., 25., 50., 75., 100.])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "[10] * 5\n", - "#> [10, 10, 10, 10, 10]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.1.2 ファクタ(Rのみ)\n", - "\n", - "### 3.3.2 数値計算やデータ解析用の1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "x = np.array([2, 3, 5, 7])\n", - "\n", - "x + 10 # 加算\n", - "#> array([12, 13, 15, 17])\n", - "\n", - "x * 10 # 乗算\n", - "#> array([20, 30, 50, 70])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = [2, 3]\n", - "np.sin(x)\n", - "#> array([0.90929743, 0.14112001])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.array([2, 3, 5, 7])\n", - "y = np.array([1, 10, 100, 1000])\n", - "x + y\n", - "#> array([ 3, 13, 105, 1007])\n", - "\n", - "x * y\n", - "#> array([ 2, 30, 500, 7000])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.dot(x, y)\n", - "# あるいは\n", - "x @ y\n", - "\n", - "#> 7532" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.array([True, False])\n", - "y = np.array([True, True])\n", - "x & y\n", - "#> array([ True, False])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.2.1 1次元データ同士の比較" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "u = np.array([1, 2, 3])\n", - "v = np.array([1, 2, 3])\n", - "w = np.array([1, 2, 4])\n", - "\n", - "all(u == v) # 全体の比較\n", - "#> True\n", - "\n", - "all(u == w) # 全体の比較\n", - "#> False\n", - "\n", - "u == v # 要素ごとの比較\n", - "#> array([ True, True, True])\n", - "\n", - "u == w # 要素ごとの比較\n", - "#> array([ True, True, False])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(u == w).sum() # 同じ要素の数\n", - "#> 2\n", - "\n", - "(u == w).mean() # 同じ要素の割合\n", - "#> [1] 0.6666667" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.3 複数種類のデータをひとまとめにする" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = [1, \"two\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[1]\n", - "#> 'two'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.4 文字列と値のペアのコレクション" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = {'apple' : 'りんご',\n", - " 'orange': 'みかん'}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x['grape'] = 'ぶどう'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x['apple']\n", - "# あるいは\n", - "tmp = 'apple'\n", - "x[tmp]\n", - "\n", - "#> 'りんご'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.5 補足:コピーと参照" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = ['foo', 'bar', 'baz']\n", - "y = x\n", - "y[1] = 'BAR' # yを更新する.\n", - "y\n", - "#> ['foo', 'BAR', 'baz']\n", - "\n", - "x # xも変わる.\n", - "#> ['foo', 'BAR', 'baz']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = ['foo', 'bar', 'baz']\n", - "y = x.copy() # 「y = x」とせずに,コピーする.\n", - "x == y, x is y\n", - "#> (True, False) # xとyは,等価(内容は同じ)だが同一ではない.\n", - "\n", - "y[1] = 'BAR' # yを更新しても,\n", - "x\n", - "#> ['foo', 'bar', 'baz'] # xは変化しない." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.4 データフレーム\n", - "\n", - "### 3.4.1 データフレームの作成" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.1 データを列ごとに記述する方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame({\n", - " 'name': ['A', 'B', 'C', 'D'],\n", - " 'english': [ 60, 90, 70, 90],\n", - " 'math': [ 70, 80, 90, 100],\n", - " 'gender': ['f', 'm', 'm', 'f']})" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.2 データを見た目のとおりに記述する方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame([\n", - " ['A', 60, 70, 'f'],\n", - " ['B', 90, 80, 'm'],\n", - " ['C', 70, 90, 'm'],\n", - " ['D', 90, 100, 'f']],\n", - " columns=['name', 'english',\n", - " 'math', 'gender'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.head()\n", - "# 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.3 データフレームのサイズ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "r, c = my_df.shape # 行数と列数\n", - "r, c\n", - "#> (4, 4)\n", - "\n", - "r # 行数(len(my_df)も可)\n", - "#> 4\n", - "\n", - "c # 列数\n", - "#> 4" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.4 組合せ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from itertools import product\n", - "my_df2 = pd.DataFrame(\n", - " product([1, 2, 3],\n", - " [10, 100]),\n", - " columns=['X', 'Y'])\n", - "my_df2\n", - "#> X Y\n", - "#> 0 1 10\n", - "#> 1 1 100\n", - "#> 2 2 10\n", - "#> 3 2 100\n", - "#> 4 3 10\n", - "#> 5 3 100" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.5 列と行の名前" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2.columns\n", - "#> Index(['X', 'Y'], dtype='object')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2.columns = ['P', 'Q']\n", - "my_df2\n", - "#> P Q\n", - "#> 0 1 10\n", - "#> 1 1 100\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "list(my_df.index)\n", - "#> [0, 1, 2, 3]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2.index = [\n", - " 'a', 'b', 'c', 'd', 'e', 'f']\n", - "my_df2\n", - "#> P Q\n", - "#> a 1 10\n", - "#> b 1 100\n", - "#> c 2 10\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df3 = pd.DataFrame({\n", - " 'english': [ 60, 90, 70, 90],\n", - " 'math': [ 70, 80, 90, 100],\n", - " 'gender': ['f', 'm', 'm', 'f']},\n", - " index= ['A', 'B', 'C', 'D'])\n", - "my_df3\n", - "#> english math gender\n", - "#> A 60 70 f\n", - "#> B 90 80 m\n", - "#> C 70 90 m\n", - "#> D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.2 データの追加\n", - "\n", - "#### 3.4.2.1 行の追加(データフレームの結合)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = pd.DataFrame({\n", - " 'name' : ['E'],\n", - " 'english': [80],\n", - " 'math' : [80],\n", - " 'gender' : ['m']})\n", - "my_df2 = my_df.append(tmp)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.2.2 列の追加" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 = my_df.assign(id=[1, 2, 3, 4])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df3 = my_df.copy() # コピー\n", - "my_df3['id'] = [1, 2, 3, 4] # 更新\n", - "my_df3 # 結果の確認(割愛)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.3 データの取り出し\n", - "\n", - "#### 3.4.3.1 観測値の取り出し" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.iloc[0, 1]\n", - "#> 60" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.2 1列の取り出し(結果は1次元データ)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.iloc[:, 1]\n", - "# あるいは\n", - "x = my_df['english']\n", - "# あるいは\n", - "x = my_df.english\n", - "# あるいは\n", - "tmp = 'english'\n", - "x = my_df[tmp]\n", - "\n", - "x # 結果の確認(割愛)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.3 複数列の取り出し(結果はデータフレーム)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df[['name', 'math']]\n", - "# あるいは\n", - "x = my_df.loc[:, ['name', 'math']]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.take([0, 2], axis=1)\n", - "# あるいは\n", - "x = my_df.iloc[:, [0, 2]]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.drop(\n", - " columns=['english', 'gender'])\n", - "# あるいは\n", - "x = my_df.drop(\n", - " columns=my_df.columns[[1, 3]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.4 複数行の取り出し(結果はデータフレーム)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.take([0, 2])\n", - "# あるいは\n", - "x = my_df.iloc[[0, 2], :]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.drop([1, 3])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.5 検索" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df[my_df['gender'] == 'm']\n", - "# あるいは\n", - "x = my_df.query('gender == \"m\"')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df[(my_df['english'] > 80) & (my_df['gender'] == \"m\")]\n", - "# あるいは\n", - "x = my_df.query('english > 80 and gender == \"m\"')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df[my_df['english'] == my_df['english'].max()]\n", - "# あるいは\n", - "tmp = my_df['english'].max()\n", - "x = my_df.query('english == @tmp')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 = my_df.copy() # コピー\n", - "my_df2.loc[my_df['gender'] == 'm', 'gender'] = 'M'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2\n", - "#> name english math gender\n", - "#> 0 A 60 70 f\n", - "#> 1 B 90 80 M\n", - "#> 2 C 70 90 M\n", - "#> 3 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.6 並べ替え" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.sort_values('english')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = my_df.sort_values('english',\n", - " ascending=False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.4 補足:行列\n", - "\n", - "#### 3.4.4.1 行列の生成" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "x = [2, 3, 5, 7, 11, 13, 17, 19, 23,\n", - " 29, 31, 37]\n", - "A = np.array(x).reshape(3, 4)\n", - "A\n", - "#> array([[ 2, 3, 5, 7],\n", - "#> [11, 13, 17, 19],\n", - "#> [23, 29, 31, 37]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.2 データフレームと行列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A = my_df.iloc[:, [1, 2]].values\n", - "A\n", - "#> array([[ 60, 70],\n", - "#> [ 90, 80],\n", - "#> [ 70, 90],\n", - "#> [ 90, 100]])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.DataFrame(A)\n", - "#> 0 1\n", - "#> 0 60 70\n", - "#> 1 90 80\n", - "#> 2 70 90\n", - "#> 3 90 100" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.3 行列の変形" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A.T\n", - "#> array([[ 60, 90, 70, 90],\n", - "#> [ 70, 80, 90, 100]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.4 行列の積" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A.T @ A\n", - "#> array([[24700, 26700],\n", - "#> [26700, 29400]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.5 縦型と横型" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame({\n", - " 'day': [25, 26, 27],\n", - " 'min': [20, 21, 15],\n", - " 'max': [24, 27, 21]})" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_longer = my_df.melt(id_vars='day')\n", - "my_longer\n", - "#> day variable value\n", - "#> 0 25 min 20\n", - "#> 1 26 min 21\n", - "#> 2 27 min 15\n", - "#> 3 25 max 24\n", - "#> 4 26 max 27\n", - "#> 5 27 max 21" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_wider = my_longer.pivot(\n", - " index='day',\n", - " columns='variable',\n", - " values='value')\n", - "my_wider\n", - "#> variable max min\n", - "#> day\n", - "#> 25 24 20\n", - "#> 26 27 21\n", - "#> 27 21 15" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_wider.plot(\n", - " style='o-',\n", - " xticks=my_wider.index, # x軸目盛り\n", - " ylabel='temperature') # y軸ラベル" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.5 1次元データの(非)類似度\n", - "\n", - "### 3.5.1 ユークリッド距離" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from scipy.spatial import distance\n", - "from scipy.stats import pearsonr\n", - "\n", - "A = np.array([3, 4, 5])\n", - "B = np.array([3, 4, 29])\n", - "C = np.array([9, -18, 8])\n", - "\n", - "distance.euclidean(A, B)\n", - "#> 24.0\n", - "\n", - "distance.euclidean(A, C)\n", - "#> 23.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.2 マンハッタン距離" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "distance.cityblock(A, B)\n", - "#> 24\n", - "\n", - "distance.cityblock(A, C)\n", - "#> 31" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.3 コサイン類似度" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1 - distance.cosine(A, B)\n", - "#> 0.8169678632647616\n", - "\n", - "1 - distance.cosine(A, C)\n", - "#> -0.032651157422416865" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.4 相関係数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1 - distance.correlation(A, B)\n", - "# あるいは\n", - "pearsonr(A, B)[0]\n", - "#> 0.8824975032927698\n", - "\n", - "1 - distance.correlation(A, C)\n", - "# あるいは\n", - "pearsonr(A, C)[0]\n", - "#> -0.032662766723200676" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.5.4.1 データフレームを使う方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 小数点以下は3桁表示\n", - "np.set_printoptions(precision=3)\n", - "import pandas as pd\n", - "\n", - "my_df = pd.DataFrame({\n", - " 'x': [3, 3, 9],\n", - " 'y': [4, 4, -18],\n", - " 'z': [5, 29, 8]},\n", - " index=['A', 'B', 'C'])\n", - "\n", - "# ユークリッド距離\n", - "distance.cdist(my_df, my_df,\n", - " metric='euclidean')\n", - "#> array([[ 0., 24., 23.],\n", - "#> [24., 0., 31.],\n", - "#> [23., 31., 0.]])\n", - "\n", - "# マンハッタン距離\n", - "distance.cdist(my_df, my_df,\n", - " metric='cityblock')\n", - "#> array([[ 0., 24., 31.],\n", - "#> [24., 0., 49.],\n", - "#> [31., 49., 0.]])\n", - "\n", - "# コサイン類似度\n", - "1 - distance.cdist(my_df, my_df,\n", - " metric='cosine')\n", - "#> array([[ 1. , 0.817, -0.033],\n", - "#> [ 0.817, 1. , 0.293],\n", - "#> [-0.033, 0.293, 1. ]])\n", - "\n", - "# 相関係数\n", - "1 - distance.cdist(my_df, my_df,\n", - " metric='correlation')\n", - "#> array([[ 1. , 0.882, -0.033],\n", - "#> [ 0.882, 1. , 0.441],\n", - "#> [-0.033, 0.441, 1. ]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.6 Rのパッケージ,Pythonのモジュール\n", - "\n", - "### 3.6.1 Rのパッケージ\n", - "\n", - "### 3.6.2 Pythonのモジュール" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import math\n", - "import numpy as np\n", - "import pandas as pd" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy\n", - "numpy.array([1, 2, 3, 4])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "np.array([1, 2, 3, 4])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from numpy import array\n", - "array([1, 2, 3, 4])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from numpy import *\n", - "array([1, 2, 3, 4])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.7 反復処理" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.1 指定した回数→1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f1(x):\n", - " tmp = np.random.random(x)\n", - " return np.mean(tmp)\n", - "\n", - "f1(10) # 動作確認\n", - "#> 0.5427033207230424 # 結果の例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "[f1(10) for i in range(3)]\n", - "#> [0.4864425069985622,\n", - "#> 0.4290935578857099,\n", - "#> 0.535206509631883]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "[f1(10)] * 3\n", - "#> [0.43725641184595576,\n", - "#> 0.43725641184595576,\n", - "#> 0.43725641184595576]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.2 1次元データ→1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v = [5, 10, 100]\n", - "[f1(x) for x in v] # 方法1\n", - "#> [0.454, 0.419, 0.552]\n", - "\n", - "# あるいは\n", - "\n", - "v = pd.Series([5, 10, 100])\n", - "v.apply(f1) # 方法2\n", - "#> 0 0.394206\n", - "#> 1 0.503949\n", - "#> 2 0.532698\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.Series([10] * 3).apply(f1)\n", - "# 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.3 1次元データ→データフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f2(n):\n", - " tmp = np.random.random(n)\n", - " return pd.Series([\n", - " n,\n", - " tmp.mean(),\n", - " tmp.std(ddof=1)],\n", - " index=['x', 'p', 'q'])\n", - "\n", - "f2(10) # 動作確認\n", - "#> x 10.000000\n", - "#> p 0.405898 (平均の例)\n", - "#> q 0.317374 (標準偏差の例)\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v = pd.Series([5, 10, 100])\n", - "v.apply(f2)\n", - "#> x p q\n", - "#> 0 5.0 0.507798 0.207970\n", - "#> 1 10.0 0.687198 0.264427\n", - "#> 2 100.0 0.487872 0.280743" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.4 データフレーム→データフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f3(x, y):\n", - " tmp = np.random.random(x) * y\n", - " return pd.Series([\n", - " x,\n", - " y,\n", - " tmp.mean(),\n", - " tmp.std(ddof=1)],\n", - " index=['x', 'y', 'p', 'q'])\n", - "\n", - "f3(10, 6) # 動作確認\n", - "#> x 10.000000\n", - "#> y 6.000000\n", - "#> p 2.136413 (平均の例)\n", - "#> q 1.798755 (標準偏差の例)\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame({\n", - " 'x': [5, 10, 100, 5, 10, 100],\n", - " 'y': [6, 6, 6, 12, 12, 12]})\n", - "\n", - "my_df.apply(\n", - " lambda row: f3(row['x'], row['y']),\n", - " axis=1)\n", - "# あるいは\n", - "my_df.apply(lambda row:\n", - " f3(*row), axis=1)\n", - "\n", - "#> x y p q\n", - "#> 0 5.00 6.00 3.37 1.96\n", - "#> 1 10.00 6.00 1.92 0.95\n", - "#> 2 100.00 6.00 2.90 1.73\n", - "#> 3 5.00 12.00 6.82 3.00\n", - "#> 4 10.00 12.00 7.05 2.42\n", - "#> 5 100.00 12.00 5.90 3.54" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.5 補足:反復処理の並列化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from pandarallel import pandarallel\n", - "pandarallel.initialize() # 準備\n", - "\n", - "v = pd.Series([5, 10, 100])\n", - "v.parallel_apply(f1)\n", - "# 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.8 その他\n", - "\n", - "### 3.8.1 よく遭遇するエラーとその対処方法\n", - "\n", - "### 3.8.2 変数や関数についての調査" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = 123\n", - "type(x)\n", - "#> int" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%whos\n", - "#> Variable Type Data/Info\n", - "#> ------------------------------\n", - "#> x int 123" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import math\n", - "?math.log\n", - "# あるいは\n", - "help(math.log)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.8.3 RのNA,Pythonのnan" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "v = [1, np.nan, 3]\n", - "v\n", - "#> [1, nan, 3]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.isnan(v[1])\n", - "#> True\n", - "\n", - "v[1] == np.nan # 誤り\n", - "#> False" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch04/04-colab.ipynb b/code/Python-notebook/ch04/04-colab.ipynb deleted file mode 100644 index 8a97df9..0000000 --- a/code/Python-notebook/ch04/04-colab.ipynb +++ /dev/null @@ -1,1022 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 04\n", - "\n", - "## 4.1 記述統計\n", - "\n", - "### 4.1.1 平均・分散・標準偏差" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "\n", - "x = [165, 170, 175, 180, 185]\n", - "np.mean(x) # リストの場合\n", - "#> 175.0\n", - "\n", - "x = np.array( # アレイ\n", - " [165, 170, 175, 180, 185])\n", - "x.mean() # np.mean(x)も可\n", - "#> 175.0\n", - "\n", - "x = pd.Series( # シリーズ\n", - " [165, 170, 175, 180, 185])\n", - "x.mean() # np.mean(x)も可\n", - "#> 175.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n = len(x) # サンプルサイズ\n", - "sum(x) / n\n", - "#> 175.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y = [173, 174, 175, 176, 177]\n", - "np.mean(y)\n", - "#> 175.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.var(x, ddof=1) # xの分散\n", - "#> 62.5\n", - "\n", - "np.var(y, ddof=1) # yの分散\n", - "#> 2.5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum((x - np.mean(x))**2) / (n - 1)\n", - "#> 62.5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.std(x, ddof=1) # xの標準偏差\n", - "#> 7.905694150420948\n", - "\n", - "np.std(y, ddof=1) # yの標準偏差\n", - "#> 1.5811388300841898" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.var(x, ddof=1)**0.5 # xの標準偏差\n", - "#> 7.905694150420948" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s = pd.Series(x)\n", - "s.describe()\n", - "#> count 5.000000 (データ数)\n", - "#> mean 175.000000 (平均)\n", - "#> std 7.905694 (標準偏差)\n", - "#> min 165.000000 (最小値)\n", - "#> 25% 170.000000 (第1四分位数)\n", - "#> 50% 175.000000 (中央値)\n", - "#> 75% 180.000000 (第3四分位数)\n", - "#> max 185.000000 (最大値)\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# s.describe()で計算済み" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.1.1 不偏分散とその非負の平方根" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = [165, 170, 175, 180, 185]\n", - "\n", - "np.var(x, ddof=1) # 不偏分散\n", - "#> 62.5\n", - "\n", - "np.var(x, ddof=0) # 標本分散\n", - "#> 50.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.std(x, ddof=1) # √不偏分散\n", - "#> 7.905694150420949\n", - "\n", - "np.std(x, ddof=0) # √標本分散\n", - "#> 7.0710678118654755" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.std(x, ddof=1) / len(x)**0.5\n", - "#> 3.5355339059327373" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.1.2 データフレームの統計処理" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "\n", - "my_df = pd.DataFrame({\n", - " 'name': ['A', 'B', 'C', 'D'],\n", - " 'english': [ 60, 90, 70, 90],\n", - " 'math': [ 70, 80, 90, 100],\n", - " 'gender': ['f', 'm', 'm', 'f']})" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.2.1 列ごとの集計" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df['english'].var(ddof=1)\n", - "# あるいは\n", - "np.var(my_df['english'], ddof=1)\n", - "\n", - "#> 225.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.var()\n", - "# あるいは\n", - "my_df.apply('var')\n", - "# あるいは\n", - "my_df.iloc[:, [1, 2]].apply(\n", - " lambda x: np.var(x, ddof=1))\n", - "\n", - "#> english 225.000000\n", - "#> math 166.666667\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.describe()\n", - "#> english math\n", - "#> count 4.0 4.000000\n", - "#> mean 77.5 85.000000\n", - "#> std 15.0 12.909944\n", - "#> min 60.0 70.000000\n", - "#> 25% 67.5 77.500000\n", - "#> 50% 80.0 85.000000\n", - "#> 75% 90.0 92.500000\n", - "#> max 90.0 100.000000" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.2.2 分割表とグループごとの集計" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from collections import Counter\n", - "Counter(my_df.gender)\n", - "#> Counter({'f': 2, 'm': 2})\n", - "\n", - "# あるいは\n", - "\n", - "my_df.groupby('gender').apply(len)\n", - "#> gender\n", - "#> f 2\n", - "#> m 2\n", - "#> dtype: int64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 = my_df.assign(\n", - " excel=my_df.math >= 80)\n", - "pd.crosstab(my_df2.gender,\n", - " my_df2.excel)\n", - "#> excel False True\n", - "#> gender\n", - "#> f 1 1\n", - "#> m 0 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.groupby('gender').mean()\n", - "# あるいは\n", - "my_df.groupby('gender').agg('mean')\n", - "# あるいは\n", - "my_df.groupby('gender').agg(np.mean)\n", - "\n", - "#> english math\n", - "#> gender\n", - "#> f 75.0 85.0\n", - "#> m 80.0 85.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.2 データの可視化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "iris = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "iris.head()\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 0 5.1 3.5 1.4 0.2 setosa\n", - "#> 1 4.9 3.0 1.4 0.2 setosa\n", - "#> 2 4.7 3.2 1.3 0.2 setosa\n", - "#> 3 4.6 3.1 1.5 0.2 setosa\n", - "#> 4 5.0 3.6 1.4 0.2 setosa" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.1 ヒストグラム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris.hist('Sepal.Length')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame(\n", - " {'x': [10, 20, 30]})\n", - "my_df.hist('x', bins=2) # 階級数は2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = iris['Sepal.Length']\n", - "tmp = np.linspace(min(x), max(x), 10)\n", - "iris.hist('Sepal.Length',\n", - " bins=tmp.round(2))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.2 散布図" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris.plot('Sepal.Length',\n", - " 'Sepal.Width',\n", - " kind='scatter')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.3 箱ひげ図" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris.boxplot()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.4 棒グラフとエラーバー" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.options.display.float_format = (\n", - " '{:.2f}'.format)\n", - "my_df = (iris.describe().transpose()\n", - " [['mean', 'std']])\n", - "my_df['se'] = (my_df['std'] /\n", - " len(iris)**0.5)\n", - "my_df\n", - "#> mean std se\n", - "#> Sepal.Length 5.84 0.83 0.07\n", - "#> Sepal.Width 3.06 0.44 0.04\n", - "#> Petal.Length 3.76 1.77 0.14\n", - "#> Petal.Width 1.20 0.76 0.06" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.plot(y='mean', kind='bar', yerr='se', capsize=10)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_group = iris.groupby('Species') # 品種ごとに,\n", - "my_df = my_group.agg('mean') # 各変数の,平均と\n", - "my_se = my_group.agg(lambda x: x.std() / len(x)**0.5) # 標準誤差を求める.\n", - "my_se\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width\n", - "#> Species\n", - "#> setosa 0.05 0.05 0.02 0.01\n", - "#> versicolor 0.07 0.04 0.07 0.03\n", - "#> virginica 0.09 0.05 0.08 0.04" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_group.agg('mean').plot(kind='bar', yerr=my_se, capsize=5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.5 モザイクプロット" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from statsmodels.graphics.mosaicplot \\\n", - " import mosaic\n", - "\n", - "my_df = pd.DataFrame({\n", - " 'Species': iris.Species,\n", - " 'w_Sepal': iris['Sepal.Width'] > 3})\n", - "\n", - "my_table = pd.crosstab( # 分割表\n", - " my_df['Species'],\n", - " my_df['w_Sepal'])\n", - "my_table\n", - "#> w_Sepal False True\n", - "#> Species\n", - "#> setosa 8 42\n", - "#> versicolor 42 8\n", - "#> virginica 33 17\n", - "\n", - "mosaic(my_df,\n", - " index=['Species', 'w_Sepal'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_table.columns = [str(x) for x in my_table.columns]\n", - "my_table.index = [str(x) for x in my_table.index]\n", - "mosaic(my_df, index=['Species', 'w_Sepal'], labelizer=lambda k: my_table.loc[k])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.6 関数のグラフ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "\n", - "x = np.linspace(-2, 2, 100)\n", - "y = x**3 - x\n", - "plt.plot(x, y)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.7 ggplot2 (R)\n", - "\n", - "## 4.3 乱数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "rng = np.random.default_rng()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.1 一様乱数(離散)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.random.choice(\n", - " a=range(1, 7), # 1から6\n", - " size=10000, # 乱数の数\n", - " replace=True) # 重複あり\n", - "# あるいは\n", - "x = np.random.randint(\n", - "# あるいは\n", - "#x = rng.integers(\n", - " low=1, # 最小\n", - " high=7, # 最大+1\n", - " size=10000) # 乱数の数\n", - "\n", - "plt.hist(x, bins=6) # ヒストグラム" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.2 一様乱数(連続)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.random.random(size=1000)\n", - "# あるいは\n", - "x = rng.random(size=10000)\n", - "# あるいは\n", - "x = np.random.uniform(\n", - " low=0, # 最小\n", - " high=1, # 最大\n", - " size=1000) # 乱数の数\n", - "plt.hist(x)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = np.random.uniform(\n", - " low=1, # 最小\n", - " high=7, # 最大 + 1\n", - " size=1000) # 乱数の数\n", - "x = [int(k) for k in tmp]\n", - "plt.hist(x, bins=6) # 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.3 二項乱数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n = 100\n", - "p = 0.5\n", - "r = 10000\n", - "x = np.random.binomial(\n", - "# あるいは\n", - "#x = rng.binomial(\n", - " n=n, # 試行回数\n", - " p=p, # 確率\n", - " size=r) # 乱数の数\n", - "plt.hist(x, bins=max(x) - min(x))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.4 正規乱数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "r = 10000\n", - "x = np.random.normal(\n", - "# あるいは\n", - "#x = rng.normal(\n", - " loc=50, # 平均\n", - " scale=5, # 標準偏差\n", - " size=r) # 乱数の数\n", - "plt.hist(x, bins=40)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.3.4.1 補足:不偏性の具体例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "\n", - "def f(k):\n", - " n = 10000\n", - " tmp = [g(np.random.normal(size=k, scale=3)) for _ in range(n)]\n", - " return pd.Series([k,\n", - " np.mean(tmp), # 平均\n", - " np.std(tmp, ddof=1) / n**0.5], # 標準誤差\n", - " index=['k', 'mean', 'se'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def g(x):\n", - " return np.var(x, ddof=1)\n", - "pd.Series([10, 20, 30]).apply(f)\n", - "#> k mean se\n", - "#> 0 10.0 9.025140 0.042690\n", - "#> 1 20.0 9.022280 0.029525\n", - "#> 2 30.0 8.983166 0.023584" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def g(x):\n", - " return np.std(x, ddof=1)\n", - "pd.Series([10, 20, 30]).apply(f)\n", - "#> k mean se\n", - "#> 0 10.0 2.923114 0.006983\n", - "#> 1 20.0 2.961450 0.004811\n", - "#> 2 30.0 2.968328 0.003977" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from math import gamma\n", - "\n", - "def g(x):\n", - " n = len(x)\n", - " return (np.std(x, ddof=1) *\n", - " (np.sqrt((n - 1) / 2) *\n", - " gamma((n - 1) / 2) /\n", - " gamma(n / 2)))\n", - "pd.Series([10, 20, 30]).apply(f)\n", - "#> k mean se\n", - "#> 0 10.0 3.005788 0.007121\n", - "#> 1 20.0 3.001857 0.004894\n", - "#> 2 30.0 2.995965 0.003925" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.4 統計的推測\n", - "\n", - "### 4.4.1 検定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from statsmodels.stats.proportion import binom_test, proportion_confint\n", - "\n", - "binom_test(count=2, # 当たった回数\n", - " nobs=15, # くじを引いた回数\n", - " prop=4 / 10, # 当たる確率(仮説)\n", - " alternative='two-sided') # 両側検定(デフォルト)\n", - " # 左片側検定なら'smaller'\n", - " # 右片側検定なら'larger'\n", - "#> 0.03646166155263999" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.4.1.1 補足:p値とは何か" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "from scipy import stats\n", - "\n", - "t = 4 / 10 # 当たる確率\n", - "n = 15 # くじを引いた回数\n", - "x = np.array(range(0, n + 1)) # 当たった回数\n", - "my_pr = stats.binom.pmf(x, n, t) # x回当たる確率\n", - "my_pr2 = stats.binom.pmf(2, n, t) # 2回当たる確率\n", - "\n", - "my_data = pd.DataFrame({'x': x, 'y1': my_pr, 'y2': my_pr})\n", - "my_data.loc[my_pr > my_pr2, 'y1'] = np.nan # 当たる確率が,2回当たる確率超過\n", - "my_data.loc[my_pr <= my_pr2, 'y2'] = np.nan # 当たる確率が,2回当たる確率以下\n", - "ax = my_data.plot(x='x', style='o', ylabel='probability',\n", - " legend=False) # 凡例を表示しない.\n", - "ax.hlines(y=my_pr2, xmin=0, xmax=15) # 水平線\n", - "ax.vlines(x=x, ymin=0, ymax=my_pr) # 垂直線" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.2 推定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "a = 0.05\n", - "proportion_confint(\n", - " count=2, # 当たった回数\n", - " nobs=15, # くじを引いた回数\n", - " alpha=a, # 有意水準(省略可)\n", - " method='binom_test')\n", - "#> (0.024225732468536626,\n", - "#> 0.3967139842509865)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "a = 0.05 # 有意水準\n", - "tmp = np.linspace(0, 1, 100)\n", - "\n", - "my_df = pd.DataFrame({\n", - " 't': tmp, # 当たる確率\n", - " 'q': a, # 水平線\n", - " 'p': [binom_test(count=2, nobs=15, prop=t) for t in tmp]}) # p値\n", - "\n", - "my_df.plot(x='t', legend=None, xlabel=r'$\\theta$', ylabel=r'p-value')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.3 平均の差の検定と推定(t検定)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from statsmodels.stats.weightstats import CompareMeans, DescrStatsW\n", - "\n", - "X = [32.1, 26.2, 27.5, 31.8, 32.1, 31.2, 30.1, 32.4, 32.3, 29.9,\n", - " 29.6, 26.6, 31.2, 30.9, 29.3]\n", - "Y = [35.4, 34.6, 31.1, 32.4, 33.3, 34.7, 35.3, 34.3, 32.1, 28.3,\n", - " 33.3, 30.5, 32.6, 33.3, 32.2]\n", - "\n", - "a = 0.05 # 有意水準(デフォルト) = 1 - 信頼係数\n", - "alt = 'two-sided' # 両側検定(デフォルト)\n", - " # 左片側検定なら'smaller'\n", - " # 右片側検定なら'larger'\n", - "\n", - "d = DescrStatsW(np.array(X) - np.array(Y)) # 対標本の場合\n", - "d.ttest_mean(alternative=alt)[1] # p値\n", - "#> 0.0006415571512322235\n", - "\n", - "d.tconfint_mean(alpha=a, alternative=alt) # 信頼区間\n", - "#> (-3.9955246743198867, -1.3644753256801117)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c = CompareMeans(DescrStatsW(X), DescrStatsW(Y)) # 対標本でない場合\n", - "\n", - "ve = 'pooled' # 等分散を仮定する(デフォルト).仮定しないなら'unequal'.\n", - "c.ttest_ind(alternative=alt, usevar=ve)[1] # p値\n", - "#> 0.000978530937238609\n", - "\n", - "c.tconfint_diff(alpha=a, alternative=alt, usevar=ve) # 信頼区間\n", - "#> (-4.170905570517185, -1.1890944294828283)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.4 独立性の検定(カイ2乗検定)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/smoker.csv')\n", - "my_data = pd.read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.head()\n", - "#> alive smoker\n", - "#> 0 Yes No\n", - "#> 1 Yes No\n", - "#> 2 Yes No\n", - "#> 3 Yes No\n", - "#> 4 Yes No" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_table = pd.crosstab(\n", - " my_data['alive'],\n", - " my_data['smoker'])\n", - "my_table\n", - "#> smoker No Yes\n", - "#> alive\n", - "#> No 117 54\n", - "#> Yes 950 348" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from scipy.stats import chi2_contingency\n", - "chi2_contingency(my_table, correction=False)[1]\n", - "#> 0.18860725715300422" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.5 ブートストラップ\n", - "\n", - "#### 4.4.5.1 15回引いて2回当たったくじ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X = [0] * 13 + [1] * 2 # 手順1\n", - "X\n", - "#> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]\n", - "\n", - "tmp = np.random.choice(X, 15, replace=True) # 手順2\n", - "tmp\n", - "#> array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0])\n", - "\n", - "sum(tmp) # 手順3\n", - "#> 2\n", - "\n", - "n = 10**5\n", - "result = [sum(np.random.choice(X, len(X), replace=True)) for _ in range(n)] # 手順4" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "plt.hist(result, bins=range(0, 16))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.quantile(result, [0.025, 0.975])\n", - "#> array([0., 5.])" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch04/04.01.ipynb b/code/Python-notebook/ch04/04.01.ipynb deleted file mode 100644 index bfee7c2..0000000 --- a/code/Python-notebook/ch04/04.01.ipynb +++ /dev/null @@ -1,325 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.1 記述統計\n", - "\n", - "### 4.1.1 平均・分散・標準偏差" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "\n", - "x = [165, 170, 175, 180, 185]\n", - "np.mean(x) # リストの場合\n", - "#> 175.0\n", - "\n", - "x = np.array( # アレイ\n", - " [165, 170, 175, 180, 185])\n", - "x.mean() # np.mean(x)も可\n", - "#> 175.0\n", - "\n", - "x = pd.Series( # シリーズ\n", - " [165, 170, 175, 180, 185])\n", - "x.mean() # np.mean(x)も可\n", - "#> 175.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n = len(x) # サンプルサイズ\n", - "sum(x) / n\n", - "#> 175.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y = [173, 174, 175, 176, 177]\n", - "np.mean(y)\n", - "#> 175.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.var(x, ddof=1) # xの分散\n", - "#> 62.5\n", - "\n", - "np.var(y, ddof=1) # yの分散\n", - "#> 2.5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum((x - np.mean(x))**2) / (n - 1)\n", - "#> 62.5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.std(x, ddof=1) # xの標準偏差\n", - "#> 7.905694150420948\n", - "\n", - "np.std(y, ddof=1) # yの標準偏差\n", - "#> 1.5811388300841898" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.var(x, ddof=1)**0.5 # xの標準偏差\n", - "#> 7.905694150420948" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s = pd.Series(x)\n", - "s.describe()\n", - "#> count 5.000000 (データ数)\n", - "#> mean 175.000000 (平均)\n", - "#> std 7.905694 (標準偏差)\n", - "#> min 165.000000 (最小値)\n", - "#> 25% 170.000000 (第1四分位数)\n", - "#> 50% 175.000000 (中央値)\n", - "#> 75% 180.000000 (第3四分位数)\n", - "#> max 185.000000 (最大値)\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# s.describe()で計算済み" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.1.1 不偏分散とその非負の平方根" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = [165, 170, 175, 180, 185]\n", - "\n", - "np.var(x, ddof=1) # 不偏分散\n", - "#> 62.5\n", - "\n", - "np.var(x, ddof=0) # 標本分散\n", - "#> 50.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.std(x, ddof=1) # √不偏分散\n", - "#> 7.905694150420949\n", - "\n", - "np.std(x, ddof=0) # √標本分散\n", - "#> 7.0710678118654755" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.std(x, ddof=1) / len(x)**0.5\n", - "#> 3.5355339059327373" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.1.2 データフレームの統計処理" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "\n", - "my_df = pd.DataFrame({\n", - " 'name': ['A', 'B', 'C', 'D'],\n", - " 'english': [ 60, 90, 70, 90],\n", - " 'math': [ 70, 80, 90, 100],\n", - " 'gender': ['f', 'm', 'm', 'f']})" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.2.1 列ごとの集計" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df['english'].var(ddof=1)\n", - "# あるいは\n", - "np.var(my_df['english'], ddof=1)\n", - "\n", - "#> 225.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.var()\n", - "# あるいは\n", - "my_df.apply('var')\n", - "# あるいは\n", - "my_df.iloc[:, [1, 2]].apply(\n", - " lambda x: np.var(x, ddof=1))\n", - "\n", - "#> english 225.000000\n", - "#> math 166.666667\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.describe()\n", - "#> english math\n", - "#> count 4.0 4.000000\n", - "#> mean 77.5 85.000000\n", - "#> std 15.0 12.909944\n", - "#> min 60.0 70.000000\n", - "#> 25% 67.5 77.500000\n", - "#> 50% 80.0 85.000000\n", - "#> 75% 90.0 92.500000\n", - "#> max 90.0 100.000000" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.2.2 分割表とグループごとの集計" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from collections import Counter\n", - "Counter(my_df.gender)\n", - "#> Counter({'f': 2, 'm': 2})\n", - "\n", - "# あるいは\n", - "\n", - "my_df.groupby('gender').apply(len)\n", - "#> gender\n", - "#> f 2\n", - "#> m 2\n", - "#> dtype: int64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 = my_df.assign(\n", - " excel=my_df.math >= 80)\n", - "pd.crosstab(my_df2.gender,\n", - " my_df2.excel)\n", - "#> excel False True\n", - "#> gender\n", - "#> f 1 1\n", - "#> m 0 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.groupby('gender').mean()\n", - "# あるいは\n", - "my_df.groupby('gender').agg('mean')\n", - "# あるいは\n", - "my_df.groupby('gender').agg(np.mean)\n", - "\n", - "#> english math\n", - "#> gender\n", - "#> f 75.0 85.0\n", - "#> m 80.0 85.0" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch04/04.02.ipynb b/code/Python-notebook/ch04/04.02.ipynb deleted file mode 100644 index 4cc9a12..0000000 --- a/code/Python-notebook/ch04/04.02.ipynb +++ /dev/null @@ -1,246 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.2 データの可視化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "iris = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "iris.head()\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 0 5.1 3.5 1.4 0.2 setosa\n", - "#> 1 4.9 3.0 1.4 0.2 setosa\n", - "#> 2 4.7 3.2 1.3 0.2 setosa\n", - "#> 3 4.6 3.1 1.5 0.2 setosa\n", - "#> 4 5.0 3.6 1.4 0.2 setosa" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.1 ヒストグラム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris.hist('Sepal.Length')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame(\n", - " {'x': [10, 20, 30]})\n", - "my_df.hist('x', bins=2) # 階級数は2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = iris['Sepal.Length']\n", - "tmp = np.linspace(min(x), max(x), 10)\n", - "iris.hist('Sepal.Length',\n", - " bins=tmp.round(2))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.2 散布図" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris.plot('Sepal.Length',\n", - " 'Sepal.Width',\n", - " kind='scatter')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.3 箱ひげ図" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris.boxplot()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.4 棒グラフとエラーバー" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.options.display.float_format = (\n", - " '{:.2f}'.format)\n", - "my_df = (iris.describe().transpose()\n", - " [['mean', 'std']])\n", - "my_df['se'] = (my_df['std'] /\n", - " len(iris)**0.5)\n", - "my_df\n", - "#> mean std se\n", - "#> Sepal.Length 5.84 0.83 0.07\n", - "#> Sepal.Width 3.06 0.44 0.04\n", - "#> Petal.Length 3.76 1.77 0.14\n", - "#> Petal.Width 1.20 0.76 0.06" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.plot(y='mean', kind='bar', yerr='se', capsize=10)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_group = iris.groupby('Species') # 品種ごとに,\n", - "my_df = my_group.agg('mean') # 各変数の,平均と\n", - "my_se = my_group.agg(lambda x: x.std() / len(x)**0.5) # 標準誤差を求める.\n", - "my_se\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width\n", - "#> Species\n", - "#> setosa 0.05 0.05 0.02 0.01\n", - "#> versicolor 0.07 0.04 0.07 0.03\n", - "#> virginica 0.09 0.05 0.08 0.04" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_group.agg('mean').plot(kind='bar', yerr=my_se, capsize=5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.5 モザイクプロット" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from statsmodels.graphics.mosaicplot \\\n", - " import mosaic\n", - "\n", - "my_df = pd.DataFrame({\n", - " 'Species': iris.Species,\n", - " 'w_Sepal': iris['Sepal.Width'] > 3})\n", - "\n", - "my_table = pd.crosstab( # 分割表\n", - " my_df['Species'],\n", - " my_df['w_Sepal'])\n", - "my_table\n", - "#> w_Sepal False True\n", - "#> Species\n", - "#> setosa 8 42\n", - "#> versicolor 42 8\n", - "#> virginica 33 17\n", - "\n", - "mosaic(my_df,\n", - " index=['Species', 'w_Sepal'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_table.columns = [str(x) for x in my_table.columns]\n", - "my_table.index = [str(x) for x in my_table.index]\n", - "mosaic(my_df, index=['Species', 'w_Sepal'], labelizer=lambda k: my_table.loc[k])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.6 関数のグラフ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "\n", - "x = np.linspace(-2, 2, 100)\n", - "y = x**3 - x\n", - "plt.plot(x, y)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.7 ggplot2 (R)" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch04/04.03.ipynb b/code/Python-notebook/ch04/04.03.ipynb deleted file mode 100644 index a2a1c75..0000000 --- a/code/Python-notebook/ch04/04.03.ipynb +++ /dev/null @@ -1,220 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.3 乱数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "rng = np.random.default_rng()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.1 一様乱数(離散)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.random.choice(\n", - " a=range(1, 7), # 1から6\n", - " size=10000, # 乱数の数\n", - " replace=True) # 重複あり\n", - "# あるいは\n", - "x = np.random.randint(\n", - "# あるいは\n", - "#x = rng.integers(\n", - " low=1, # 最小\n", - " high=7, # 最大+1\n", - " size=10000) # 乱数の数\n", - "\n", - "plt.hist(x, bins=6) # ヒストグラム" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.2 一様乱数(連続)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.random.random(size=1000)\n", - "# あるいは\n", - "x = rng.random(size=10000)\n", - "# あるいは\n", - "x = np.random.uniform(\n", - " low=0, # 最小\n", - " high=1, # 最大\n", - " size=1000) # 乱数の数\n", - "plt.hist(x)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = np.random.uniform(\n", - " low=1, # 最小\n", - " high=7, # 最大 + 1\n", - " size=1000) # 乱数の数\n", - "x = [int(k) for k in tmp]\n", - "plt.hist(x, bins=6) # 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.3 二項乱数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n = 100\n", - "p = 0.5\n", - "r = 10000\n", - "x = np.random.binomial(\n", - "# あるいは\n", - "#x = rng.binomial(\n", - " n=n, # 試行回数\n", - " p=p, # 確率\n", - " size=r) # 乱数の数\n", - "plt.hist(x, bins=max(x) - min(x))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.4 正規乱数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "r = 10000\n", - "x = np.random.normal(\n", - "# あるいは\n", - "#x = rng.normal(\n", - " loc=50, # 平均\n", - " scale=5, # 標準偏差\n", - " size=r) # 乱数の数\n", - "plt.hist(x, bins=40)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.3.4.1 補足:不偏性の具体例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "\n", - "def f(k):\n", - " n = 10000\n", - " tmp = [g(np.random.normal(size=k, scale=3)) for _ in range(n)]\n", - " return pd.Series([k,\n", - " np.mean(tmp), # 平均\n", - " np.std(tmp, ddof=1) / n**0.5], # 標準誤差\n", - " index=['k', 'mean', 'se'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def g(x):\n", - " return np.var(x, ddof=1)\n", - "pd.Series([10, 20, 30]).apply(f)\n", - "#> k mean se\n", - "#> 0 10.0 9.025140 0.042690\n", - "#> 1 20.0 9.022280 0.029525\n", - "#> 2 30.0 8.983166 0.023584" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def g(x):\n", - " return np.std(x, ddof=1)\n", - "pd.Series([10, 20, 30]).apply(f)\n", - "#> k mean se\n", - "#> 0 10.0 2.923114 0.006983\n", - "#> 1 20.0 2.961450 0.004811\n", - "#> 2 30.0 2.968328 0.003977" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from math import gamma\n", - "\n", - "def g(x):\n", - " n = len(x)\n", - " return (np.std(x, ddof=1) *\n", - " (np.sqrt((n - 1) / 2) *\n", - " gamma((n - 1) / 2) /\n", - " gamma(n / 2)))\n", - "pd.Series([10, 20, 30]).apply(f)\n", - "#> k mean se\n", - "#> 0 10.0 3.005788 0.007121\n", - "#> 1 20.0 3.001857 0.004894\n", - "#> 2 30.0 2.995965 0.003925" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch04/04.04.ipynb b/code/Python-notebook/ch04/04.04.ipynb deleted file mode 100644 index 94bc0d3..0000000 --- a/code/Python-notebook/ch04/04.04.ipynb +++ /dev/null @@ -1,270 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.4 統計的推測\n", - "\n", - "### 4.4.1 検定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from statsmodels.stats.proportion import binom_test, proportion_confint\n", - "\n", - "binom_test(count=2, # 当たった回数\n", - " nobs=15, # くじを引いた回数\n", - " prop=4 / 10, # 当たる確率(仮説)\n", - " alternative='two-sided') # 両側検定(デフォルト)\n", - " # 左片側検定なら'smaller'\n", - " # 右片側検定なら'larger'\n", - "#> 0.03646166155263999" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.4.1.1 補足:p値とは何か" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "from scipy import stats\n", - "\n", - "t = 4 / 10 # 当たる確率\n", - "n = 15 # くじを引いた回数\n", - "x = np.array(range(0, n + 1)) # 当たった回数\n", - "my_pr = stats.binom.pmf(x, n, t) # x回当たる確率\n", - "my_pr2 = stats.binom.pmf(2, n, t) # 2回当たる確率\n", - "\n", - "my_data = pd.DataFrame({'x': x, 'y1': my_pr, 'y2': my_pr})\n", - "my_data.loc[my_pr > my_pr2, 'y1'] = np.nan # 当たる確率が,2回当たる確率超過\n", - "my_data.loc[my_pr <= my_pr2, 'y2'] = np.nan # 当たる確率が,2回当たる確率以下\n", - "ax = my_data.plot(x='x', style='o', ylabel='probability',\n", - " legend=False) # 凡例を表示しない.\n", - "ax.hlines(y=my_pr2, xmin=0, xmax=15) # 水平線\n", - "ax.vlines(x=x, ymin=0, ymax=my_pr) # 垂直線" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.2 推定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "a = 0.05\n", - "proportion_confint(\n", - " count=2, # 当たった回数\n", - " nobs=15, # くじを引いた回数\n", - " alpha=a, # 有意水準(省略可)\n", - " method='binom_test')\n", - "#> (0.024225732468536626,\n", - "#> 0.3967139842509865)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "a = 0.05 # 有意水準\n", - "tmp = np.linspace(0, 1, 100)\n", - "\n", - "my_df = pd.DataFrame({\n", - " 't': tmp, # 当たる確率\n", - " 'q': a, # 水平線\n", - " 'p': [binom_test(count=2, nobs=15, prop=t) for t in tmp]}) # p値\n", - "\n", - "my_df.plot(x='t', legend=None, xlabel=r'$\\theta$', ylabel=r'p-value')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.3 平均の差の検定と推定(t検定)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from statsmodels.stats.weightstats import CompareMeans, DescrStatsW\n", - "\n", - "X = [32.1, 26.2, 27.5, 31.8, 32.1, 31.2, 30.1, 32.4, 32.3, 29.9,\n", - " 29.6, 26.6, 31.2, 30.9, 29.3]\n", - "Y = [35.4, 34.6, 31.1, 32.4, 33.3, 34.7, 35.3, 34.3, 32.1, 28.3,\n", - " 33.3, 30.5, 32.6, 33.3, 32.2]\n", - "\n", - "a = 0.05 # 有意水準(デフォルト) = 1 - 信頼係数\n", - "alt = 'two-sided' # 両側検定(デフォルト)\n", - " # 左片側検定なら'smaller'\n", - " # 右片側検定なら'larger'\n", - "\n", - "d = DescrStatsW(np.array(X) - np.array(Y)) # 対標本の場合\n", - "d.ttest_mean(alternative=alt)[1] # p値\n", - "#> 0.0006415571512322235\n", - "\n", - "d.tconfint_mean(alpha=a, alternative=alt) # 信頼区間\n", - "#> (-3.9955246743198867, -1.3644753256801117)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c = CompareMeans(DescrStatsW(X), DescrStatsW(Y)) # 対標本でない場合\n", - "\n", - "ve = 'pooled' # 等分散を仮定する(デフォルト).仮定しないなら'unequal'.\n", - "c.ttest_ind(alternative=alt, usevar=ve)[1] # p値\n", - "#> 0.000978530937238609\n", - "\n", - "c.tconfint_diff(alpha=a, alternative=alt, usevar=ve) # 信頼区間\n", - "#> (-4.170905570517185, -1.1890944294828283)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.4 独立性の検定(カイ2乗検定)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/smoker.csv')\n", - "my_data = pd.read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.head()\n", - "#> alive smoker\n", - "#> 0 Yes No\n", - "#> 1 Yes No\n", - "#> 2 Yes No\n", - "#> 3 Yes No\n", - "#> 4 Yes No" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_table = pd.crosstab(\n", - " my_data['alive'],\n", - " my_data['smoker'])\n", - "my_table\n", - "#> smoker No Yes\n", - "#> alive\n", - "#> No 117 54\n", - "#> Yes 950 348" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from scipy.stats import chi2_contingency\n", - "chi2_contingency(my_table, correction=False)[1]\n", - "#> 0.18860725715300422" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.5 ブートストラップ\n", - "\n", - "#### 4.4.5.1 15回引いて2回当たったくじ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X = [0] * 13 + [1] * 2 # 手順1\n", - "X\n", - "#> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]\n", - "\n", - "tmp = np.random.choice(X, 15, replace=True) # 手順2\n", - "tmp\n", - "#> array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0])\n", - "\n", - "sum(tmp) # 手順3\n", - "#> 2\n", - "\n", - "n = 10**5\n", - "result = [sum(np.random.choice(X, len(X), replace=True)) for _ in range(n)] # 手順4" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "plt.hist(result, bins=range(0, 16))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.quantile(result, [0.025, 0.975])\n", - "#> array([0., 5.])" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch04/04.ipynb b/code/Python-notebook/ch04/04.ipynb deleted file mode 100644 index 8a97df9..0000000 --- a/code/Python-notebook/ch04/04.ipynb +++ /dev/null @@ -1,1022 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 04\n", - "\n", - "## 4.1 記述統計\n", - "\n", - "### 4.1.1 平均・分散・標準偏差" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "\n", - "x = [165, 170, 175, 180, 185]\n", - "np.mean(x) # リストの場合\n", - "#> 175.0\n", - "\n", - "x = np.array( # アレイ\n", - " [165, 170, 175, 180, 185])\n", - "x.mean() # np.mean(x)も可\n", - "#> 175.0\n", - "\n", - "x = pd.Series( # シリーズ\n", - " [165, 170, 175, 180, 185])\n", - "x.mean() # np.mean(x)も可\n", - "#> 175.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n = len(x) # サンプルサイズ\n", - "sum(x) / n\n", - "#> 175.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y = [173, 174, 175, 176, 177]\n", - "np.mean(y)\n", - "#> 175.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.var(x, ddof=1) # xの分散\n", - "#> 62.5\n", - "\n", - "np.var(y, ddof=1) # yの分散\n", - "#> 2.5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum((x - np.mean(x))**2) / (n - 1)\n", - "#> 62.5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.std(x, ddof=1) # xの標準偏差\n", - "#> 7.905694150420948\n", - "\n", - "np.std(y, ddof=1) # yの標準偏差\n", - "#> 1.5811388300841898" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.var(x, ddof=1)**0.5 # xの標準偏差\n", - "#> 7.905694150420948" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "s = pd.Series(x)\n", - "s.describe()\n", - "#> count 5.000000 (データ数)\n", - "#> mean 175.000000 (平均)\n", - "#> std 7.905694 (標準偏差)\n", - "#> min 165.000000 (最小値)\n", - "#> 25% 170.000000 (第1四分位数)\n", - "#> 50% 175.000000 (中央値)\n", - "#> 75% 180.000000 (第3四分位数)\n", - "#> max 185.000000 (最大値)\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# s.describe()で計算済み" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.1.1 不偏分散とその非負の平方根" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = [165, 170, 175, 180, 185]\n", - "\n", - "np.var(x, ddof=1) # 不偏分散\n", - "#> 62.5\n", - "\n", - "np.var(x, ddof=0) # 標本分散\n", - "#> 50.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.std(x, ddof=1) # √不偏分散\n", - "#> 7.905694150420949\n", - "\n", - "np.std(x, ddof=0) # √標本分散\n", - "#> 7.0710678118654755" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.std(x, ddof=1) / len(x)**0.5\n", - "#> 3.5355339059327373" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.1.2 データフレームの統計処理" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "\n", - "my_df = pd.DataFrame({\n", - " 'name': ['A', 'B', 'C', 'D'],\n", - " 'english': [ 60, 90, 70, 90],\n", - " 'math': [ 70, 80, 90, 100],\n", - " 'gender': ['f', 'm', 'm', 'f']})" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.2.1 列ごとの集計" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df['english'].var(ddof=1)\n", - "# あるいは\n", - "np.var(my_df['english'], ddof=1)\n", - "\n", - "#> 225.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.var()\n", - "# あるいは\n", - "my_df.apply('var')\n", - "# あるいは\n", - "my_df.iloc[:, [1, 2]].apply(\n", - " lambda x: np.var(x, ddof=1))\n", - "\n", - "#> english 225.000000\n", - "#> math 166.666667\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.describe()\n", - "#> english math\n", - "#> count 4.0 4.000000\n", - "#> mean 77.5 85.000000\n", - "#> std 15.0 12.909944\n", - "#> min 60.0 70.000000\n", - "#> 25% 67.5 77.500000\n", - "#> 50% 80.0 85.000000\n", - "#> 75% 90.0 92.500000\n", - "#> max 90.0 100.000000" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.2.2 分割表とグループごとの集計" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from collections import Counter\n", - "Counter(my_df.gender)\n", - "#> Counter({'f': 2, 'm': 2})\n", - "\n", - "# あるいは\n", - "\n", - "my_df.groupby('gender').apply(len)\n", - "#> gender\n", - "#> f 2\n", - "#> m 2\n", - "#> dtype: int64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 = my_df.assign(\n", - " excel=my_df.math >= 80)\n", - "pd.crosstab(my_df2.gender,\n", - " my_df2.excel)\n", - "#> excel False True\n", - "#> gender\n", - "#> f 1 1\n", - "#> m 0 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.groupby('gender').mean()\n", - "# あるいは\n", - "my_df.groupby('gender').agg('mean')\n", - "# あるいは\n", - "my_df.groupby('gender').agg(np.mean)\n", - "\n", - "#> english math\n", - "#> gender\n", - "#> f 75.0 85.0\n", - "#> m 80.0 85.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.2 データの可視化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "iris = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "iris.head()\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 0 5.1 3.5 1.4 0.2 setosa\n", - "#> 1 4.9 3.0 1.4 0.2 setosa\n", - "#> 2 4.7 3.2 1.3 0.2 setosa\n", - "#> 3 4.6 3.1 1.5 0.2 setosa\n", - "#> 4 5.0 3.6 1.4 0.2 setosa" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.1 ヒストグラム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris.hist('Sepal.Length')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame(\n", - " {'x': [10, 20, 30]})\n", - "my_df.hist('x', bins=2) # 階級数は2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = iris['Sepal.Length']\n", - "tmp = np.linspace(min(x), max(x), 10)\n", - "iris.hist('Sepal.Length',\n", - " bins=tmp.round(2))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.2 散布図" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris.plot('Sepal.Length',\n", - " 'Sepal.Width',\n", - " kind='scatter')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.3 箱ひげ図" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris.boxplot()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.4 棒グラフとエラーバー" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.options.display.float_format = (\n", - " '{:.2f}'.format)\n", - "my_df = (iris.describe().transpose()\n", - " [['mean', 'std']])\n", - "my_df['se'] = (my_df['std'] /\n", - " len(iris)**0.5)\n", - "my_df\n", - "#> mean std se\n", - "#> Sepal.Length 5.84 0.83 0.07\n", - "#> Sepal.Width 3.06 0.44 0.04\n", - "#> Petal.Length 3.76 1.77 0.14\n", - "#> Petal.Width 1.20 0.76 0.06" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.plot(y='mean', kind='bar', yerr='se', capsize=10)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_group = iris.groupby('Species') # 品種ごとに,\n", - "my_df = my_group.agg('mean') # 各変数の,平均と\n", - "my_se = my_group.agg(lambda x: x.std() / len(x)**0.5) # 標準誤差を求める.\n", - "my_se\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width\n", - "#> Species\n", - "#> setosa 0.05 0.05 0.02 0.01\n", - "#> versicolor 0.07 0.04 0.07 0.03\n", - "#> virginica 0.09 0.05 0.08 0.04" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_group.agg('mean').plot(kind='bar', yerr=my_se, capsize=5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.5 モザイクプロット" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from statsmodels.graphics.mosaicplot \\\n", - " import mosaic\n", - "\n", - "my_df = pd.DataFrame({\n", - " 'Species': iris.Species,\n", - " 'w_Sepal': iris['Sepal.Width'] > 3})\n", - "\n", - "my_table = pd.crosstab( # 分割表\n", - " my_df['Species'],\n", - " my_df['w_Sepal'])\n", - "my_table\n", - "#> w_Sepal False True\n", - "#> Species\n", - "#> setosa 8 42\n", - "#> versicolor 42 8\n", - "#> virginica 33 17\n", - "\n", - "mosaic(my_df,\n", - " index=['Species', 'w_Sepal'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_table.columns = [str(x) for x in my_table.columns]\n", - "my_table.index = [str(x) for x in my_table.index]\n", - "mosaic(my_df, index=['Species', 'w_Sepal'], labelizer=lambda k: my_table.loc[k])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.6 関数のグラフ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "\n", - "x = np.linspace(-2, 2, 100)\n", - "y = x**3 - x\n", - "plt.plot(x, y)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.7 ggplot2 (R)\n", - "\n", - "## 4.3 乱数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "rng = np.random.default_rng()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.1 一様乱数(離散)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.random.choice(\n", - " a=range(1, 7), # 1から6\n", - " size=10000, # 乱数の数\n", - " replace=True) # 重複あり\n", - "# あるいは\n", - "x = np.random.randint(\n", - "# あるいは\n", - "#x = rng.integers(\n", - " low=1, # 最小\n", - " high=7, # 最大+1\n", - " size=10000) # 乱数の数\n", - "\n", - "plt.hist(x, bins=6) # ヒストグラム" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.2 一様乱数(連続)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.random.random(size=1000)\n", - "# あるいは\n", - "x = rng.random(size=10000)\n", - "# あるいは\n", - "x = np.random.uniform(\n", - " low=0, # 最小\n", - " high=1, # 最大\n", - " size=1000) # 乱数の数\n", - "plt.hist(x)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = np.random.uniform(\n", - " low=1, # 最小\n", - " high=7, # 最大 + 1\n", - " size=1000) # 乱数の数\n", - "x = [int(k) for k in tmp]\n", - "plt.hist(x, bins=6) # 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.3 二項乱数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n = 100\n", - "p = 0.5\n", - "r = 10000\n", - "x = np.random.binomial(\n", - "# あるいは\n", - "#x = rng.binomial(\n", - " n=n, # 試行回数\n", - " p=p, # 確率\n", - " size=r) # 乱数の数\n", - "plt.hist(x, bins=max(x) - min(x))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.4 正規乱数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "r = 10000\n", - "x = np.random.normal(\n", - "# あるいは\n", - "#x = rng.normal(\n", - " loc=50, # 平均\n", - " scale=5, # 標準偏差\n", - " size=r) # 乱数の数\n", - "plt.hist(x, bins=40)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.3.4.1 補足:不偏性の具体例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "\n", - "def f(k):\n", - " n = 10000\n", - " tmp = [g(np.random.normal(size=k, scale=3)) for _ in range(n)]\n", - " return pd.Series([k,\n", - " np.mean(tmp), # 平均\n", - " np.std(tmp, ddof=1) / n**0.5], # 標準誤差\n", - " index=['k', 'mean', 'se'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def g(x):\n", - " return np.var(x, ddof=1)\n", - "pd.Series([10, 20, 30]).apply(f)\n", - "#> k mean se\n", - "#> 0 10.0 9.025140 0.042690\n", - "#> 1 20.0 9.022280 0.029525\n", - "#> 2 30.0 8.983166 0.023584" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def g(x):\n", - " return np.std(x, ddof=1)\n", - "pd.Series([10, 20, 30]).apply(f)\n", - "#> k mean se\n", - "#> 0 10.0 2.923114 0.006983\n", - "#> 1 20.0 2.961450 0.004811\n", - "#> 2 30.0 2.968328 0.003977" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from math import gamma\n", - "\n", - "def g(x):\n", - " n = len(x)\n", - " return (np.std(x, ddof=1) *\n", - " (np.sqrt((n - 1) / 2) *\n", - " gamma((n - 1) / 2) /\n", - " gamma(n / 2)))\n", - "pd.Series([10, 20, 30]).apply(f)\n", - "#> k mean se\n", - "#> 0 10.0 3.005788 0.007121\n", - "#> 1 20.0 3.001857 0.004894\n", - "#> 2 30.0 2.995965 0.003925" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.4 統計的推測\n", - "\n", - "### 4.4.1 検定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from statsmodels.stats.proportion import binom_test, proportion_confint\n", - "\n", - "binom_test(count=2, # 当たった回数\n", - " nobs=15, # くじを引いた回数\n", - " prop=4 / 10, # 当たる確率(仮説)\n", - " alternative='two-sided') # 両側検定(デフォルト)\n", - " # 左片側検定なら'smaller'\n", - " # 右片側検定なら'larger'\n", - "#> 0.03646166155263999" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.4.1.1 補足:p値とは何か" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "from scipy import stats\n", - "\n", - "t = 4 / 10 # 当たる確率\n", - "n = 15 # くじを引いた回数\n", - "x = np.array(range(0, n + 1)) # 当たった回数\n", - "my_pr = stats.binom.pmf(x, n, t) # x回当たる確率\n", - "my_pr2 = stats.binom.pmf(2, n, t) # 2回当たる確率\n", - "\n", - "my_data = pd.DataFrame({'x': x, 'y1': my_pr, 'y2': my_pr})\n", - "my_data.loc[my_pr > my_pr2, 'y1'] = np.nan # 当たる確率が,2回当たる確率超過\n", - "my_data.loc[my_pr <= my_pr2, 'y2'] = np.nan # 当たる確率が,2回当たる確率以下\n", - "ax = my_data.plot(x='x', style='o', ylabel='probability',\n", - " legend=False) # 凡例を表示しない.\n", - "ax.hlines(y=my_pr2, xmin=0, xmax=15) # 水平線\n", - "ax.vlines(x=x, ymin=0, ymax=my_pr) # 垂直線" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.2 推定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "a = 0.05\n", - "proportion_confint(\n", - " count=2, # 当たった回数\n", - " nobs=15, # くじを引いた回数\n", - " alpha=a, # 有意水準(省略可)\n", - " method='binom_test')\n", - "#> (0.024225732468536626,\n", - "#> 0.3967139842509865)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "a = 0.05 # 有意水準\n", - "tmp = np.linspace(0, 1, 100)\n", - "\n", - "my_df = pd.DataFrame({\n", - " 't': tmp, # 当たる確率\n", - " 'q': a, # 水平線\n", - " 'p': [binom_test(count=2, nobs=15, prop=t) for t in tmp]}) # p値\n", - "\n", - "my_df.plot(x='t', legend=None, xlabel=r'$\\theta$', ylabel=r'p-value')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.3 平均の差の検定と推定(t検定)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from statsmodels.stats.weightstats import CompareMeans, DescrStatsW\n", - "\n", - "X = [32.1, 26.2, 27.5, 31.8, 32.1, 31.2, 30.1, 32.4, 32.3, 29.9,\n", - " 29.6, 26.6, 31.2, 30.9, 29.3]\n", - "Y = [35.4, 34.6, 31.1, 32.4, 33.3, 34.7, 35.3, 34.3, 32.1, 28.3,\n", - " 33.3, 30.5, 32.6, 33.3, 32.2]\n", - "\n", - "a = 0.05 # 有意水準(デフォルト) = 1 - 信頼係数\n", - "alt = 'two-sided' # 両側検定(デフォルト)\n", - " # 左片側検定なら'smaller'\n", - " # 右片側検定なら'larger'\n", - "\n", - "d = DescrStatsW(np.array(X) - np.array(Y)) # 対標本の場合\n", - "d.ttest_mean(alternative=alt)[1] # p値\n", - "#> 0.0006415571512322235\n", - "\n", - "d.tconfint_mean(alpha=a, alternative=alt) # 信頼区間\n", - "#> (-3.9955246743198867, -1.3644753256801117)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c = CompareMeans(DescrStatsW(X), DescrStatsW(Y)) # 対標本でない場合\n", - "\n", - "ve = 'pooled' # 等分散を仮定する(デフォルト).仮定しないなら'unequal'.\n", - "c.ttest_ind(alternative=alt, usevar=ve)[1] # p値\n", - "#> 0.000978530937238609\n", - "\n", - "c.tconfint_diff(alpha=a, alternative=alt, usevar=ve) # 信頼区間\n", - "#> (-4.170905570517185, -1.1890944294828283)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.4 独立性の検定(カイ2乗検定)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/smoker.csv')\n", - "my_data = pd.read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.head()\n", - "#> alive smoker\n", - "#> 0 Yes No\n", - "#> 1 Yes No\n", - "#> 2 Yes No\n", - "#> 3 Yes No\n", - "#> 4 Yes No" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_table = pd.crosstab(\n", - " my_data['alive'],\n", - " my_data['smoker'])\n", - "my_table\n", - "#> smoker No Yes\n", - "#> alive\n", - "#> No 117 54\n", - "#> Yes 950 348" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from scipy.stats import chi2_contingency\n", - "chi2_contingency(my_table, correction=False)[1]\n", - "#> 0.18860725715300422" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.5 ブートストラップ\n", - "\n", - "#### 4.4.5.1 15回引いて2回当たったくじ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X = [0] * 13 + [1] * 2 # 手順1\n", - "X\n", - "#> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]\n", - "\n", - "tmp = np.random.choice(X, 15, replace=True) # 手順2\n", - "tmp\n", - "#> array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0])\n", - "\n", - "sum(tmp) # 手順3\n", - "#> 2\n", - "\n", - "n = 10**5\n", - "result = [sum(np.random.choice(X, len(X), replace=True)) for _ in range(n)] # 手順4" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "plt.hist(result, bins=range(0, 16))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.quantile(result, [0.025, 0.975])\n", - "#> array([0., 5.])" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch05/05-colab.ipynb b/code/Python-notebook/ch05/05-colab.ipynb deleted file mode 100644 index 3dfb1fb..0000000 --- a/code/Python-notebook/ch05/05-colab.ipynb +++ /dev/null @@ -1,435 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 05\n", - "\n", - "## 5.1 データの読み込み\n", - "\n", - "### 5.1.1 CSV" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!wget https://raw.githubusercontent.com/taroyabuki/fromzero/master/data/exam.csv" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.1.1 CSVの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "my_df = pd.read_csv('exam.csv')\n", - "my_df\n", - "#> name english math gender\n", - "#> 0 A 60 70 f\n", - "#> 1 B 90 80 m\n", - "#> 2 C 70 90 m\n", - "#> 3 D 90 100 f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/exam.csv')\n", - "my_df = pd.read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 = pd.read_csv('exam.csv',\n", - " index_col='name')\n", - "my_df2\n", - "#> english math gender\n", - "#> name\n", - "#> A 60 70 f\n", - "#> B 90 80 m\n", - "#> C 70 90 m\n", - "#> D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.1.2 CSVファイルへの書き出し" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.to_csv('exam2.csv', index=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2.to_csv('exam3.csv')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.2 文字コード" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.read_csv('exam.csv',\n", - " encoding='UTF-8')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.to_csv('exam2.csv', index=False, encoding='UTF-8')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.3 ウェブ上の表" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url = 'https://taroyabuki.github.io/fromzero/exam.html'\n", - "my_tables = pd.read_html(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_tables\n", - "#> [ Unnamed: 0 name english ...\n", - "#> 0 NaN A 60 ...\n", - "#> 1 NaN B 90 ...\n", - "#> 2 NaN C 70 ...\n", - "#> 3 NaN D 90 ...]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_tables[0]\n", - "#> Unnamed: 0 name english ...\n", - "#> 0 NaN A 60 ...\n", - "#> 1 NaN B 90 ...\n", - "#> 2 NaN C 70 ...\n", - "#> 3 NaN D 90 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 1列目以降を取り出す.\n", - "my_data = my_tables[0].iloc[:, 1:]\n", - "my_data\n", - "#> name english math gender\n", - "#> 0 A 60 70 f\n", - "#> 1 B 90 80 m\n", - "#> 2 C 70 90 m\n", - "#> 3 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.4 JSONとXML\n", - "\n", - "#### 5.1.4.1 JSONデータの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/exam.json')\n", - "my_data = pd.read_json(my_url)\n", - "#my_data = pd.read_json('exam.json') # (ファイルを使う場合)\n", - "my_data\n", - "#> name english math gender\n", - "#> 0 A 60 70 f\n", - "#> 1 B 90 80 m\n", - "#> 2 C 70 90 m\n", - "#> 3 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.4.2 XMLデータの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import xml.etree.ElementTree as ET\n", - "from urllib.request import urlopen\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/exam.xml')\n", - "with urlopen(my_url) as f:\n", - " my_tree = ET.parse(f) # XMLデータの読み込み\n", - "\n", - "#my_tree = ET.parse('exam.xml') # (ファイルを使う場合)\n", - "my_ns = '{https://www.example.net/ns/1.0}' # 名前空間" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_records = my_tree.findall(f'.//{my_ns}record')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f(record):\n", - " my_dic1 = record.attrib # 属性を取り出す.\n", - " # 子要素の名前と内容のペアを辞書にする.\n", - " my_dic2 = {child.tag.replace(my_ns, ''): child.text for child in list(record)}\n", - " return {**my_dic1, **my_dic2} # 辞書を結合する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data = pd.DataFrame([f(record) for record in my_records])\n", - "my_data['english'] = pd.to_numeric(my_data['english'])\n", - "my_data['math'] = pd.to_numeric(my_data['math'])\n", - "my_data\n", - "#> english math gender name\n", - "#> 0 60 70 f A\n", - "#> 1 90 80 m B\n", - "#> 2 70 90 m C\n", - "#> 3 90 100 f D" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 5.2 データの変換\n", - "\n", - "### 5.2.1 標準化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from scipy.stats import zscore\n", - "\n", - "x1 = [1, 2, 3]\n", - "\n", - "z1 = ((x1 - np.mean(x1)) /\n", - " np.std(x1, ddof=1))\n", - "# あるいは\n", - "z1 = zscore(x1, ddof=1)\n", - "\n", - "z1\n", - "#> array([-1., 0., 1.])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "z1.mean(), np.std(z1, ddof=1)\n", - "#> (0.0, 1.0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "z1 * np.std(x1, ddof=1) + np.mean(x1)\n", - "#> array([1., 2., 3.])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x2 = [1, 3, 5]\n", - "z2 = ((x2 - np.mean(x1)) /\n", - " np.std(x1, ddof=1))\n", - "z2.mean(), np.std(z2, ddof=1)\n", - "#> (1.0, 2.0)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.2.2 ワンホットエンコーディング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.preprocessing import (\n", - " OneHotEncoder)\n", - "\n", - "my_df = pd.DataFrame({\n", - " 'id': [ 1 , 2 , 3 ],\n", - " 'class': ['A', 'B', 'C']})\n", - "\n", - "my_enc = OneHotEncoder()\n", - "tmp = my_enc.fit_transform(\n", - " my_df[['class']]).toarray()\n", - "my_names = my_enc.get_feature_names() \\\n", - "if hasattr(my_enc, 'get_feature_names') \\\n", - "else my_enc.get_feature_names_out()\n", - "pd.DataFrame(tmp, columns=my_names)\n", - "#> x0_A x0_B x0_C\n", - "#> 0 1.0 0.0 0.0\n", - "#> 1 0.0 1.0 0.0\n", - "#> 2 0.0 0.0 1.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 = pd.DataFrame({\n", - " 'id': [ 4 , 5, 6 ],\n", - " 'class': ['B', 'C', 'B']})\n", - "tmp = my_enc.transform(\n", - " my_df2[['class']]).toarray()\n", - "pd.DataFrame(tmp, columns=my_names)\n", - "#> x0_A x0_B x0_C\n", - "#> 0 0.0 1.0 0.0\n", - "#> 1 0.0 0.0 1.0\n", - "#> 2 0.0 1.0 0.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.2.2.1 補足:冗長性の排除" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_enc = OneHotEncoder(drop='first')\n", - "\n", - "tmp = my_enc.fit_transform(\n", - " my_df[['class']]).toarray()\n", - "my_names = my_enc.get_feature_names() \\\n", - "if hasattr(my_enc, 'get_feature_names') \\\n", - "else my_enc.get_feature_names_out()\n", - "pd.DataFrame(tmp, columns=my_names)\n", - "#> x0_B x0_C\n", - "#> 0 0.0 0.0\n", - "#> 1 1.0 0.0\n", - "#> 2 0.0 1.0\n", - "\n", - "tmp = my_enc.transform(\n", - " my_df2[['class']]).toarray()\n", - "pd.DataFrame(tmp, columns=my_names)\n", - "#> x0_B x0_C\n", - "#> 0 1.0 0.0\n", - "#> 1 0.0 1.0\n", - "#> 2 1.0 0.0" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch05/05.01.ipynb b/code/Python-notebook/ch05/05.01.ipynb deleted file mode 100644 index b9f02ad..0000000 --- a/code/Python-notebook/ch05/05.01.ipynb +++ /dev/null @@ -1,284 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 5.1 データの読み込み\n", - "\n", - "### 5.1.1 CSV" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!wget https://raw.githubusercontent.com/taroyabuki/fromzero/master/data/exam.csv" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.1.1 CSVの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "my_df = pd.read_csv('exam.csv')\n", - "my_df\n", - "#> name english math gender\n", - "#> 0 A 60 70 f\n", - "#> 1 B 90 80 m\n", - "#> 2 C 70 90 m\n", - "#> 3 D 90 100 f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/exam.csv')\n", - "my_df = pd.read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 = pd.read_csv('exam.csv',\n", - " index_col='name')\n", - "my_df2\n", - "#> english math gender\n", - "#> name\n", - "#> A 60 70 f\n", - "#> B 90 80 m\n", - "#> C 70 90 m\n", - "#> D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.1.2 CSVファイルへの書き出し" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.to_csv('exam2.csv', index=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2.to_csv('exam3.csv')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.2 文字コード" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.read_csv('exam.csv',\n", - " encoding='UTF-8')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.to_csv('exam2.csv', index=False, encoding='UTF-8')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.3 ウェブ上の表" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url = 'https://taroyabuki.github.io/fromzero/exam.html'\n", - "my_tables = pd.read_html(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_tables\n", - "#> [ Unnamed: 0 name english ...\n", - "#> 0 NaN A 60 ...\n", - "#> 1 NaN B 90 ...\n", - "#> 2 NaN C 70 ...\n", - "#> 3 NaN D 90 ...]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_tables[0]\n", - "#> Unnamed: 0 name english ...\n", - "#> 0 NaN A 60 ...\n", - "#> 1 NaN B 90 ...\n", - "#> 2 NaN C 70 ...\n", - "#> 3 NaN D 90 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 1列目以降を取り出す.\n", - "my_data = my_tables[0].iloc[:, 1:]\n", - "my_data\n", - "#> name english math gender\n", - "#> 0 A 60 70 f\n", - "#> 1 B 90 80 m\n", - "#> 2 C 70 90 m\n", - "#> 3 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.4 JSONとXML\n", - "\n", - "#### 5.1.4.1 JSONデータの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/exam.json')\n", - "my_data = pd.read_json(my_url)\n", - "#my_data = pd.read_json('exam.json') # (ファイルを使う場合)\n", - "my_data\n", - "#> name english math gender\n", - "#> 0 A 60 70 f\n", - "#> 1 B 90 80 m\n", - "#> 2 C 70 90 m\n", - "#> 3 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.4.2 XMLデータの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import xml.etree.ElementTree as ET\n", - "from urllib.request import urlopen\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/exam.xml')\n", - "with urlopen(my_url) as f:\n", - " my_tree = ET.parse(f) # XMLデータの読み込み\n", - "\n", - "#my_tree = ET.parse('exam.xml') # (ファイルを使う場合)\n", - "my_ns = '{https://www.example.net/ns/1.0}' # 名前空間" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_records = my_tree.findall(f'.//{my_ns}record')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f(record):\n", - " my_dic1 = record.attrib # 属性を取り出す.\n", - " # 子要素の名前と内容のペアを辞書にする.\n", - " my_dic2 = {child.tag.replace(my_ns, ''): child.text for child in list(record)}\n", - " return {**my_dic1, **my_dic2} # 辞書を結合する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data = pd.DataFrame([f(record) for record in my_records])\n", - "my_data['english'] = pd.to_numeric(my_data['english'])\n", - "my_data['math'] = pd.to_numeric(my_data['math'])\n", - "my_data\n", - "#> english math gender name\n", - "#> 0 60 70 f A\n", - "#> 1 90 80 m B\n", - "#> 2 70 90 m C\n", - "#> 3 90 100 f D" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch05/05.02.ipynb b/code/Python-notebook/ch05/05.02.ipynb deleted file mode 100644 index 1603ba3..0000000 --- a/code/Python-notebook/ch05/05.02.ipynb +++ /dev/null @@ -1,161 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 5.2 データの変換\n", - "\n", - "### 5.2.1 標準化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from scipy.stats import zscore\n", - "\n", - "x1 = [1, 2, 3]\n", - "\n", - "z1 = ((x1 - np.mean(x1)) /\n", - " np.std(x1, ddof=1))\n", - "# あるいは\n", - "z1 = zscore(x1, ddof=1)\n", - "\n", - "z1\n", - "#> array([-1., 0., 1.])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "z1.mean(), np.std(z1, ddof=1)\n", - "#> (0.0, 1.0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "z1 * np.std(x1, ddof=1) + np.mean(x1)\n", - "#> array([1., 2., 3.])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x2 = [1, 3, 5]\n", - "z2 = ((x2 - np.mean(x1)) /\n", - " np.std(x1, ddof=1))\n", - "z2.mean(), np.std(z2, ddof=1)\n", - "#> (1.0, 2.0)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.2.2 ワンホットエンコーディング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.preprocessing import (\n", - " OneHotEncoder)\n", - "\n", - "my_df = pd.DataFrame({\n", - " 'id': [ 1 , 2 , 3 ],\n", - " 'class': ['A', 'B', 'C']})\n", - "\n", - "my_enc = OneHotEncoder()\n", - "tmp = my_enc.fit_transform(\n", - " my_df[['class']]).toarray()\n", - "my_names = my_enc.get_feature_names() \\\n", - "if hasattr(my_enc, 'get_feature_names') \\\n", - "else my_enc.get_feature_names_out()\n", - "pd.DataFrame(tmp, columns=my_names)\n", - "#> x0_A x0_B x0_C\n", - "#> 0 1.0 0.0 0.0\n", - "#> 1 0.0 1.0 0.0\n", - "#> 2 0.0 0.0 1.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 = pd.DataFrame({\n", - " 'id': [ 4 , 5, 6 ],\n", - " 'class': ['B', 'C', 'B']})\n", - "tmp = my_enc.transform(\n", - " my_df2[['class']]).toarray()\n", - "pd.DataFrame(tmp, columns=my_names)\n", - "#> x0_A x0_B x0_C\n", - "#> 0 0.0 1.0 0.0\n", - "#> 1 0.0 0.0 1.0\n", - "#> 2 0.0 1.0 0.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.2.2.1 補足:冗長性の排除" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_enc = OneHotEncoder(drop='first')\n", - "\n", - "tmp = my_enc.fit_transform(\n", - " my_df[['class']]).toarray()\n", - "my_names = my_enc.get_feature_names() \\\n", - "if hasattr(my_enc, 'get_feature_names') \\\n", - "else my_enc.get_feature_names_out()\n", - "pd.DataFrame(tmp, columns=my_names)\n", - "#> x0_B x0_C\n", - "#> 0 0.0 0.0\n", - "#> 1 1.0 0.0\n", - "#> 2 0.0 1.0\n", - "\n", - "tmp = my_enc.transform(\n", - " my_df2[['class']]).toarray()\n", - "pd.DataFrame(tmp, columns=my_names)\n", - "#> x0_B x0_C\n", - "#> 0 1.0 0.0\n", - "#> 1 0.0 1.0\n", - "#> 2 1.0 0.0" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch05/05.ipynb b/code/Python-notebook/ch05/05.ipynb deleted file mode 100644 index 3dfb1fb..0000000 --- a/code/Python-notebook/ch05/05.ipynb +++ /dev/null @@ -1,435 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 05\n", - "\n", - "## 5.1 データの読み込み\n", - "\n", - "### 5.1.1 CSV" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!wget https://raw.githubusercontent.com/taroyabuki/fromzero/master/data/exam.csv" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.1.1 CSVの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "my_df = pd.read_csv('exam.csv')\n", - "my_df\n", - "#> name english math gender\n", - "#> 0 A 60 70 f\n", - "#> 1 B 90 80 m\n", - "#> 2 C 70 90 m\n", - "#> 3 D 90 100 f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/exam.csv')\n", - "my_df = pd.read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 = pd.read_csv('exam.csv',\n", - " index_col='name')\n", - "my_df2\n", - "#> english math gender\n", - "#> name\n", - "#> A 60 70 f\n", - "#> B 90 80 m\n", - "#> C 70 90 m\n", - "#> D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.1.2 CSVファイルへの書き出し" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.to_csv('exam2.csv', index=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2.to_csv('exam3.csv')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.2 文字コード" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.read_csv('exam.csv',\n", - " encoding='UTF-8')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.to_csv('exam2.csv', index=False, encoding='UTF-8')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.3 ウェブ上の表" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url = 'https://taroyabuki.github.io/fromzero/exam.html'\n", - "my_tables = pd.read_html(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_tables\n", - "#> [ Unnamed: 0 name english ...\n", - "#> 0 NaN A 60 ...\n", - "#> 1 NaN B 90 ...\n", - "#> 2 NaN C 70 ...\n", - "#> 3 NaN D 90 ...]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_tables[0]\n", - "#> Unnamed: 0 name english ...\n", - "#> 0 NaN A 60 ...\n", - "#> 1 NaN B 90 ...\n", - "#> 2 NaN C 70 ...\n", - "#> 3 NaN D 90 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 1列目以降を取り出す.\n", - "my_data = my_tables[0].iloc[:, 1:]\n", - "my_data\n", - "#> name english math gender\n", - "#> 0 A 60 70 f\n", - "#> 1 B 90 80 m\n", - "#> 2 C 70 90 m\n", - "#> 3 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.4 JSONとXML\n", - "\n", - "#### 5.1.4.1 JSONデータの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/exam.json')\n", - "my_data = pd.read_json(my_url)\n", - "#my_data = pd.read_json('exam.json') # (ファイルを使う場合)\n", - "my_data\n", - "#> name english math gender\n", - "#> 0 A 60 70 f\n", - "#> 1 B 90 80 m\n", - "#> 2 C 70 90 m\n", - "#> 3 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.4.2 XMLデータの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import xml.etree.ElementTree as ET\n", - "from urllib.request import urlopen\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/exam.xml')\n", - "with urlopen(my_url) as f:\n", - " my_tree = ET.parse(f) # XMLデータの読み込み\n", - "\n", - "#my_tree = ET.parse('exam.xml') # (ファイルを使う場合)\n", - "my_ns = '{https://www.example.net/ns/1.0}' # 名前空間" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_records = my_tree.findall(f'.//{my_ns}record')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f(record):\n", - " my_dic1 = record.attrib # 属性を取り出す.\n", - " # 子要素の名前と内容のペアを辞書にする.\n", - " my_dic2 = {child.tag.replace(my_ns, ''): child.text for child in list(record)}\n", - " return {**my_dic1, **my_dic2} # 辞書を結合する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data = pd.DataFrame([f(record) for record in my_records])\n", - "my_data['english'] = pd.to_numeric(my_data['english'])\n", - "my_data['math'] = pd.to_numeric(my_data['math'])\n", - "my_data\n", - "#> english math gender name\n", - "#> 0 60 70 f A\n", - "#> 1 90 80 m B\n", - "#> 2 70 90 m C\n", - "#> 3 90 100 f D" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 5.2 データの変換\n", - "\n", - "### 5.2.1 標準化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from scipy.stats import zscore\n", - "\n", - "x1 = [1, 2, 3]\n", - "\n", - "z1 = ((x1 - np.mean(x1)) /\n", - " np.std(x1, ddof=1))\n", - "# あるいは\n", - "z1 = zscore(x1, ddof=1)\n", - "\n", - "z1\n", - "#> array([-1., 0., 1.])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "z1.mean(), np.std(z1, ddof=1)\n", - "#> (0.0, 1.0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "z1 * np.std(x1, ddof=1) + np.mean(x1)\n", - "#> array([1., 2., 3.])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x2 = [1, 3, 5]\n", - "z2 = ((x2 - np.mean(x1)) /\n", - " np.std(x1, ddof=1))\n", - "z2.mean(), np.std(z2, ddof=1)\n", - "#> (1.0, 2.0)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.2.2 ワンホットエンコーディング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.preprocessing import (\n", - " OneHotEncoder)\n", - "\n", - "my_df = pd.DataFrame({\n", - " 'id': [ 1 , 2 , 3 ],\n", - " 'class': ['A', 'B', 'C']})\n", - "\n", - "my_enc = OneHotEncoder()\n", - "tmp = my_enc.fit_transform(\n", - " my_df[['class']]).toarray()\n", - "my_names = my_enc.get_feature_names() \\\n", - "if hasattr(my_enc, 'get_feature_names') \\\n", - "else my_enc.get_feature_names_out()\n", - "pd.DataFrame(tmp, columns=my_names)\n", - "#> x0_A x0_B x0_C\n", - "#> 0 1.0 0.0 0.0\n", - "#> 1 0.0 1.0 0.0\n", - "#> 2 0.0 0.0 1.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 = pd.DataFrame({\n", - " 'id': [ 4 , 5, 6 ],\n", - " 'class': ['B', 'C', 'B']})\n", - "tmp = my_enc.transform(\n", - " my_df2[['class']]).toarray()\n", - "pd.DataFrame(tmp, columns=my_names)\n", - "#> x0_A x0_B x0_C\n", - "#> 0 0.0 1.0 0.0\n", - "#> 1 0.0 0.0 1.0\n", - "#> 2 0.0 1.0 0.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.2.2.1 補足:冗長性の排除" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_enc = OneHotEncoder(drop='first')\n", - "\n", - "tmp = my_enc.fit_transform(\n", - " my_df[['class']]).toarray()\n", - "my_names = my_enc.get_feature_names() \\\n", - "if hasattr(my_enc, 'get_feature_names') \\\n", - "else my_enc.get_feature_names_out()\n", - "pd.DataFrame(tmp, columns=my_names)\n", - "#> x0_B x0_C\n", - "#> 0 0.0 0.0\n", - "#> 1 1.0 0.0\n", - "#> 2 0.0 1.0\n", - "\n", - "tmp = my_enc.transform(\n", - " my_df2[['class']]).toarray()\n", - "pd.DataFrame(tmp, columns=my_names)\n", - "#> x0_B x0_C\n", - "#> 0 1.0 0.0\n", - "#> 1 0.0 1.0\n", - "#> 2 1.0 0.0" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch06/06-colab.ipynb b/code/Python-notebook/ch06/06-colab.ipynb deleted file mode 100644 index b59c006..0000000 --- a/code/Python-notebook/ch06/06-colab.ipynb +++ /dev/null @@ -1,93 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 06\n", - "\n", - "## 6.1 機械学習の目的(本書の場合)\n", - "\n", - "## 6.2 機械学習のためのデータ\n", - "\n", - "### 6.2.1 機械学習を学ぶのに使うデータセット\n", - "\n", - "#### 6.2.1.1 教師データあり\n", - "\n", - "#### 6.2.1.2 時系列データ(第\\\\ref{時系列予測\n", - "\n", - "#### 6.2.1.3 教師データなし(第\\\\ref{教師なし学習\n", - "\n", - "### 6.2.2 補足:アヤメのデータ\n", - "\n", - "#### 6.2.2.1 R\n", - "\n", - "#### 6.2.2.2 Python" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "iris = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "iris.head()\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 0 5.1 3.5 1.4 0.2 setosa\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import seaborn as sns\n", - "iris = sns.load_dataset('iris')\n", - "iris.head()\n", - "#> sepal_length sepal_width petal_length petal_width species\n", - "#> 0 5.1 3.5 1.4 0.2 setosa\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.datasets import load_iris\n", - "tmp = load_iris()\n", - "iris = pd.DataFrame(tmp.data, columns=tmp.feature_names)\n", - "iris['target'] = tmp.target_names[tmp.target]\n", - "iris.head()\n", - "#> sepal length (cm) sepal width (cm) ... petal width (cm) target\n", - "#> 0 5.1 3.5 ... 0.2 setosa\n", - "# 以下省略" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 6.3 機械学習のための手法\n", - "\n", - "### 6.3.1 教師あり学習のためのフレームワーク\n", - "\n", - "### 6.3.2 本書で勧める手法とデータセットの組合せ" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch06/06.01.ipynb b/code/Python-notebook/ch06/06.01.ipynb deleted file mode 100644 index 563cf26..0000000 --- a/code/Python-notebook/ch06/06.01.ipynb +++ /dev/null @@ -1,19 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 6.1 機械学習の目的(本書の場合)" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch06/06.02.ipynb b/code/Python-notebook/ch06/06.02.ipynb deleted file mode 100644 index 1302d8a..0000000 --- a/code/Python-notebook/ch06/06.02.ipynb +++ /dev/null @@ -1,78 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 6.2 機械学習のためのデータ\n", - "\n", - "### 6.2.1 機械学習を学ぶのに使うデータセット\n", - "\n", - "#### 6.2.1.1 教師データあり\n", - "\n", - "#### 6.2.1.2 時系列データ(第\\\\ref{時系列予測\n", - "\n", - "#### 6.2.1.3 教師データなし(第\\\\ref{教師なし学習\n", - "\n", - "### 6.2.2 補足:アヤメのデータ\n", - "\n", - "#### 6.2.2.1 R\n", - "\n", - "#### 6.2.2.2 Python" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "iris = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "iris.head()\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 0 5.1 3.5 1.4 0.2 setosa\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import seaborn as sns\n", - "iris = sns.load_dataset('iris')\n", - "iris.head()\n", - "#> sepal_length sepal_width petal_length petal_width species\n", - "#> 0 5.1 3.5 1.4 0.2 setosa\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.datasets import load_iris\n", - "tmp = load_iris()\n", - "iris = pd.DataFrame(tmp.data, columns=tmp.feature_names)\n", - "iris['target'] = tmp.target_names[tmp.target]\n", - "iris.head()\n", - "#> sepal length (cm) sepal width (cm) ... petal width (cm) target\n", - "#> 0 5.1 3.5 ... 0.2 setosa\n", - "# 以下省略" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch06/06.03.ipynb b/code/Python-notebook/ch06/06.03.ipynb deleted file mode 100644 index 332ae55..0000000 --- a/code/Python-notebook/ch06/06.03.ipynb +++ /dev/null @@ -1,23 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 6.3 機械学習のための手法\n", - "\n", - "### 6.3.1 教師あり学習のためのフレームワーク\n", - "\n", - "### 6.3.2 本書で勧める手法とデータセットの組合せ" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch06/06.ipynb b/code/Python-notebook/ch06/06.ipynb deleted file mode 100644 index b59c006..0000000 --- a/code/Python-notebook/ch06/06.ipynb +++ /dev/null @@ -1,93 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 06\n", - "\n", - "## 6.1 機械学習の目的(本書の場合)\n", - "\n", - "## 6.2 機械学習のためのデータ\n", - "\n", - "### 6.2.1 機械学習を学ぶのに使うデータセット\n", - "\n", - "#### 6.2.1.1 教師データあり\n", - "\n", - "#### 6.2.1.2 時系列データ(第\\\\ref{時系列予測\n", - "\n", - "#### 6.2.1.3 教師データなし(第\\\\ref{教師なし学習\n", - "\n", - "### 6.2.2 補足:アヤメのデータ\n", - "\n", - "#### 6.2.2.1 R\n", - "\n", - "#### 6.2.2.2 Python" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "iris = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "iris.head()\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 0 5.1 3.5 1.4 0.2 setosa\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import seaborn as sns\n", - "iris = sns.load_dataset('iris')\n", - "iris.head()\n", - "#> sepal_length sepal_width petal_length petal_width species\n", - "#> 0 5.1 3.5 1.4 0.2 setosa\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.datasets import load_iris\n", - "tmp = load_iris()\n", - "iris = pd.DataFrame(tmp.data, columns=tmp.feature_names)\n", - "iris['target'] = tmp.target_names[tmp.target]\n", - "iris.head()\n", - "#> sepal length (cm) sepal width (cm) ... petal width (cm) target\n", - "#> 0 5.1 3.5 ... 0.2 setosa\n", - "# 以下省略" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 6.3 機械学習のための手法\n", - "\n", - "### 6.3.1 教師あり学習のためのフレームワーク\n", - "\n", - "### 6.3.2 本書で勧める手法とデータセットの組合せ" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch07/07-colab.ipynb b/code/Python-notebook/ch07/07-colab.ipynb deleted file mode 100644 index d5886e5..0000000 --- a/code/Python-notebook/ch07/07-colab.ipynb +++ /dev/null @@ -1,881 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 07\n", - "\n", - "## 7.1 自動車の停止距離\n", - "\n", - "## 7.2 データの確認" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.shape\n", - "#> (50, 2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.head()\n", - "#> speed dist\n", - "#> 0 4 2\n", - "#> 1 4 10\n", - "#> 2 7 4\n", - "#> 3 7 22\n", - "#> 4 8 16" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.describe()\n", - "#> speed dist\n", - "#> count 50.000000 50.000000\n", - "#> mean 15.400000 42.980000\n", - "#> std 5.287644 25.769377\n", - "#> min 4.000000 2.000000\n", - "#> 25% 12.000000 26.000000\n", - "#> 50% 15.000000 36.000000\n", - "#> 75% 19.000000 56.000000\n", - "#> max 25.000000 120.000000" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.plot(x='speed', style='o')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.3 回帰分析\n", - "\n", - "### 7.3.1 回帰分析とは何か\n", - "\n", - "### 7.3.2 線形単回帰分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import seaborn as sns\n", - "import statsmodels.api as sm\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "ax = sns.regplot(x='speed', y='dist', data=my_data)\n", - "ax.vlines(x=21.5, ymin=-5, ymax=67, linestyles='dotted')\n", - "ax.hlines(y=67, xmin=4, xmax=21.5, linestyles='dotted')\n", - "ax.set_xlim(4, 25)\n", - "ax.set_ylim(-5, 125)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.3.3 回帰分析の実践\n", - "\n", - "#### 7.3.3.1 データの用意" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.2 訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# モデルの指定\n", - "from sklearn.linear_model import LinearRegression\n", - "my_model = LinearRegression()\n", - "\n", - "# 訓練(モデルをデータにフィットさせる.)\n", - "my_model.fit(X, y)\n", - "\n", - "# まとめて実行してもよい.\n", - "# my_model = LinearRegression().fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.intercept_, my_model.coef_\n", - "#> (-17.579094890510973,\n", - "#> array([3.93240876]))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.3 予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = [[21.5]]\n", - "my_model.predict(tmp)\n", - "#> array([66.96769343])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.4 モデルの可視化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "\n", - "tmp = pd.DataFrame({'speed': np.linspace(min(my_data.speed),\n", - " max(my_data.speed),\n", - " 100)})\n", - "tmp['model'] = my_model.predict(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.concat([my_data, tmp]).plot(\n", - " x='speed', style=['o', '-'])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.4 当てはまりの良さの指標\n", - "\n", - "### 7.4.1 RMSE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.metrics import mean_squared_error, r2_score\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "my_model = LinearRegression()\n", - "my_model.fit(X, y)\n", - "y_ = my_model.predict(X)\n", - "my_data['y_'] = y_" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.options.display.float_format = (\n", - " '{:.2f}'.format)\n", - "my_data['residual'] = y - y_\n", - "my_data.head()\n", - "#> speed dist y_ residual\n", - "#> 0 4 2 -1.85 3.85\n", - "#> 1 4 10 -1.85 11.85\n", - "#> 2 7 4 9.95 -5.95\n", - "#> 3 7 22 9.95 12.05\n", - "#> 4 8 16 13.88 2.12" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ax = my_data.plot(x='speed', y='dist', style='o', legend=False)\n", - "my_data.plot(x='speed', y='y_', style='-', legend=False, ax=ax)\n", - "ax.vlines(x=X, ymin=y, ymax=y_, linestyles='dotted')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mean_squared_error(y, y_)**0.5\n", - "# あるいは\n", - "(my_data['residual']**2).mean()**0.5\n", - "\n", - "#> 15.068855995791381" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.4.2 決定係数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.score(X, y)\n", - "# あるいは\n", - "r2_score(y_true=y, y_pred=y_)\n", - "#> 0.6510793807582509" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.6510793807582511" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test = my_data[:3]\n", - "X = my_test[['speed']]\n", - "y = my_test['dist']\n", - "y_ = my_model.predict(X)\n", - "\n", - "my_model.score(X, y)\n", - "# あるいは\n", - "r2_score(y_true=y, y_pred=y_)\n", - "#> -4.498191310376778 # 決定係数1\n", - "\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.0769230769230769 # 決定係数6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.4.3 当てはまりの良さの指標の問題点" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.preprocessing import PolynomialFeatures\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "\n", - "my_idx = [1, 10, 26, 33, 38, 43]\n", - "my_sample = my_data.iloc[my_idx, ]\n", - "X, y = my_sample[['speed']], my_sample['dist']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "d = 5\n", - "X5 = PolynomialFeatures(d, include_bias=False).fit_transform(X) # Xの1乗から5乗の変数\n", - "\n", - "my_model = LinearRegression()\n", - "my_model.fit(X5, y)\n", - "y_ = my_model.predict(X5)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "((y - y_)**2).mean()**0.5\n", - "#> 7.725744805546204e-07 # RMSE\n", - "\n", - "my_model.score(X5, y)\n", - "#> 0.9999999999999989 # 決定係数1\n", - "\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.9999999999999991 # 決定係数6" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = pd.DataFrame({'speed': np.linspace(min(my_data.speed),\n", - " max(my_data.speed),\n", - " 100)})\n", - "X5 = PolynomialFeatures(d, include_bias=False).fit_transform(tmp)\n", - "tmp['model'] = my_model.predict(X5)\n", - "\n", - "my_sample = my_sample.assign(sample=y)\n", - "my_df = pd.concat([my_data, my_sample, tmp])\n", - "my_df.plot(x='speed', style=['o', 'o', '-'], ylim=(0, 130))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.5 K最近傍法\n", - "\n", - "### 7.5.1 K最近傍法とは何か\n", - "\n", - "### 7.5.2 K最近傍法の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 準備\n", - "import numpy as np\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.neighbors import KNeighborsRegressor\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "# 訓練\n", - "my_model = KNeighborsRegressor()\n", - "my_model.fit(X, y)\n", - "\n", - "# 可視化の準備\n", - "tmp = pd.DataFrame({'speed': np.linspace(min(my_data.speed),\n", - " max(my_data.speed),\n", - " 100)})\n", - "tmp['model'] = my_model.predict(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.concat([my_data, tmp]).plot(\n", - " x='speed', style=['o', '-'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = my_model.predict(X)\n", - "\n", - "((y - y_)**2).mean()**0.5\n", - "#> 13.087184571174962 # RMSE\n", - "\n", - "my_model.score(X, y)\n", - "#> 0.7368165812204317 # 決定係数1\n", - "\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.7380949412509705 # 決定係数6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.6 検証\n", - "\n", - "### 7.6.1 訓練データ・検証データ・テストデータ\n", - "\n", - "### 7.6.2 検証とは何か\n", - "\n", - "### 7.6.3 検証の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.model_selection import cross_val_score\n", - "\n", - "# データの準備\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "# モデルの指定\n", - "my_model = LinearRegression()\n", - "\n", - "# 検証(5分割交差検証)\n", - "my_scores = cross_val_score(my_model, X, y)\n", - "\n", - "# 5個の決定係数1を得る.\n", - "my_scores\n", - "#> array([-0.25789256, -0.21421069, -0.30902773, -0.27346232, 0.02312918])\n", - "\n", - "# 平均を決定係数1(検証)とする.\n", - "my_scores.mean()\n", - "#> -0.20629282165364665" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scores = cross_val_score(my_model, X, y,\n", - " scoring='neg_root_mean_squared_error')\n", - "-my_scores.mean()\n", - "#> 15.58402474583013 # RMSE(検証)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.6.4 検証の並列化\n", - "\n", - "### 7.6.5 指標のまとめ\n", - "\n", - "#### 7.6.5.1 準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import statsmodels.api as sm\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.metrics import mean_squared_error, r2_score\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "my_model = LinearRegression().fit(X, y)\n", - "y_ = my_model.predict(X)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.2 当てはまりの良さの指標" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# RMSE(訓練)\n", - "mean_squared_error(y, y_)**0.5\n", - "#> 15.068855995791381\n", - "\n", - "# 決定係数1(訓練)\n", - "my_model.score(X, y)\n", - "# あるいは\n", - "r2_score(y_true=y, y_pred=y_)\n", - "#> 0.6510793807582509\n", - "\n", - "# 決定係数6(訓練)\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.6510793807582511" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.3 予測性能の指標(簡単に求められるもの)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scores = cross_val_score(my_model, X, y,\n", - " scoring='neg_root_mean_squared_error')\n", - "-my_scores.mean()\n", - "#> 15.301860331378464 # RMSE(検証)\n", - "\n", - "my_scores = cross_val_score(my_model, X, y, scoring='r2') # scoring='r2'は省略可\n", - "my_scores.mean()\n", - "#> 0.49061365458235245 # 決定係数1(検証)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.4 予測性能の指標(RとPythonで同じ結果を得る)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 方法1\n", - "my_scores1 = cross_val_score(my_model, X, y, cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "(-my_scores1.mean())**0.5\n", - "#> 15.697306009399101\n", - "\n", - "# 方法2\n", - "my_scores2 = cross_val_score(my_model, X, y, cv=LeaveOneOut(),\n", - " scoring='neg_root_mean_squared_error')\n", - "(my_scores2**2).mean()**0.5\n", - "#> 15.697306009399101" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "-my_scores2.mean()\n", - "#> 12.059178648637483" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.6.6 補足:検証による手法の比較" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.metrics import mean_squared_error\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.neighbors import KNeighborsRegressor\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "my_lm_scores = cross_val_score(\n", - " LinearRegression(),\n", - " X, y, cv=LeaveOneOut(), scoring='neg_mean_squared_error')\n", - "\n", - "my_knn_socres = cross_val_score(\n", - " KNeighborsRegressor(n_neighbors=5),\n", - " X, y, cv=LeaveOneOut(), scoring='neg_mean_squared_error')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(-my_lm_scores.mean())**0.5\n", - "#> 15.697306009399101 # 線形回帰分析\n", - "\n", - "(-my_knn_socres.mean())**0.5\n", - "#> 16.07308308943869 # K最近傍法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame({\n", - " 'lm': -my_lm_scores,\n", - " 'knn': -my_knn_socres})\n", - "my_df.head()\n", - "#> lm knn\n", - "#> 0 18.913720 108.16\n", - "#> 1 179.215044 0.64\n", - "#> 2 41.034336 64.00\n", - "#> 3 168.490212 184.96\n", - "#> 4 5.085308 0.00" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.boxplot().set_ylabel(\"$r^2$\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from statsmodels.stats.weightstats import DescrStatsW\n", - "d = DescrStatsW(my_df.lm - my_df.knn)\n", - "d.ttest_mean()[1] # p値\n", - "#> 0.6952755720536115\n", - "\n", - "d.tconfint_mean(alpha=0.05, alternative='two-sided') # 信頼区間\n", - "#> (-72.8275283312228, 48.95036023665703)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.7 パラメータチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.metrics import mean_squared_error\n", - "from sklearn.model_selection import GridSearchCV, LeaveOneOut\n", - "from sklearn.neighbors import KNeighborsRegressor\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "my_params = {'n_neighbors': range(1, 16)} # 探索範囲(1以上16未満の整数)\n", - "\n", - "my_search = GridSearchCV(estimator=KNeighborsRegressor(),\n", - " param_grid=my_params,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "my_search.fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_search.cv_results_ # チューニングの詳細\n", - "my_scores = (-tmp['mean_test_score'])**0.5 # RMSE\n", - "my_results = pd.DataFrame(tmp['params']).assign(validation=my_scores)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_results.head()\n", - "#> n_neighbors validation\n", - "#> 0 1 20.089798\n", - "#> 1 2 17.577685\n", - "#> 2 3 16.348836\n", - "#> 3 4 16.198804\n", - "#> 4 5 16.073083" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_results.plot(x='n_neighbors',\n", - " style='o-',\n", - " ylabel='RMSE')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_search.best_params_\n", - "#> {'n_neighbors': 5}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(-my_search.best_score_)**0.5\n", - "#> 16.07308308943869" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = my_search.best_estimator_\n", - "y_ = my_model.predict(X)\n", - "mean_squared_error(y_, y)**0.5\n", - "#> 13.087184571174962" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.7.1 補足:ハイパーパラメータとRMSE(訓練)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.metrics import mean_squared_error\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.neighbors import KNeighborsRegressor\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "def my_loocv(k):\n", - " my_model = KNeighborsRegressor(n_neighbors=k)\n", - " my_scores = cross_val_score(estimator=my_model, X=X, y=y,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - " y_ = my_model.fit(X, y).predict(X)\n", - " return pd.Series([k,\n", - " (-my_scores.mean())**0.5, # RMSE(検証)\n", - " mean_squared_error(y_, y)**0.5], # RMSE(訓練)\n", - " index=['n_neighbors', 'validation', 'training'])\n", - "\n", - "my_results = pd.Series(range(1, 16)).apply(my_loocv)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_results.plot(x='n_neighbors',\n", - " style='o-',\n", - " ylabel='RMSE')" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch07/07.01.ipynb b/code/Python-notebook/ch07/07.01.ipynb deleted file mode 100644 index f901d89..0000000 --- a/code/Python-notebook/ch07/07.01.ipynb +++ /dev/null @@ -1,19 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.1 自動車の停止距離" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch07/07.02.ipynb b/code/Python-notebook/ch07/07.02.ipynb deleted file mode 100644 index 87e3517..0000000 --- a/code/Python-notebook/ch07/07.02.ipynb +++ /dev/null @@ -1,81 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.2 データの確認" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.shape\n", - "#> (50, 2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.head()\n", - "#> speed dist\n", - "#> 0 4 2\n", - "#> 1 4 10\n", - "#> 2 7 4\n", - "#> 3 7 22\n", - "#> 4 8 16" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.describe()\n", - "#> speed dist\n", - "#> count 50.000000 50.000000\n", - "#> mean 15.400000 42.980000\n", - "#> std 5.287644 25.769377\n", - "#> min 4.000000 2.000000\n", - "#> 25% 12.000000 26.000000\n", - "#> 50% 15.000000 36.000000\n", - "#> 75% 19.000000 56.000000\n", - "#> max 25.000000 120.000000" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.plot(x='speed', style='o')" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch07/07.03.ipynb b/code/Python-notebook/ch07/07.03.ipynb deleted file mode 100644 index de8b291..0000000 --- a/code/Python-notebook/ch07/07.03.ipynb +++ /dev/null @@ -1,145 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.3 回帰分析\n", - "\n", - "### 7.3.1 回帰分析とは何か\n", - "\n", - "### 7.3.2 線形単回帰分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import seaborn as sns\n", - "import statsmodels.api as sm\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "ax = sns.regplot(x='speed', y='dist', data=my_data)\n", - "ax.vlines(x=21.5, ymin=-5, ymax=67, linestyles='dotted')\n", - "ax.hlines(y=67, xmin=4, xmax=21.5, linestyles='dotted')\n", - "ax.set_xlim(4, 25)\n", - "ax.set_ylim(-5, 125)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.3.3 回帰分析の実践\n", - "\n", - "#### 7.3.3.1 データの用意" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.2 訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# モデルの指定\n", - "from sklearn.linear_model import LinearRegression\n", - "my_model = LinearRegression()\n", - "\n", - "# 訓練(モデルをデータにフィットさせる.)\n", - "my_model.fit(X, y)\n", - "\n", - "# まとめて実行してもよい.\n", - "# my_model = LinearRegression().fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.intercept_, my_model.coef_\n", - "#> (-17.579094890510973,\n", - "#> array([3.93240876]))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.3 予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = [[21.5]]\n", - "my_model.predict(tmp)\n", - "#> array([66.96769343])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.4 モデルの可視化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "\n", - "tmp = pd.DataFrame({'speed': np.linspace(min(my_data.speed),\n", - " max(my_data.speed),\n", - " 100)})\n", - "tmp['model'] = my_model.predict(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.concat([my_data, tmp]).plot(\n", - " x='speed', style=['o', '-'])" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch07/07.04.ipynb b/code/Python-notebook/ch07/07.04.ipynb deleted file mode 100644 index 6fd48c2..0000000 --- a/code/Python-notebook/ch07/07.04.ipynb +++ /dev/null @@ -1,206 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.4 当てはまりの良さの指標\n", - "\n", - "### 7.4.1 RMSE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.metrics import mean_squared_error, r2_score\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "my_model = LinearRegression()\n", - "my_model.fit(X, y)\n", - "y_ = my_model.predict(X)\n", - "my_data['y_'] = y_" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.options.display.float_format = (\n", - " '{:.2f}'.format)\n", - "my_data['residual'] = y - y_\n", - "my_data.head()\n", - "#> speed dist y_ residual\n", - "#> 0 4 2 -1.85 3.85\n", - "#> 1 4 10 -1.85 11.85\n", - "#> 2 7 4 9.95 -5.95\n", - "#> 3 7 22 9.95 12.05\n", - "#> 4 8 16 13.88 2.12" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ax = my_data.plot(x='speed', y='dist', style='o', legend=False)\n", - "my_data.plot(x='speed', y='y_', style='-', legend=False, ax=ax)\n", - "ax.vlines(x=X, ymin=y, ymax=y_, linestyles='dotted')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mean_squared_error(y, y_)**0.5\n", - "# あるいは\n", - "(my_data['residual']**2).mean()**0.5\n", - "\n", - "#> 15.068855995791381" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.4.2 決定係数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.score(X, y)\n", - "# あるいは\n", - "r2_score(y_true=y, y_pred=y_)\n", - "#> 0.6510793807582509" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.6510793807582511" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test = my_data[:3]\n", - "X = my_test[['speed']]\n", - "y = my_test['dist']\n", - "y_ = my_model.predict(X)\n", - "\n", - "my_model.score(X, y)\n", - "# あるいは\n", - "r2_score(y_true=y, y_pred=y_)\n", - "#> -4.498191310376778 # 決定係数1\n", - "\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.0769230769230769 # 決定係数6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.4.3 当てはまりの良さの指標の問題点" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.preprocessing import PolynomialFeatures\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "\n", - "my_idx = [1, 10, 26, 33, 38, 43]\n", - "my_sample = my_data.iloc[my_idx, ]\n", - "X, y = my_sample[['speed']], my_sample['dist']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "d = 5\n", - "X5 = PolynomialFeatures(d, include_bias=False).fit_transform(X) # Xの1乗から5乗の変数\n", - "\n", - "my_model = LinearRegression()\n", - "my_model.fit(X5, y)\n", - "y_ = my_model.predict(X5)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "((y - y_)**2).mean()**0.5\n", - "#> 7.725744805546204e-07 # RMSE\n", - "\n", - "my_model.score(X5, y)\n", - "#> 0.9999999999999989 # 決定係数1\n", - "\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.9999999999999991 # 決定係数6" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = pd.DataFrame({'speed': np.linspace(min(my_data.speed),\n", - " max(my_data.speed),\n", - " 100)})\n", - "X5 = PolynomialFeatures(d, include_bias=False).fit_transform(tmp)\n", - "tmp['model'] = my_model.predict(X5)\n", - "\n", - "my_sample = my_sample.assign(sample=y)\n", - "my_df = pd.concat([my_data, my_sample, tmp])\n", - "my_df.plot(x='speed', style=['o', 'o', '-'], ylim=(0, 130))" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch07/07.05.ipynb b/code/Python-notebook/ch07/07.05.ipynb deleted file mode 100644 index 3a45a49..0000000 --- a/code/Python-notebook/ch07/07.05.ipynb +++ /dev/null @@ -1,77 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.5 K最近傍法\n", - "\n", - "### 7.5.1 K最近傍法とは何か\n", - "\n", - "### 7.5.2 K最近傍法の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 準備\n", - "import numpy as np\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.neighbors import KNeighborsRegressor\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "# 訓練\n", - "my_model = KNeighborsRegressor()\n", - "my_model.fit(X, y)\n", - "\n", - "# 可視化の準備\n", - "tmp = pd.DataFrame({'speed': np.linspace(min(my_data.speed),\n", - " max(my_data.speed),\n", - " 100)})\n", - "tmp['model'] = my_model.predict(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.concat([my_data, tmp]).plot(\n", - " x='speed', style=['o', '-'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = my_model.predict(X)\n", - "\n", - "((y - y_)**2).mean()**0.5\n", - "#> 13.087184571174962 # RMSE\n", - "\n", - "my_model.score(X, y)\n", - "#> 0.7368165812204317 # 決定係数1\n", - "\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.7380949412509705 # 決定係数6" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch07/07.06.ipynb b/code/Python-notebook/ch07/07.06.ipynb deleted file mode 100644 index 11d93ae..0000000 --- a/code/Python-notebook/ch07/07.06.ipynb +++ /dev/null @@ -1,269 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.6 検証\n", - "\n", - "### 7.6.1 訓練データ・検証データ・テストデータ\n", - "\n", - "### 7.6.2 検証とは何か\n", - "\n", - "### 7.6.3 検証の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.model_selection import cross_val_score\n", - "\n", - "# データの準備\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "# モデルの指定\n", - "my_model = LinearRegression()\n", - "\n", - "# 検証(5分割交差検証)\n", - "my_scores = cross_val_score(my_model, X, y)\n", - "\n", - "# 5個の決定係数1を得る.\n", - "my_scores\n", - "#> array([-0.25789256, -0.21421069, -0.30902773, -0.27346232, 0.02312918])\n", - "\n", - "# 平均を決定係数1(検証)とする.\n", - "my_scores.mean()\n", - "#> -0.20629282165364665" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scores = cross_val_score(my_model, X, y,\n", - " scoring='neg_root_mean_squared_error')\n", - "-my_scores.mean()\n", - "#> 15.58402474583013 # RMSE(検証)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.6.4 検証の並列化\n", - "\n", - "### 7.6.5 指標のまとめ\n", - "\n", - "#### 7.6.5.1 準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import statsmodels.api as sm\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.metrics import mean_squared_error, r2_score\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "my_model = LinearRegression().fit(X, y)\n", - "y_ = my_model.predict(X)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.2 当てはまりの良さの指標" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# RMSE(訓練)\n", - "mean_squared_error(y, y_)**0.5\n", - "#> 15.068855995791381\n", - "\n", - "# 決定係数1(訓練)\n", - "my_model.score(X, y)\n", - "# あるいは\n", - "r2_score(y_true=y, y_pred=y_)\n", - "#> 0.6510793807582509\n", - "\n", - "# 決定係数6(訓練)\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.6510793807582511" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.3 予測性能の指標(簡単に求められるもの)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scores = cross_val_score(my_model, X, y,\n", - " scoring='neg_root_mean_squared_error')\n", - "-my_scores.mean()\n", - "#> 15.301860331378464 # RMSE(検証)\n", - "\n", - "my_scores = cross_val_score(my_model, X, y, scoring='r2') # scoring='r2'は省略可\n", - "my_scores.mean()\n", - "#> 0.49061365458235245 # 決定係数1(検証)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.4 予測性能の指標(RとPythonで同じ結果を得る)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 方法1\n", - "my_scores1 = cross_val_score(my_model, X, y, cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "(-my_scores1.mean())**0.5\n", - "#> 15.697306009399101\n", - "\n", - "# 方法2\n", - "my_scores2 = cross_val_score(my_model, X, y, cv=LeaveOneOut(),\n", - " scoring='neg_root_mean_squared_error')\n", - "(my_scores2**2).mean()**0.5\n", - "#> 15.697306009399101" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "-my_scores2.mean()\n", - "#> 12.059178648637483" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.6.6 補足:検証による手法の比較" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.metrics import mean_squared_error\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.neighbors import KNeighborsRegressor\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "my_lm_scores = cross_val_score(\n", - " LinearRegression(),\n", - " X, y, cv=LeaveOneOut(), scoring='neg_mean_squared_error')\n", - "\n", - "my_knn_socres = cross_val_score(\n", - " KNeighborsRegressor(n_neighbors=5),\n", - " X, y, cv=LeaveOneOut(), scoring='neg_mean_squared_error')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(-my_lm_scores.mean())**0.5\n", - "#> 15.697306009399101 # 線形回帰分析\n", - "\n", - "(-my_knn_socres.mean())**0.5\n", - "#> 16.07308308943869 # K最近傍法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame({\n", - " 'lm': -my_lm_scores,\n", - " 'knn': -my_knn_socres})\n", - "my_df.head()\n", - "#> lm knn\n", - "#> 0 18.913720 108.16\n", - "#> 1 179.215044 0.64\n", - "#> 2 41.034336 64.00\n", - "#> 3 168.490212 184.96\n", - "#> 4 5.085308 0.00" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.boxplot().set_ylabel(\"$r^2$\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from statsmodels.stats.weightstats import DescrStatsW\n", - "d = DescrStatsW(my_df.lm - my_df.knn)\n", - "d.ttest_mean()[1] # p値\n", - "#> 0.6952755720536115\n", - "\n", - "d.tconfint_mean(alpha=0.05, alternative='two-sided') # 信頼区間\n", - "#> (-72.8275283312228, 48.95036023665703)" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch07/07.07.ipynb b/code/Python-notebook/ch07/07.07.ipynb deleted file mode 100644 index 4e80f7e..0000000 --- a/code/Python-notebook/ch07/07.07.ipynb +++ /dev/null @@ -1,159 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.7 パラメータチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.metrics import mean_squared_error\n", - "from sklearn.model_selection import GridSearchCV, LeaveOneOut\n", - "from sklearn.neighbors import KNeighborsRegressor\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "my_params = {'n_neighbors': range(1, 16)} # 探索範囲(1以上16未満の整数)\n", - "\n", - "my_search = GridSearchCV(estimator=KNeighborsRegressor(),\n", - " param_grid=my_params,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "my_search.fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_search.cv_results_ # チューニングの詳細\n", - "my_scores = (-tmp['mean_test_score'])**0.5 # RMSE\n", - "my_results = pd.DataFrame(tmp['params']).assign(validation=my_scores)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_results.head()\n", - "#> n_neighbors validation\n", - "#> 0 1 20.089798\n", - "#> 1 2 17.577685\n", - "#> 2 3 16.348836\n", - "#> 3 4 16.198804\n", - "#> 4 5 16.073083" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_results.plot(x='n_neighbors',\n", - " style='o-',\n", - " ylabel='RMSE')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_search.best_params_\n", - "#> {'n_neighbors': 5}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(-my_search.best_score_)**0.5\n", - "#> 16.07308308943869" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = my_search.best_estimator_\n", - "y_ = my_model.predict(X)\n", - "mean_squared_error(y_, y)**0.5\n", - "#> 13.087184571174962" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.7.1 補足:ハイパーパラメータとRMSE(訓練)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.metrics import mean_squared_error\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.neighbors import KNeighborsRegressor\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "def my_loocv(k):\n", - " my_model = KNeighborsRegressor(n_neighbors=k)\n", - " my_scores = cross_val_score(estimator=my_model, X=X, y=y,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - " y_ = my_model.fit(X, y).predict(X)\n", - " return pd.Series([k,\n", - " (-my_scores.mean())**0.5, # RMSE(検証)\n", - " mean_squared_error(y_, y)**0.5], # RMSE(訓練)\n", - " index=['n_neighbors', 'validation', 'training'])\n", - "\n", - "my_results = pd.Series(range(1, 16)).apply(my_loocv)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_results.plot(x='n_neighbors',\n", - " style='o-',\n", - " ylabel='RMSE')" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch07/07.ipynb b/code/Python-notebook/ch07/07.ipynb deleted file mode 100644 index d5886e5..0000000 --- a/code/Python-notebook/ch07/07.ipynb +++ /dev/null @@ -1,881 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 07\n", - "\n", - "## 7.1 自動車の停止距離\n", - "\n", - "## 7.2 データの確認" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.shape\n", - "#> (50, 2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.head()\n", - "#> speed dist\n", - "#> 0 4 2\n", - "#> 1 4 10\n", - "#> 2 7 4\n", - "#> 3 7 22\n", - "#> 4 8 16" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.describe()\n", - "#> speed dist\n", - "#> count 50.000000 50.000000\n", - "#> mean 15.400000 42.980000\n", - "#> std 5.287644 25.769377\n", - "#> min 4.000000 2.000000\n", - "#> 25% 12.000000 26.000000\n", - "#> 50% 15.000000 36.000000\n", - "#> 75% 19.000000 56.000000\n", - "#> max 25.000000 120.000000" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.plot(x='speed', style='o')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.3 回帰分析\n", - "\n", - "### 7.3.1 回帰分析とは何か\n", - "\n", - "### 7.3.2 線形単回帰分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import seaborn as sns\n", - "import statsmodels.api as sm\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "ax = sns.regplot(x='speed', y='dist', data=my_data)\n", - "ax.vlines(x=21.5, ymin=-5, ymax=67, linestyles='dotted')\n", - "ax.hlines(y=67, xmin=4, xmax=21.5, linestyles='dotted')\n", - "ax.set_xlim(4, 25)\n", - "ax.set_ylim(-5, 125)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.3.3 回帰分析の実践\n", - "\n", - "#### 7.3.3.1 データの用意" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.2 訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# モデルの指定\n", - "from sklearn.linear_model import LinearRegression\n", - "my_model = LinearRegression()\n", - "\n", - "# 訓練(モデルをデータにフィットさせる.)\n", - "my_model.fit(X, y)\n", - "\n", - "# まとめて実行してもよい.\n", - "# my_model = LinearRegression().fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.intercept_, my_model.coef_\n", - "#> (-17.579094890510973,\n", - "#> array([3.93240876]))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.3 予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = [[21.5]]\n", - "my_model.predict(tmp)\n", - "#> array([66.96769343])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.4 モデルの可視化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "\n", - "tmp = pd.DataFrame({'speed': np.linspace(min(my_data.speed),\n", - " max(my_data.speed),\n", - " 100)})\n", - "tmp['model'] = my_model.predict(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.concat([my_data, tmp]).plot(\n", - " x='speed', style=['o', '-'])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.4 当てはまりの良さの指標\n", - "\n", - "### 7.4.1 RMSE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.metrics import mean_squared_error, r2_score\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "my_model = LinearRegression()\n", - "my_model.fit(X, y)\n", - "y_ = my_model.predict(X)\n", - "my_data['y_'] = y_" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.options.display.float_format = (\n", - " '{:.2f}'.format)\n", - "my_data['residual'] = y - y_\n", - "my_data.head()\n", - "#> speed dist y_ residual\n", - "#> 0 4 2 -1.85 3.85\n", - "#> 1 4 10 -1.85 11.85\n", - "#> 2 7 4 9.95 -5.95\n", - "#> 3 7 22 9.95 12.05\n", - "#> 4 8 16 13.88 2.12" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ax = my_data.plot(x='speed', y='dist', style='o', legend=False)\n", - "my_data.plot(x='speed', y='y_', style='-', legend=False, ax=ax)\n", - "ax.vlines(x=X, ymin=y, ymax=y_, linestyles='dotted')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mean_squared_error(y, y_)**0.5\n", - "# あるいは\n", - "(my_data['residual']**2).mean()**0.5\n", - "\n", - "#> 15.068855995791381" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.4.2 決定係数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.score(X, y)\n", - "# あるいは\n", - "r2_score(y_true=y, y_pred=y_)\n", - "#> 0.6510793807582509" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.6510793807582511" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test = my_data[:3]\n", - "X = my_test[['speed']]\n", - "y = my_test['dist']\n", - "y_ = my_model.predict(X)\n", - "\n", - "my_model.score(X, y)\n", - "# あるいは\n", - "r2_score(y_true=y, y_pred=y_)\n", - "#> -4.498191310376778 # 決定係数1\n", - "\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.0769230769230769 # 決定係数6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.4.3 当てはまりの良さの指標の問題点" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.preprocessing import PolynomialFeatures\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "\n", - "my_idx = [1, 10, 26, 33, 38, 43]\n", - "my_sample = my_data.iloc[my_idx, ]\n", - "X, y = my_sample[['speed']], my_sample['dist']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "d = 5\n", - "X5 = PolynomialFeatures(d, include_bias=False).fit_transform(X) # Xの1乗から5乗の変数\n", - "\n", - "my_model = LinearRegression()\n", - "my_model.fit(X5, y)\n", - "y_ = my_model.predict(X5)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "((y - y_)**2).mean()**0.5\n", - "#> 7.725744805546204e-07 # RMSE\n", - "\n", - "my_model.score(X5, y)\n", - "#> 0.9999999999999989 # 決定係数1\n", - "\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.9999999999999991 # 決定係数6" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = pd.DataFrame({'speed': np.linspace(min(my_data.speed),\n", - " max(my_data.speed),\n", - " 100)})\n", - "X5 = PolynomialFeatures(d, include_bias=False).fit_transform(tmp)\n", - "tmp['model'] = my_model.predict(X5)\n", - "\n", - "my_sample = my_sample.assign(sample=y)\n", - "my_df = pd.concat([my_data, my_sample, tmp])\n", - "my_df.plot(x='speed', style=['o', 'o', '-'], ylim=(0, 130))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.5 K最近傍法\n", - "\n", - "### 7.5.1 K最近傍法とは何か\n", - "\n", - "### 7.5.2 K最近傍法の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 準備\n", - "import numpy as np\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.neighbors import KNeighborsRegressor\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "# 訓練\n", - "my_model = KNeighborsRegressor()\n", - "my_model.fit(X, y)\n", - "\n", - "# 可視化の準備\n", - "tmp = pd.DataFrame({'speed': np.linspace(min(my_data.speed),\n", - " max(my_data.speed),\n", - " 100)})\n", - "tmp['model'] = my_model.predict(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.concat([my_data, tmp]).plot(\n", - " x='speed', style=['o', '-'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = my_model.predict(X)\n", - "\n", - "((y - y_)**2).mean()**0.5\n", - "#> 13.087184571174962 # RMSE\n", - "\n", - "my_model.score(X, y)\n", - "#> 0.7368165812204317 # 決定係数1\n", - "\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.7380949412509705 # 決定係数6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.6 検証\n", - "\n", - "### 7.6.1 訓練データ・検証データ・テストデータ\n", - "\n", - "### 7.6.2 検証とは何か\n", - "\n", - "### 7.6.3 検証の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.model_selection import cross_val_score\n", - "\n", - "# データの準備\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "# モデルの指定\n", - "my_model = LinearRegression()\n", - "\n", - "# 検証(5分割交差検証)\n", - "my_scores = cross_val_score(my_model, X, y)\n", - "\n", - "# 5個の決定係数1を得る.\n", - "my_scores\n", - "#> array([-0.25789256, -0.21421069, -0.30902773, -0.27346232, 0.02312918])\n", - "\n", - "# 平均を決定係数1(検証)とする.\n", - "my_scores.mean()\n", - "#> -0.20629282165364665" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scores = cross_val_score(my_model, X, y,\n", - " scoring='neg_root_mean_squared_error')\n", - "-my_scores.mean()\n", - "#> 15.58402474583013 # RMSE(検証)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.6.4 検証の並列化\n", - "\n", - "### 7.6.5 指標のまとめ\n", - "\n", - "#### 7.6.5.1 準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import statsmodels.api as sm\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.metrics import mean_squared_error, r2_score\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "my_model = LinearRegression().fit(X, y)\n", - "y_ = my_model.predict(X)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.2 当てはまりの良さの指標" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# RMSE(訓練)\n", - "mean_squared_error(y, y_)**0.5\n", - "#> 15.068855995791381\n", - "\n", - "# 決定係数1(訓練)\n", - "my_model.score(X, y)\n", - "# あるいは\n", - "r2_score(y_true=y, y_pred=y_)\n", - "#> 0.6510793807582509\n", - "\n", - "# 決定係数6(訓練)\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.6510793807582511" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.3 予測性能の指標(簡単に求められるもの)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scores = cross_val_score(my_model, X, y,\n", - " scoring='neg_root_mean_squared_error')\n", - "-my_scores.mean()\n", - "#> 15.301860331378464 # RMSE(検証)\n", - "\n", - "my_scores = cross_val_score(my_model, X, y, scoring='r2') # scoring='r2'は省略可\n", - "my_scores.mean()\n", - "#> 0.49061365458235245 # 決定係数1(検証)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.4 予測性能の指標(RとPythonで同じ結果を得る)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 方法1\n", - "my_scores1 = cross_val_score(my_model, X, y, cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "(-my_scores1.mean())**0.5\n", - "#> 15.697306009399101\n", - "\n", - "# 方法2\n", - "my_scores2 = cross_val_score(my_model, X, y, cv=LeaveOneOut(),\n", - " scoring='neg_root_mean_squared_error')\n", - "(my_scores2**2).mean()**0.5\n", - "#> 15.697306009399101" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "-my_scores2.mean()\n", - "#> 12.059178648637483" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.6.6 補足:検証による手法の比較" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.metrics import mean_squared_error\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.neighbors import KNeighborsRegressor\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "my_lm_scores = cross_val_score(\n", - " LinearRegression(),\n", - " X, y, cv=LeaveOneOut(), scoring='neg_mean_squared_error')\n", - "\n", - "my_knn_socres = cross_val_score(\n", - " KNeighborsRegressor(n_neighbors=5),\n", - " X, y, cv=LeaveOneOut(), scoring='neg_mean_squared_error')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(-my_lm_scores.mean())**0.5\n", - "#> 15.697306009399101 # 線形回帰分析\n", - "\n", - "(-my_knn_socres.mean())**0.5\n", - "#> 16.07308308943869 # K最近傍法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df = pd.DataFrame({\n", - " 'lm': -my_lm_scores,\n", - " 'knn': -my_knn_socres})\n", - "my_df.head()\n", - "#> lm knn\n", - "#> 0 18.913720 108.16\n", - "#> 1 179.215044 0.64\n", - "#> 2 41.034336 64.00\n", - "#> 3 168.490212 184.96\n", - "#> 4 5.085308 0.00" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df.boxplot().set_ylabel(\"$r^2$\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from statsmodels.stats.weightstats import DescrStatsW\n", - "d = DescrStatsW(my_df.lm - my_df.knn)\n", - "d.ttest_mean()[1] # p値\n", - "#> 0.6952755720536115\n", - "\n", - "d.tconfint_mean(alpha=0.05, alternative='two-sided') # 信頼区間\n", - "#> (-72.8275283312228, 48.95036023665703)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.7 パラメータチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.metrics import mean_squared_error\n", - "from sklearn.model_selection import GridSearchCV, LeaveOneOut\n", - "from sklearn.neighbors import KNeighborsRegressor\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "my_params = {'n_neighbors': range(1, 16)} # 探索範囲(1以上16未満の整数)\n", - "\n", - "my_search = GridSearchCV(estimator=KNeighborsRegressor(),\n", - " param_grid=my_params,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "my_search.fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_search.cv_results_ # チューニングの詳細\n", - "my_scores = (-tmp['mean_test_score'])**0.5 # RMSE\n", - "my_results = pd.DataFrame(tmp['params']).assign(validation=my_scores)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_results.head()\n", - "#> n_neighbors validation\n", - "#> 0 1 20.089798\n", - "#> 1 2 17.577685\n", - "#> 2 3 16.348836\n", - "#> 3 4 16.198804\n", - "#> 4 5 16.073083" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_results.plot(x='n_neighbors',\n", - " style='o-',\n", - " ylabel='RMSE')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_search.best_params_\n", - "#> {'n_neighbors': 5}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(-my_search.best_score_)**0.5\n", - "#> 16.07308308943869" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = my_search.best_estimator_\n", - "y_ = my_model.predict(X)\n", - "mean_squared_error(y_, y)**0.5\n", - "#> 13.087184571174962" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.7.1 補足:ハイパーパラメータとRMSE(訓練)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.metrics import mean_squared_error\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.neighbors import KNeighborsRegressor\n", - "\n", - "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", - "X, y = my_data[['speed']], my_data['dist']\n", - "\n", - "def my_loocv(k):\n", - " my_model = KNeighborsRegressor(n_neighbors=k)\n", - " my_scores = cross_val_score(estimator=my_model, X=X, y=y,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - " y_ = my_model.fit(X, y).predict(X)\n", - " return pd.Series([k,\n", - " (-my_scores.mean())**0.5, # RMSE(検証)\n", - " mean_squared_error(y_, y)**0.5], # RMSE(訓練)\n", - " index=['n_neighbors', 'validation', 'training'])\n", - "\n", - "my_results = pd.Series(range(1, 16)).apply(my_loocv)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_results.plot(x='n_neighbors',\n", - " style='o-',\n", - " ylabel='RMSE')" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch08/08-colab.ipynb b/code/Python-notebook/ch08/08-colab.ipynb deleted file mode 100644 index f6cab75..0000000 --- a/code/Python-notebook/ch08/08-colab.ipynb +++ /dev/null @@ -1,669 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 08\n", - "\n", - "## 8.1 ブドウの生育条件とワインの価格" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "my_url = 'http://www.liquidasset.com/winedata.html'\n", - "tmp = pd.read_table(my_url, skiprows=62, nrows=38, sep='\\\\s+', na_values='.')\n", - "tmp.describe()\n", - "#> OBS VINT LPRICE2 WRAIN DEGREES ...\n", - "#> count 38.000000 38.000000 27.000000 38.000000 37.000000 ...\n", - "#> mean 19.500000 1970.500000 -1.451765 605.000000 16.522973 ...\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data = tmp.iloc[:, 2:].dropna()\n", - "my_data.head()\n", - "#> LPRICE2 WRAIN DEGREES ...\n", - "#> 0 -0.99868 600 17.1167 ...\n", - "#> 1 -0.45440 690 16.7333 ...\n", - "#> 3 -0.80796 502 17.1500 ...\n", - "#> 5 -1.50926 420 16.1333 ...\n", - "#> 6 -1.71655 582 16.4167 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.shape\n", - "#> (27, 5)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.to_csv('wine.csv',\n", - " index=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#my_data = pd.read_csv('wine.csv') # 作ったファイルを使う場合\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.2 重回帰分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.metrics import mean_squared_error\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2']\n", - "\n", - "my_model = LinearRegression().fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.intercept_\n", - "#> -12.145333576510417\n", - "\n", - "pd.Series(my_model.coef_,\n", - " index=X.columns)\n", - "#> WRAIN 0.001167\n", - "#> DEGREES 0.616392\n", - "#> HRAIN -0.003861\n", - "#> TIME_SV 0.023847\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test = [[500, 17, 120, 2]]\n", - "my_model.predict(my_test)\n", - "#> array([-1.49884253])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = my_model.predict(X)\n", - "\n", - "mean_squared_error(y_, y)**0.5\n", - "#> 0.2586166620130621 # RMSE(訓練)\n", - "\n", - "my_model.score(X, y)\n", - "#> 0.8275277990052154 # 決定係数1\n", - "\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.8275277990052158 # 決定係数6" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scores = cross_val_score(my_model, X, y,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "(-my_scores.mean())**0.5\n", - "#> 0.32300426518411957 # RMSE(検証)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.2.1 補足:行列計算による再現" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "M = np.matrix(X.assign(b0=1))\n", - "b = np.linalg.pinv(M) @ y\n", - "pd.Series(b,\n", - " index=list(X.columns) + ['b0'])\n", - "#> WRAIN 0.001167\n", - "#> DEGREES 0.616392\n", - "#> HRAIN -0.003861\n", - "#> TIME_SV 0.023847\n", - "#> b0 -12.145334\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.3 標準化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import StandardScaler\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2']\n", - "\n", - "# StandardScalerで標準化した結果をデータフレームに戻してから描画する.\n", - "pd.DataFrame(StandardScaler().fit_transform(X), columns=X.columns\n", - " ).boxplot(showmeans=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_pipeline = Pipeline([\n", - " ('sc', StandardScaler()),\n", - " ('lr', LinearRegression())])\n", - "my_pipeline.fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 線形回帰の部分だけを取り出す.\n", - "my_lr = my_pipeline.named_steps.lr\n", - "my_lr.intercept_\n", - "#> -1.4517651851851847\n", - "\n", - "pd.Series(my_lr.coef_,\n", - " index=X.columns)\n", - "#> WRAIN 0.147741\n", - "#> DEGREES 0.398724\n", - "#> HRAIN -0.276802\n", - "#> TIME_SV 0.192979\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test = [[500, 17, 120, 2]]\n", - "my_pipeline.predict(my_test)\n", - "#> array([-1.49884253])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.4 入力変数の数とモデルの良さ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.metrics import mean_squared_error\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "\n", - "n = len(my_data)\n", - "my_data2 = my_data.assign(v1=[i % 2 for i in range(n)],\n", - " v2=[i % 3 for i in range(n)])\n", - "my_data2.head()\n", - "#> LPRICE2 WRAIN DEGREES HRAIN TIME_SV v1 v2\n", - "#> 0 -0.99868 600 17.1167 160 31 0 0\n", - "#> 1 -0.45440 690 16.7333 80 30 1 1\n", - "#> 2 -0.80796 502 17.1500 130 28 0 2\n", - "#> 3 -1.50926 420 16.1333 110 26 1 0\n", - "#> 4 -1.71655 582 16.4167 187 25 0 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X, y = my_data2.drop(columns=['LPRICE2']), my_data2['LPRICE2']\n", - "my_model2 = LinearRegression().fit(X, y)\n", - "\n", - "y_ = my_model2.predict(X)\n", - "mean_squared_error(y_, y)**0.5\n", - "#> 0.2562120047505748 # RMSE(訓練)\n", - "\n", - "my_scores = cross_val_score(my_model2, X, y,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "(-my_scores.mean())**0.5\n", - "#> 0.3569918035928941 # RMSE(検証)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.5 変数選択" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.feature_selection import SequentialFeatureSelector\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.model_selection import GridSearchCV, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "\n", - "n = len(my_data)\n", - "my_data2 = my_data.assign(v1=[i % 2 for i in range(n)],\n", - " v2=[i % 3 for i in range(n)])\n", - "X, y = my_data2.drop(columns=['LPRICE2']), my_data2['LPRICE2']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_sfs = SequentialFeatureSelector(\n", - " estimator=LinearRegression(),\n", - " direction='forward', # 変数増加法\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "\n", - "my_pipeline = Pipeline([ # 変数選択の後で再訓練を行うようにする.\n", - " ('sfs', my_sfs), # 変数選択\n", - " ('lr', LinearRegression())]) # 回帰分析\n", - "\n", - "my_params = {'sfs__n_features_to_select': range(1, 6)} # 選択する変数の上限\n", - "my_search = GridSearchCV(estimator=my_pipeline,\n", - " param_grid=my_params,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error',\n", - " n_jobs=-1).fit(X, y)\n", - "my_model = my_search.best_estimator_ # 最良のパラメータで再訓練したモデル\n", - "my_search.best_estimator_.named_steps.sfs.get_support()\n", - "#> array([ True, True, True, True, False, False])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.6 補足:正則化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import warnings\n", - "from sklearn.exceptions import ConvergenceWarning\n", - "from sklearn.linear_model import ElasticNet, enet_path\n", - "from sklearn.model_selection import GridSearchCV, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import StandardScaler\n", - "from scipy.stats import zscore\n", - "warnings.simplefilter('ignore', ConvergenceWarning) # これ以降,警告を表示しない.\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.1 正則化の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A = 2\n", - "B = 0.1\n", - "\n", - "my_pipeline = Pipeline([\n", - " ('sc', StandardScaler()),\n", - " ('enet', ElasticNet(\n", - " alpha=A,\n", - " l1_ratio=B))])\n", - "my_pipeline.fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_enet = my_pipeline.named_steps.enet\n", - "my_enet.intercept_\n", - "#> -1.4517651851851852\n", - "\n", - "pd.Series(my_enet.coef_,\n", - " index=X.columns)\n", - "#> WRAIN 0.000000\n", - "#> DEGREES 0.074101\n", - "#> HRAIN -0.041159\n", - "#> TIME_SV 0.024027\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test = pd.DataFrame(\n", - " [[500, 17, 120, 2]])\n", - "my_pipeline.predict(my_test)\n", - "#> array([-1.41981616])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.2 ペナルティの強さと係数の関係" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "As = np.e**np.arange(2, -5.5, -0.1)\n", - "B = 0.1\n", - "\n", - "_, my_path, _ = enet_path(\n", - " zscore(X), zscore(y),\n", - " alphas=As,\n", - " l1_ratio=B)\n", - "\n", - "pd.DataFrame(\n", - " my_path.T,\n", - " columns=X.columns,\n", - " index=np.log(As)\n", - ").plot(\n", - " xlabel='log A ( = log alpha)',\n", - " ylabel='Coefficients')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.3 パラメータの決定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "As = np.linspace(0, 0.1, 21)\n", - "Bs = np.linspace(0, 0.1, 6)\n", - "\n", - "my_pipeline = Pipeline([('sc', StandardScaler()),\n", - " ('enet', ElasticNet())])\n", - "my_search = GridSearchCV(\n", - " estimator=my_pipeline,\n", - " param_grid={'enet__alpha': As, 'enet__l1_ratio': Bs},\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error',\n", - " n_jobs=-1).fit(X, y)\n", - "my_model = my_search.best_estimator_ # 最良モデル\n", - "\n", - "my_search.best_params_ # 最良パラメータ\n", - "#> {'enet__alpha': 0.075, 'enet__l1_ratio': 0.0}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_search.cv_results_ # チューニングの詳細\n", - "my_scores = (-tmp['mean_test_score'])**0.5 # RMSE\n", - "\n", - "my_results = pd.DataFrame(tmp['params']).assign(RMSE=my_scores).pivot(\n", - " index='enet__alpha',\n", - " columns='enet__l1_ratio',\n", - " values='RMSE')\n", - "\n", - "my_results.plot(style='o-', xlabel='A ( = alpha)', ylabel='RMSE').legend(\n", - " title='B ( = l1_ratio)')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(-my_search.best_score_)**0.5\n", - "#> 0.31945619679509646" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.4 補足:RとPythonで結果を同じにする方法\n", - "\n", - "## 8.7 ニューラルネットワーク\n", - "\n", - "### 8.7.1 ニューラルネットワークとは何か" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "x = np.linspace(-6, 6, 100)\n", - "y = 1 / (1 + np.exp(-x))\n", - "plt.plot(x, y)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.7.2 ニューラルネットワークの訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import warnings\n", - "from sklearn.exceptions import ConvergenceWarning\n", - "from sklearn.neural_network import MLPRegressor\n", - "from sklearn.model_selection import cross_val_score, GridSearchCV, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import StandardScaler\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "warnings.simplefilter(\"ignore\", ConvergenceWarning) # これ以降,警告を表示しない.\n", - "my_pipeline = Pipeline([('sc', StandardScaler()), # 標準化\n", - " ('mlp', MLPRegressor())]) # ニューラルネットワーク\n", - "my_pipeline.fit(X, y) # 訓練\n", - "\n", - "my_scores = cross_val_score(my_pipeline, X, y, cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "warnings.simplefilter(\"default\", ConvergenceWarning) # これ以降,警告を表示する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(-my_scores.mean())**0.5\n", - "#> 0.41735891601426384" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.7.3 ニューラルネットワークのチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_pipeline = Pipeline([\n", - " ('sc', StandardScaler()),\n", - " ('mlp', MLPRegressor(tol=1e-5, # 改善したと見なす基準\n", - " max_iter=5000))]) # 改善しなくなるまでの反復数\n", - "my_layers = (1, 3, 5, # 隠れ層1層の場合\n", - " (1, 1), (3, 1), (5, 1), (1, 2), (3, 2), (5, 2)) # 隠れ層2層の場合\n", - "my_params = {'mlp__hidden_layer_sizes': my_layers}\n", - "my_search = GridSearchCV(estimator=my_pipeline,\n", - " param_grid=my_params,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error',\n", - " n_jobs=-1).fit(X, y)\n", - "my_model = my_search.best_estimator_ # 最良モデル\n", - "\n", - "my_search.best_params_ # 最良パラメータ\n", - "#> {'mlp__hidden_layer_sizes': 5}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(-my_search.best_score_)**0.5\n", - "#> 0.3759690731968538" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch08/08.01.ipynb b/code/Python-notebook/ch08/08.01.ipynb deleted file mode 100644 index 4e61554..0000000 --- a/code/Python-notebook/ch08/08.01.ipynb +++ /dev/null @@ -1,83 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.1 ブドウの生育条件とワインの価格" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "my_url = 'http://www.liquidasset.com/winedata.html'\n", - "tmp = pd.read_table(my_url, skiprows=62, nrows=38, sep='\\\\s+', na_values='.')\n", - "tmp.describe()\n", - "#> OBS VINT LPRICE2 WRAIN DEGREES ...\n", - "#> count 38.000000 38.000000 27.000000 38.000000 37.000000 ...\n", - "#> mean 19.500000 1970.500000 -1.451765 605.000000 16.522973 ...\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data = tmp.iloc[:, 2:].dropna()\n", - "my_data.head()\n", - "#> LPRICE2 WRAIN DEGREES ...\n", - "#> 0 -0.99868 600 17.1167 ...\n", - "#> 1 -0.45440 690 16.7333 ...\n", - "#> 3 -0.80796 502 17.1500 ...\n", - "#> 5 -1.50926 420 16.1333 ...\n", - "#> 6 -1.71655 582 16.4167 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.shape\n", - "#> (27, 5)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.to_csv('wine.csv',\n", - " index=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#my_data = pd.read_csv('wine.csv') # 作ったファイルを使う場合\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch08/08.02.ipynb b/code/Python-notebook/ch08/08.02.ipynb deleted file mode 100644 index 5cd2dab..0000000 --- a/code/Python-notebook/ch08/08.02.ipynb +++ /dev/null @@ -1,125 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.2 重回帰分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.metrics import mean_squared_error\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2']\n", - "\n", - "my_model = LinearRegression().fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.intercept_\n", - "#> -12.145333576510417\n", - "\n", - "pd.Series(my_model.coef_,\n", - " index=X.columns)\n", - "#> WRAIN 0.001167\n", - "#> DEGREES 0.616392\n", - "#> HRAIN -0.003861\n", - "#> TIME_SV 0.023847\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test = [[500, 17, 120, 2]]\n", - "my_model.predict(my_test)\n", - "#> array([-1.49884253])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = my_model.predict(X)\n", - "\n", - "mean_squared_error(y_, y)**0.5\n", - "#> 0.2586166620130621 # RMSE(訓練)\n", - "\n", - "my_model.score(X, y)\n", - "#> 0.8275277990052154 # 決定係数1\n", - "\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.8275277990052158 # 決定係数6" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scores = cross_val_score(my_model, X, y,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "(-my_scores.mean())**0.5\n", - "#> 0.32300426518411957 # RMSE(検証)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.2.1 補足:行列計算による再現" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "M = np.matrix(X.assign(b0=1))\n", - "b = np.linalg.pinv(M) @ y\n", - "pd.Series(b,\n", - " index=list(X.columns) + ['b0'])\n", - "#> WRAIN 0.001167\n", - "#> DEGREES 0.616392\n", - "#> HRAIN -0.003861\n", - "#> TIME_SV 0.023847\n", - "#> b0 -12.145334\n", - "#> dtype: float64" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch08/08.03.ipynb b/code/Python-notebook/ch08/08.03.ipynb deleted file mode 100644 index 4b094e7..0000000 --- a/code/Python-notebook/ch08/08.03.ipynb +++ /dev/null @@ -1,82 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.3 標準化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import StandardScaler\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2']\n", - "\n", - "# StandardScalerで標準化した結果をデータフレームに戻してから描画する.\n", - "pd.DataFrame(StandardScaler().fit_transform(X), columns=X.columns\n", - " ).boxplot(showmeans=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_pipeline = Pipeline([\n", - " ('sc', StandardScaler()),\n", - " ('lr', LinearRegression())])\n", - "my_pipeline.fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 線形回帰の部分だけを取り出す.\n", - "my_lr = my_pipeline.named_steps.lr\n", - "my_lr.intercept_\n", - "#> -1.4517651851851847\n", - "\n", - "pd.Series(my_lr.coef_,\n", - " index=X.columns)\n", - "#> WRAIN 0.147741\n", - "#> DEGREES 0.398724\n", - "#> HRAIN -0.276802\n", - "#> TIME_SV 0.192979\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test = [[500, 17, 120, 2]]\n", - "my_pipeline.predict(my_test)\n", - "#> array([-1.49884253])" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch08/08.04.ipynb b/code/Python-notebook/ch08/08.04.ipynb deleted file mode 100644 index f06f864..0000000 --- a/code/Python-notebook/ch08/08.04.ipynb +++ /dev/null @@ -1,66 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.4 入力変数の数とモデルの良さ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.metrics import mean_squared_error\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "\n", - "n = len(my_data)\n", - "my_data2 = my_data.assign(v1=[i % 2 for i in range(n)],\n", - " v2=[i % 3 for i in range(n)])\n", - "my_data2.head()\n", - "#> LPRICE2 WRAIN DEGREES HRAIN TIME_SV v1 v2\n", - "#> 0 -0.99868 600 17.1167 160 31 0 0\n", - "#> 1 -0.45440 690 16.7333 80 30 1 1\n", - "#> 2 -0.80796 502 17.1500 130 28 0 2\n", - "#> 3 -1.50926 420 16.1333 110 26 1 0\n", - "#> 4 -1.71655 582 16.4167 187 25 0 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X, y = my_data2.drop(columns=['LPRICE2']), my_data2['LPRICE2']\n", - "my_model2 = LinearRegression().fit(X, y)\n", - "\n", - "y_ = my_model2.predict(X)\n", - "mean_squared_error(y_, y)**0.5\n", - "#> 0.2562120047505748 # RMSE(訓練)\n", - "\n", - "my_scores = cross_val_score(my_model2, X, y,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "(-my_scores.mean())**0.5\n", - "#> 0.3569918035928941 # RMSE(検証)" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch08/08.05.ipynb b/code/Python-notebook/ch08/08.05.ipynb deleted file mode 100644 index 9aeee8b..0000000 --- a/code/Python-notebook/ch08/08.05.ipynb +++ /dev/null @@ -1,68 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.5 変数選択" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.feature_selection import SequentialFeatureSelector\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.model_selection import GridSearchCV, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "\n", - "n = len(my_data)\n", - "my_data2 = my_data.assign(v1=[i % 2 for i in range(n)],\n", - " v2=[i % 3 for i in range(n)])\n", - "X, y = my_data2.drop(columns=['LPRICE2']), my_data2['LPRICE2']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_sfs = SequentialFeatureSelector(\n", - " estimator=LinearRegression(),\n", - " direction='forward', # 変数増加法\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "\n", - "my_pipeline = Pipeline([ # 変数選択の後で再訓練を行うようにする.\n", - " ('sfs', my_sfs), # 変数選択\n", - " ('lr', LinearRegression())]) # 回帰分析\n", - "\n", - "my_params = {'sfs__n_features_to_select': range(1, 6)} # 選択する変数の上限\n", - "my_search = GridSearchCV(estimator=my_pipeline,\n", - " param_grid=my_params,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error',\n", - " n_jobs=-1).fit(X, y)\n", - "my_model = my_search.best_estimator_ # 最良のパラメータで再訓練したモデル\n", - "my_search.best_estimator_.named_steps.sfs.get_support()\n", - "#> array([ True, True, True, True, False, False])" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch08/08.06.ipynb b/code/Python-notebook/ch08/08.06.ipynb deleted file mode 100644 index 34daa10..0000000 --- a/code/Python-notebook/ch08/08.06.ipynb +++ /dev/null @@ -1,192 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.6 補足:正則化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import warnings\n", - "from sklearn.exceptions import ConvergenceWarning\n", - "from sklearn.linear_model import ElasticNet, enet_path\n", - "from sklearn.model_selection import GridSearchCV, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import StandardScaler\n", - "from scipy.stats import zscore\n", - "warnings.simplefilter('ignore', ConvergenceWarning) # これ以降,警告を表示しない.\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.1 正則化の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A = 2\n", - "B = 0.1\n", - "\n", - "my_pipeline = Pipeline([\n", - " ('sc', StandardScaler()),\n", - " ('enet', ElasticNet(\n", - " alpha=A,\n", - " l1_ratio=B))])\n", - "my_pipeline.fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_enet = my_pipeline.named_steps.enet\n", - "my_enet.intercept_\n", - "#> -1.4517651851851852\n", - "\n", - "pd.Series(my_enet.coef_,\n", - " index=X.columns)\n", - "#> WRAIN 0.000000\n", - "#> DEGREES 0.074101\n", - "#> HRAIN -0.041159\n", - "#> TIME_SV 0.024027\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test = pd.DataFrame(\n", - " [[500, 17, 120, 2]])\n", - "my_pipeline.predict(my_test)\n", - "#> array([-1.41981616])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.2 ペナルティの強さと係数の関係" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "As = np.e**np.arange(2, -5.5, -0.1)\n", - "B = 0.1\n", - "\n", - "_, my_path, _ = enet_path(\n", - " zscore(X), zscore(y),\n", - " alphas=As,\n", - " l1_ratio=B)\n", - "\n", - "pd.DataFrame(\n", - " my_path.T,\n", - " columns=X.columns,\n", - " index=np.log(As)\n", - ").plot(\n", - " xlabel='log A ( = log alpha)',\n", - " ylabel='Coefficients')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.3 パラメータの決定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "As = np.linspace(0, 0.1, 21)\n", - "Bs = np.linspace(0, 0.1, 6)\n", - "\n", - "my_pipeline = Pipeline([('sc', StandardScaler()),\n", - " ('enet', ElasticNet())])\n", - "my_search = GridSearchCV(\n", - " estimator=my_pipeline,\n", - " param_grid={'enet__alpha': As, 'enet__l1_ratio': Bs},\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error',\n", - " n_jobs=-1).fit(X, y)\n", - "my_model = my_search.best_estimator_ # 最良モデル\n", - "\n", - "my_search.best_params_ # 最良パラメータ\n", - "#> {'enet__alpha': 0.075, 'enet__l1_ratio': 0.0}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_search.cv_results_ # チューニングの詳細\n", - "my_scores = (-tmp['mean_test_score'])**0.5 # RMSE\n", - "\n", - "my_results = pd.DataFrame(tmp['params']).assign(RMSE=my_scores).pivot(\n", - " index='enet__alpha',\n", - " columns='enet__l1_ratio',\n", - " values='RMSE')\n", - "\n", - "my_results.plot(style='o-', xlabel='A ( = alpha)', ylabel='RMSE').legend(\n", - " title='B ( = l1_ratio)')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(-my_search.best_score_)**0.5\n", - "#> 0.31945619679509646" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.4 補足:RとPythonで結果を同じにする方法" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch08/08.07.ipynb b/code/Python-notebook/ch08/08.07.ipynb deleted file mode 100644 index d98d8b3..0000000 --- a/code/Python-notebook/ch08/08.07.ipynb +++ /dev/null @@ -1,128 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.7 ニューラルネットワーク\n", - "\n", - "### 8.7.1 ニューラルネットワークとは何か" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "x = np.linspace(-6, 6, 100)\n", - "y = 1 / (1 + np.exp(-x))\n", - "plt.plot(x, y)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.7.2 ニューラルネットワークの訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import warnings\n", - "from sklearn.exceptions import ConvergenceWarning\n", - "from sklearn.neural_network import MLPRegressor\n", - "from sklearn.model_selection import cross_val_score, GridSearchCV, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import StandardScaler\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "warnings.simplefilter(\"ignore\", ConvergenceWarning) # これ以降,警告を表示しない.\n", - "my_pipeline = Pipeline([('sc', StandardScaler()), # 標準化\n", - " ('mlp', MLPRegressor())]) # ニューラルネットワーク\n", - "my_pipeline.fit(X, y) # 訓練\n", - "\n", - "my_scores = cross_val_score(my_pipeline, X, y, cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "warnings.simplefilter(\"default\", ConvergenceWarning) # これ以降,警告を表示する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(-my_scores.mean())**0.5\n", - "#> 0.41735891601426384" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.7.3 ニューラルネットワークのチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_pipeline = Pipeline([\n", - " ('sc', StandardScaler()),\n", - " ('mlp', MLPRegressor(tol=1e-5, # 改善したと見なす基準\n", - " max_iter=5000))]) # 改善しなくなるまでの反復数\n", - "my_layers = (1, 3, 5, # 隠れ層1層の場合\n", - " (1, 1), (3, 1), (5, 1), (1, 2), (3, 2), (5, 2)) # 隠れ層2層の場合\n", - "my_params = {'mlp__hidden_layer_sizes': my_layers}\n", - "my_search = GridSearchCV(estimator=my_pipeline,\n", - " param_grid=my_params,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error',\n", - " n_jobs=-1).fit(X, y)\n", - "my_model = my_search.best_estimator_ # 最良モデル\n", - "\n", - "my_search.best_params_ # 最良パラメータ\n", - "#> {'mlp__hidden_layer_sizes': 5}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(-my_search.best_score_)**0.5\n", - "#> 0.3759690731968538" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch08/08.ipynb b/code/Python-notebook/ch08/08.ipynb deleted file mode 100644 index f6cab75..0000000 --- a/code/Python-notebook/ch08/08.ipynb +++ /dev/null @@ -1,669 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 08\n", - "\n", - "## 8.1 ブドウの生育条件とワインの価格" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "my_url = 'http://www.liquidasset.com/winedata.html'\n", - "tmp = pd.read_table(my_url, skiprows=62, nrows=38, sep='\\\\s+', na_values='.')\n", - "tmp.describe()\n", - "#> OBS VINT LPRICE2 WRAIN DEGREES ...\n", - "#> count 38.000000 38.000000 27.000000 38.000000 37.000000 ...\n", - "#> mean 19.500000 1970.500000 -1.451765 605.000000 16.522973 ...\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data = tmp.iloc[:, 2:].dropna()\n", - "my_data.head()\n", - "#> LPRICE2 WRAIN DEGREES ...\n", - "#> 0 -0.99868 600 17.1167 ...\n", - "#> 1 -0.45440 690 16.7333 ...\n", - "#> 3 -0.80796 502 17.1500 ...\n", - "#> 5 -1.50926 420 16.1333 ...\n", - "#> 6 -1.71655 582 16.4167 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.shape\n", - "#> (27, 5)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.to_csv('wine.csv',\n", - " index=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#my_data = pd.read_csv('wine.csv') # 作ったファイルを使う場合\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.2 重回帰分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.metrics import mean_squared_error\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2']\n", - "\n", - "my_model = LinearRegression().fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.intercept_\n", - "#> -12.145333576510417\n", - "\n", - "pd.Series(my_model.coef_,\n", - " index=X.columns)\n", - "#> WRAIN 0.001167\n", - "#> DEGREES 0.616392\n", - "#> HRAIN -0.003861\n", - "#> TIME_SV 0.023847\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test = [[500, 17, 120, 2]]\n", - "my_model.predict(my_test)\n", - "#> array([-1.49884253])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = my_model.predict(X)\n", - "\n", - "mean_squared_error(y_, y)**0.5\n", - "#> 0.2586166620130621 # RMSE(訓練)\n", - "\n", - "my_model.score(X, y)\n", - "#> 0.8275277990052154 # 決定係数1\n", - "\n", - "np.corrcoef(y, y_)[0, 1]**2\n", - "#> 0.8275277990052158 # 決定係数6" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scores = cross_val_score(my_model, X, y,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "(-my_scores.mean())**0.5\n", - "#> 0.32300426518411957 # RMSE(検証)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.2.1 補足:行列計算による再現" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "M = np.matrix(X.assign(b0=1))\n", - "b = np.linalg.pinv(M) @ y\n", - "pd.Series(b,\n", - " index=list(X.columns) + ['b0'])\n", - "#> WRAIN 0.001167\n", - "#> DEGREES 0.616392\n", - "#> HRAIN -0.003861\n", - "#> TIME_SV 0.023847\n", - "#> b0 -12.145334\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.3 標準化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import StandardScaler\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2']\n", - "\n", - "# StandardScalerで標準化した結果をデータフレームに戻してから描画する.\n", - "pd.DataFrame(StandardScaler().fit_transform(X), columns=X.columns\n", - " ).boxplot(showmeans=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_pipeline = Pipeline([\n", - " ('sc', StandardScaler()),\n", - " ('lr', LinearRegression())])\n", - "my_pipeline.fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 線形回帰の部分だけを取り出す.\n", - "my_lr = my_pipeline.named_steps.lr\n", - "my_lr.intercept_\n", - "#> -1.4517651851851847\n", - "\n", - "pd.Series(my_lr.coef_,\n", - " index=X.columns)\n", - "#> WRAIN 0.147741\n", - "#> DEGREES 0.398724\n", - "#> HRAIN -0.276802\n", - "#> TIME_SV 0.192979\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test = [[500, 17, 120, 2]]\n", - "my_pipeline.predict(my_test)\n", - "#> array([-1.49884253])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.4 入力変数の数とモデルの良さ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.metrics import mean_squared_error\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "\n", - "n = len(my_data)\n", - "my_data2 = my_data.assign(v1=[i % 2 for i in range(n)],\n", - " v2=[i % 3 for i in range(n)])\n", - "my_data2.head()\n", - "#> LPRICE2 WRAIN DEGREES HRAIN TIME_SV v1 v2\n", - "#> 0 -0.99868 600 17.1167 160 31 0 0\n", - "#> 1 -0.45440 690 16.7333 80 30 1 1\n", - "#> 2 -0.80796 502 17.1500 130 28 0 2\n", - "#> 3 -1.50926 420 16.1333 110 26 1 0\n", - "#> 4 -1.71655 582 16.4167 187 25 0 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X, y = my_data2.drop(columns=['LPRICE2']), my_data2['LPRICE2']\n", - "my_model2 = LinearRegression().fit(X, y)\n", - "\n", - "y_ = my_model2.predict(X)\n", - "mean_squared_error(y_, y)**0.5\n", - "#> 0.2562120047505748 # RMSE(訓練)\n", - "\n", - "my_scores = cross_val_score(my_model2, X, y,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "(-my_scores.mean())**0.5\n", - "#> 0.3569918035928941 # RMSE(検証)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.5 変数選択" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.feature_selection import SequentialFeatureSelector\n", - "from sklearn.linear_model import LinearRegression\n", - "from sklearn.model_selection import GridSearchCV, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "\n", - "n = len(my_data)\n", - "my_data2 = my_data.assign(v1=[i % 2 for i in range(n)],\n", - " v2=[i % 3 for i in range(n)])\n", - "X, y = my_data2.drop(columns=['LPRICE2']), my_data2['LPRICE2']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_sfs = SequentialFeatureSelector(\n", - " estimator=LinearRegression(),\n", - " direction='forward', # 変数増加法\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "\n", - "my_pipeline = Pipeline([ # 変数選択の後で再訓練を行うようにする.\n", - " ('sfs', my_sfs), # 変数選択\n", - " ('lr', LinearRegression())]) # 回帰分析\n", - "\n", - "my_params = {'sfs__n_features_to_select': range(1, 6)} # 選択する変数の上限\n", - "my_search = GridSearchCV(estimator=my_pipeline,\n", - " param_grid=my_params,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error',\n", - " n_jobs=-1).fit(X, y)\n", - "my_model = my_search.best_estimator_ # 最良のパラメータで再訓練したモデル\n", - "my_search.best_estimator_.named_steps.sfs.get_support()\n", - "#> array([ True, True, True, True, False, False])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.6 補足:正則化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import warnings\n", - "from sklearn.exceptions import ConvergenceWarning\n", - "from sklearn.linear_model import ElasticNet, enet_path\n", - "from sklearn.model_selection import GridSearchCV, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import StandardScaler\n", - "from scipy.stats import zscore\n", - "warnings.simplefilter('ignore', ConvergenceWarning) # これ以降,警告を表示しない.\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.1 正則化の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A = 2\n", - "B = 0.1\n", - "\n", - "my_pipeline = Pipeline([\n", - " ('sc', StandardScaler()),\n", - " ('enet', ElasticNet(\n", - " alpha=A,\n", - " l1_ratio=B))])\n", - "my_pipeline.fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_enet = my_pipeline.named_steps.enet\n", - "my_enet.intercept_\n", - "#> -1.4517651851851852\n", - "\n", - "pd.Series(my_enet.coef_,\n", - " index=X.columns)\n", - "#> WRAIN 0.000000\n", - "#> DEGREES 0.074101\n", - "#> HRAIN -0.041159\n", - "#> TIME_SV 0.024027\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test = pd.DataFrame(\n", - " [[500, 17, 120, 2]])\n", - "my_pipeline.predict(my_test)\n", - "#> array([-1.41981616])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.2 ペナルティの強さと係数の関係" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "As = np.e**np.arange(2, -5.5, -0.1)\n", - "B = 0.1\n", - "\n", - "_, my_path, _ = enet_path(\n", - " zscore(X), zscore(y),\n", - " alphas=As,\n", - " l1_ratio=B)\n", - "\n", - "pd.DataFrame(\n", - " my_path.T,\n", - " columns=X.columns,\n", - " index=np.log(As)\n", - ").plot(\n", - " xlabel='log A ( = log alpha)',\n", - " ylabel='Coefficients')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.3 パラメータの決定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "As = np.linspace(0, 0.1, 21)\n", - "Bs = np.linspace(0, 0.1, 6)\n", - "\n", - "my_pipeline = Pipeline([('sc', StandardScaler()),\n", - " ('enet', ElasticNet())])\n", - "my_search = GridSearchCV(\n", - " estimator=my_pipeline,\n", - " param_grid={'enet__alpha': As, 'enet__l1_ratio': Bs},\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error',\n", - " n_jobs=-1).fit(X, y)\n", - "my_model = my_search.best_estimator_ # 最良モデル\n", - "\n", - "my_search.best_params_ # 最良パラメータ\n", - "#> {'enet__alpha': 0.075, 'enet__l1_ratio': 0.0}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_search.cv_results_ # チューニングの詳細\n", - "my_scores = (-tmp['mean_test_score'])**0.5 # RMSE\n", - "\n", - "my_results = pd.DataFrame(tmp['params']).assign(RMSE=my_scores).pivot(\n", - " index='enet__alpha',\n", - " columns='enet__l1_ratio',\n", - " values='RMSE')\n", - "\n", - "my_results.plot(style='o-', xlabel='A ( = alpha)', ylabel='RMSE').legend(\n", - " title='B ( = l1_ratio)')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(-my_search.best_score_)**0.5\n", - "#> 0.31945619679509646" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.4 補足:RとPythonで結果を同じにする方法\n", - "\n", - "## 8.7 ニューラルネットワーク\n", - "\n", - "### 8.7.1 ニューラルネットワークとは何か" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "x = np.linspace(-6, 6, 100)\n", - "y = 1 / (1 + np.exp(-x))\n", - "plt.plot(x, y)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.7.2 ニューラルネットワークの訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import warnings\n", - "from sklearn.exceptions import ConvergenceWarning\n", - "from sklearn.neural_network import MLPRegressor\n", - "from sklearn.model_selection import cross_val_score, GridSearchCV, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import StandardScaler\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "warnings.simplefilter(\"ignore\", ConvergenceWarning) # これ以降,警告を表示しない.\n", - "my_pipeline = Pipeline([('sc', StandardScaler()), # 標準化\n", - " ('mlp', MLPRegressor())]) # ニューラルネットワーク\n", - "my_pipeline.fit(X, y) # 訓練\n", - "\n", - "my_scores = cross_val_score(my_pipeline, X, y, cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error')\n", - "warnings.simplefilter(\"default\", ConvergenceWarning) # これ以降,警告を表示する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(-my_scores.mean())**0.5\n", - "#> 0.41735891601426384" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.7.3 ニューラルネットワークのチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_pipeline = Pipeline([\n", - " ('sc', StandardScaler()),\n", - " ('mlp', MLPRegressor(tol=1e-5, # 改善したと見なす基準\n", - " max_iter=5000))]) # 改善しなくなるまでの反復数\n", - "my_layers = (1, 3, 5, # 隠れ層1層の場合\n", - " (1, 1), (3, 1), (5, 1), (1, 2), (3, 2), (5, 2)) # 隠れ層2層の場合\n", - "my_params = {'mlp__hidden_layer_sizes': my_layers}\n", - "my_search = GridSearchCV(estimator=my_pipeline,\n", - " param_grid=my_params,\n", - " cv=LeaveOneOut(),\n", - " scoring='neg_mean_squared_error',\n", - " n_jobs=-1).fit(X, y)\n", - "my_model = my_search.best_estimator_ # 最良モデル\n", - "\n", - "my_search.best_params_ # 最良パラメータ\n", - "#> {'mlp__hidden_layer_sizes': 5}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(-my_search.best_score_)**0.5\n", - "#> 0.3759690731968538" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch09/09-colab.ipynb b/code/Python-notebook/ch09/09-colab.ipynb deleted file mode 100644 index 047253b..0000000 --- a/code/Python-notebook/ch09/09-colab.ipynb +++ /dev/null @@ -1,509 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 09\n", - "\n", - "## 9.1 アヤメのデータ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "my_data.head()\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 0 5.1 3.5 1.4 0.2 setosa\n", - "#> 1 4.9 3.0 1.4 0.2 setosa\n", - "#> 2 4.7 3.2 1.3 0.2 setosa\n", - "#> 3 4.6 3.1 1.5 0.2 setosa\n", - "#> 4 5.0 3.6 1.4 0.2 setosa" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.describe()\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width\n", - "#> count 150.000000 150.000000 150.000000 150.000000\n", - "#> mean 5.843333 3.057333 3.758000 1.199333\n", - "# 以下省略" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.2 木による分類\n", - "\n", - "### 9.2.1 分類木の作成と利用" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import graphviz\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn import tree\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species\n", - "\n", - "my_model = tree.DecisionTreeClassifier(max_depth=2, random_state=0)\n", - "my_model.fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_dot = tree.export_graphviz(\n", - " decision_tree=my_model,\n", - " out_file=None, # ファイルに出力しない.\n", - " feature_names=X.columns, # 変数名\n", - " class_names=my_model.classes_, # カテゴリ名\n", - " filled=True) # 色を塗る.\n", - "graphviz.Source(my_dot)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test = pd.DataFrame([[5.0, 3.5, 1.5, 0.5],\n", - " [6.5, 3.0, 5.0, 2.0]])\n", - "my_model.predict(my_test)\n", - "#> array(['setosa', 'virginica'], dtype=object)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.DataFrame(\n", - " my_model.predict_proba(my_test),\n", - " columns=my_model.classes_)\n", - "#> setosa versicolor virginica\n", - "#> 0 1.0 0.000000 0.000000\n", - "#> 1 0.0 0.021739 0.978261" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.3 正解率\n", - "\n", - "### 9.3.1 混同行列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import graphviz\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn import tree\n", - "from sklearn.metrics import confusion_matrix\n", - "from sklearn.model_selection import cross_val_score, GridSearchCV, LeaveOneOut\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species\n", - "\n", - "my_model = tree.DecisionTreeClassifier(max_depth=2, random_state=0).fit(X, y)\n", - "y_ = my_model.predict(X)\n", - "confusion_matrix(y_true=y, y_pred=y_)\n", - "#> array([[50, 0, 0],\n", - "#> [ 0, 49, 1],\n", - "#> [ 0, 5, 45]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.2 正解率(訓練)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.score(X, y)\n", - "# あるいは\n", - "y_ = my_model.predict(X)\n", - "(y_ == y).mean()\n", - "\n", - "#> 0.96" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.3 正解率(検証)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "cross_val_score(my_model, X, y, cv=LeaveOneOut()).mean()\n", - "#> 0.9533333333333334" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.4 パラメータチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_search = GridSearchCV(estimator=tree.DecisionTreeClassifier(random_state=0),\n", - " param_grid={'max_depth': range(1, 11)},\n", - " cv=LeaveOneOut(),\n", - " n_jobs=-1).fit(X, y)\n", - "my_search.best_params_, my_search.best_score_\n", - "#> ({'max_depth': 2}, 0.9533333333333334)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.5 補足:木の複雑さの制限" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_params = {\n", - " 'max_depth': range(2, 6),\n", - " 'min_samples_split': [2, 20],\n", - " 'min_samples_leaf': range(1, 8)}\n", - "\n", - "my_search = GridSearchCV(\n", - " estimator=tree.DecisionTreeClassifier(min_impurity_decrease=0.01,\n", - " random_state=0),\n", - " param_grid=my_params,\n", - " cv=LeaveOneOut(),\n", - " n_jobs=-1).fit(X, y)\n", - "my_search.best_params_, my_search.best_score_\n", - "#> ({'max_depth': 3, 'min_samples_leaf': 5, 'min_samples_split': 2},\n", - "#> 0.9733333333333334)\n", - "\n", - "tmp = my_search.cv_results_\n", - "my_results = pd.DataFrame(tmp['params']).assign(\n", - " Accuracy=tmp['mean_test_score'])\n", - "# 正解率(検証)の最大値\n", - "my_results[my_results.Accuracy == my_results.Accuracy.max()]\n", - "#> max_depth min_samples_leaf min_samples_split Accuracy\n", - "#> 22 3 5 2 0.973333\n", - "#> 23 3 5 20 0.973333\n", - "#> 36 4 5 2 0.973333\n", - "#> 37 4 5 20 0.973333\n", - "#> 50 5 5 2 0.973333\n", - "#> 51 5 5 20 0.973333" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = my_search.best_estimator_\n", - "my_dot = tree.export_graphviz(\n", - " decision_tree=my_model,\n", - " out_file=None,\n", - " feature_names=X.columns,\n", - " class_names=my_model.classes_,\n", - " filled=True)\n", - "graphviz.Source(my_dot)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.4 複数の木を使う方法\n", - "\n", - "### 9.4.1 ランダムフォレスト" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "import warnings\n", - "import xgboost\n", - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.model_selection import GridSearchCV, LeaveOneOut\n", - "from sklearn.preprocessing import LabelEncoder\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species\n", - "label_encoder = LabelEncoder(); y = label_encoder.fit_transform(y)\n", - "\n", - "my_search = GridSearchCV(RandomForestClassifier(),\n", - " param_grid={'max_features': [2, 3, 4]},\n", - " cv=LeaveOneOut(),\n", - " n_jobs=-1).fit(X, y)\n", - "my_search.best_params_\n", - "#> {'max_features': 2}\n", - "\n", - "my_search.cv_results_['mean_test_score']\n", - "#> array([0.96 , 0.96 , 0.95333333])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.4.2 ブースティング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "warnings.simplefilter('ignore') # これ以降,警告を表示しない.\n", - "my_search = GridSearchCV(\n", - " xgboost.XGBClassifier(eval_metric='mlogloss'),\n", - " param_grid={'n_estimators' : [50, 100, 150],\n", - " 'max_depth' : [1, 2, 3],\n", - " 'learning_rate' : [0.3, 0.4],\n", - " 'gamma' : [0],\n", - " 'colsample_bytree': [0.6, 0.8],\n", - " 'min_child_weight': [1],\n", - " 'subsample' : [0.5, 0.75, 1]},\n", - " cv=5, # 5分割交差検証\n", - " n_jobs=1).fit(X, y) # n_jobs=-1ではない.\n", - "warnings.simplefilter('default') # これ以降,警告を表示する.\n", - "\n", - "my_search.best_params_\n", - "#> {'colsample_bytree': 0.6,\n", - "#> 'gamma': 0,\n", - "#> 'learning_rate': 0.3,\n", - "#> 'max_depth': 1,\n", - "#> 'min_child_weight': 1,\n", - "#> 'n_estimators': 50,\n", - "#> 'subsample': 0.75}\n", - "\n", - "my_search.best_score_\n", - "#> 0.9666666666666668" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.4.3 入力変数の重要度" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = RandomForestClassifier().fit(X, y)\n", - "tmp = pd.Series(my_model.feature_importances_, index=X.columns)\n", - "tmp.sort_values().plot(kind='barh')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.5 欠損のあるデータでの学習\n", - "\n", - "### 9.5.1 欠損のあるデータの準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import statsmodels.api as sm\n", - "import warnings\n", - "import xgboost\n", - "from sklearn import tree\n", - "from sklearn.impute import SimpleImputer\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "\n", - "n = len(my_data)\n", - "my_data['Petal.Length'] = [np.nan if i % 10 == 0 else\n", - " my_data['Petal.Length'][i] for i in range(n)]\n", - "my_data['Petal.Width'] = [np.nan if i % 10 == 1 else\n", - " my_data['Petal.Width'][i] for i in range(n)]\n", - "\n", - "my_data.describe() # countの値が135の変数に,150-135=15個の欠損がある.\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width\n", - "#> count 150.000000 150.000000 135.000000 135.000000\n", - "#> mean 5.843333 3.057333 3.751852 1.197037\n", - "# 以下省略\n", - "\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.5.2 方針1:欠損を埋めて学習する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_pipeline = Pipeline([\n", - " ('imputer', SimpleImputer(strategy='median')), # 欠損を中央値で埋める.\n", - " ('tree', tree.DecisionTreeClassifier(random_state=0))])\n", - "my_scores = cross_val_score(my_pipeline, X, y, cv=LeaveOneOut(), n_jobs=-1)\n", - "my_scores.mean()\n", - "#> 0.9333333333333333" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.5.3 方針2:欠損があっても使える手法で学習する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from sklearn.preprocessing import LabelEncoder\n", - "label_encoder = LabelEncoder()\n", - "y = label_encoder.fit_transform(y)\n", - "\n", - "warnings.simplefilter('ignore') # これ以降,警告を表示しない.\n", - "my_scores = cross_val_score(\n", - " xgboost.XGBClassifier(eval_metric='mlogloss'), X, y, cv=5)\n", - "warnings.simplefilter('default') # これ以降,警告を表示する.\n", - "\n", - "my_scores.mean()\n", - "#> 0.9666666666666668" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.6 他の分類手法\n", - "\n", - "### 9.6.1 K最近傍法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.neighbors import KNeighborsClassifier\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species\n", - "\n", - "my_scores = cross_val_score(KNeighborsClassifier(), X, y, cv=LeaveOneOut())\n", - "my_scores.mean()\n", - "#> 0.9666666666666667" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.6.2 ニューラルネットワーク" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.neural_network import MLPClassifier\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import StandardScaler\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species\n", - "\n", - "my_pipeline = Pipeline([('sc', StandardScaler()), # 標準化\n", - " ('mlp', MLPClassifier(max_iter=1000))]) # ニューラルネットワーク\n", - "my_scores = cross_val_score(my_pipeline, X, y, cv=LeaveOneOut(), n_jobs=-1)\n", - "my_scores.mean()\n", - "#> 0.9533333333333334" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch09/09.01.ipynb b/code/Python-notebook/ch09/09.01.ipynb deleted file mode 100644 index 53b7747..0000000 --- a/code/Python-notebook/ch09/09.01.ipynb +++ /dev/null @@ -1,49 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.1 アヤメのデータ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "my_data.head()\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 0 5.1 3.5 1.4 0.2 setosa\n", - "#> 1 4.9 3.0 1.4 0.2 setosa\n", - "#> 2 4.7 3.2 1.3 0.2 setosa\n", - "#> 3 4.6 3.1 1.5 0.2 setosa\n", - "#> 4 5.0 3.6 1.4 0.2 setosa" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.describe()\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width\n", - "#> count 150.000000 150.000000 150.000000 150.000000\n", - "#> mean 5.843333 3.057333 3.758000 1.199333\n", - "# 以下省略" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch09/09.02.ipynb b/code/Python-notebook/ch09/09.02.ipynb deleted file mode 100644 index 37ed621..0000000 --- a/code/Python-notebook/ch09/09.02.ipynb +++ /dev/null @@ -1,80 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.2 木による分類\n", - "\n", - "### 9.2.1 分類木の作成と利用" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import graphviz\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn import tree\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species\n", - "\n", - "my_model = tree.DecisionTreeClassifier(max_depth=2, random_state=0)\n", - "my_model.fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_dot = tree.export_graphviz(\n", - " decision_tree=my_model,\n", - " out_file=None, # ファイルに出力しない.\n", - " feature_names=X.columns, # 変数名\n", - " class_names=my_model.classes_, # カテゴリ名\n", - " filled=True) # 色を塗る.\n", - "graphviz.Source(my_dot)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test = pd.DataFrame([[5.0, 3.5, 1.5, 0.5],\n", - " [6.5, 3.0, 5.0, 2.0]])\n", - "my_model.predict(my_test)\n", - "#> array(['setosa', 'virginica'], dtype=object)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.DataFrame(\n", - " my_model.predict_proba(my_test),\n", - " columns=my_model.classes_)\n", - "#> setosa versicolor virginica\n", - "#> 0 1.0 0.000000 0.000000\n", - "#> 1 0.0 0.021739 0.978261" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch09/09.03.ipynb b/code/Python-notebook/ch09/09.03.ipynb deleted file mode 100644 index 18b0193..0000000 --- a/code/Python-notebook/ch09/09.03.ipynb +++ /dev/null @@ -1,162 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.3 正解率\n", - "\n", - "### 9.3.1 混同行列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import graphviz\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn import tree\n", - "from sklearn.metrics import confusion_matrix\n", - "from sklearn.model_selection import cross_val_score, GridSearchCV, LeaveOneOut\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species\n", - "\n", - "my_model = tree.DecisionTreeClassifier(max_depth=2, random_state=0).fit(X, y)\n", - "y_ = my_model.predict(X)\n", - "confusion_matrix(y_true=y, y_pred=y_)\n", - "#> array([[50, 0, 0],\n", - "#> [ 0, 49, 1],\n", - "#> [ 0, 5, 45]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.2 正解率(訓練)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.score(X, y)\n", - "# あるいは\n", - "y_ = my_model.predict(X)\n", - "(y_ == y).mean()\n", - "\n", - "#> 0.96" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.3 正解率(検証)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "cross_val_score(my_model, X, y, cv=LeaveOneOut()).mean()\n", - "#> 0.9533333333333334" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.4 パラメータチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_search = GridSearchCV(estimator=tree.DecisionTreeClassifier(random_state=0),\n", - " param_grid={'max_depth': range(1, 11)},\n", - " cv=LeaveOneOut(),\n", - " n_jobs=-1).fit(X, y)\n", - "my_search.best_params_, my_search.best_score_\n", - "#> ({'max_depth': 2}, 0.9533333333333334)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.5 補足:木の複雑さの制限" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_params = {\n", - " 'max_depth': range(2, 6),\n", - " 'min_samples_split': [2, 20],\n", - " 'min_samples_leaf': range(1, 8)}\n", - "\n", - "my_search = GridSearchCV(\n", - " estimator=tree.DecisionTreeClassifier(min_impurity_decrease=0.01,\n", - " random_state=0),\n", - " param_grid=my_params,\n", - " cv=LeaveOneOut(),\n", - " n_jobs=-1).fit(X, y)\n", - "my_search.best_params_, my_search.best_score_\n", - "#> ({'max_depth': 3, 'min_samples_leaf': 5, 'min_samples_split': 2},\n", - "#> 0.9733333333333334)\n", - "\n", - "tmp = my_search.cv_results_\n", - "my_results = pd.DataFrame(tmp['params']).assign(\n", - " Accuracy=tmp['mean_test_score'])\n", - "# 正解率(検証)の最大値\n", - "my_results[my_results.Accuracy == my_results.Accuracy.max()]\n", - "#> max_depth min_samples_leaf min_samples_split Accuracy\n", - "#> 22 3 5 2 0.973333\n", - "#> 23 3 5 20 0.973333\n", - "#> 36 4 5 2 0.973333\n", - "#> 37 4 5 20 0.973333\n", - "#> 50 5 5 2 0.973333\n", - "#> 51 5 5 20 0.973333" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = my_search.best_estimator_\n", - "my_dot = tree.export_graphviz(\n", - " decision_tree=my_model,\n", - " out_file=None,\n", - " feature_names=X.columns,\n", - " class_names=my_model.classes_,\n", - " filled=True)\n", - "graphviz.Source(my_dot)" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch09/09.04.ipynb b/code/Python-notebook/ch09/09.04.ipynb deleted file mode 100644 index d291342..0000000 --- a/code/Python-notebook/ch09/09.04.ipynb +++ /dev/null @@ -1,108 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.4 複数の木を使う方法\n", - "\n", - "### 9.4.1 ランダムフォレスト" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "import warnings\n", - "import xgboost\n", - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.model_selection import GridSearchCV, LeaveOneOut\n", - "from sklearn.preprocessing import LabelEncoder\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species\n", - "label_encoder = LabelEncoder(); y = label_encoder.fit_transform(y)\n", - "\n", - "my_search = GridSearchCV(RandomForestClassifier(),\n", - " param_grid={'max_features': [2, 3, 4]},\n", - " cv=LeaveOneOut(),\n", - " n_jobs=-1).fit(X, y)\n", - "my_search.best_params_\n", - "#> {'max_features': 2}\n", - "\n", - "my_search.cv_results_['mean_test_score']\n", - "#> array([0.96 , 0.96 , 0.95333333])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.4.2 ブースティング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "warnings.simplefilter('ignore') # これ以降,警告を表示しない.\n", - "my_search = GridSearchCV(\n", - " xgboost.XGBClassifier(eval_metric='mlogloss'),\n", - " param_grid={'n_estimators' : [50, 100, 150],\n", - " 'max_depth' : [1, 2, 3],\n", - " 'learning_rate' : [0.3, 0.4],\n", - " 'gamma' : [0],\n", - " 'colsample_bytree': [0.6, 0.8],\n", - " 'min_child_weight': [1],\n", - " 'subsample' : [0.5, 0.75, 1]},\n", - " cv=5, # 5分割交差検証\n", - " n_jobs=1).fit(X, y) # n_jobs=-1ではない.\n", - "warnings.simplefilter('default') # これ以降,警告を表示する.\n", - "\n", - "my_search.best_params_\n", - "#> {'colsample_bytree': 0.6,\n", - "#> 'gamma': 0,\n", - "#> 'learning_rate': 0.3,\n", - "#> 'max_depth': 1,\n", - "#> 'min_child_weight': 1,\n", - "#> 'n_estimators': 50,\n", - "#> 'subsample': 0.75}\n", - "\n", - "my_search.best_score_\n", - "#> 0.9666666666666668" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.4.3 入力変数の重要度" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = RandomForestClassifier().fit(X, y)\n", - "tmp = pd.Series(my_model.feature_importances_, index=X.columns)\n", - "tmp.sort_values().plot(kind='barh')" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch09/09.05.ipynb b/code/Python-notebook/ch09/09.05.ipynb deleted file mode 100644 index 9ced5c0..0000000 --- a/code/Python-notebook/ch09/09.05.ipynb +++ /dev/null @@ -1,100 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.5 欠損のあるデータでの学習\n", - "\n", - "### 9.5.1 欠損のあるデータの準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import statsmodels.api as sm\n", - "import warnings\n", - "import xgboost\n", - "from sklearn import tree\n", - "from sklearn.impute import SimpleImputer\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "\n", - "n = len(my_data)\n", - "my_data['Petal.Length'] = [np.nan if i % 10 == 0 else\n", - " my_data['Petal.Length'][i] for i in range(n)]\n", - "my_data['Petal.Width'] = [np.nan if i % 10 == 1 else\n", - " my_data['Petal.Width'][i] for i in range(n)]\n", - "\n", - "my_data.describe() # countの値が135の変数に,150-135=15個の欠損がある.\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width\n", - "#> count 150.000000 150.000000 135.000000 135.000000\n", - "#> mean 5.843333 3.057333 3.751852 1.197037\n", - "# 以下省略\n", - "\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.5.2 方針1:欠損を埋めて学習する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_pipeline = Pipeline([\n", - " ('imputer', SimpleImputer(strategy='median')), # 欠損を中央値で埋める.\n", - " ('tree', tree.DecisionTreeClassifier(random_state=0))])\n", - "my_scores = cross_val_score(my_pipeline, X, y, cv=LeaveOneOut(), n_jobs=-1)\n", - "my_scores.mean()\n", - "#> 0.9333333333333333" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.5.3 方針2:欠損があっても使える手法で学習する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from sklearn.preprocessing import LabelEncoder\n", - "label_encoder = LabelEncoder()\n", - "y = label_encoder.fit_transform(y)\n", - "\n", - "warnings.simplefilter('ignore') # これ以降,警告を表示しない.\n", - "my_scores = cross_val_score(\n", - " xgboost.XGBClassifier(eval_metric='mlogloss'), X, y, cv=5)\n", - "warnings.simplefilter('default') # これ以降,警告を表示する.\n", - "\n", - "my_scores.mean()\n", - "#> 0.9666666666666668" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch09/09.06.ipynb b/code/Python-notebook/ch09/09.06.ipynb deleted file mode 100644 index 946733a..0000000 --- a/code/Python-notebook/ch09/09.06.ipynb +++ /dev/null @@ -1,68 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.6 他の分類手法\n", - "\n", - "### 9.6.1 K最近傍法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.neighbors import KNeighborsClassifier\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species\n", - "\n", - "my_scores = cross_val_score(KNeighborsClassifier(), X, y, cv=LeaveOneOut())\n", - "my_scores.mean()\n", - "#> 0.9666666666666667" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.6.2 ニューラルネットワーク" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.neural_network import MLPClassifier\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import StandardScaler\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species\n", - "\n", - "my_pipeline = Pipeline([('sc', StandardScaler()), # 標準化\n", - " ('mlp', MLPClassifier(max_iter=1000))]) # ニューラルネットワーク\n", - "my_scores = cross_val_score(my_pipeline, X, y, cv=LeaveOneOut(), n_jobs=-1)\n", - "my_scores.mean()\n", - "#> 0.9533333333333334" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch09/09.ipynb b/code/Python-notebook/ch09/09.ipynb deleted file mode 100644 index 047253b..0000000 --- a/code/Python-notebook/ch09/09.ipynb +++ /dev/null @@ -1,509 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 09\n", - "\n", - "## 9.1 アヤメのデータ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "my_data.head()\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 0 5.1 3.5 1.4 0.2 setosa\n", - "#> 1 4.9 3.0 1.4 0.2 setosa\n", - "#> 2 4.7 3.2 1.3 0.2 setosa\n", - "#> 3 4.6 3.1 1.5 0.2 setosa\n", - "#> 4 5.0 3.6 1.4 0.2 setosa" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.describe()\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width\n", - "#> count 150.000000 150.000000 150.000000 150.000000\n", - "#> mean 5.843333 3.057333 3.758000 1.199333\n", - "# 以下省略" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.2 木による分類\n", - "\n", - "### 9.2.1 分類木の作成と利用" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import graphviz\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn import tree\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species\n", - "\n", - "my_model = tree.DecisionTreeClassifier(max_depth=2, random_state=0)\n", - "my_model.fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_dot = tree.export_graphviz(\n", - " decision_tree=my_model,\n", - " out_file=None, # ファイルに出力しない.\n", - " feature_names=X.columns, # 変数名\n", - " class_names=my_model.classes_, # カテゴリ名\n", - " filled=True) # 色を塗る.\n", - "graphviz.Source(my_dot)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test = pd.DataFrame([[5.0, 3.5, 1.5, 0.5],\n", - " [6.5, 3.0, 5.0, 2.0]])\n", - "my_model.predict(my_test)\n", - "#> array(['setosa', 'virginica'], dtype=object)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.DataFrame(\n", - " my_model.predict_proba(my_test),\n", - " columns=my_model.classes_)\n", - "#> setosa versicolor virginica\n", - "#> 0 1.0 0.000000 0.000000\n", - "#> 1 0.0 0.021739 0.978261" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.3 正解率\n", - "\n", - "### 9.3.1 混同行列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import graphviz\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn import tree\n", - "from sklearn.metrics import confusion_matrix\n", - "from sklearn.model_selection import cross_val_score, GridSearchCV, LeaveOneOut\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species\n", - "\n", - "my_model = tree.DecisionTreeClassifier(max_depth=2, random_state=0).fit(X, y)\n", - "y_ = my_model.predict(X)\n", - "confusion_matrix(y_true=y, y_pred=y_)\n", - "#> array([[50, 0, 0],\n", - "#> [ 0, 49, 1],\n", - "#> [ 0, 5, 45]])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.2 正解率(訓練)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.score(X, y)\n", - "# あるいは\n", - "y_ = my_model.predict(X)\n", - "(y_ == y).mean()\n", - "\n", - "#> 0.96" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.3 正解率(検証)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "cross_val_score(my_model, X, y, cv=LeaveOneOut()).mean()\n", - "#> 0.9533333333333334" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.4 パラメータチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_search = GridSearchCV(estimator=tree.DecisionTreeClassifier(random_state=0),\n", - " param_grid={'max_depth': range(1, 11)},\n", - " cv=LeaveOneOut(),\n", - " n_jobs=-1).fit(X, y)\n", - "my_search.best_params_, my_search.best_score_\n", - "#> ({'max_depth': 2}, 0.9533333333333334)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.5 補足:木の複雑さの制限" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_params = {\n", - " 'max_depth': range(2, 6),\n", - " 'min_samples_split': [2, 20],\n", - " 'min_samples_leaf': range(1, 8)}\n", - "\n", - "my_search = GridSearchCV(\n", - " estimator=tree.DecisionTreeClassifier(min_impurity_decrease=0.01,\n", - " random_state=0),\n", - " param_grid=my_params,\n", - " cv=LeaveOneOut(),\n", - " n_jobs=-1).fit(X, y)\n", - "my_search.best_params_, my_search.best_score_\n", - "#> ({'max_depth': 3, 'min_samples_leaf': 5, 'min_samples_split': 2},\n", - "#> 0.9733333333333334)\n", - "\n", - "tmp = my_search.cv_results_\n", - "my_results = pd.DataFrame(tmp['params']).assign(\n", - " Accuracy=tmp['mean_test_score'])\n", - "# 正解率(検証)の最大値\n", - "my_results[my_results.Accuracy == my_results.Accuracy.max()]\n", - "#> max_depth min_samples_leaf min_samples_split Accuracy\n", - "#> 22 3 5 2 0.973333\n", - "#> 23 3 5 20 0.973333\n", - "#> 36 4 5 2 0.973333\n", - "#> 37 4 5 20 0.973333\n", - "#> 50 5 5 2 0.973333\n", - "#> 51 5 5 20 0.973333" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = my_search.best_estimator_\n", - "my_dot = tree.export_graphviz(\n", - " decision_tree=my_model,\n", - " out_file=None,\n", - " feature_names=X.columns,\n", - " class_names=my_model.classes_,\n", - " filled=True)\n", - "graphviz.Source(my_dot)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.4 複数の木を使う方法\n", - "\n", - "### 9.4.1 ランダムフォレスト" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "import warnings\n", - "import xgboost\n", - "from sklearn.ensemble import RandomForestClassifier\n", - "from sklearn.model_selection import GridSearchCV, LeaveOneOut\n", - "from sklearn.preprocessing import LabelEncoder\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species\n", - "label_encoder = LabelEncoder(); y = label_encoder.fit_transform(y)\n", - "\n", - "my_search = GridSearchCV(RandomForestClassifier(),\n", - " param_grid={'max_features': [2, 3, 4]},\n", - " cv=LeaveOneOut(),\n", - " n_jobs=-1).fit(X, y)\n", - "my_search.best_params_\n", - "#> {'max_features': 2}\n", - "\n", - "my_search.cv_results_['mean_test_score']\n", - "#> array([0.96 , 0.96 , 0.95333333])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.4.2 ブースティング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "warnings.simplefilter('ignore') # これ以降,警告を表示しない.\n", - "my_search = GridSearchCV(\n", - " xgboost.XGBClassifier(eval_metric='mlogloss'),\n", - " param_grid={'n_estimators' : [50, 100, 150],\n", - " 'max_depth' : [1, 2, 3],\n", - " 'learning_rate' : [0.3, 0.4],\n", - " 'gamma' : [0],\n", - " 'colsample_bytree': [0.6, 0.8],\n", - " 'min_child_weight': [1],\n", - " 'subsample' : [0.5, 0.75, 1]},\n", - " cv=5, # 5分割交差検証\n", - " n_jobs=1).fit(X, y) # n_jobs=-1ではない.\n", - "warnings.simplefilter('default') # これ以降,警告を表示する.\n", - "\n", - "my_search.best_params_\n", - "#> {'colsample_bytree': 0.6,\n", - "#> 'gamma': 0,\n", - "#> 'learning_rate': 0.3,\n", - "#> 'max_depth': 1,\n", - "#> 'min_child_weight': 1,\n", - "#> 'n_estimators': 50,\n", - "#> 'subsample': 0.75}\n", - "\n", - "my_search.best_score_\n", - "#> 0.9666666666666668" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.4.3 入力変数の重要度" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = RandomForestClassifier().fit(X, y)\n", - "tmp = pd.Series(my_model.feature_importances_, index=X.columns)\n", - "tmp.sort_values().plot(kind='barh')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.5 欠損のあるデータでの学習\n", - "\n", - "### 9.5.1 欠損のあるデータの準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import statsmodels.api as sm\n", - "import warnings\n", - "import xgboost\n", - "from sklearn import tree\n", - "from sklearn.impute import SimpleImputer\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "\n", - "n = len(my_data)\n", - "my_data['Petal.Length'] = [np.nan if i % 10 == 0 else\n", - " my_data['Petal.Length'][i] for i in range(n)]\n", - "my_data['Petal.Width'] = [np.nan if i % 10 == 1 else\n", - " my_data['Petal.Width'][i] for i in range(n)]\n", - "\n", - "my_data.describe() # countの値が135の変数に,150-135=15個の欠損がある.\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width\n", - "#> count 150.000000 150.000000 135.000000 135.000000\n", - "#> mean 5.843333 3.057333 3.751852 1.197037\n", - "# 以下省略\n", - "\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.5.2 方針1:欠損を埋めて学習する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_pipeline = Pipeline([\n", - " ('imputer', SimpleImputer(strategy='median')), # 欠損を中央値で埋める.\n", - " ('tree', tree.DecisionTreeClassifier(random_state=0))])\n", - "my_scores = cross_val_score(my_pipeline, X, y, cv=LeaveOneOut(), n_jobs=-1)\n", - "my_scores.mean()\n", - "#> 0.9333333333333333" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.5.3 方針2:欠損があっても使える手法で学習する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from sklearn.preprocessing import LabelEncoder\n", - "label_encoder = LabelEncoder()\n", - "y = label_encoder.fit_transform(y)\n", - "\n", - "warnings.simplefilter('ignore') # これ以降,警告を表示しない.\n", - "my_scores = cross_val_score(\n", - " xgboost.XGBClassifier(eval_metric='mlogloss'), X, y, cv=5)\n", - "warnings.simplefilter('default') # これ以降,警告を表示する.\n", - "\n", - "my_scores.mean()\n", - "#> 0.9666666666666668" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.6 他の分類手法\n", - "\n", - "### 9.6.1 K最近傍法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.neighbors import KNeighborsClassifier\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species\n", - "\n", - "my_scores = cross_val_score(KNeighborsClassifier(), X, y, cv=LeaveOneOut())\n", - "my_scores.mean()\n", - "#> 0.9666666666666667" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.6.2 ニューラルネットワーク" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import statsmodels.api as sm\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.neural_network import MLPClassifier\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import StandardScaler\n", - "\n", - "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "X, y = my_data.iloc[:, 0:4], my_data.Species\n", - "\n", - "my_pipeline = Pipeline([('sc', StandardScaler()), # 標準化\n", - " ('mlp', MLPClassifier(max_iter=1000))]) # ニューラルネットワーク\n", - "my_scores = cross_val_score(my_pipeline, X, y, cv=LeaveOneOut(), n_jobs=-1)\n", - "my_scores.mean()\n", - "#> 0.9533333333333334" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch10/10-colab.ipynb b/code/Python-notebook/ch10/10-colab.ipynb deleted file mode 100644 index 844c5ba..0000000 --- a/code/Python-notebook/ch10/10-colab.ipynb +++ /dev/null @@ -1,376 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 10\n", - "\n", - "## 10.1 2値分類の性能指標\n", - "\n", - "### 10.1.1 陽性と陰性" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from sklearn.metrics import classification_report, confusion_matrix\n", - "\n", - "y = np.array([ 0, 1, 1, 0, 1, 0, 1, 0, 0, 1])\n", - "y_score = np.array([0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = np.array([1 if 0.5 <= p else 0 for p in y_score])\n", - "y_\n", - "#> array([1, 1, 0, 0, 1, 1, 1, 0, 0, 1])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "confusion_matrix(y_true=y, y_pred=y_)\n", - "#> array([[3, 2],\n", - "#> [1, 4]])\n", - "\n", - "print(classification_report(y_true=y, y_pred=y_))\n", - "#> precision recall f1-score support\n", - "#>\n", - "#> 0 0.75 0.60 0.67 5\n", - "#> 1 0.67 0.80 0.73 5\n", - "#>\n", - "#> accuracy 0.70 10\n", - "#> macro avg 0.71 0.70 0.70 10\n", - "#> weighted avg 0.71 0.70 0.70 10" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.2 トレードオフ\n", - "\n", - "### 10.2.1 偽陽性率と真陽性率のトレードオフ(ROC曲線)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from sklearn.metrics import (roc_curve, RocCurveDisplay,\n", - " precision_recall_curve, PrecisionRecallDisplay, auc)\n", - "\n", - "y = np.array([ 0, 1, 1, 0, 1, 0, 1, 0, 0, 1])\n", - "y_score = np.array([0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5])\n", - "y_ = np.array([1 if 0.5 <= p else 0 for p in y_score])\n", - "\n", - "[sum((y == 0) & (y_ == 1)) / sum(y == 0), # FPR\n", - " sum((y == 1) & (y_ == 1)) / sum(y == 1)] # TPR\n", - "#> [0.4, 0.8]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_fpr, my_tpr, _ = roc_curve(y_true=y,\n", - " y_score=y_score,\n", - " pos_label=1) # 1が陽性である.\n", - "RocCurveDisplay(fpr=my_fpr, tpr=my_tpr).plot()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "auc(x=my_fpr, y=my_tpr)\n", - "#> 0.8" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.2.2 再現率と精度のトレードオフ(PR曲線)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "[sum((y == 1) & (y_ == 1)) / sum(y == 1), # Recall == TPR\n", - " sum((y == 1) & (y_ == 1)) / sum(y_ == 1)] # Precision\n", - "#> [0.8, 0.6666666666666666]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_precision, my_recall, _ = precision_recall_curve(y_true=y,\n", - " probas_pred=y_score,\n", - " pos_label=1)\n", - "PrecisionRecallDisplay(precision=my_precision, recall=my_recall).plot()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "auc(x=my_recall, y=my_precision)\n", - "#> 0.8463095238095237" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.3 タイタニック" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import graphviz\n", - "import pandas as pd\n", - "from sklearn import tree\n", - "from sklearn.metrics import roc_curve, RocCurveDisplay, auc\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import OneHotEncoder\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/titanic.csv')\n", - "my_data = pd.read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.head()\n", - "#> Class Sex Age Survived\n", - "#> 0 1st Male Child Yes\n", - "#> 1 1st Male Child Yes\n", - "#> 2 1st Male Child Yes\n", - "#> 3 1st Male Child Yes\n", - "#> 4 1st Male Child Yes" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.1 質的入力変数の扱い方\n", - "\n", - "### 10.3.2 決定木の訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X, y = my_data.iloc[:, 0:3], my_data.Survived\n", - "\n", - "my_pipeline = Pipeline([\n", - " ('ohe', OneHotEncoder(drop='first')),\n", - " ('tree', tree.DecisionTreeClassifier(max_depth=2, random_state=0,\n", - " min_impurity_decrease=0.01))])\n", - "my_pipeline.fit(X, y)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.3 決定木の描画" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_enc = my_pipeline.named_steps['ohe'] # パイプラインからエンコーダを取り出す.\n", - "my_tree = my_pipeline.named_steps['tree'] # パイプラインから木を取り出す.\n", - "\n", - "my_dot = tree.export_graphviz(\n", - " decision_tree=my_tree,\n", - " out_file=None,\n", - " feature_names=my_enc.get_feature_names() \\\n", - " if hasattr(my_enc, 'get_feature_names') else my_enc.get_feature_names_out(),\n", - " class_names=my_pipeline.classes_,\n", - " filled=True)\n", - "graphviz.Source(my_dot)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.4 決定木の評価" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scores = cross_val_score(\n", - " my_pipeline, X, y,\n", - " cv=LeaveOneOut(),\n", - " n_jobs=-1)\n", - "my_scores.mean()\n", - "#> 0.7832803271240345" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = pd.DataFrame(\n", - " my_pipeline.predict_proba(X),\n", - " columns=my_pipeline.classes_)\n", - "y_score = tmp.Yes\n", - "\n", - "my_fpr, my_tpr, _ = roc_curve(y_true=y,\n", - " y_score=y_score,\n", - " pos_label='Yes')\n", - "my_auc = auc(x=my_fpr, y=my_tpr)\n", - "my_auc\n", - "#> 0.7114886868858494\n", - "\n", - "RocCurveDisplay(fpr=my_fpr, tpr=my_tpr, roc_auc=my_auc).plot()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.5 補足:質的入力変数の扱い\n", - "\n", - "## 10.4 ロジスティック回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "\n", - "x = np.arange(-6, 6, 0.1)\n", - "y = 1 / (1 + np.exp(-x))\n", - "plt.plot(x, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.linear_model import LogisticRegression\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import OneHotEncoder\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/titanic.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "\n", - "X, y = my_data.iloc[:, 0:3], my_data.Survived\n", - "\n", - "my_pipeline = Pipeline([('ohe', OneHotEncoder(drop='first')),\n", - " ('lr', LogisticRegression(penalty='none'))])\n", - "my_pipeline.fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_ohe = my_pipeline.named_steps.ohe\n", - "my_lr = my_pipeline.named_steps.lr\n", - "\n", - "my_lr.intercept_[0]\n", - "#> 2.043878162056783\n", - "\n", - "tmp = my_ohe.get_feature_names() \\\n", - "if hasattr(my_ohe, 'get_feature_names') \\\n", - "else my_ohe.get_feature_names_out()\n", - "pd.Series(my_lr.coef_[0],\n", - " index=tmp)\n", - "#> x0_2nd -1.018069\n", - "#> x0_3rd -1.777746\n", - "#> x0_Crew -0.857708\n", - "#> x1_Male -2.420090\n", - "#> x2_Child 1.061531\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scores = cross_val_score(\n", - " my_pipeline, X, y,\n", - " cv=LeaveOneOut(),\n", - " n_jobs=-1)\n", - "my_scores.mean()\n", - "#> 0.7782825988187188" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch10/10.01.ipynb b/code/Python-notebook/ch10/10.01.ipynb deleted file mode 100644 index 7c633ab..0000000 --- a/code/Python-notebook/ch10/10.01.ipynb +++ /dev/null @@ -1,66 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.1 2値分類の性能指標\n", - "\n", - "### 10.1.1 陽性と陰性" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from sklearn.metrics import classification_report, confusion_matrix\n", - "\n", - "y = np.array([ 0, 1, 1, 0, 1, 0, 1, 0, 0, 1])\n", - "y_score = np.array([0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = np.array([1 if 0.5 <= p else 0 for p in y_score])\n", - "y_\n", - "#> array([1, 1, 0, 0, 1, 1, 1, 0, 0, 1])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "confusion_matrix(y_true=y, y_pred=y_)\n", - "#> array([[3, 2],\n", - "#> [1, 4]])\n", - "\n", - "print(classification_report(y_true=y, y_pred=y_))\n", - "#> precision recall f1-score support\n", - "#>\n", - "#> 0 0.75 0.60 0.67 5\n", - "#> 1 0.67 0.80 0.73 5\n", - "#>\n", - "#> accuracy 0.70 10\n", - "#> macro avg 0.71 0.70 0.70 10\n", - "#> weighted avg 0.71 0.70 0.70 10" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch10/10.02.ipynb b/code/Python-notebook/ch10/10.02.ipynb deleted file mode 100644 index ae5c21a..0000000 --- a/code/Python-notebook/ch10/10.02.ipynb +++ /dev/null @@ -1,102 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.2 トレードオフ\n", - "\n", - "### 10.2.1 偽陽性率と真陽性率のトレードオフ(ROC曲線)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from sklearn.metrics import (roc_curve, RocCurveDisplay,\n", - " precision_recall_curve, PrecisionRecallDisplay, auc)\n", - "\n", - "y = np.array([ 0, 1, 1, 0, 1, 0, 1, 0, 0, 1])\n", - "y_score = np.array([0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5])\n", - "y_ = np.array([1 if 0.5 <= p else 0 for p in y_score])\n", - "\n", - "[sum((y == 0) & (y_ == 1)) / sum(y == 0), # FPR\n", - " sum((y == 1) & (y_ == 1)) / sum(y == 1)] # TPR\n", - "#> [0.4, 0.8]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_fpr, my_tpr, _ = roc_curve(y_true=y,\n", - " y_score=y_score,\n", - " pos_label=1) # 1が陽性である.\n", - "RocCurveDisplay(fpr=my_fpr, tpr=my_tpr).plot()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "auc(x=my_fpr, y=my_tpr)\n", - "#> 0.8" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.2.2 再現率と精度のトレードオフ(PR曲線)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "[sum((y == 1) & (y_ == 1)) / sum(y == 1), # Recall == TPR\n", - " sum((y == 1) & (y_ == 1)) / sum(y_ == 1)] # Precision\n", - "#> [0.8, 0.6666666666666666]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_precision, my_recall, _ = precision_recall_curve(y_true=y,\n", - " probas_pred=y_score,\n", - " pos_label=1)\n", - "PrecisionRecallDisplay(precision=my_precision, recall=my_recall).plot()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "auc(x=my_recall, y=my_precision)\n", - "#> 0.8463095238095237" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch10/10.03.ipynb b/code/Python-notebook/ch10/10.03.ipynb deleted file mode 100644 index 04a6bbe..0000000 --- a/code/Python-notebook/ch10/10.03.ipynb +++ /dev/null @@ -1,152 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.3 タイタニック" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import graphviz\n", - "import pandas as pd\n", - "from sklearn import tree\n", - "from sklearn.metrics import roc_curve, RocCurveDisplay, auc\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import OneHotEncoder\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/titanic.csv')\n", - "my_data = pd.read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.head()\n", - "#> Class Sex Age Survived\n", - "#> 0 1st Male Child Yes\n", - "#> 1 1st Male Child Yes\n", - "#> 2 1st Male Child Yes\n", - "#> 3 1st Male Child Yes\n", - "#> 4 1st Male Child Yes" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.1 質的入力変数の扱い方\n", - "\n", - "### 10.3.2 決定木の訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X, y = my_data.iloc[:, 0:3], my_data.Survived\n", - "\n", - "my_pipeline = Pipeline([\n", - " ('ohe', OneHotEncoder(drop='first')),\n", - " ('tree', tree.DecisionTreeClassifier(max_depth=2, random_state=0,\n", - " min_impurity_decrease=0.01))])\n", - "my_pipeline.fit(X, y)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.3 決定木の描画" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_enc = my_pipeline.named_steps['ohe'] # パイプラインからエンコーダを取り出す.\n", - "my_tree = my_pipeline.named_steps['tree'] # パイプラインから木を取り出す.\n", - "\n", - "my_dot = tree.export_graphviz(\n", - " decision_tree=my_tree,\n", - " out_file=None,\n", - " feature_names=my_enc.get_feature_names() \\\n", - " if hasattr(my_enc, 'get_feature_names') else my_enc.get_feature_names_out(),\n", - " class_names=my_pipeline.classes_,\n", - " filled=True)\n", - "graphviz.Source(my_dot)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.4 決定木の評価" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scores = cross_val_score(\n", - " my_pipeline, X, y,\n", - " cv=LeaveOneOut(),\n", - " n_jobs=-1)\n", - "my_scores.mean()\n", - "#> 0.7832803271240345" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = pd.DataFrame(\n", - " my_pipeline.predict_proba(X),\n", - " columns=my_pipeline.classes_)\n", - "y_score = tmp.Yes\n", - "\n", - "my_fpr, my_tpr, _ = roc_curve(y_true=y,\n", - " y_score=y_score,\n", - " pos_label='Yes')\n", - "my_auc = auc(x=my_fpr, y=my_tpr)\n", - "my_auc\n", - "#> 0.7114886868858494\n", - "\n", - "RocCurveDisplay(fpr=my_fpr, tpr=my_tpr, roc_auc=my_auc).plot()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.5 補足:質的入力変数の扱い" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch10/10.04.ipynb b/code/Python-notebook/ch10/10.04.ipynb deleted file mode 100644 index d902bfa..0000000 --- a/code/Python-notebook/ch10/10.04.ipynb +++ /dev/null @@ -1,95 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.4 ロジスティック回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "\n", - "x = np.arange(-6, 6, 0.1)\n", - "y = 1 / (1 + np.exp(-x))\n", - "plt.plot(x, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.linear_model import LogisticRegression\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import OneHotEncoder\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/titanic.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "\n", - "X, y = my_data.iloc[:, 0:3], my_data.Survived\n", - "\n", - "my_pipeline = Pipeline([('ohe', OneHotEncoder(drop='first')),\n", - " ('lr', LogisticRegression(penalty='none'))])\n", - "my_pipeline.fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_ohe = my_pipeline.named_steps.ohe\n", - "my_lr = my_pipeline.named_steps.lr\n", - "\n", - "my_lr.intercept_[0]\n", - "#> 2.043878162056783\n", - "\n", - "tmp = my_ohe.get_feature_names() \\\n", - "if hasattr(my_ohe, 'get_feature_names') \\\n", - "else my_ohe.get_feature_names_out()\n", - "pd.Series(my_lr.coef_[0],\n", - " index=tmp)\n", - "#> x0_2nd -1.018069\n", - "#> x0_3rd -1.777746\n", - "#> x0_Crew -0.857708\n", - "#> x1_Male -2.420090\n", - "#> x2_Child 1.061531\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scores = cross_val_score(\n", - " my_pipeline, X, y,\n", - " cv=LeaveOneOut(),\n", - " n_jobs=-1)\n", - "my_scores.mean()\n", - "#> 0.7782825988187188" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch10/10.ipynb b/code/Python-notebook/ch10/10.ipynb deleted file mode 100644 index 844c5ba..0000000 --- a/code/Python-notebook/ch10/10.ipynb +++ /dev/null @@ -1,376 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 10\n", - "\n", - "## 10.1 2値分類の性能指標\n", - "\n", - "### 10.1.1 陽性と陰性" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from sklearn.metrics import classification_report, confusion_matrix\n", - "\n", - "y = np.array([ 0, 1, 1, 0, 1, 0, 1, 0, 0, 1])\n", - "y_score = np.array([0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = np.array([1 if 0.5 <= p else 0 for p in y_score])\n", - "y_\n", - "#> array([1, 1, 0, 0, 1, 1, 1, 0, 0, 1])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "confusion_matrix(y_true=y, y_pred=y_)\n", - "#> array([[3, 2],\n", - "#> [1, 4]])\n", - "\n", - "print(classification_report(y_true=y, y_pred=y_))\n", - "#> precision recall f1-score support\n", - "#>\n", - "#> 0 0.75 0.60 0.67 5\n", - "#> 1 0.67 0.80 0.73 5\n", - "#>\n", - "#> accuracy 0.70 10\n", - "#> macro avg 0.71 0.70 0.70 10\n", - "#> weighted avg 0.71 0.70 0.70 10" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.2 トレードオフ\n", - "\n", - "### 10.2.1 偽陽性率と真陽性率のトレードオフ(ROC曲線)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from sklearn.metrics import (roc_curve, RocCurveDisplay,\n", - " precision_recall_curve, PrecisionRecallDisplay, auc)\n", - "\n", - "y = np.array([ 0, 1, 1, 0, 1, 0, 1, 0, 0, 1])\n", - "y_score = np.array([0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5])\n", - "y_ = np.array([1 if 0.5 <= p else 0 for p in y_score])\n", - "\n", - "[sum((y == 0) & (y_ == 1)) / sum(y == 0), # FPR\n", - " sum((y == 1) & (y_ == 1)) / sum(y == 1)] # TPR\n", - "#> [0.4, 0.8]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_fpr, my_tpr, _ = roc_curve(y_true=y,\n", - " y_score=y_score,\n", - " pos_label=1) # 1が陽性である.\n", - "RocCurveDisplay(fpr=my_fpr, tpr=my_tpr).plot()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "auc(x=my_fpr, y=my_tpr)\n", - "#> 0.8" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.2.2 再現率と精度のトレードオフ(PR曲線)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "[sum((y == 1) & (y_ == 1)) / sum(y == 1), # Recall == TPR\n", - " sum((y == 1) & (y_ == 1)) / sum(y_ == 1)] # Precision\n", - "#> [0.8, 0.6666666666666666]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_precision, my_recall, _ = precision_recall_curve(y_true=y,\n", - " probas_pred=y_score,\n", - " pos_label=1)\n", - "PrecisionRecallDisplay(precision=my_precision, recall=my_recall).plot()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "auc(x=my_recall, y=my_precision)\n", - "#> 0.8463095238095237" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.3 タイタニック" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import graphviz\n", - "import pandas as pd\n", - "from sklearn import tree\n", - "from sklearn.metrics import roc_curve, RocCurveDisplay, auc\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import OneHotEncoder\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/titanic.csv')\n", - "my_data = pd.read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data.head()\n", - "#> Class Sex Age Survived\n", - "#> 0 1st Male Child Yes\n", - "#> 1 1st Male Child Yes\n", - "#> 2 1st Male Child Yes\n", - "#> 3 1st Male Child Yes\n", - "#> 4 1st Male Child Yes" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.1 質的入力変数の扱い方\n", - "\n", - "### 10.3.2 決定木の訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X, y = my_data.iloc[:, 0:3], my_data.Survived\n", - "\n", - "my_pipeline = Pipeline([\n", - " ('ohe', OneHotEncoder(drop='first')),\n", - " ('tree', tree.DecisionTreeClassifier(max_depth=2, random_state=0,\n", - " min_impurity_decrease=0.01))])\n", - "my_pipeline.fit(X, y)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.3 決定木の描画" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_enc = my_pipeline.named_steps['ohe'] # パイプラインからエンコーダを取り出す.\n", - "my_tree = my_pipeline.named_steps['tree'] # パイプラインから木を取り出す.\n", - "\n", - "my_dot = tree.export_graphviz(\n", - " decision_tree=my_tree,\n", - " out_file=None,\n", - " feature_names=my_enc.get_feature_names() \\\n", - " if hasattr(my_enc, 'get_feature_names') else my_enc.get_feature_names_out(),\n", - " class_names=my_pipeline.classes_,\n", - " filled=True)\n", - "graphviz.Source(my_dot)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.4 決定木の評価" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scores = cross_val_score(\n", - " my_pipeline, X, y,\n", - " cv=LeaveOneOut(),\n", - " n_jobs=-1)\n", - "my_scores.mean()\n", - "#> 0.7832803271240345" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = pd.DataFrame(\n", - " my_pipeline.predict_proba(X),\n", - " columns=my_pipeline.classes_)\n", - "y_score = tmp.Yes\n", - "\n", - "my_fpr, my_tpr, _ = roc_curve(y_true=y,\n", - " y_score=y_score,\n", - " pos_label='Yes')\n", - "my_auc = auc(x=my_fpr, y=my_tpr)\n", - "my_auc\n", - "#> 0.7114886868858494\n", - "\n", - "RocCurveDisplay(fpr=my_fpr, tpr=my_tpr, roc_auc=my_auc).plot()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.5 補足:質的入力変数の扱い\n", - "\n", - "## 10.4 ロジスティック回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "\n", - "x = np.arange(-6, 6, 0.1)\n", - "y = 1 / (1 + np.exp(-x))\n", - "plt.plot(x, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.linear_model import LogisticRegression\n", - "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", - "from sklearn.pipeline import Pipeline\n", - "from sklearn.preprocessing import OneHotEncoder\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/titanic.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "\n", - "X, y = my_data.iloc[:, 0:3], my_data.Survived\n", - "\n", - "my_pipeline = Pipeline([('ohe', OneHotEncoder(drop='first')),\n", - " ('lr', LogisticRegression(penalty='none'))])\n", - "my_pipeline.fit(X, y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_ohe = my_pipeline.named_steps.ohe\n", - "my_lr = my_pipeline.named_steps.lr\n", - "\n", - "my_lr.intercept_[0]\n", - "#> 2.043878162056783\n", - "\n", - "tmp = my_ohe.get_feature_names() \\\n", - "if hasattr(my_ohe, 'get_feature_names') \\\n", - "else my_ohe.get_feature_names_out()\n", - "pd.Series(my_lr.coef_[0],\n", - " index=tmp)\n", - "#> x0_2nd -1.018069\n", - "#> x0_3rd -1.777746\n", - "#> x0_Crew -0.857708\n", - "#> x1_Male -2.420090\n", - "#> x2_Child 1.061531\n", - "#> dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scores = cross_val_score(\n", - " my_pipeline, X, y,\n", - " cv=LeaveOneOut(),\n", - " n_jobs=-1)\n", - "my_scores.mean()\n", - "#> 0.7782825988187188" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch11/11-colab.ipynb b/code/Python-notebook/ch11/11-colab.ipynb deleted file mode 100644 index 5719847..0000000 --- a/code/Python-notebook/ch11/11-colab.ipynb +++ /dev/null @@ -1,949 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 11" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Google Colaboratoryの環境設定\n", - "!pip install h2o | tail -n 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.1 Kerasによる回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import pandas as pd\n", - "from keras import activations, callbacks, layers, models\n", - "from sklearn.preprocessing import StandardScaler\n", - "from sklearn.utils import shuffle\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "tmp = pd.read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data = shuffle(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scaler = StandardScaler()\n", - "X = my_scaler.fit_transform(\n", - " my_data.drop(columns=['LPRICE2']))\n", - "y = my_data['LPRICE2']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.linspace(-3, 3, 100)\n", - "plt.plot(x, activations.relu(x))\n", - "plt.xlabel('x')\n", - "plt.ylabel('ReLU(x)')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = models.Sequential()\n", - "my_model.add(layers.Dense(units=3, activation='relu', input_shape=[4]))\n", - "my_model.add(layers.Dense(units=1))\n", - "\n", - "my_model.summary() # ネットワークの概要\n", - "#> Model: \"sequential\"\n", - "#> _________________________________________________________________\n", - "#> Layer (type) Output Shape Param #\n", - "#> =================================================================\n", - "#> dense (Dense) (None, 3) 15\n", - "#> _________________________________________________________________\n", - "#> dense_1 (Dense) (None, 1) 4\n", - "#> =================================================================\n", - "#> Total params: 19\n", - "#> Trainable params: 19\n", - "#> Non-trainable params: 0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.compile(\n", - " loss='mse',\n", - " optimizer='rmsprop')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_cb = callbacks.EarlyStopping(\n", - " patience=20,\n", - " restore_best_weights=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history = my_model.fit(\n", - " x=X,\n", - " y=y,\n", - " validation_split=0.25,\n", - " batch_size=10,\n", - " epochs=500,\n", - " callbacks=[my_cb],\n", - " verbose=0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = pd.DataFrame(my_history.history)\n", - "tmp.plot(xlabel='epoch')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp.iloc[-1, ]\n", - "#> loss 0.192743\n", - "#> val_loss 0.342249\n", - "#> Name: 499, dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = my_model.predict(X)\n", - "((y_.ravel() - y)**2).mean()\n", - "#> 0.23050613964540986" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.2 Kerasによる分類" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from keras import callbacks, layers, losses, models\n", - "from sklearn.preprocessing import StandardScaler, LabelEncoder\n", - "from sklearn.utils import shuffle\n", - "\n", - "tmp = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "my_data = shuffle(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scaler = StandardScaler()\n", - "X = my_scaler.fit_transform(\n", - " my_data.drop(columns=['Species']))\n", - "my_enc = LabelEncoder()\n", - "y = my_enc.fit_transform(\n", - " my_data['Species'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = models.Sequential()\n", - "my_model.add(layers.Dense(units=3, activation='relu', input_shape=[4]))\n", - "my_model.add(layers.Dense(units=3, activation='softmax'))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.compile(loss='sparse_categorical_crossentropy',\n", - " optimizer='rmsprop',\n", - " metrics=['accuracy'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_cb = callbacks.EarlyStopping(\n", - " patience=20,\n", - " restore_best_weights=True)\n", - "\n", - "my_history = my_model.fit(\n", - " x=X,\n", - " y=y,\n", - " validation_split=0.25,\n", - " batch_size=10,\n", - " epochs=500,\n", - " callbacks=[my_cb],\n", - " verbose=0)\n", - "\n", - "tmp = pd.DataFrame(my_history.history)\n", - "tmp.plot(xlabel='epoch')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp.iloc[-1, ]\n", - "#> loss 0.067497\n", - "#> accuracy 0.973214\n", - "#> val_loss 0.143529\n", - "#> val_accuracy 0.921053" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_model.predict(X)\n", - "y_ = np.argmax(tmp, axis=-1)\n", - "(y_ == y).mean()\n", - "#> 0.96" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.2.1 交差エントロピー" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "-np.log([0.8, 0.7, 0.3, 0.8]).mean()\n", - "#> 0.5017337127232719\n", - "\n", - "-np.log([0.7, 0.6, 0.2, 0.7]).mean()\n", - "#> 0.708403356019389" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y = [2, 1, 0, 1]\n", - "y_1 = [[0.1, 0.1, 0.8],\n", - " [0.1, 0.7, 0.2],\n", - " [0.3, 0.4, 0.3],\n", - " [0.1, 0.8, 0.1]]\n", - "y_2 = [[0.1, 0.2, 0.7],\n", - " [0.2, 0.6, 0.2],\n", - " [0.2, 0.5, 0.3],\n", - " [0.2, 0.7, 0.1]]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "[losses.sparse_categorical_crossentropy(y_true=y, y_pred=y_1).numpy().mean(),\n", - " losses.sparse_categorical_crossentropy(y_true=y, y_pred=y_2).numpy().mean()]\n", - "#> [0.5017337, 0.70840335]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.3 MNIST:手書き数字の分類\n", - "\n", - "### 11.3.1 データの形式" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import pandas as pd\n", - "import tensorflow as tf\n", - "from random import sample\n", - "from keras import callbacks, layers, models\n", - "from sklearn.metrics import confusion_matrix\n", - "\n", - "(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train.shape\n", - "#> (60000, 28, 28)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.set_printoptions(linewidth=170)\n", - "x_train[4, :, :]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.matshow(x_train[4, :, :])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_train\n", - "#> array([5, 0, 4, ..., 5, 6, 8],\n", - "#> dtype=uint8)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train.min(), x_train.max()\n", - "#> (0, 255)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train = x_train / 255\n", - "x_test = x_test / 255" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_index = sample(range(60000), 6000)\n", - "x_train = x_train[my_index, :, :]\n", - "y_train = y_train[my_index]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.3.2 多層パーセプトロン" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = models.Sequential()\n", - "my_model.add(layers.Flatten(input_shape=[28, 28]))\n", - "my_model.add(layers.Dense(units=256, activation=\"relu\"))\n", - "my_model.add(layers.Dense(units=10, activation=\"softmax\"))\n", - "\n", - "my_model.summary()\n", - "#> Model: \"sequential\"\n", - "#> _________________________________________________________________\n", - "#> Layer (type) Output Shape Param #\n", - "#> =================================================================\n", - "#> flatten (Flatten) (None, 784) 0\n", - "#> _________________________________________________________________\n", - "#> dense (Dense) (None, 256) 200960\n", - "#> _________________________________________________________________\n", - "#> dense_1 (Dense) (None, 10) 2570\n", - "#> =================================================================\n", - "#> Total params: 203,530\n", - "#> Trainable params: 203,530\n", - "#> Non-trainable params: 0\n", - "#> _________________________________________________________________\n", - "\n", - "my_model.compile(loss='sparse_categorical_crossentropy',\n", - " optimizer='rmsprop',\n", - " metrics=['accuracy'])\n", - "\n", - "my_cb = callbacks.EarlyStopping(patience=5, restore_best_weights=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history = my_model.fit(\n", - " x=x_train,\n", - " y=y_train,\n", - " validation_split=0.2,\n", - " batch_size=128,\n", - " epochs=20,\n", - " callbacks=[my_cb],\n", - " verbose=0)\n", - "\n", - "tmp = pd.DataFrame(my_history.history)\n", - "tmp.plot(xlabel='epoch', style='o-')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_model.predict(x_test)\n", - "y_ = np.argmax(tmp, axis=-1)\n", - "confusion_matrix(y_true=y_test,\n", - " y_pred=y_)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#> [[ 962 0 2 1 1 2 7 1 2 2]\n", - "#> [ 0 1123 4 0 0 1 3 0 4 0]\n", - "#> [ 11 4 954 11 6 2 7 9 26 2]\n", - "#> [ 3 0 20 930 2 12 2 11 21 9]\n", - "#> [ 1 1 7 0 927 1 11 1 5 28]\n", - "#> [ 10 1 3 16 4 812 11 7 24 4]\n", - "#> [ 9 3 4 0 9 10 919 0 4 0]\n", - "#> [ 3 6 17 4 11 0 0 965 2 20]\n", - "#> [ 8 4 6 12 6 9 9 7 901 12]\n", - "#> [ 9 8 0 8 31 4 1 14 7 927]]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(y_ == y_test).mean()\n", - "#> 0.942" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.evaluate(x=x_test, y=y_test)\n", - "#> [0.20125965774059296,\n", - "#> 0.9419999718666077]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.3.3 畳み込みニューラルネットワーク(CNN)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train2d = x_train.reshape(-1, 28, 28, 1)\n", - "x_test2d = x_test.reshape(-1, 28, 28, 1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.1 単純なCNN" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = models.Sequential()\n", - "my_model.add(layers.Conv2D(filters=32, kernel_size=3, # 畳み込み層\n", - " activation='relu',\n", - " input_shape=[28, 28, 1]))\n", - "my_model.add(layers.MaxPooling2D(pool_size=2)) # プーリング層\n", - "my_model.add(layers.Flatten())\n", - "my_model.add(layers.Dense(128, activation='relu'))\n", - "my_model.add(layers.Dense(10, activation='softmax'))\n", - "\n", - "my_model.summary()\n", - "#> Model: \"sequential\"\n", - "#> _________________________________________________________________\n", - "#> Layer (type) Output Shape Param #\n", - "#> =================================================================\n", - "#> conv2d (Conv2D) (None, 26, 26, 32) 320\n", - "#> _________________________________________________________________\n", - "#> max_pooling2d (MaxPooling2D) (None, 13, 13, 32) 0\n", - "#> _________________________________________________________________\n", - "#> flatten (Flatten) (None, 5408) 0\n", - "#> _________________________________________________________________\n", - "#> dense (Dense) (None, 128) 692352\n", - "#> _________________________________________________________________\n", - "#> dense_1 (Dense) (None, 10) 1290\n", - "#> =================================================================\n", - "#> Total params: 693,962\n", - "#> Trainable params: 693,962\n", - "#> Non-trainable params: 0\n", - "#> _________________________________________________________________\n", - "\n", - "my_model.compile(loss='sparse_categorical_crossentropy',\n", - " optimizer='rmsprop',\n", - " metrics=['accuracy'])\n", - "\n", - "from keras.callbacks import EarlyStopping\n", - "my_cb = EarlyStopping(patience=5,\n", - " restore_best_weights=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history = my_model.fit(\n", - " x=x_train2d,\n", - " y=y_train,\n", - " validation_split=0.2,\n", - " batch_size=128,\n", - " epochs=20,\n", - " callbacks=my_cb,\n", - " verbose=0)\n", - "\n", - "tmp = pd.DataFrame(my_history.history)\n", - "tmp.plot(xlabel='epoch', style='o-')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.evaluate(x=x_test2d, y=y_test)\n", - "#> [0.1359061449766159,\n", - "#> 0.9581000208854675]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.2 LeNet" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = models.Sequential()\n", - "my_model.add(layers.Conv2D(filters=20, kernel_size=5, activation='relu',\n", - " input_shape=(28, 28, 1)))\n", - "my_model.add(layers.MaxPooling2D(pool_size=2, strides=2))\n", - "my_model.add(layers.Conv2D(filters=20, kernel_size=5, activation='relu'))\n", - "my_model.add(layers.MaxPooling2D(pool_size=2, strides=2))\n", - "my_model.add(layers.Dropout(rate=0.25))\n", - "my_model.add(layers.Flatten())\n", - "my_model.add(layers.Dense(500, activation='relu'))\n", - "my_model.add(layers.Dropout(rate=0.5))\n", - "my_model.add(layers.Dense(10, activation='softmax'))\n", - "\n", - "my_model.compile(loss='sparse_categorical_crossentropy',\n", - " optimizer='rmsprop',\n", - " metrics=['accuracy'])\n", - "\n", - "my_cb = callbacks.EarlyStopping(patience=5,\n", - " restore_best_weights=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history = my_model.fit(\n", - " x=x_train2d,\n", - " y=y_train,\n", - " validation_split=0.2,\n", - " batch_size=128,\n", - " epochs=20,\n", - " callbacks=my_cb,\n", - " verbose=0)\n", - "\n", - "tmp = pd.DataFrame(my_history.history)\n", - "tmp.plot(xlabel='epoch', style='o-')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.evaluate(x=x_test2d, y=y_test)\n", - "#> [0.06491111218929291,\n", - "#> 0.9797000288963318]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.3 補足:LeNetが自信満々で間違う例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_prob = my_model.predict(x_test2d) # カテゴリに属する確率\n", - "\n", - "tmp = pd.DataFrame({\n", - " 'y_prob': np.max(y_prob, axis=1), # 確率の最大値\n", - " 'y_': np.argmax(y_prob, axis=1), # 予測カテゴリ\n", - " 'y': y_test, # 正解\n", - " 'id': range(len(y_test))}) # 番号\n", - "\n", - "tmp = tmp[tmp.y_ != tmp.y] # 予測がはずれたものを残す\n", - "my_result = tmp.sort_values('y_prob', ascending=False) # 確率の大きい順に並び替える" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result.head()\n", - "#> y_prob y_ y id\n", - "#> 2654 0.999997 1 6 2654\n", - "#> 1232 0.999988 4 9 1232\n", - "#> 3520 0.999926 4 6 3520\n", - "#> 9729 0.999881 6 5 9729\n", - "#> 2896 0.999765 0 8 2896" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "for i in range(5):\n", - " plt.subplot(1, 5, i + 1)\n", - " ans = my_result['y'].iloc[i]\n", - " id = my_result['id'].iloc[i]\n", - " plt.title(f'{ans} ({id})')\n", - " plt.imshow(x_test[id])\n", - " plt.axis('off')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.4 AutoML\n", - "\n", - "### 11.4.1 H2Oの起動と停止" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import h2o\n", - "import pandas as pd\n", - "import tensorflow as tf\n", - "from h2o.automl import H2OAutoML\n", - "from random import sample\n", - "\n", - "h2o.init()\n", - "h2o.no_progress()\n", - "# h2o.cluster().shutdown() # 停止" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.2 H2Oのデータフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "my_frame = h2o.H2OFrame(my_data) # 通常のデータフレームをH2OFrameに変換する.\n", - "# あるいは\n", - "my_frame = h2o.import_file(my_url, header=1) # データを読み込む." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_frame.head(5)\n", - "#> LPRICE2 WRAIN DEGREES ...\n", - "#> --------- ------- --------- ...\n", - "#> -0.99868 600 17.1167 ...\n", - "#> -0.4544 690 16.7333 ...\n", - "#> -0.80796 502 17.15 ...\n", - "#> -1.50926 420 16.1333 ...\n", - "#> -1.71655 582 16.4167 ...\n", - "\n", - "# 通常のデータフレームに戻す.\n", - "h2o.as_list(my_frame).head()\n", - "# 結果は割愛(見た目は同じ)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.3 AutoMLによる回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = H2OAutoML(\n", - " max_runtime_secs=60)\n", - "my_model.train(\n", - " y='LPRICE2',\n", - " training_frame=my_frame)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.leaderboard['rmse'].min()\n", - "#> 0.2704643402377778" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = h2o.as_list(\n", - " my_model.predict(my_frame))\n", - "\n", - "pd.DataFrame({\n", - " 'y': my_data['LPRICE2'],\n", - " 'y_': tmp['predict']}\n", - ").plot('y', 'y_', kind='scatter')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.4 AutoMLによる分類" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()\n", - "my_index = sample(range(60000), 6000)\n", - "x_train = x_train[my_index, :, :]\n", - "y_train = y_train[my_index]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = pd.DataFrame(\n", - " x_train.reshape(-1, 28 * 28))\n", - "y = 'y'\n", - "tmp[y] = y_train\n", - "my_train = h2o.H2OFrame(tmp)\n", - "my_train[y] = my_train[y].asfactor()\n", - "\n", - "tmp = pd.DataFrame(\n", - " x_test.reshape(-1, 28 * 28))\n", - "my_test = h2o.H2OFrame(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = H2OAutoML(\n", - " max_runtime_secs=120)\n", - "my_model.train(\n", - " y=y,\n", - " training_frame=my_train)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.leaderboard[\n", - " 'mean_per_class_error'].min()\n", - "#> 0.06803754348177862" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = h2o.as_list(\n", - " my_model.predict(my_test))\n", - "y_ = tmp.predict\n", - "\n", - "(y_ == y_test).mean()\n", - "#> 0.938" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch11/11.01.ipynb b/code/Python-notebook/ch11/11.01.ipynb deleted file mode 100644 index 80118ca..0000000 --- a/code/Python-notebook/ch11/11.01.ipynb +++ /dev/null @@ -1,165 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.1 Kerasによる回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import pandas as pd\n", - "from keras import activations, callbacks, layers, models\n", - "from sklearn.preprocessing import StandardScaler\n", - "from sklearn.utils import shuffle\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "tmp = pd.read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data = shuffle(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scaler = StandardScaler()\n", - "X = my_scaler.fit_transform(\n", - " my_data.drop(columns=['LPRICE2']))\n", - "y = my_data['LPRICE2']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.linspace(-3, 3, 100)\n", - "plt.plot(x, activations.relu(x))\n", - "plt.xlabel('x')\n", - "plt.ylabel('ReLU(x)')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = models.Sequential()\n", - "my_model.add(layers.Dense(units=3, activation='relu', input_shape=[4]))\n", - "my_model.add(layers.Dense(units=1))\n", - "\n", - "my_model.summary() # ネットワークの概要\n", - "#> Model: \"sequential\"\n", - "#> _________________________________________________________________\n", - "#> Layer (type) Output Shape Param #\n", - "#> =================================================================\n", - "#> dense (Dense) (None, 3) 15\n", - "#> _________________________________________________________________\n", - "#> dense_1 (Dense) (None, 1) 4\n", - "#> =================================================================\n", - "#> Total params: 19\n", - "#> Trainable params: 19\n", - "#> Non-trainable params: 0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.compile(\n", - " loss='mse',\n", - " optimizer='rmsprop')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_cb = callbacks.EarlyStopping(\n", - " patience=20,\n", - " restore_best_weights=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history = my_model.fit(\n", - " x=X,\n", - " y=y,\n", - " validation_split=0.25,\n", - " batch_size=10,\n", - " epochs=500,\n", - " callbacks=[my_cb],\n", - " verbose=0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = pd.DataFrame(my_history.history)\n", - "tmp.plot(xlabel='epoch')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp.iloc[-1, ]\n", - "#> loss 0.192743\n", - "#> val_loss 0.342249\n", - "#> Name: 499, dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = my_model.predict(X)\n", - "((y_.ravel() - y)**2).mean()\n", - "#> 0.23050613964540986" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch11/11.02.ipynb b/code/Python-notebook/ch11/11.02.ipynb deleted file mode 100644 index 35f4554..0000000 --- a/code/Python-notebook/ch11/11.02.ipynb +++ /dev/null @@ -1,168 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.2 Kerasによる分類" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from keras import callbacks, layers, losses, models\n", - "from sklearn.preprocessing import StandardScaler, LabelEncoder\n", - "from sklearn.utils import shuffle\n", - "\n", - "tmp = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "my_data = shuffle(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scaler = StandardScaler()\n", - "X = my_scaler.fit_transform(\n", - " my_data.drop(columns=['Species']))\n", - "my_enc = LabelEncoder()\n", - "y = my_enc.fit_transform(\n", - " my_data['Species'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = models.Sequential()\n", - "my_model.add(layers.Dense(units=3, activation='relu', input_shape=[4]))\n", - "my_model.add(layers.Dense(units=3, activation='softmax'))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.compile(loss='sparse_categorical_crossentropy',\n", - " optimizer='rmsprop',\n", - " metrics=['accuracy'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_cb = callbacks.EarlyStopping(\n", - " patience=20,\n", - " restore_best_weights=True)\n", - "\n", - "my_history = my_model.fit(\n", - " x=X,\n", - " y=y,\n", - " validation_split=0.25,\n", - " batch_size=10,\n", - " epochs=500,\n", - " callbacks=[my_cb],\n", - " verbose=0)\n", - "\n", - "tmp = pd.DataFrame(my_history.history)\n", - "tmp.plot(xlabel='epoch')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp.iloc[-1, ]\n", - "#> loss 0.067497\n", - "#> accuracy 0.973214\n", - "#> val_loss 0.143529\n", - "#> val_accuracy 0.921053" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_model.predict(X)\n", - "y_ = np.argmax(tmp, axis=-1)\n", - "(y_ == y).mean()\n", - "#> 0.96" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.2.1 交差エントロピー" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "-np.log([0.8, 0.7, 0.3, 0.8]).mean()\n", - "#> 0.5017337127232719\n", - "\n", - "-np.log([0.7, 0.6, 0.2, 0.7]).mean()\n", - "#> 0.708403356019389" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y = [2, 1, 0, 1]\n", - "y_1 = [[0.1, 0.1, 0.8],\n", - " [0.1, 0.7, 0.2],\n", - " [0.3, 0.4, 0.3],\n", - " [0.1, 0.8, 0.1]]\n", - "y_2 = [[0.1, 0.2, 0.7],\n", - " [0.2, 0.6, 0.2],\n", - " [0.2, 0.5, 0.3],\n", - " [0.2, 0.7, 0.1]]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "[losses.sparse_categorical_crossentropy(y_true=y, y_pred=y_1).numpy().mean(),\n", - " losses.sparse_categorical_crossentropy(y_true=y, y_pred=y_2).numpy().mean()]\n", - "#> [0.5017337, 0.70840335]" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch11/11.03.ipynb b/code/Python-notebook/ch11/11.03.ipynb deleted file mode 100644 index c6756e5..0000000 --- a/code/Python-notebook/ch11/11.03.ipynb +++ /dev/null @@ -1,436 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.3 MNIST:手書き数字の分類\n", - "\n", - "### 11.3.1 データの形式" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import pandas as pd\n", - "import tensorflow as tf\n", - "from random import sample\n", - "from keras import callbacks, layers, models\n", - "from sklearn.metrics import confusion_matrix\n", - "\n", - "(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train.shape\n", - "#> (60000, 28, 28)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.set_printoptions(linewidth=170)\n", - "x_train[4, :, :]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.matshow(x_train[4, :, :])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_train\n", - "#> array([5, 0, 4, ..., 5, 6, 8],\n", - "#> dtype=uint8)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train.min(), x_train.max()\n", - "#> (0, 255)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train = x_train / 255\n", - "x_test = x_test / 255" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_index = sample(range(60000), 6000)\n", - "x_train = x_train[my_index, :, :]\n", - "y_train = y_train[my_index]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.3.2 多層パーセプトロン" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = models.Sequential()\n", - "my_model.add(layers.Flatten(input_shape=[28, 28]))\n", - "my_model.add(layers.Dense(units=256, activation=\"relu\"))\n", - "my_model.add(layers.Dense(units=10, activation=\"softmax\"))\n", - "\n", - "my_model.summary()\n", - "#> Model: \"sequential\"\n", - "#> _________________________________________________________________\n", - "#> Layer (type) Output Shape Param #\n", - "#> =================================================================\n", - "#> flatten (Flatten) (None, 784) 0\n", - "#> _________________________________________________________________\n", - "#> dense (Dense) (None, 256) 200960\n", - "#> _________________________________________________________________\n", - "#> dense_1 (Dense) (None, 10) 2570\n", - "#> =================================================================\n", - "#> Total params: 203,530\n", - "#> Trainable params: 203,530\n", - "#> Non-trainable params: 0\n", - "#> _________________________________________________________________\n", - "\n", - "my_model.compile(loss='sparse_categorical_crossentropy',\n", - " optimizer='rmsprop',\n", - " metrics=['accuracy'])\n", - "\n", - "my_cb = callbacks.EarlyStopping(patience=5, restore_best_weights=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history = my_model.fit(\n", - " x=x_train,\n", - " y=y_train,\n", - " validation_split=0.2,\n", - " batch_size=128,\n", - " epochs=20,\n", - " callbacks=[my_cb],\n", - " verbose=0)\n", - "\n", - "tmp = pd.DataFrame(my_history.history)\n", - "tmp.plot(xlabel='epoch', style='o-')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_model.predict(x_test)\n", - "y_ = np.argmax(tmp, axis=-1)\n", - "confusion_matrix(y_true=y_test,\n", - " y_pred=y_)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#> [[ 962 0 2 1 1 2 7 1 2 2]\n", - "#> [ 0 1123 4 0 0 1 3 0 4 0]\n", - "#> [ 11 4 954 11 6 2 7 9 26 2]\n", - "#> [ 3 0 20 930 2 12 2 11 21 9]\n", - "#> [ 1 1 7 0 927 1 11 1 5 28]\n", - "#> [ 10 1 3 16 4 812 11 7 24 4]\n", - "#> [ 9 3 4 0 9 10 919 0 4 0]\n", - "#> [ 3 6 17 4 11 0 0 965 2 20]\n", - "#> [ 8 4 6 12 6 9 9 7 901 12]\n", - "#> [ 9 8 0 8 31 4 1 14 7 927]]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(y_ == y_test).mean()\n", - "#> 0.942" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.evaluate(x=x_test, y=y_test)\n", - "#> [0.20125965774059296,\n", - "#> 0.9419999718666077]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.3.3 畳み込みニューラルネットワーク(CNN)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train2d = x_train.reshape(-1, 28, 28, 1)\n", - "x_test2d = x_test.reshape(-1, 28, 28, 1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.1 単純なCNN" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = models.Sequential()\n", - "my_model.add(layers.Conv2D(filters=32, kernel_size=3, # 畳み込み層\n", - " activation='relu',\n", - " input_shape=[28, 28, 1]))\n", - "my_model.add(layers.MaxPooling2D(pool_size=2)) # プーリング層\n", - "my_model.add(layers.Flatten())\n", - "my_model.add(layers.Dense(128, activation='relu'))\n", - "my_model.add(layers.Dense(10, activation='softmax'))\n", - "\n", - "my_model.summary()\n", - "#> Model: \"sequential\"\n", - "#> _________________________________________________________________\n", - "#> Layer (type) Output Shape Param #\n", - "#> =================================================================\n", - "#> conv2d (Conv2D) (None, 26, 26, 32) 320\n", - "#> _________________________________________________________________\n", - "#> max_pooling2d (MaxPooling2D) (None, 13, 13, 32) 0\n", - "#> _________________________________________________________________\n", - "#> flatten (Flatten) (None, 5408) 0\n", - "#> _________________________________________________________________\n", - "#> dense (Dense) (None, 128) 692352\n", - "#> _________________________________________________________________\n", - "#> dense_1 (Dense) (None, 10) 1290\n", - "#> =================================================================\n", - "#> Total params: 693,962\n", - "#> Trainable params: 693,962\n", - "#> Non-trainable params: 0\n", - "#> _________________________________________________________________\n", - "\n", - "my_model.compile(loss='sparse_categorical_crossentropy',\n", - " optimizer='rmsprop',\n", - " metrics=['accuracy'])\n", - "\n", - "from keras.callbacks import EarlyStopping\n", - "my_cb = EarlyStopping(patience=5,\n", - " restore_best_weights=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history = my_model.fit(\n", - " x=x_train2d,\n", - " y=y_train,\n", - " validation_split=0.2,\n", - " batch_size=128,\n", - " epochs=20,\n", - " callbacks=my_cb,\n", - " verbose=0)\n", - "\n", - "tmp = pd.DataFrame(my_history.history)\n", - "tmp.plot(xlabel='epoch', style='o-')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.evaluate(x=x_test2d, y=y_test)\n", - "#> [0.1359061449766159,\n", - "#> 0.9581000208854675]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.2 LeNet" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = models.Sequential()\n", - "my_model.add(layers.Conv2D(filters=20, kernel_size=5, activation='relu',\n", - " input_shape=(28, 28, 1)))\n", - "my_model.add(layers.MaxPooling2D(pool_size=2, strides=2))\n", - "my_model.add(layers.Conv2D(filters=20, kernel_size=5, activation='relu'))\n", - "my_model.add(layers.MaxPooling2D(pool_size=2, strides=2))\n", - "my_model.add(layers.Dropout(rate=0.25))\n", - "my_model.add(layers.Flatten())\n", - "my_model.add(layers.Dense(500, activation='relu'))\n", - "my_model.add(layers.Dropout(rate=0.5))\n", - "my_model.add(layers.Dense(10, activation='softmax'))\n", - "\n", - "my_model.compile(loss='sparse_categorical_crossentropy',\n", - " optimizer='rmsprop',\n", - " metrics=['accuracy'])\n", - "\n", - "my_cb = callbacks.EarlyStopping(patience=5,\n", - " restore_best_weights=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history = my_model.fit(\n", - " x=x_train2d,\n", - " y=y_train,\n", - " validation_split=0.2,\n", - " batch_size=128,\n", - " epochs=20,\n", - " callbacks=my_cb,\n", - " verbose=0)\n", - "\n", - "tmp = pd.DataFrame(my_history.history)\n", - "tmp.plot(xlabel='epoch', style='o-')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.evaluate(x=x_test2d, y=y_test)\n", - "#> [0.06491111218929291,\n", - "#> 0.9797000288963318]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.3 補足:LeNetが自信満々で間違う例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_prob = my_model.predict(x_test2d) # カテゴリに属する確率\n", - "\n", - "tmp = pd.DataFrame({\n", - " 'y_prob': np.max(y_prob, axis=1), # 確率の最大値\n", - " 'y_': np.argmax(y_prob, axis=1), # 予測カテゴリ\n", - " 'y': y_test, # 正解\n", - " 'id': range(len(y_test))}) # 番号\n", - "\n", - "tmp = tmp[tmp.y_ != tmp.y] # 予測がはずれたものを残す\n", - "my_result = tmp.sort_values('y_prob', ascending=False) # 確率の大きい順に並び替える" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result.head()\n", - "#> y_prob y_ y id\n", - "#> 2654 0.999997 1 6 2654\n", - "#> 1232 0.999988 4 9 1232\n", - "#> 3520 0.999926 4 6 3520\n", - "#> 9729 0.999881 6 5 9729\n", - "#> 2896 0.999765 0 8 2896" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "for i in range(5):\n", - " plt.subplot(1, 5, i + 1)\n", - " ans = my_result['y'].iloc[i]\n", - " id = my_result['id'].iloc[i]\n", - " plt.title(f'{ans} ({id})')\n", - " plt.imshow(x_test[id])\n", - " plt.axis('off')" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch11/11.04.ipynb b/code/Python-notebook/ch11/11.04.ipynb deleted file mode 100644 index 8dd5720..0000000 --- a/code/Python-notebook/ch11/11.04.ipynb +++ /dev/null @@ -1,199 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.4 AutoML\n", - "\n", - "### 11.4.1 H2Oの起動と停止" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import h2o\n", - "import pandas as pd\n", - "import tensorflow as tf\n", - "from h2o.automl import H2OAutoML\n", - "from random import sample\n", - "\n", - "h2o.init()\n", - "h2o.no_progress()\n", - "# h2o.cluster().shutdown() # 停止" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.2 H2Oのデータフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "my_frame = h2o.H2OFrame(my_data) # 通常のデータフレームをH2OFrameに変換する.\n", - "# あるいは\n", - "my_frame = h2o.import_file(my_url, header=1) # データを読み込む." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_frame.head(5)\n", - "#> LPRICE2 WRAIN DEGREES ...\n", - "#> --------- ------- --------- ...\n", - "#> -0.99868 600 17.1167 ...\n", - "#> -0.4544 690 16.7333 ...\n", - "#> -0.80796 502 17.15 ...\n", - "#> -1.50926 420 16.1333 ...\n", - "#> -1.71655 582 16.4167 ...\n", - "\n", - "# 通常のデータフレームに戻す.\n", - "h2o.as_list(my_frame).head()\n", - "# 結果は割愛(見た目は同じ)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.3 AutoMLによる回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = H2OAutoML(\n", - " max_runtime_secs=60)\n", - "my_model.train(\n", - " y='LPRICE2',\n", - " training_frame=my_frame)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.leaderboard['rmse'].min()\n", - "#> 0.2704643402377778" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = h2o.as_list(\n", - " my_model.predict(my_frame))\n", - "\n", - "pd.DataFrame({\n", - " 'y': my_data['LPRICE2'],\n", - " 'y_': tmp['predict']}\n", - ").plot('y', 'y_', kind='scatter')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.4 AutoMLによる分類" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()\n", - "my_index = sample(range(60000), 6000)\n", - "x_train = x_train[my_index, :, :]\n", - "y_train = y_train[my_index]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = pd.DataFrame(\n", - " x_train.reshape(-1, 28 * 28))\n", - "y = 'y'\n", - "tmp[y] = y_train\n", - "my_train = h2o.H2OFrame(tmp)\n", - "my_train[y] = my_train[y].asfactor()\n", - "\n", - "tmp = pd.DataFrame(\n", - " x_test.reshape(-1, 28 * 28))\n", - "my_test = h2o.H2OFrame(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = H2OAutoML(\n", - " max_runtime_secs=120)\n", - "my_model.train(\n", - " y=y,\n", - " training_frame=my_train)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.leaderboard[\n", - " 'mean_per_class_error'].min()\n", - "#> 0.06803754348177862" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = h2o.as_list(\n", - " my_model.predict(my_test))\n", - "y_ = tmp.predict\n", - "\n", - "(y_ == y_test).mean()\n", - "#> 0.938" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch11/11.ipynb b/code/Python-notebook/ch11/11.ipynb deleted file mode 100644 index e476d02..0000000 --- a/code/Python-notebook/ch11/11.ipynb +++ /dev/null @@ -1,934 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 11\n", - "\n", - "## 11.1 Kerasによる回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import pandas as pd\n", - "from keras import activations, callbacks, layers, models\n", - "from sklearn.preprocessing import StandardScaler\n", - "from sklearn.utils import shuffle\n", - "\n", - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "tmp = pd.read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data = shuffle(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scaler = StandardScaler()\n", - "X = my_scaler.fit_transform(\n", - " my_data.drop(columns=['LPRICE2']))\n", - "y = my_data['LPRICE2']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = np.linspace(-3, 3, 100)\n", - "plt.plot(x, activations.relu(x))\n", - "plt.xlabel('x')\n", - "plt.ylabel('ReLU(x)')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = models.Sequential()\n", - "my_model.add(layers.Dense(units=3, activation='relu', input_shape=[4]))\n", - "my_model.add(layers.Dense(units=1))\n", - "\n", - "my_model.summary() # ネットワークの概要\n", - "#> Model: \"sequential\"\n", - "#> _________________________________________________________________\n", - "#> Layer (type) Output Shape Param #\n", - "#> =================================================================\n", - "#> dense (Dense) (None, 3) 15\n", - "#> _________________________________________________________________\n", - "#> dense_1 (Dense) (None, 1) 4\n", - "#> =================================================================\n", - "#> Total params: 19\n", - "#> Trainable params: 19\n", - "#> Non-trainable params: 0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.compile(\n", - " loss='mse',\n", - " optimizer='rmsprop')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_cb = callbacks.EarlyStopping(\n", - " patience=20,\n", - " restore_best_weights=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history = my_model.fit(\n", - " x=X,\n", - " y=y,\n", - " validation_split=0.25,\n", - " batch_size=10,\n", - " epochs=500,\n", - " callbacks=[my_cb],\n", - " verbose=0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = pd.DataFrame(my_history.history)\n", - "tmp.plot(xlabel='epoch')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp.iloc[-1, ]\n", - "#> loss 0.192743\n", - "#> val_loss 0.342249\n", - "#> Name: 499, dtype: float64" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = my_model.predict(X)\n", - "((y_.ravel() - y)**2).mean()\n", - "#> 0.23050613964540986" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.2 Kerasによる分類" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from keras import callbacks, layers, losses, models\n", - "from sklearn.preprocessing import StandardScaler, LabelEncoder\n", - "from sklearn.utils import shuffle\n", - "\n", - "tmp = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "my_data = shuffle(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_scaler = StandardScaler()\n", - "X = my_scaler.fit_transform(\n", - " my_data.drop(columns=['Species']))\n", - "my_enc = LabelEncoder()\n", - "y = my_enc.fit_transform(\n", - " my_data['Species'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = models.Sequential()\n", - "my_model.add(layers.Dense(units=3, activation='relu', input_shape=[4]))\n", - "my_model.add(layers.Dense(units=3, activation='softmax'))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.compile(loss='sparse_categorical_crossentropy',\n", - " optimizer='rmsprop',\n", - " metrics=['accuracy'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_cb = callbacks.EarlyStopping(\n", - " patience=20,\n", - " restore_best_weights=True)\n", - "\n", - "my_history = my_model.fit(\n", - " x=X,\n", - " y=y,\n", - " validation_split=0.25,\n", - " batch_size=10,\n", - " epochs=500,\n", - " callbacks=[my_cb],\n", - " verbose=0)\n", - "\n", - "tmp = pd.DataFrame(my_history.history)\n", - "tmp.plot(xlabel='epoch')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp.iloc[-1, ]\n", - "#> loss 0.067497\n", - "#> accuracy 0.973214\n", - "#> val_loss 0.143529\n", - "#> val_accuracy 0.921053" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_model.predict(X)\n", - "y_ = np.argmax(tmp, axis=-1)\n", - "(y_ == y).mean()\n", - "#> 0.96" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.2.1 交差エントロピー" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "-np.log([0.8, 0.7, 0.3, 0.8]).mean()\n", - "#> 0.5017337127232719\n", - "\n", - "-np.log([0.7, 0.6, 0.2, 0.7]).mean()\n", - "#> 0.708403356019389" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y = [2, 1, 0, 1]\n", - "y_1 = [[0.1, 0.1, 0.8],\n", - " [0.1, 0.7, 0.2],\n", - " [0.3, 0.4, 0.3],\n", - " [0.1, 0.8, 0.1]]\n", - "y_2 = [[0.1, 0.2, 0.7],\n", - " [0.2, 0.6, 0.2],\n", - " [0.2, 0.5, 0.3],\n", - " [0.2, 0.7, 0.1]]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "[losses.sparse_categorical_crossentropy(y_true=y, y_pred=y_1).numpy().mean(),\n", - " losses.sparse_categorical_crossentropy(y_true=y, y_pred=y_2).numpy().mean()]\n", - "#> [0.5017337, 0.70840335]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.3 MNIST:手書き数字の分類\n", - "\n", - "### 11.3.1 データの形式" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import pandas as pd\n", - "import tensorflow as tf\n", - "from random import sample\n", - "from keras import callbacks, layers, models\n", - "from sklearn.metrics import confusion_matrix\n", - "\n", - "(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train.shape\n", - "#> (60000, 28, 28)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.set_printoptions(linewidth=170)\n", - "x_train[4, :, :]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.matshow(x_train[4, :, :])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_train\n", - "#> array([5, 0, 4, ..., 5, 6, 8],\n", - "#> dtype=uint8)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train.min(), x_train.max()\n", - "#> (0, 255)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train = x_train / 255\n", - "x_test = x_test / 255" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_index = sample(range(60000), 6000)\n", - "x_train = x_train[my_index, :, :]\n", - "y_train = y_train[my_index]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.3.2 多層パーセプトロン" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = models.Sequential()\n", - "my_model.add(layers.Flatten(input_shape=[28, 28]))\n", - "my_model.add(layers.Dense(units=256, activation=\"relu\"))\n", - "my_model.add(layers.Dense(units=10, activation=\"softmax\"))\n", - "\n", - "my_model.summary()\n", - "#> Model: \"sequential\"\n", - "#> _________________________________________________________________\n", - "#> Layer (type) Output Shape Param #\n", - "#> =================================================================\n", - "#> flatten (Flatten) (None, 784) 0\n", - "#> _________________________________________________________________\n", - "#> dense (Dense) (None, 256) 200960\n", - "#> _________________________________________________________________\n", - "#> dense_1 (Dense) (None, 10) 2570\n", - "#> =================================================================\n", - "#> Total params: 203,530\n", - "#> Trainable params: 203,530\n", - "#> Non-trainable params: 0\n", - "#> _________________________________________________________________\n", - "\n", - "my_model.compile(loss='sparse_categorical_crossentropy',\n", - " optimizer='rmsprop',\n", - " metrics=['accuracy'])\n", - "\n", - "my_cb = callbacks.EarlyStopping(patience=5, restore_best_weights=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history = my_model.fit(\n", - " x=x_train,\n", - " y=y_train,\n", - " validation_split=0.2,\n", - " batch_size=128,\n", - " epochs=20,\n", - " callbacks=[my_cb],\n", - " verbose=0)\n", - "\n", - "tmp = pd.DataFrame(my_history.history)\n", - "tmp.plot(xlabel='epoch', style='o-')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_model.predict(x_test)\n", - "y_ = np.argmax(tmp, axis=-1)\n", - "confusion_matrix(y_true=y_test,\n", - " y_pred=y_)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#> [[ 962 0 2 1 1 2 7 1 2 2]\n", - "#> [ 0 1123 4 0 0 1 3 0 4 0]\n", - "#> [ 11 4 954 11 6 2 7 9 26 2]\n", - "#> [ 3 0 20 930 2 12 2 11 21 9]\n", - "#> [ 1 1 7 0 927 1 11 1 5 28]\n", - "#> [ 10 1 3 16 4 812 11 7 24 4]\n", - "#> [ 9 3 4 0 9 10 919 0 4 0]\n", - "#> [ 3 6 17 4 11 0 0 965 2 20]\n", - "#> [ 8 4 6 12 6 9 9 7 901 12]\n", - "#> [ 9 8 0 8 31 4 1 14 7 927]]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(y_ == y_test).mean()\n", - "#> 0.942" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.evaluate(x=x_test, y=y_test)\n", - "#> [0.20125965774059296,\n", - "#> 0.9419999718666077]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.3.3 畳み込みニューラルネットワーク(CNN)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train2d = x_train.reshape(-1, 28, 28, 1)\n", - "x_test2d = x_test.reshape(-1, 28, 28, 1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.1 単純なCNN" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = models.Sequential()\n", - "my_model.add(layers.Conv2D(filters=32, kernel_size=3, # 畳み込み層\n", - " activation='relu',\n", - " input_shape=[28, 28, 1]))\n", - "my_model.add(layers.MaxPooling2D(pool_size=2)) # プーリング層\n", - "my_model.add(layers.Flatten())\n", - "my_model.add(layers.Dense(128, activation='relu'))\n", - "my_model.add(layers.Dense(10, activation='softmax'))\n", - "\n", - "my_model.summary()\n", - "#> Model: \"sequential\"\n", - "#> _________________________________________________________________\n", - "#> Layer (type) Output Shape Param #\n", - "#> =================================================================\n", - "#> conv2d (Conv2D) (None, 26, 26, 32) 320\n", - "#> _________________________________________________________________\n", - "#> max_pooling2d (MaxPooling2D) (None, 13, 13, 32) 0\n", - "#> _________________________________________________________________\n", - "#> flatten (Flatten) (None, 5408) 0\n", - "#> _________________________________________________________________\n", - "#> dense (Dense) (None, 128) 692352\n", - "#> _________________________________________________________________\n", - "#> dense_1 (Dense) (None, 10) 1290\n", - "#> =================================================================\n", - "#> Total params: 693,962\n", - "#> Trainable params: 693,962\n", - "#> Non-trainable params: 0\n", - "#> _________________________________________________________________\n", - "\n", - "my_model.compile(loss='sparse_categorical_crossentropy',\n", - " optimizer='rmsprop',\n", - " metrics=['accuracy'])\n", - "\n", - "from keras.callbacks import EarlyStopping\n", - "my_cb = EarlyStopping(patience=5,\n", - " restore_best_weights=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history = my_model.fit(\n", - " x=x_train2d,\n", - " y=y_train,\n", - " validation_split=0.2,\n", - " batch_size=128,\n", - " epochs=20,\n", - " callbacks=my_cb,\n", - " verbose=0)\n", - "\n", - "tmp = pd.DataFrame(my_history.history)\n", - "tmp.plot(xlabel='epoch', style='o-')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.evaluate(x=x_test2d, y=y_test)\n", - "#> [0.1359061449766159,\n", - "#> 0.9581000208854675]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.2 LeNet" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = models.Sequential()\n", - "my_model.add(layers.Conv2D(filters=20, kernel_size=5, activation='relu',\n", - " input_shape=(28, 28, 1)))\n", - "my_model.add(layers.MaxPooling2D(pool_size=2, strides=2))\n", - "my_model.add(layers.Conv2D(filters=20, kernel_size=5, activation='relu'))\n", - "my_model.add(layers.MaxPooling2D(pool_size=2, strides=2))\n", - "my_model.add(layers.Dropout(rate=0.25))\n", - "my_model.add(layers.Flatten())\n", - "my_model.add(layers.Dense(500, activation='relu'))\n", - "my_model.add(layers.Dropout(rate=0.5))\n", - "my_model.add(layers.Dense(10, activation='softmax'))\n", - "\n", - "my_model.compile(loss='sparse_categorical_crossentropy',\n", - " optimizer='rmsprop',\n", - " metrics=['accuracy'])\n", - "\n", - "my_cb = callbacks.EarlyStopping(patience=5,\n", - " restore_best_weights=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history = my_model.fit(\n", - " x=x_train2d,\n", - " y=y_train,\n", - " validation_split=0.2,\n", - " batch_size=128,\n", - " epochs=20,\n", - " callbacks=my_cb,\n", - " verbose=0)\n", - "\n", - "tmp = pd.DataFrame(my_history.history)\n", - "tmp.plot(xlabel='epoch', style='o-')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.evaluate(x=x_test2d, y=y_test)\n", - "#> [0.06491111218929291,\n", - "#> 0.9797000288963318]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.3 補足:LeNetが自信満々で間違う例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_prob = my_model.predict(x_test2d) # カテゴリに属する確率\n", - "\n", - "tmp = pd.DataFrame({\n", - " 'y_prob': np.max(y_prob, axis=1), # 確率の最大値\n", - " 'y_': np.argmax(y_prob, axis=1), # 予測カテゴリ\n", - " 'y': y_test, # 正解\n", - " 'id': range(len(y_test))}) # 番号\n", - "\n", - "tmp = tmp[tmp.y_ != tmp.y] # 予測がはずれたものを残す\n", - "my_result = tmp.sort_values('y_prob', ascending=False) # 確率の大きい順に並び替える" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result.head()\n", - "#> y_prob y_ y id\n", - "#> 2654 0.999997 1 6 2654\n", - "#> 1232 0.999988 4 9 1232\n", - "#> 3520 0.999926 4 6 3520\n", - "#> 9729 0.999881 6 5 9729\n", - "#> 2896 0.999765 0 8 2896" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "for i in range(5):\n", - " plt.subplot(1, 5, i + 1)\n", - " ans = my_result['y'].iloc[i]\n", - " id = my_result['id'].iloc[i]\n", - " plt.title(f'{ans} ({id})')\n", - " plt.imshow(x_test[id])\n", - " plt.axis('off')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.4 AutoML\n", - "\n", - "### 11.4.1 H2Oの起動と停止" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import h2o\n", - "import pandas as pd\n", - "import tensorflow as tf\n", - "from h2o.automl import H2OAutoML\n", - "from random import sample\n", - "\n", - "h2o.init()\n", - "h2o.no_progress()\n", - "# h2o.cluster().shutdown() # 停止" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.2 H2Oのデータフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", - " '/fromzero/master/data/wine.csv')\n", - "my_data = pd.read_csv(my_url)\n", - "my_frame = h2o.H2OFrame(my_data) # 通常のデータフレームをH2OFrameに変換する.\n", - "# あるいは\n", - "my_frame = h2o.import_file(my_url, header=1) # データを読み込む." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_frame.head(5)\n", - "#> LPRICE2 WRAIN DEGREES ...\n", - "#> --------- ------- --------- ...\n", - "#> -0.99868 600 17.1167 ...\n", - "#> -0.4544 690 16.7333 ...\n", - "#> -0.80796 502 17.15 ...\n", - "#> -1.50926 420 16.1333 ...\n", - "#> -1.71655 582 16.4167 ...\n", - "\n", - "# 通常のデータフレームに戻す.\n", - "h2o.as_list(my_frame).head()\n", - "# 結果は割愛(見た目は同じ)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.3 AutoMLによる回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = H2OAutoML(\n", - " max_runtime_secs=60)\n", - "my_model.train(\n", - " y='LPRICE2',\n", - " training_frame=my_frame)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.leaderboard['rmse'].min()\n", - "#> 0.2704643402377778" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = h2o.as_list(\n", - " my_model.predict(my_frame))\n", - "\n", - "pd.DataFrame({\n", - " 'y': my_data['LPRICE2'],\n", - " 'y_': tmp['predict']}\n", - ").plot('y', 'y_', kind='scatter')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.4 AutoMLによる分類" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()\n", - "my_index = sample(range(60000), 6000)\n", - "x_train = x_train[my_index, :, :]\n", - "y_train = y_train[my_index]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = pd.DataFrame(\n", - " x_train.reshape(-1, 28 * 28))\n", - "y = 'y'\n", - "tmp[y] = y_train\n", - "my_train = h2o.H2OFrame(tmp)\n", - "my_train[y] = my_train[y].asfactor()\n", - "\n", - "tmp = pd.DataFrame(\n", - " x_test.reshape(-1, 28 * 28))\n", - "my_test = h2o.H2OFrame(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model = H2OAutoML(\n", - " max_runtime_secs=120)\n", - "my_model.train(\n", - " y=y,\n", - " training_frame=my_train)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.leaderboard[\n", - " 'mean_per_class_error'].min()\n", - "#> 0.06803754348177862" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = h2o.as_list(\n", - " my_model.predict(my_test))\n", - "y_ = tmp.predict\n", - "\n", - "(y_ == y_test).mean()\n", - "#> 0.938" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch12/12-colab.ipynb b/code/Python-notebook/ch12/12-colab.ipynb deleted file mode 100644 index 8e66a65..0000000 --- a/code/Python-notebook/ch12/12-colab.ipynb +++ /dev/null @@ -1,340 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 12" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Google Colaboratoryの環境設定\n", - "!pip install pmdarima prophet | tail -n 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 12.1 日時と日時の列\n", - "\n", - "### 12.1.1 日時" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "pd.to_datetime('2020-01-01')\n", - "#> Timestamp('2020-01-01 00:00:00')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.1.2 等間隔の日時" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.date_range(start='2021-01-01', end='2023-01-01', freq='1A')\n", - "#> DatetimeIndex(['2021-12-31', '2022-12-31'],\n", - "#> dtype='datetime64[ns]', freq='A-DEC')\n", - "\n", - "pd.date_range(start='2021-01-01', end='2023-01-01', freq='1AS')\n", - "#> DatetimeIndex(['2021-01-01', '2022-01-01', '2023-01-01'],\n", - "#> dtype='datetime64[ns]', freq='AS-JAN')\n", - "\n", - "pd.date_range(start='2021-01-01', end='2021-03-01', freq='2M')\n", - "#> DatetimeIndex(['2021-01-31'], dtype='datetime64[ns]', freq='2M')\n", - "\n", - "pd.date_range(start='2021-01-01', end='2021-03-01', freq='2MS')\n", - "#> DatetimeIndex(['2021-01-01', '2021-03-01'],\n", - "#> dtype='datetime64[ns]', freq='2MS')\n", - "\n", - "pd.date_range(start='2021-01-01', end='2021-01-03', freq='1D')\n", - "#> DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03'],\n", - "#> dtype='datetime64[ns]', freq='D')\n", - "\n", - "pd.date_range(start='2021-01-01 00:00:00', end='2021-01-01 03:00:00', freq='2H')\n", - "#> DatetimeIndex(['2021-01-01 00:00:00', '2021-01-01 02:00:00'],\n", - "#> dtype='datetime64[ns]', freq='2H')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 12.2 時系列データの予測\n", - "\n", - "### 12.2.1 データの準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "from pmdarima.datasets import airpassengers\n", - "from sklearn.metrics import mean_squared_error\n", - "\n", - "my_data = airpassengers.load_airpassengers()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n = len(my_data) # データ数(144)\n", - "k = 108 # 訓練データ数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_ds = pd.date_range(\n", - " start='1949/01/01',\n", - " end='1960/12/01',\n", - " freq='MS')\n", - "my_df = pd.DataFrame({\n", - " 'ds': my_ds,\n", - " 'x': range(n),\n", - " 'y': my_data},\n", - " index=my_ds)\n", - "my_df.head()\n", - "#> ds x y\n", - "#> 1949-01-01 1949-01-01 0 112.0\n", - "#> 1949-02-01 1949-02-01 1 118.0\n", - "#> 1949-03-01 1949-03-01 2 132.0\n", - "#> 1949-04-01 1949-04-01 3 129.0\n", - "#> 1949-05-01 1949-05-01 4 121.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_train = my_df[ :k]\n", - "my_test = my_df[-(n - k): ]\n", - "y = my_test.y" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.plot(my_train.y, label='train')\n", - "plt.plot(my_test.y, label='test')\n", - "plt.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.2 線形回帰分析による時系列予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from sklearn.linear_model import LinearRegression\n", - "\n", - "my_lm_model = LinearRegression()\n", - "my_lm_model.fit(my_train[['x']], my_train.y)\n", - "\n", - "X = my_test[['x']]\n", - "y_ = my_lm_model.predict(X)\n", - "mean_squared_error(y, y_)**0.5 # RMSE(テスト)\n", - "#> 70.63707081783771" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = my_lm_model.predict(my_df[['x']])\n", - "tmp = pd.DataFrame(y_,\n", - " index=my_df.index)\n", - "plt.plot(my_train.y, label='train')\n", - "plt.plot(my_test.y, label='test')\n", - "plt.plot(tmp, label='model')\n", - "plt.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.3 SARIMAによる時系列予測\n", - "\n", - "#### 12.2.3.1 モデルの構築" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pmdarima as pm\n", - "my_arima_model = pm.auto_arima(my_train.y, m=12, trace=True)\n", - "#> (省略)\n", - "#> Best model: ARIMA(1,1,0)(0,1,0)[12]\n", - "#> Total fit time: 0.838 seconds" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 12.2.3.2 予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_, my_ci = my_arima_model.predict(len(my_test), # 期間はテストデータと同じ.\n", - " alpha=0.05, # 有意水準(デフォルト)\n", - " return_conf_int=True) # 信頼区間を求める.\n", - "tmp = pd.DataFrame({'y': y_,\n", - " 'Lo': my_ci[:, 0],\n", - " 'Hi': my_ci[:, 1]},\n", - " index=my_test.index)\n", - "tmp.head()\n", - "#> y Lo Hi\n", - "#> 1958-01-01 345.964471 327.088699 364.840243\n", - "#> 1958-02-01 331.731920 308.036230 355.427610\n", - "#> 1958-03-01 386.787992 358.515741 415.060244\n", - "#> 1958-04-01 378.774472 346.695454 410.853490\n", - "#> 1958-05-01 385.777732 350.270765 421.284700" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mean_squared_error(y, y_)**0.5\n", - "#> 22.132236727738697" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.plot(my_train.y, label='train')\n", - "plt.plot(my_test.y, label='test')\n", - "plt.plot(tmp.y, label='model')\n", - "plt.fill_between(tmp.index,\n", - " tmp.Lo,\n", - " tmp.Hi,\n", - " alpha=0.25) # 不透明度\n", - "plt.legend(loc='upper left')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.4 Prophetによる時系列予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "try: from fbprophet import Prophet\n", - "except ImportError: from prophet import Prophet\n", - "my_prophet_model = Prophet(seasonality_mode='multiplicative')\n", - "my_prophet_model.fit(my_train)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_prophet_model.predict(my_test)\n", - "tmp[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].head()\n", - "#> ds yhat yhat_lower yhat_upper\n", - "#> 0 1958-01-01 359.239305 350.910898 368.464588\n", - "#> 1 1958-02-01 350.690546 341.748862 359.964881\n", - "#> 2 1958-03-01 407.188556 398.483316 415.463759\n", - "#> 3 1958-04-01 398.481739 389.244105 406.742333\n", - "#> 4 1958-05-01 402.595604 393.721421 411.331761" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = tmp.yhat\n", - "mean_squared_error(y, y_)**0.5\n", - "#> 33.795549086036466" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# my_prophet_model.plot(tmp) # 予測結果のみでよい場合\n", - "\n", - "fig = my_prophet_model.plot(tmp)\n", - "fig.axes[0].plot(my_train.ds, my_train.y)\n", - "fig.axes[0].plot(my_test.ds, my_test.y, color='red')" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch12/12.01.ipynb b/code/Python-notebook/ch12/12.01.ipynb deleted file mode 100644 index 4dc7722..0000000 --- a/code/Python-notebook/ch12/12.01.ipynb +++ /dev/null @@ -1,69 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 12.1 日時と日時の列\n", - "\n", - "### 12.1.1 日時" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "pd.to_datetime('2020-01-01')\n", - "#> Timestamp('2020-01-01 00:00:00')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.1.2 等間隔の日時" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.date_range(start='2021-01-01', end='2023-01-01', freq='1A')\n", - "#> DatetimeIndex(['2021-12-31', '2022-12-31'],\n", - "#> dtype='datetime64[ns]', freq='A-DEC')\n", - "\n", - "pd.date_range(start='2021-01-01', end='2023-01-01', freq='1AS')\n", - "#> DatetimeIndex(['2021-01-01', '2022-01-01', '2023-01-01'],\n", - "#> dtype='datetime64[ns]', freq='AS-JAN')\n", - "\n", - "pd.date_range(start='2021-01-01', end='2021-03-01', freq='2M')\n", - "#> DatetimeIndex(['2021-01-31'], dtype='datetime64[ns]', freq='2M')\n", - "\n", - "pd.date_range(start='2021-01-01', end='2021-03-01', freq='2MS')\n", - "#> DatetimeIndex(['2021-01-01', '2021-03-01'],\n", - "#> dtype='datetime64[ns]', freq='2MS')\n", - "\n", - "pd.date_range(start='2021-01-01', end='2021-01-03', freq='1D')\n", - "#> DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03'],\n", - "#> dtype='datetime64[ns]', freq='D')\n", - "\n", - "pd.date_range(start='2021-01-01 00:00:00', end='2021-01-01 03:00:00', freq='2H')\n", - "#> DatetimeIndex(['2021-01-01 00:00:00', '2021-01-01 02:00:00'],\n", - "#> dtype='datetime64[ns]', freq='2H')" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch12/12.02.ipynb b/code/Python-notebook/ch12/12.02.ipynb deleted file mode 100644 index b480b72..0000000 --- a/code/Python-notebook/ch12/12.02.ipynb +++ /dev/null @@ -1,266 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 12.2 時系列データの予測\n", - "\n", - "### 12.2.1 データの準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "from pmdarima.datasets import airpassengers\n", - "from sklearn.metrics import mean_squared_error\n", - "\n", - "my_data = airpassengers.load_airpassengers()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n = len(my_data) # データ数(144)\n", - "k = 108 # 訓練データ数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_ds = pd.date_range(\n", - " start='1949/01/01',\n", - " end='1960/12/01',\n", - " freq='MS')\n", - "my_df = pd.DataFrame({\n", - " 'ds': my_ds,\n", - " 'x': range(n),\n", - " 'y': my_data},\n", - " index=my_ds)\n", - "my_df.head()\n", - "#> ds x y\n", - "#> 1949-01-01 1949-01-01 0 112.0\n", - "#> 1949-02-01 1949-02-01 1 118.0\n", - "#> 1949-03-01 1949-03-01 2 132.0\n", - "#> 1949-04-01 1949-04-01 3 129.0\n", - "#> 1949-05-01 1949-05-01 4 121.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_train = my_df[ :k]\n", - "my_test = my_df[-(n - k): ]\n", - "y = my_test.y" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.plot(my_train.y, label='train')\n", - "plt.plot(my_test.y, label='test')\n", - "plt.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.2 線形回帰分析による時系列予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from sklearn.linear_model import LinearRegression\n", - "\n", - "my_lm_model = LinearRegression()\n", - "my_lm_model.fit(my_train[['x']], my_train.y)\n", - "\n", - "X = my_test[['x']]\n", - "y_ = my_lm_model.predict(X)\n", - "mean_squared_error(y, y_)**0.5 # RMSE(テスト)\n", - "#> 70.63707081783771" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = my_lm_model.predict(my_df[['x']])\n", - "tmp = pd.DataFrame(y_,\n", - " index=my_df.index)\n", - "plt.plot(my_train.y, label='train')\n", - "plt.plot(my_test.y, label='test')\n", - "plt.plot(tmp, label='model')\n", - "plt.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.3 SARIMAによる時系列予測\n", - "\n", - "#### 12.2.3.1 モデルの構築" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pmdarima as pm\n", - "my_arima_model = pm.auto_arima(my_train.y, m=12, trace=True)\n", - "#> (省略)\n", - "#> Best model: ARIMA(1,1,0)(0,1,0)[12]\n", - "#> Total fit time: 0.838 seconds" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 12.2.3.2 予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_, my_ci = my_arima_model.predict(len(my_test), # 期間はテストデータと同じ.\n", - " alpha=0.05, # 有意水準(デフォルト)\n", - " return_conf_int=True) # 信頼区間を求める.\n", - "tmp = pd.DataFrame({'y': y_,\n", - " 'Lo': my_ci[:, 0],\n", - " 'Hi': my_ci[:, 1]},\n", - " index=my_test.index)\n", - "tmp.head()\n", - "#> y Lo Hi\n", - "#> 1958-01-01 345.964471 327.088699 364.840243\n", - "#> 1958-02-01 331.731920 308.036230 355.427610\n", - "#> 1958-03-01 386.787992 358.515741 415.060244\n", - "#> 1958-04-01 378.774472 346.695454 410.853490\n", - "#> 1958-05-01 385.777732 350.270765 421.284700" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mean_squared_error(y, y_)**0.5\n", - "#> 22.132236727738697" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.plot(my_train.y, label='train')\n", - "plt.plot(my_test.y, label='test')\n", - "plt.plot(tmp.y, label='model')\n", - "plt.fill_between(tmp.index,\n", - " tmp.Lo,\n", - " tmp.Hi,\n", - " alpha=0.25) # 不透明度\n", - "plt.legend(loc='upper left')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.4 Prophetによる時系列予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "try: from fbprophet import Prophet\n", - "except ImportError: from prophet import Prophet\n", - "my_prophet_model = Prophet(seasonality_mode='multiplicative')\n", - "my_prophet_model.fit(my_train)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_prophet_model.predict(my_test)\n", - "tmp[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].head()\n", - "#> ds yhat yhat_lower yhat_upper\n", - "#> 0 1958-01-01 359.239305 350.910898 368.464588\n", - "#> 1 1958-02-01 350.690546 341.748862 359.964881\n", - "#> 2 1958-03-01 407.188556 398.483316 415.463759\n", - "#> 3 1958-04-01 398.481739 389.244105 406.742333\n", - "#> 4 1958-05-01 402.595604 393.721421 411.331761" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = tmp.yhat\n", - "mean_squared_error(y, y_)**0.5\n", - "#> 33.795549086036466" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# my_prophet_model.plot(tmp) # 予測結果のみでよい場合\n", - "\n", - "fig = my_prophet_model.plot(tmp)\n", - "fig.axes[0].plot(my_train.ds, my_train.y)\n", - "fig.axes[0].plot(my_test.ds, my_test.y, color='red')" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch12/12.ipynb b/code/Python-notebook/ch12/12.ipynb deleted file mode 100644 index 382bae4..0000000 --- a/code/Python-notebook/ch12/12.ipynb +++ /dev/null @@ -1,325 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 12\n", - "\n", - "## 12.1 日時と日時の列\n", - "\n", - "### 12.1.1 日時" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "pd.to_datetime('2020-01-01')\n", - "#> Timestamp('2020-01-01 00:00:00')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.1.2 等間隔の日時" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.date_range(start='2021-01-01', end='2023-01-01', freq='1A')\n", - "#> DatetimeIndex(['2021-12-31', '2022-12-31'],\n", - "#> dtype='datetime64[ns]', freq='A-DEC')\n", - "\n", - "pd.date_range(start='2021-01-01', end='2023-01-01', freq='1AS')\n", - "#> DatetimeIndex(['2021-01-01', '2022-01-01', '2023-01-01'],\n", - "#> dtype='datetime64[ns]', freq='AS-JAN')\n", - "\n", - "pd.date_range(start='2021-01-01', end='2021-03-01', freq='2M')\n", - "#> DatetimeIndex(['2021-01-31'], dtype='datetime64[ns]', freq='2M')\n", - "\n", - "pd.date_range(start='2021-01-01', end='2021-03-01', freq='2MS')\n", - "#> DatetimeIndex(['2021-01-01', '2021-03-01'],\n", - "#> dtype='datetime64[ns]', freq='2MS')\n", - "\n", - "pd.date_range(start='2021-01-01', end='2021-01-03', freq='1D')\n", - "#> DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03'],\n", - "#> dtype='datetime64[ns]', freq='D')\n", - "\n", - "pd.date_range(start='2021-01-01 00:00:00', end='2021-01-01 03:00:00', freq='2H')\n", - "#> DatetimeIndex(['2021-01-01 00:00:00', '2021-01-01 02:00:00'],\n", - "#> dtype='datetime64[ns]', freq='2H')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 12.2 時系列データの予測\n", - "\n", - "### 12.2.1 データの準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "from pmdarima.datasets import airpassengers\n", - "from sklearn.metrics import mean_squared_error\n", - "\n", - "my_data = airpassengers.load_airpassengers()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n = len(my_data) # データ数(144)\n", - "k = 108 # 訓練データ数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_ds = pd.date_range(\n", - " start='1949/01/01',\n", - " end='1960/12/01',\n", - " freq='MS')\n", - "my_df = pd.DataFrame({\n", - " 'ds': my_ds,\n", - " 'x': range(n),\n", - " 'y': my_data},\n", - " index=my_ds)\n", - "my_df.head()\n", - "#> ds x y\n", - "#> 1949-01-01 1949-01-01 0 112.0\n", - "#> 1949-02-01 1949-02-01 1 118.0\n", - "#> 1949-03-01 1949-03-01 2 132.0\n", - "#> 1949-04-01 1949-04-01 3 129.0\n", - "#> 1949-05-01 1949-05-01 4 121.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_train = my_df[ :k]\n", - "my_test = my_df[-(n - k): ]\n", - "y = my_test.y" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.plot(my_train.y, label='train')\n", - "plt.plot(my_test.y, label='test')\n", - "plt.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.2 線形回帰分析による時系列予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from sklearn.linear_model import LinearRegression\n", - "\n", - "my_lm_model = LinearRegression()\n", - "my_lm_model.fit(my_train[['x']], my_train.y)\n", - "\n", - "X = my_test[['x']]\n", - "y_ = my_lm_model.predict(X)\n", - "mean_squared_error(y, y_)**0.5 # RMSE(テスト)\n", - "#> 70.63707081783771" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = my_lm_model.predict(my_df[['x']])\n", - "tmp = pd.DataFrame(y_,\n", - " index=my_df.index)\n", - "plt.plot(my_train.y, label='train')\n", - "plt.plot(my_test.y, label='test')\n", - "plt.plot(tmp, label='model')\n", - "plt.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.3 SARIMAによる時系列予測\n", - "\n", - "#### 12.2.3.1 モデルの構築" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pmdarima as pm\n", - "my_arima_model = pm.auto_arima(my_train.y, m=12, trace=True)\n", - "#> (省略)\n", - "#> Best model: ARIMA(1,1,0)(0,1,0)[12]\n", - "#> Total fit time: 0.838 seconds" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 12.2.3.2 予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_, my_ci = my_arima_model.predict(len(my_test), # 期間はテストデータと同じ.\n", - " alpha=0.05, # 有意水準(デフォルト)\n", - " return_conf_int=True) # 信頼区間を求める.\n", - "tmp = pd.DataFrame({'y': y_,\n", - " 'Lo': my_ci[:, 0],\n", - " 'Hi': my_ci[:, 1]},\n", - " index=my_test.index)\n", - "tmp.head()\n", - "#> y Lo Hi\n", - "#> 1958-01-01 345.964471 327.088699 364.840243\n", - "#> 1958-02-01 331.731920 308.036230 355.427610\n", - "#> 1958-03-01 386.787992 358.515741 415.060244\n", - "#> 1958-04-01 378.774472 346.695454 410.853490\n", - "#> 1958-05-01 385.777732 350.270765 421.284700" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mean_squared_error(y, y_)**0.5\n", - "#> 22.132236727738697" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.plot(my_train.y, label='train')\n", - "plt.plot(my_test.y, label='test')\n", - "plt.plot(tmp.y, label='model')\n", - "plt.fill_between(tmp.index,\n", - " tmp.Lo,\n", - " tmp.Hi,\n", - " alpha=0.25) # 不透明度\n", - "plt.legend(loc='upper left')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.4 Prophetによる時系列予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "try: from fbprophet import Prophet\n", - "except ImportError: from prophet import Prophet\n", - "my_prophet_model = Prophet(seasonality_mode='multiplicative')\n", - "my_prophet_model.fit(my_train)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_prophet_model.predict(my_test)\n", - "tmp[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].head()\n", - "#> ds yhat yhat_lower yhat_upper\n", - "#> 0 1958-01-01 359.239305 350.910898 368.464588\n", - "#> 1 1958-02-01 350.690546 341.748862 359.964881\n", - "#> 2 1958-03-01 407.188556 398.483316 415.463759\n", - "#> 3 1958-04-01 398.481739 389.244105 406.742333\n", - "#> 4 1958-05-01 402.595604 393.721421 411.331761" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ = tmp.yhat\n", - "mean_squared_error(y, y_)**0.5\n", - "#> 33.795549086036466" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# my_prophet_model.plot(tmp) # 予測結果のみでよい場合\n", - "\n", - "fig = my_prophet_model.plot(tmp)\n", - "fig.axes[0].plot(my_train.ds, my_train.y)\n", - "fig.axes[0].plot(my_test.ds, my_test.y, color='red')" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch13/13-colab.ipynb b/code/Python-notebook/ch13/13-colab.ipynb deleted file mode 100644 index 8fd3d0c..0000000 --- a/code/Python-notebook/ch13/13-colab.ipynb +++ /dev/null @@ -1,380 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 13" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Google Colaboratoryの環境設定\n", - "!pip install pca | tail -n 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 13.1 主成分分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "from pca import pca\n", - "from scipy.stats import zscore\n", - "\n", - "my_data = pd.DataFrame(\n", - " {'language': [ 0, 20, 20, 25, 22, 17],\n", - " 'english': [ 0, 20, 40, 20, 24, 18],\n", - " 'math': [100, 20, 5, 30, 17, 25],\n", - " 'science': [ 0, 20, 5, 25, 16, 23],\n", - " 'society': [ 0, 20, 30, 0, 21, 17]},\n", - " index= ['A', 'B', 'C', 'D', 'E', 'F'])\n", - "my_model = pca(n_components=5)\n", - "my_result = my_model.fit_transform(my_data) # 主成分分析の実行" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result['PC'] # 主成分スコア\n", - "#> PC1 PC2 ...\n", - "#> A 74.907282 7.010808 ...\n", - "#> B -13.818842 -2.753459 ...\n", - "#> C -33.714034 18.417290 ...\n", - "#> D -1.730630 -17.876372 ...\n", - "#> E -17.837474 1.064998 ...\n", - "#> F -7.806303 -5.863266 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.biplot(legend=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result['loadings']\n", - "#> language english math science society\n", - "#> PC1 -0.207498 -0.304360 0.887261 -0.130198 -0.245204\n", - "#> PC2 -0.279463 0.325052 0.097643 -0.702667 0.559435\n", - "#> PC3 0.306117 0.615799 0.056345 -0.338446 -0.639815\n", - "#> PC4 0.764943 -0.471697 -0.007655 -0.418045 0.132455\n", - "#> PC5 -0.447214 -0.447214 -0.447214 -0.447214 -0.447214" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result['explained_var']\n", - "#> array([0.88848331, 0.97962854, 0.99858005, 1. , 1. ])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.1.1 標準化+主成分分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = zscore(my_data, ddof=1) # 標準化\n", - "my_result = my_model.fit_transform(\n", - " tmp)\n", - "my_result['PC'] # 主成分スコア\n", - "#> PC1 PC2 ...\n", - "#> 1.0 3.673722 0.568850 ...\n", - "#> 1.0 -0.652879 -0.246926 ...\n", - "#> 1.0 -1.568294 1.742598 ...\n", - "#> 1.0 -0.250504 -1.640039 ...\n", - "#> 1.0 -0.886186 0.110493 ...\n", - "#> 1.0 -0.315858 -0.534976 ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.1.2 補足:行列計算による再現" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_data - my_data.mean()\n", - "Z = np.matrix(tmp) # 標準化しない場合\n", - "#Z = np.matrix(tmp / my_data.std(ddof=1)) # √不偏分散で標準化する場合\n", - "#Z = np.matrix(tmp / my_data.std(ddof=0)) # pca(normalize=True)に合わせる場合\n", - "\n", - "n = len(my_data)\n", - "S = np.cov(Z, rowvar=0, ddof=0) # 分散共分散行列\n", - "#S = Z.T @ Z / n # (同じ結果)\n", - "vals, vecs = np.linalg.eig(S) # 固有値と固有ベクトル\n", - "idx = np.argsort(-vals) # 固有値の大きい順の番号\n", - "vals, vecs = vals[idx], vecs[:, idx] # 固有値の大きい順での並べ替え\n", - "Z @ vecs # 主成分スコア(結果は割愛)\n", - "vals.cumsum() / vals.sum() # 累積寄与率\n", - "#> array([0.88848331, 0.97962854, 0.99858005, 1. , 1. ])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "U, d, V = np.linalg.svd(Z, full_matrices=False) # 特異値分解\n", - "W = np.diag(d)\n", - "\n", - "[np.isclose(Z, U @ W @ V).all(), # 確認1\n", - " np.isclose(U.T @ U, np.identity(U.shape[1])).all(), # 確認2\n", - " np.isclose(V @ V.T, np.identity(V.shape[0])).all()] # 確認3\n", - "#> [True, True, True]\n", - "\n", - "U @ W # 主成分スコア(結果は割愛)\n", - "\n", - "e = d ** 2 / n # 分散共分散行列の固有値\n", - "e.cumsum() / e.sum() # 累積寄与率\n", - "#> array([0.88848331, 0.97962854, 0.99858005, 1. , 1. ])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 13.2 クラスタ分析\n", - "\n", - "### 13.2.1 階層的クラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from scipy.cluster import hierarchy\n", - "\n", - "my_data = pd.DataFrame(\n", - " {'x': [ 0, -16, 10, 10],\n", - " 'y': [ 0, 0, 10, -15]},\n", - " index=['A', 'B', 'C', 'D'])\n", - "\n", - "my_result = hierarchy.linkage(\n", - " my_data,\n", - " metric='euclidean', # 省略可\n", - " method='complete')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "hierarchy.dendrogram(my_result,\n", - " labels=my_data.index)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "hierarchy.cut_tree(my_result, 3)\n", - "#> array([[0], [1], [0], [2]])\n", - "\n", - "# 補足(見やすくする)\n", - "my_data.assign(cluster=\n", - " hierarchy.cut_tree(my_result, 3))\n", - "#> x y cluster\n", - "#> A 0 0 0\n", - "#> B -16 0 1\n", - "#> C 10 10 0\n", - "#> D 10 -15 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.2 階層的クラスタ分析とヒートマップ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import seaborn as sns\n", - "\n", - "my_data = pd.DataFrame(\n", - " {'language': [ 0, 20, 20, 25, 22, 17],\n", - " 'english': [ 0, 20, 40, 20, 24, 18],\n", - " 'math': [100, 20, 5, 30, 17, 25],\n", - " 'science': [ 0, 20, 5, 25, 16, 23],\n", - " 'society': [ 0, 20, 30, 0, 21, 17]},\n", - " index= ['A', 'B', 'C', 'D', 'E', 'F'])\n", - "\n", - "sns.clustermap(my_data, z_score=1) # 列ごとの標準化" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.3 非階層的クラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.cluster import KMeans\n", - "\n", - "my_data = pd.DataFrame(\n", - " {'x': [ 0, -16, 10, 10],\n", - " 'y': [ 0, 0, 10, -15]},\n", - " index=['A', 'B', 'C', 'D'])\n", - "\n", - "my_result = KMeans(\n", - " n_clusters=3).fit(my_data)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result.labels_\n", - "#> array([1, 0, 1, 2], dtype=int32)\n", - "\n", - "# 補足(見やすくする)\n", - "my_data.assign(\n", - " cluster=my_result.labels_)\n", - "#> x y cluster\n", - "#> A 0 0 1\n", - "#> B -16 0 0\n", - "#> C 10 10 1\n", - "#> D 10 -15 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.4 クラスタ数の決定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.cluster import KMeans\n", - "\n", - "iris = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "my_data = iris.iloc[:, 0:4]\n", - "\n", - "k = range(1, 11)\n", - "my_df = pd.DataFrame({\n", - " 'k': k,\n", - " 'inertia': [KMeans(k).fit(my_data).inertia_ for k in range(1, 11)]})\n", - "my_df.plot(x='k', style='o-', legend=False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.5 主成分分析とクラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import seaborn as sns\n", - "import statsmodels.api as sm\n", - "from pca import pca\n", - "from scipy.cluster import hierarchy\n", - "from scipy.stats import zscore\n", - "from sklearn.cluster import KMeans\n", - "\n", - "iris = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "my_data = zscore(iris.iloc[:, 0:4])\n", - "\n", - "my_model = pca() # 主成分分析\n", - "my_result = my_model.fit_transform(my_data)['PC']\n", - "my_result['Species'] = list(iris.Species)\n", - "\n", - "# 非階層的クラスタ分析の場合\n", - "my_result['cluster'] = KMeans(n_clusters=3).fit(my_data).labels_\n", - "\n", - "# 階層的クラスタ分析の場合\n", - "#my_result['cluster'] = hierarchy.cut_tree(\n", - "# hierarchy.linkage(my_data, method='complete'), 3)[:,0]\n", - "\n", - "sns.scatterplot(x='PC1', y='PC2', data=my_result, legend=False,\n", - " hue='cluster', # 色でクラスタを表現する.\n", - " style='Species', # 形で品種を表現する.\n", - " palette='bright')" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch13/13.01.ipynb b/code/Python-notebook/ch13/13.01.ipynb deleted file mode 100644 index 9e7fe76..0000000 --- a/code/Python-notebook/ch13/13.01.ipynb +++ /dev/null @@ -1,167 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 13.1 主成分分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "from pca import pca\n", - "from scipy.stats import zscore\n", - "\n", - "my_data = pd.DataFrame(\n", - " {'language': [ 0, 20, 20, 25, 22, 17],\n", - " 'english': [ 0, 20, 40, 20, 24, 18],\n", - " 'math': [100, 20, 5, 30, 17, 25],\n", - " 'science': [ 0, 20, 5, 25, 16, 23],\n", - " 'society': [ 0, 20, 30, 0, 21, 17]},\n", - " index= ['A', 'B', 'C', 'D', 'E', 'F'])\n", - "my_model = pca(n_components=5)\n", - "my_result = my_model.fit_transform(my_data) # 主成分分析の実行" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result['PC'] # 主成分スコア\n", - "#> PC1 PC2 ...\n", - "#> A 74.907282 7.010808 ...\n", - "#> B -13.818842 -2.753459 ...\n", - "#> C -33.714034 18.417290 ...\n", - "#> D -1.730630 -17.876372 ...\n", - "#> E -17.837474 1.064998 ...\n", - "#> F -7.806303 -5.863266 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.biplot(legend=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result['loadings']\n", - "#> language english math science society\n", - "#> PC1 -0.207498 -0.304360 0.887261 -0.130198 -0.245204\n", - "#> PC2 -0.279463 0.325052 0.097643 -0.702667 0.559435\n", - "#> PC3 0.306117 0.615799 0.056345 -0.338446 -0.639815\n", - "#> PC4 0.764943 -0.471697 -0.007655 -0.418045 0.132455\n", - "#> PC5 -0.447214 -0.447214 -0.447214 -0.447214 -0.447214" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result['explained_var']\n", - "#> array([0.88848331, 0.97962854, 0.99858005, 1. , 1. ])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.1.1 標準化+主成分分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = zscore(my_data, ddof=1) # 標準化\n", - "my_result = my_model.fit_transform(\n", - " tmp)\n", - "my_result['PC'] # 主成分スコア\n", - "#> PC1 PC2 ...\n", - "#> 1.0 3.673722 0.568850 ...\n", - "#> 1.0 -0.652879 -0.246926 ...\n", - "#> 1.0 -1.568294 1.742598 ...\n", - "#> 1.0 -0.250504 -1.640039 ...\n", - "#> 1.0 -0.886186 0.110493 ...\n", - "#> 1.0 -0.315858 -0.534976 ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.1.2 補足:行列計算による再現" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_data - my_data.mean()\n", - "Z = np.matrix(tmp) # 標準化しない場合\n", - "#Z = np.matrix(tmp / my_data.std(ddof=1)) # √不偏分散で標準化する場合\n", - "#Z = np.matrix(tmp / my_data.std(ddof=0)) # pca(normalize=True)に合わせる場合\n", - "\n", - "n = len(my_data)\n", - "S = np.cov(Z, rowvar=0, ddof=0) # 分散共分散行列\n", - "#S = Z.T @ Z / n # (同じ結果)\n", - "vals, vecs = np.linalg.eig(S) # 固有値と固有ベクトル\n", - "idx = np.argsort(-vals) # 固有値の大きい順の番号\n", - "vals, vecs = vals[idx], vecs[:, idx] # 固有値の大きい順での並べ替え\n", - "Z @ vecs # 主成分スコア(結果は割愛)\n", - "vals.cumsum() / vals.sum() # 累積寄与率\n", - "#> array([0.88848331, 0.97962854, 0.99858005, 1. , 1. ])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "U, d, V = np.linalg.svd(Z, full_matrices=False) # 特異値分解\n", - "W = np.diag(d)\n", - "\n", - "[np.isclose(Z, U @ W @ V).all(), # 確認1\n", - " np.isclose(U.T @ U, np.identity(U.shape[1])).all(), # 確認2\n", - " np.isclose(V @ V.T, np.identity(V.shape[0])).all()] # 確認3\n", - "#> [True, True, True]\n", - "\n", - "U @ W # 主成分スコア(結果は割愛)\n", - "\n", - "e = d ** 2 / n # 分散共分散行列の固有値\n", - "e.cumsum() / e.sum() # 累積寄与率\n", - "#> array([0.88848331, 0.97962854, 0.99858005, 1. , 1. ])" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch13/13.02.ipynb b/code/Python-notebook/ch13/13.02.ipynb deleted file mode 100644 index c4792a0..0000000 --- a/code/Python-notebook/ch13/13.02.ipynb +++ /dev/null @@ -1,208 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 13.2 クラスタ分析\n", - "\n", - "### 13.2.1 階層的クラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from scipy.cluster import hierarchy\n", - "\n", - "my_data = pd.DataFrame(\n", - " {'x': [ 0, -16, 10, 10],\n", - " 'y': [ 0, 0, 10, -15]},\n", - " index=['A', 'B', 'C', 'D'])\n", - "\n", - "my_result = hierarchy.linkage(\n", - " my_data,\n", - " metric='euclidean', # 省略可\n", - " method='complete')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "hierarchy.dendrogram(my_result,\n", - " labels=my_data.index)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "hierarchy.cut_tree(my_result, 3)\n", - "#> array([[0], [1], [0], [2]])\n", - "\n", - "# 補足(見やすくする)\n", - "my_data.assign(cluster=\n", - " hierarchy.cut_tree(my_result, 3))\n", - "#> x y cluster\n", - "#> A 0 0 0\n", - "#> B -16 0 1\n", - "#> C 10 10 0\n", - "#> D 10 -15 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.2 階層的クラスタ分析とヒートマップ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import seaborn as sns\n", - "\n", - "my_data = pd.DataFrame(\n", - " {'language': [ 0, 20, 20, 25, 22, 17],\n", - " 'english': [ 0, 20, 40, 20, 24, 18],\n", - " 'math': [100, 20, 5, 30, 17, 25],\n", - " 'science': [ 0, 20, 5, 25, 16, 23],\n", - " 'society': [ 0, 20, 30, 0, 21, 17]},\n", - " index= ['A', 'B', 'C', 'D', 'E', 'F'])\n", - "\n", - "sns.clustermap(my_data, z_score=1) # 列ごとの標準化" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.3 非階層的クラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.cluster import KMeans\n", - "\n", - "my_data = pd.DataFrame(\n", - " {'x': [ 0, -16, 10, 10],\n", - " 'y': [ 0, 0, 10, -15]},\n", - " index=['A', 'B', 'C', 'D'])\n", - "\n", - "my_result = KMeans(\n", - " n_clusters=3).fit(my_data)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result.labels_\n", - "#> array([1, 0, 1, 2], dtype=int32)\n", - "\n", - "# 補足(見やすくする)\n", - "my_data.assign(\n", - " cluster=my_result.labels_)\n", - "#> x y cluster\n", - "#> A 0 0 1\n", - "#> B -16 0 0\n", - "#> C 10 10 1\n", - "#> D 10 -15 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.4 クラスタ数の決定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.cluster import KMeans\n", - "\n", - "iris = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "my_data = iris.iloc[:, 0:4]\n", - "\n", - "k = range(1, 11)\n", - "my_df = pd.DataFrame({\n", - " 'k': k,\n", - " 'inertia': [KMeans(k).fit(my_data).inertia_ for k in range(1, 11)]})\n", - "my_df.plot(x='k', style='o-', legend=False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.5 主成分分析とクラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import seaborn as sns\n", - "import statsmodels.api as sm\n", - "from pca import pca\n", - "from scipy.cluster import hierarchy\n", - "from scipy.stats import zscore\n", - "from sklearn.cluster import KMeans\n", - "\n", - "iris = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "my_data = zscore(iris.iloc[:, 0:4])\n", - "\n", - "my_model = pca() # 主成分分析\n", - "my_result = my_model.fit_transform(my_data)['PC']\n", - "my_result['Species'] = list(iris.Species)\n", - "\n", - "# 非階層的クラスタ分析の場合\n", - "my_result['cluster'] = KMeans(n_clusters=3).fit(my_data).labels_\n", - "\n", - "# 階層的クラスタ分析の場合\n", - "#my_result['cluster'] = hierarchy.cut_tree(\n", - "# hierarchy.linkage(my_data, method='complete'), 3)[:,0]\n", - "\n", - "sns.scatterplot(x='PC1', y='PC2', data=my_result, legend=False,\n", - " hue='cluster', # 色でクラスタを表現する.\n", - " style='Species', # 形で品種を表現する.\n", - " palette='bright')" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/ch13/13.ipynb b/code/Python-notebook/ch13/13.ipynb deleted file mode 100644 index db88676..0000000 --- a/code/Python-notebook/ch13/13.ipynb +++ /dev/null @@ -1,365 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 13\n", - "\n", - "## 13.1 主成分分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "from pca import pca\n", - "from scipy.stats import zscore\n", - "\n", - "my_data = pd.DataFrame(\n", - " {'language': [ 0, 20, 20, 25, 22, 17],\n", - " 'english': [ 0, 20, 40, 20, 24, 18],\n", - " 'math': [100, 20, 5, 30, 17, 25],\n", - " 'science': [ 0, 20, 5, 25, 16, 23],\n", - " 'society': [ 0, 20, 30, 0, 21, 17]},\n", - " index= ['A', 'B', 'C', 'D', 'E', 'F'])\n", - "my_model = pca(n_components=5)\n", - "my_result = my_model.fit_transform(my_data) # 主成分分析の実行" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result['PC'] # 主成分スコア\n", - "#> PC1 PC2 ...\n", - "#> A 74.907282 7.010808 ...\n", - "#> B -13.818842 -2.753459 ...\n", - "#> C -33.714034 18.417290 ...\n", - "#> D -1.730630 -17.876372 ...\n", - "#> E -17.837474 1.064998 ...\n", - "#> F -7.806303 -5.863266 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model.biplot(legend=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result['loadings']\n", - "#> language english math science society\n", - "#> PC1 -0.207498 -0.304360 0.887261 -0.130198 -0.245204\n", - "#> PC2 -0.279463 0.325052 0.097643 -0.702667 0.559435\n", - "#> PC3 0.306117 0.615799 0.056345 -0.338446 -0.639815\n", - "#> PC4 0.764943 -0.471697 -0.007655 -0.418045 0.132455\n", - "#> PC5 -0.447214 -0.447214 -0.447214 -0.447214 -0.447214" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result['explained_var']\n", - "#> array([0.88848331, 0.97962854, 0.99858005, 1. , 1. ])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.1.1 標準化+主成分分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = zscore(my_data, ddof=1) # 標準化\n", - "my_result = my_model.fit_transform(\n", - " tmp)\n", - "my_result['PC'] # 主成分スコア\n", - "#> PC1 PC2 ...\n", - "#> 1.0 3.673722 0.568850 ...\n", - "#> 1.0 -0.652879 -0.246926 ...\n", - "#> 1.0 -1.568294 1.742598 ...\n", - "#> 1.0 -0.250504 -1.640039 ...\n", - "#> 1.0 -0.886186 0.110493 ...\n", - "#> 1.0 -0.315858 -0.534976 ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.1.2 補足:行列計算による再現" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = my_data - my_data.mean()\n", - "Z = np.matrix(tmp) # 標準化しない場合\n", - "#Z = np.matrix(tmp / my_data.std(ddof=1)) # √不偏分散で標準化する場合\n", - "#Z = np.matrix(tmp / my_data.std(ddof=0)) # pca(normalize=True)に合わせる場合\n", - "\n", - "n = len(my_data)\n", - "S = np.cov(Z, rowvar=0, ddof=0) # 分散共分散行列\n", - "#S = Z.T @ Z / n # (同じ結果)\n", - "vals, vecs = np.linalg.eig(S) # 固有値と固有ベクトル\n", - "idx = np.argsort(-vals) # 固有値の大きい順の番号\n", - "vals, vecs = vals[idx], vecs[:, idx] # 固有値の大きい順での並べ替え\n", - "Z @ vecs # 主成分スコア(結果は割愛)\n", - "vals.cumsum() / vals.sum() # 累積寄与率\n", - "#> array([0.88848331, 0.97962854, 0.99858005, 1. , 1. ])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "U, d, V = np.linalg.svd(Z, full_matrices=False) # 特異値分解\n", - "W = np.diag(d)\n", - "\n", - "[np.isclose(Z, U @ W @ V).all(), # 確認1\n", - " np.isclose(U.T @ U, np.identity(U.shape[1])).all(), # 確認2\n", - " np.isclose(V @ V.T, np.identity(V.shape[0])).all()] # 確認3\n", - "#> [True, True, True]\n", - "\n", - "U @ W # 主成分スコア(結果は割愛)\n", - "\n", - "e = d ** 2 / n # 分散共分散行列の固有値\n", - "e.cumsum() / e.sum() # 累積寄与率\n", - "#> array([0.88848331, 0.97962854, 0.99858005, 1. , 1. ])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 13.2 クラスタ分析\n", - "\n", - "### 13.2.1 階層的クラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from scipy.cluster import hierarchy\n", - "\n", - "my_data = pd.DataFrame(\n", - " {'x': [ 0, -16, 10, 10],\n", - " 'y': [ 0, 0, 10, -15]},\n", - " index=['A', 'B', 'C', 'D'])\n", - "\n", - "my_result = hierarchy.linkage(\n", - " my_data,\n", - " metric='euclidean', # 省略可\n", - " method='complete')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "hierarchy.dendrogram(my_result,\n", - " labels=my_data.index)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "hierarchy.cut_tree(my_result, 3)\n", - "#> array([[0], [1], [0], [2]])\n", - "\n", - "# 補足(見やすくする)\n", - "my_data.assign(cluster=\n", - " hierarchy.cut_tree(my_result, 3))\n", - "#> x y cluster\n", - "#> A 0 0 0\n", - "#> B -16 0 1\n", - "#> C 10 10 0\n", - "#> D 10 -15 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.2 階層的クラスタ分析とヒートマップ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import seaborn as sns\n", - "\n", - "my_data = pd.DataFrame(\n", - " {'language': [ 0, 20, 20, 25, 22, 17],\n", - " 'english': [ 0, 20, 40, 20, 24, 18],\n", - " 'math': [100, 20, 5, 30, 17, 25],\n", - " 'science': [ 0, 20, 5, 25, 16, 23],\n", - " 'society': [ 0, 20, 30, 0, 21, 17]},\n", - " index= ['A', 'B', 'C', 'D', 'E', 'F'])\n", - "\n", - "sns.clustermap(my_data, z_score=1) # 列ごとの標準化" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.3 非階層的クラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.cluster import KMeans\n", - "\n", - "my_data = pd.DataFrame(\n", - " {'x': [ 0, -16, 10, 10],\n", - " 'y': [ 0, 0, 10, -15]},\n", - " index=['A', 'B', 'C', 'D'])\n", - "\n", - "my_result = KMeans(\n", - " n_clusters=3).fit(my_data)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result.labels_\n", - "#> array([1, 0, 1, 2], dtype=int32)\n", - "\n", - "# 補足(見やすくする)\n", - "my_data.assign(\n", - " cluster=my_result.labels_)\n", - "#> x y cluster\n", - "#> A 0 0 1\n", - "#> B -16 0 0\n", - "#> C 10 10 1\n", - "#> D 10 -15 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.4 クラスタ数の決定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import statsmodels.api as sm\n", - "from sklearn.cluster import KMeans\n", - "\n", - "iris = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "my_data = iris.iloc[:, 0:4]\n", - "\n", - "k = range(1, 11)\n", - "my_df = pd.DataFrame({\n", - " 'k': k,\n", - " 'inertia': [KMeans(k).fit(my_data).inertia_ for k in range(1, 11)]})\n", - "my_df.plot(x='k', style='o-', legend=False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.5 主成分分析とクラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import seaborn as sns\n", - "import statsmodels.api as sm\n", - "from pca import pca\n", - "from scipy.cluster import hierarchy\n", - "from scipy.stats import zscore\n", - "from sklearn.cluster import KMeans\n", - "\n", - "iris = sm.datasets.get_rdataset('iris', 'datasets').data\n", - "my_data = zscore(iris.iloc[:, 0:4])\n", - "\n", - "my_model = pca() # 主成分分析\n", - "my_result = my_model.fit_transform(my_data)['PC']\n", - "my_result['Species'] = list(iris.Species)\n", - "\n", - "# 非階層的クラスタ分析の場合\n", - "my_result['cluster'] = KMeans(n_clusters=3).fit(my_data).labels_\n", - "\n", - "# 階層的クラスタ分析の場合\n", - "#my_result['cluster'] = hierarchy.cut_tree(\n", - "# hierarchy.linkage(my_data, method='complete'), 3)[:,0]\n", - "\n", - "sns.scatterplot(x='PC1', y='PC2', data=my_result, legend=False,\n", - " hue='cluster', # 色でクラスタを表現する.\n", - " style='Species', # 形で品種を表現する.\n", - " palette='bright')" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - } - } -} diff --git a/code/Python-notebook/python-03.ipynb b/code/Python-notebook/python-03.ipynb new file mode 100644 index 0000000..918dc0b --- /dev/null +++ b/code/Python-notebook/python-03.ipynb @@ -0,0 +1,1494 @@ +{ + "cells": [ + { + "id": "b41be3ff", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Google Colaboratory\u306e\u74b0\u5883\u8a2d\u5b9a\n", + "import os\n", + "if 'COLAB_GPU' in os.environ:\n", + " !python -m pip install pandarallel | tail -n 1" + ], + "id": "e66666f6-6cd8-4b9b-9ad1-353c690e39ba" + }, + { + "id": "69a2dde6", + "cell_type": "markdown", + "source": "## 3.1 \u5165\u9580", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "0x10" + ], + "id": "db03ea31-3862-4472-b7fc-d84d720e6c76" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "1.23e5" + ], + "id": "b6c44a84-14d8-4efa-bcc3-5177f3993c48" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "2 * 3" + ], + "id": "8cd9a288-d785-4e37-bb92-65ba0cea89fb" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "10 / 3" + ], + "id": "ba44f582-220e-42f3-bff2-c128c6734290" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "10 // 3 # \u5546\n", + "\n", + "10 % 3 # \u4f59\u308a" + ], + "id": "dfbbc5bf-3ee5-4674-8ba6-5512f2149a17" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = 2\n", + "y = 3\n", + "x * y\n", + "\n", + "x, y = 20, 30 # \u307e\u3068\u3081\u3066\u540d\u4ed8\u3051\n", + "x * y" + ], + "id": "47b6bea9-cd24-4531-afea-643020d5c6f7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = 1 + 1\n", + "# \u3053\u306e\u6bb5\u968e\u3067\u306f\u7d50\u679c\u306f\u8868\u793a\u3055\u308c\u306a\u3044\n", + "\n", + "x # \u5909\u6570\u540d\u3092\u8a55\u4fa1\u3059\u308b\uff0e" + ], + "id": "0a3ed006-0a28-48b2-b3fb-2cb50d6f2480" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_s = 'abcde'" + ], + "id": "a8e3113f-e90b-4840-81f1-092732c5ddb8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "len(my_s)" + ], + "id": "2994c161-2cca-4b73-a548-ac125ea6b314" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "'This is' ' a' ' pen.'\n", + "# \u3042\u308b\u3044\u306f\n", + "'This is ' + 'a' + ' pen.'" + ], + "id": "1e2fc4c0-844b-40d9-97b0-8d9d74fadd5f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_s[1:4]" + ], + "id": "ed8e9930-3058-4626-b8c9-7ba017d1c5ba" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = \"{} is {}.\"\n", + "tmp.format('This', 'a pen')" + ], + "id": "bda3f7a4-c92a-4b39-b237-65a3c1111769" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "1 <= 2\n", + "\n", + "1 < 0" + ], + "id": "61dbeb4b-3fc1-4ffa-bf54-edb12c4d94f1" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "0.1 + 0.1 + 0.1 == 0.3\n", + "\n", + "import math\n", + "math.isclose(0.1 + 0.1 + 0.1, 0.3)" + ], + "id": "406e302d-1b24-40ae-94ef-96bba4626e50" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "True and False # \u8ad6\u7406\u7a4d\uff08\u304b\u3064\uff09\n", + "\n", + "True or False # \u8ad6\u7406\u548c\uff08\u307e\u305f\u306f\uff09\n", + "\n", + "not True # \u5426\u5b9a\uff08\u3067\u306a\u3044\uff09" + ], + "id": "a1bcaff7-9950-41aa-acc8-a587caf56811" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "0 if 3 < 5 else 10" + ], + "id": "0746658f-ac29-42d4-acf5-2607ebba1464" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "os.getcwd()" + ], + "id": "d9298d9b-2c7c-4154-9776-e8d9aff59840" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "os.chdir('..')\n", + "os.getcwd()" + ], + "id": "b3a717f3-226f-4a7b-a29c-06f7fd5f0dd0" + }, + { + "id": "b8ade57b", + "cell_type": "markdown", + "source": "## 3.2 \u95a2\u6570", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import math\n", + "math.sqrt(4)" + ], + "id": "82ee7a7b-0435-4e16-b94a-4868bd770f8f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "math.log(100, 10)" + ], + "id": "74c4d969-dcac-4939-8a57-a37d1117034f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "math.log(100) # \u81ea\u7136\u5bfe\u6570\n", + "# \u3042\u308b\u3044\u306f\n", + "math.log(100, math.e) # \u7701\u7565\u3057\u306a\u3044\u5834\u5408\n" + ], + "id": "9a467ecc-761f-427f-950a-bf35e090283b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "math.log10(100) # \u5e38\u7528\u5bfe\u6570\n", + "\n", + "math.log2(1024) # \u5e95\u304c2\u306e\u5bfe\u6570" + ], + "id": "d55a03aa-35fc-4a2f-a2e4-99dfb6bdbaea" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def f(a, b):\n", + " return a - b" + ], + "id": "bda5a0a7-ca41-4c7c-949d-32341a7ab46d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "f(3, 5)" + ], + "id": "6159f015-4dca-4ec3-bcbf-389c884f614b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def f(a, b=5):\n", + " return a - b\n", + "\n", + "f(3) # f(3, 5)\u3068\u540c\u3058\u3053\u3068" + ], + "id": "595aaaf5-1cdc-4cbc-9b72-10b47d773fb7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "(lambda a, b: a - b)(3, 5)" + ], + "id": "6dba0f52-8f31-44b3-ae5f-d83d53ecef80" + }, + { + "id": "0c53a3cc", + "cell_type": "markdown", + "source": "## 3.3 \u30b3\u30ec\u30af\u30b7\u30e7\u30f3", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = ['foo', 'bar', 'baz']" + ], + "id": "007317f9-231c-4079-b5dd-6d67cf0c5931" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "len(x)" + ], + "id": "fccf1109-44d0-477d-b18d-f0882dc986f3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x[1]" + ], + "id": "a098f30f-c1a6-4df8-bf69-f36cce3dde58" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x[1] = 'BAR'\n", + "x # \u7d50\u679c\u306e\u78ba\u8a8d\n", + "\n", + "x[1] = 'bar' # \u5143\u306b\u623b\u3059\uff0e" + ], + "id": "6f362be8-7716-4bf7-8cbd-5edbe55d8ed9" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x[-2]" + ], + "id": "811b34ca-33b2-46fa-8cfe-cd9b7536dae7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x + ['qux']" + ], + "id": "e1a25260-c037-47bc-bece-dc5671081770" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = x + ['qux']\n", + "# \u3042\u308b\u3044\u306f\n", + "#x.append('qux')\n", + "\n", + "x # \u7d50\u679c\u306e\u78ba\u8a8d" + ], + "id": "6fe6f130-41eb-4982-9611-87b20053950b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "list(range(5))" + ], + "id": "4ff58516-8f34-42fd-a258-dd09a73a8f3b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "list(range(0, 11, 2))" + ], + "id": "53a49c73-7d96-4785-bd41-d86630a22b0f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "np.arange(0, 1.1, 0.5)" + ], + "id": "1533ff25-d1e2-4d96-adbf-1acd3a84dcc1" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "np.linspace(0, 100, 5)" + ], + "id": "42eb181f-095f-489d-b180-fcaa59bdc2dd" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "[10] * 5" + ], + "id": "e731b265-a0be-484f-b7c6-d0cf0fbeb405" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "x = np.array([2, 3, 5, 7])\n", + "\n", + "x + 10 # \u52a0\u7b97\n", + "\n", + "x * 10 # \u4e57\u7b97" + ], + "id": "96235a06-5b0e-4837-b755-f67193dc429d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = [2, 3]\n", + "np.sin(x)" + ], + "id": "3caf1f5f-1d75-40f5-b700-9cfb4c392d89" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = np.array([2, 3, 5, 7])\n", + "y = np.array([1, 10, 100, 1000])\n", + "x + y\n", + "\n", + "x * y" + ], + "id": "cf9487ab-058d-4f09-b091-d27f14bfcc98" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "np.dot(x, y)\n", + "# \u3042\u308b\u3044\u306f\n", + "x @ y\n" + ], + "id": "6ab7e973-21de-42d8-9d3a-651d0e35c486" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = np.array([True, False])\n", + "y = np.array([True, True])\n", + "x & y" + ], + "id": "a58979d3-5b39-4c23-8216-dddfb355d796" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "u = np.array([1, 2, 3])\n", + "v = np.array([1, 2, 3])\n", + "w = np.array([1, 2, 4])\n", + "\n", + "all(u == v) # \u5168\u4f53\u306e\u6bd4\u8f03\n", + "\n", + "all(u == w) # \u5168\u4f53\u306e\u6bd4\u8f03\n", + "\n", + "u == v # \u8981\u7d20\u3054\u3068\u306e\u6bd4\u8f03\n", + "\n", + "u == w # \u8981\u7d20\u3054\u3068\u306e\u6bd4\u8f03" + ], + "id": "7bc591d9-303a-4fbc-bf32-3a87a8072bdb" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "(u == w).sum() # \u540c\u3058\u8981\u7d20\u306e\u6570\n", + "\n", + "(u == w).mean() # \u540c\u3058\u8981\u7d20\u306e\u5272\u5408" + ], + "id": "232f8628-f490-44cb-9bae-b34c25ad37bc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = [1, \"two\"]" + ], + "id": "7c7bf23d-c019-4dbe-9f0c-c532f5c18811" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x[1]" + ], + "id": "178dd8d2-146c-4af4-9ffb-e05caeb4c6be" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = {'apple' : '\u308a\u3093\u3054',\n", + " 'orange': '\u307f\u304b\u3093'}" + ], + "id": "d818c9a8-87f7-4a5b-af0d-8a05106f06a8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x['grape'] = '\u3076\u3069\u3046'" + ], + "id": "cb55f805-f9b8-401a-9995-95190bc5605b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x['apple']\n", + "# \u3042\u308b\u3044\u306f\n", + "tmp = 'apple'\n", + "x[tmp]\n" + ], + "id": "d10ebeee-8ff2-4c75-a841-38b27fe1fb69" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = ['foo', 'bar', 'baz']\n", + "y = x\n", + "y[1] = 'BAR' # y\u3092\u66f4\u65b0\u3059\u308b\uff0e\n", + "y\n", + "\n", + "x # x\u3082\u5909\u308f\u308b\uff0e" + ], + "id": "3b2da85c-3708-474f-a286-6a736928da77" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = ['foo', 'bar', 'baz']\n", + "y = x.copy() # \u300cy = x\u300d\u3068\u305b\u305a\u306b\uff0c\u30b3\u30d4\u30fc\u3059\u308b\uff0e\n", + "x == y, x is y\n", + "\n", + "y[1] = 'BAR' # y\u3092\u66f4\u65b0\u3057\u3066\u3082\uff0c\n", + "x" + ], + "id": "658cbc51-957f-4127-835e-ce39536512b7" + }, + { + "id": "4bf81654", + "cell_type": "markdown", + "source": "## 3.4 \u30c7\u30fc\u30bf\u30d5\u30ec\u30fc\u30e0", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd" + ], + "id": "ac4c21ca-5bfe-42d8-a909-1251fd031756" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df = pd.DataFrame({\n", + " 'name': ['A', 'B', 'C', 'D'],\n", + " 'english': [ 60, 90, 70, 90],\n", + " 'math': [ 70, 80, 90, 100],\n", + " 'gender': ['f', 'm', 'm', 'f']})" + ], + "id": "deb41f6b-4a14-46b7-a04b-2009fa61dd71" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df = pd.DataFrame([\n", + " ['A', 60, 70, 'f'],\n", + " ['B', 90, 80, 'm'],\n", + " ['C', 70, 90, 'm'],\n", + " ['D', 90, 100, 'f']],\n", + " columns=['name', 'english',\n", + " 'math', 'gender'])" + ], + "id": "2902ea4a-2dd6-4595-9dc8-ac33aa89bc39" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df.head()\n", + "# \u7d50\u679c\u306f\u5272\u611b" + ], + "id": "63195a85-c5cc-4bc8-94e0-4690a423f6b6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "r, c = my_df.shape # \u884c\u6570\u3068\u5217\u6570\n", + "r, c\n", + "\n", + "r # \u884c\u6570\uff08len(my_df)\u3082\u53ef\uff09\n", + "\n", + "c # \u5217\u6570" + ], + "id": "8e26d5b2-685e-45e3-aef1-6513fa725c74" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from itertools import product\n", + "my_df2 = pd.DataFrame(\n", + " product([1, 2, 3],\n", + " [10, 100]),\n", + " columns=['X', 'Y'])\n", + "my_df2" + ], + "id": "a8003d64-ec9b-42d9-bb4e-6c0cbecaf354" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2.columns" + ], + "id": "031e8cd0-c924-43d1-a4f2-b028e0a3d62f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2.columns = ['P', 'Q']\n", + "my_df2\n", + "# \u4ee5\u4e0b\u7701\u7565" + ], + "id": "0419b268-75a2-4289-bc3a-f8d7802c174f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "list(my_df.index)" + ], + "id": "2b3aa624-d800-4f1f-beff-2e56ddc03c88" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2.index = [\n", + " 'a', 'b', 'c', 'd', 'e', 'f']\n", + "my_df2\n", + "# \u4ee5\u4e0b\u7701\u7565" + ], + "id": "b97c96b8-11b9-4eb0-a3a9-be112cb0a332" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df3 = pd.DataFrame({\n", + " 'english': [ 60, 90, 70, 90],\n", + " 'math': [ 70, 80, 90, 100],\n", + " 'gender': ['f', 'm', 'm', 'f']},\n", + " index= ['A', 'B', 'C', 'D'])\n", + "my_df3" + ], + "id": "dc274f3c-d4b0-4cda-a5ab-c96f56b4f19e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = pd.DataFrame({\n", + " 'name' : ['E'],\n", + " 'english': [80],\n", + " 'math' : [80],\n", + " 'gender' : ['m']})\n", + "my_df2 = my_df.append(tmp)" + ], + "id": "b906e20f-c6b1-4250-a095-3fe836847893" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2 = my_df.assign(id=[1, 2, 3, 4])" + ], + "id": "c7ba556a-da56-43fe-a919-0e86fd5953a3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df3 = my_df.copy() # \u30b3\u30d4\u30fc\n", + "my_df3['id'] = [1, 2, 3, 4] # \u66f4\u65b0\n", + "my_df3 # \u7d50\u679c\u306e\u78ba\u8a8d\uff08\u5272\u611b\uff09" + ], + "id": "f3c6c378-6c6e-4e9f-ba67-26422a7b8f9c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df.iloc[0, 1]" + ], + "id": "eab5944b-2f63-455e-ae63-a98b3fd5bd5f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = my_df.iloc[:, 1]\n", + "# \u3042\u308b\u3044\u306f\n", + "x = my_df['english']\n", + "# \u3042\u308b\u3044\u306f\n", + "x = my_df.english\n", + "# \u3042\u308b\u3044\u306f\n", + "tmp = 'english'\n", + "x = my_df[tmp]\n", + "\n", + "x # \u7d50\u679c\u306e\u78ba\u8a8d\uff08\u5272\u611b\uff09" + ], + "id": "5ab4a204-b52b-49a4-aa57-951b66adc205" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = my_df[['name', 'math']]\n", + "# \u3042\u308b\u3044\u306f\n", + "x = my_df.loc[:, ['name', 'math']]" + ], + "id": "bc5f0441-c546-448c-811b-e3bb27d7705c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = my_df.take([0, 2], axis=1)\n", + "# \u3042\u308b\u3044\u306f\n", + "x = my_df.iloc[:, [0, 2]]" + ], + "id": "bf4f2baa-2a09-44bf-a701-e56c6caae441" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = my_df.drop(\n", + " columns=['english', 'gender'])\n", + "# \u3042\u308b\u3044\u306f\n", + "x = my_df.drop(\n", + " columns=my_df.columns[[1, 3]])" + ], + "id": "25df57b4-f32f-462e-960e-c2bbe8fbfe6e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = my_df.take([0, 2])\n", + "# \u3042\u308b\u3044\u306f\n", + "x = my_df.iloc[[0, 2], :]" + ], + "id": "f52d8bd7-3fc6-4f46-94db-eefb39c8ad6f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = my_df.drop([1, 3])" + ], + "id": "ca9422a0-8c6a-4819-86a6-b21d7e258344" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = my_df[my_df['gender'] == 'm']\n", + "# \u3042\u308b\u3044\u306f\n", + "x = my_df.query('gender == \"m\"')" + ], + "id": "e58a657f-6446-401f-8abc-14a0937ea615" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = my_df[(my_df['english'] > 80) & (my_df['gender'] == \"m\")]\n", + "# \u3042\u308b\u3044\u306f\n", + "x = my_df.query('english > 80 and gender == \"m\"')" + ], + "id": "039469ea-6227-45b3-875e-7ba254cbc163" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = my_df[my_df['english'] == my_df['english'].max()]\n", + "# \u3042\u308b\u3044\u306f\n", + "tmp = my_df['english'].max()\n", + "x = my_df.query('english == @tmp')" + ], + "id": "3b2ee260-afd4-45fd-a38c-a250af30e8b8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2 = my_df.copy() # \u30b3\u30d4\u30fc\n", + "my_df2.loc[my_df['gender'] == 'm', 'gender'] = 'M'" + ], + "id": "adbf8892-f2fd-4b6c-9289-700b0a49807d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2" + ], + "id": "2864aea7-98be-4dfe-85c3-cba2527c5ff8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = my_df.sort_values('english')" + ], + "id": "f65238dd-5dc8-48b7-9e2d-ab64713601b0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = my_df.sort_values('english',\n", + " ascending=False)" + ], + "id": "b6a8ec6e-c999-40e8-9108-042461899c97" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "x = [2, 3, 5, 7, 11, 13, 17, 19, 23,\n", + " 29, 31, 37]\n", + "A = np.array(x).reshape(3, 4)\n", + "A" + ], + "id": "7b19c415-61c3-47ef-9caa-6c39a695ed4f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "A = my_df.iloc[:, [1, 2]].values\n", + "A" + ], + "id": "21a36133-1972-4da6-814d-742a77c0be1a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pd.DataFrame(A)" + ], + "id": "1332377d-f862-4a07-b828-592490f492b1" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "A.T" + ], + "id": "7eb85fd8-1b6b-460d-8e6b-904d1968a541" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "A.T @ A" + ], + "id": "79509ca6-7534-4e24-805f-26a3a1f3620b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df = pd.DataFrame({\n", + " 'day': [25, 26, 27],\n", + " 'min': [20, 21, 15],\n", + " 'max': [24, 27, 21]})" + ], + "id": "0dcf034e-31aa-4054-8d20-d25a0e602ea9" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_longer = my_df.melt(id_vars='day')\n", + "my_longer" + ], + "id": "edbe9bbd-7cdb-42e2-8fe5-89c13fd5d964" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_wider = my_longer.pivot(\n", + " index='day',\n", + " columns='variable',\n", + " values='value')\n", + "my_wider" + ], + "id": "11aaa1e3-ca7f-402c-a381-4c1d4391e527" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_wider.plot(\n", + " style='o-',\n", + " xticks=my_wider.index, # x\u8ef8\u76ee\u76db\u308a\n", + " ylabel='temperature') # y\u8ef8\u30e9\u30d9\u30eb" + ], + "id": "aa2fd525-fc6f-41cd-9f9a-de760e5d507f" + }, + { + "id": "b063a5a8", + "cell_type": "markdown", + "source": "## 3.5 1\u6b21\u5143\u30c7\u30fc\u30bf\u306e\uff08\u975e\uff09\u985e\u4f3c\u5ea6", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from scipy.spatial import distance\n", + "from scipy.stats import pearsonr\n", + "\n", + "A = np.array([3, 4, 5])\n", + "B = np.array([3, 4, 29])\n", + "C = np.array([9, -18, 8])\n", + "\n", + "distance.euclidean(A, B)\n", + "\n", + "distance.euclidean(A, C)" + ], + "id": "52a0777d-960a-48ac-8e6f-3ad4288bb829" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "distance.cityblock(A, B)\n", + "\n", + "distance.cityblock(A, C)" + ], + "id": "cc27b41a-e3b2-4a42-ac0a-91414a76b777" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "1 - distance.cosine(A, B)\n", + "\n", + "1 - distance.cosine(A, C)" + ], + "id": "e0eb122e-f713-4330-9345-c5005fd335eb" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "1 - distance.correlation(A, B)\n", + "# \u3042\u308b\u3044\u306f\n", + "pearsonr(A, B)[0]\n", + "\n", + "1 - distance.correlation(A, C)\n", + "# \u3042\u308b\u3044\u306f\n", + "pearsonr(A, C)[0]" + ], + "id": "6efa8668-f766-446c-81bf-df08b7946262" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# \u5c0f\u6570\u70b9\u4ee5\u4e0b\u306f3\u6841\u8868\u793a\n", + "np.set_printoptions(precision=3)\n", + "import pandas as pd\n", + "\n", + "my_df = pd.DataFrame({\n", + " 'x': [3, 3, 9],\n", + " 'y': [4, 4, -18],\n", + " 'z': [5, 29, 8]},\n", + " index=['A', 'B', 'C'])\n", + "\n", + "# \u30e6\u30fc\u30af\u30ea\u30c3\u30c9\u8ddd\u96e2\n", + "distance.cdist(my_df, my_df,\n", + " metric='euclidean')\n", + "\n", + "# \u30de\u30f3\u30cf\u30c3\u30bf\u30f3\u8ddd\u96e2\n", + "distance.cdist(my_df, my_df,\n", + " metric='cityblock')\n", + "\n", + "# \u30b3\u30b5\u30a4\u30f3\u985e\u4f3c\u5ea6\n", + "1 - distance.cdist(my_df, my_df,\n", + " metric='cosine')\n", + "\n", + "# \u76f8\u95a2\u4fc2\u6570\n", + "1 - distance.cdist(my_df, my_df,\n", + " metric='correlation')" + ], + "id": "f8dc286f-1cd4-4348-8d66-7c53e2a9f416" + }, + { + "id": "ae8fc742", + "cell_type": "markdown", + "source": "## 3.6 R\u306e\u30d1\u30c3\u30b1\u30fc\u30b8\uff0cPython\u306e\u30e2\u30b8\u30e5\u30fc\u30eb", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import math\n", + "import numpy as np\n", + "import pandas as pd" + ], + "id": "51fdfe34-0c8b-4a25-a620-f840a85bce7f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy\n", + "numpy.array([1, 2, 3, 4])" + ], + "id": "4422f1ae-9cd5-43a7-9b7c-2a75dbc10832" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "np.array([1, 2, 3, 4])" + ], + "id": "c6e84652-27d2-41ab-8c5e-5cabff4f855c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from numpy import array\n", + "array([1, 2, 3, 4])" + ], + "id": "b59b0234-541d-44bf-940e-724f8acec855" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from numpy import *\n", + "array([1, 2, 3, 4])" + ], + "id": "468fd50b-4f6c-4cd7-a2f7-cce5deeaa34e" + }, + { + "id": "6d4e84eb", + "cell_type": "markdown", + "source": "## 3.7 \u53cd\u5fa9\u51e6\u7406", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd" + ], + "id": "09370e69-8aef-41d2-8675-35b66a9c7359" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def f1(x):\n", + " tmp = np.random.random(x)\n", + " return np.mean(tmp)\n", + "\n", + "f1(10) # \u52d5\u4f5c\u78ba\u8a8d" + ], + "id": "62032b8d-cd53-4a68-93a6-8469d5dca5f2" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "[f1(10) for i in range(3)]" + ], + "id": "bfb3d7b4-6aa6-4402-a8ea-60550d349aef" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "[f1(10)] * 3" + ], + "id": "0624c16a-8874-4ecc-a273-b8419d3f613c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "v = [5, 10, 100]\n", + "[f1(x) for x in v] # \u65b9\u6cd51\n", + "\n", + "# \u3042\u308b\u3044\u306f\n", + "\n", + "v = pd.Series([5, 10, 100])\n", + "v.apply(f1) # \u65b9\u6cd52" + ], + "id": "a4e34674-6312-43d6-8452-a4baa8337e07" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pd.Series([10] * 3).apply(f1)\n", + "# \u7d50\u679c\u306f\u5272\u611b" + ], + "id": "0720ff4f-1d4a-400f-b57d-49d5787b7382" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def f2(n):\n", + " tmp = np.random.random(n)\n", + " return pd.Series([\n", + " n,\n", + " tmp.mean(),\n", + " tmp.std(ddof=1)],\n", + " index=['x', 'p', 'q'])\n", + "\n", + "f2(10) # \u52d5\u4f5c\u78ba\u8a8d" + ], + "id": "e75ff41d-cce9-4cf9-96ec-f57e7121a788" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "v = pd.Series([5, 10, 100])\n", + "v.apply(f2)" + ], + "id": "bbe9f09e-04d0-4f1a-bdea-5bdb9ae6abaf" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def f3(x, y):\n", + " tmp = np.random.random(x) * y\n", + " return pd.Series([\n", + " x,\n", + " y,\n", + " tmp.mean(),\n", + " tmp.std(ddof=1)],\n", + " index=['x', 'y', 'p', 'q'])\n", + "\n", + "f3(10, 6) # \u52d5\u4f5c\u78ba\u8a8d" + ], + "id": "f2313ef8-434f-438b-a22e-570d20d8d5b8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df = pd.DataFrame({\n", + " 'x': [5, 10, 100, 5, 10, 100],\n", + " 'y': [6, 6, 6, 12, 12, 12]})\n", + "\n", + "my_df.apply(\n", + " lambda row: f3(row['x'], row['y']),\n", + " axis=1)\n", + "# \u3042\u308b\u3044\u306f\n", + "my_df.apply(lambda row:\n", + " f3(*row), axis=1)\n" + ], + "id": "37900908-08ce-4327-8365-4e79900f1f5e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from pandarallel import pandarallel\n", + "pandarallel.initialize() # \u6e96\u5099\n", + "\n", + "v = pd.Series([5, 10, 100])\n", + "v.parallel_apply(f1)\n", + "# \u7d50\u679c\u306f\u5272\u611b" + ], + "id": "84bc8e71-6215-40d0-8a08-7a3644772532" + }, + { + "id": "c4d0af92", + "cell_type": "markdown", + "source": "## 3.8 \u305d\u306e\u4ed6", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = 123\n", + "type(x)" + ], + "id": "4298aff2-b565-40ca-ad09-8f0548e773fa" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%whos" + ], + "id": "21292864-7d06-4398-8562-773322ea0fc0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import math\n", + "?math.log\n", + "# \u3042\u308b\u3044\u306f\n", + "help(math.log)" + ], + "id": "d29a03f5-eb38-404e-9a73-0fc058c40283" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "v = [1, np.nan, 3]\n", + "v" + ], + "id": "8d792806-0af3-43ae-98a6-5c8d3e9afef3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "np.isnan(v[1])\n", + "\n", + "v[1] == np.nan # \u8aa4\u308a" + ], + "id": "f9646cd2-0497-4956-ae05-e161eabf3576" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + } +} \ No newline at end of file diff --git a/code/Python-notebook/python-04.ipynb b/code/Python-notebook/python-04.ipynb new file mode 100644 index 0000000..051160b --- /dev/null +++ b/code/Python-notebook/python-04.ipynb @@ -0,0 +1,820 @@ +{ + "cells": [ + { + "id": "5f8fb03e", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)\n\n\n", + "metadata": {} + }, + { + "id": "2a365362", + "cell_type": "markdown", + "source": "## 4.1 \u8a18\u8ff0\u7d71\u8a08", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "x = [165, 170, 175, 180, 185]\n", + "np.mean(x) # \u30ea\u30b9\u30c8\u306e\u5834\u5408\n", + "\n", + "x = np.array( # \u30a2\u30ec\u30a4\n", + " [165, 170, 175, 180, 185])\n", + "x.mean() # np.mean(x)\u3082\u53ef\n", + "\n", + "x = pd.Series( # \u30b7\u30ea\u30fc\u30ba\n", + " [165, 170, 175, 180, 185])\n", + "x.mean() # np.mean(x)\u3082\u53ef" + ], + "id": "e4bbf40f-8d9a-4a91-91ae-7b7537c69bda" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "n = len(x) # \u30b5\u30f3\u30d7\u30eb\u30b5\u30a4\u30ba\n", + "sum(x) / n" + ], + "id": "fa7f1f1b-e9ec-4fc4-a9a8-d87b02dbc2db" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y = [173, 174, 175, 176, 177]\n", + "np.mean(y)" + ], + "id": "ee02b38a-8968-491a-9bf0-5cc0afa3f894" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "np.var(x, ddof=1) # x\u306e\u5206\u6563\n", + "\n", + "np.var(y, ddof=1) # y\u306e\u5206\u6563" + ], + "id": "42facf81-a5bc-4525-bad0-e86315e20407" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sum((x - np.mean(x))**2) / (n - 1)" + ], + "id": "ddcaaba4-488b-43ab-a045-f41c2337406b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "np.std(x, ddof=1) # x\u306e\u6a19\u6e96\u504f\u5dee\n", + "\n", + "np.std(y, ddof=1) # y\u306e\u6a19\u6e96\u504f\u5dee" + ], + "id": "f19b39af-a211-4f38-a83f-1023a74307cb" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "np.var(x, ddof=1)**0.5 # x\u306e\u6a19\u6e96\u504f\u5dee" + ], + "id": "7ec60162-9206-4b2d-8e52-fce66769e65a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "s = pd.Series(x)\n", + "s.describe()" + ], + "id": "8592ef95-26fb-434e-a5b4-06c09ae17c6b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# s.describe()\u3067\u8a08\u7b97\u6e08\u307f" + ], + "id": "f9aa3ea5-145b-4d6e-b26e-a56cd18b0813" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = [165, 170, 175, 180, 185]\n", + "\n", + "np.var(x, ddof=1) # \u4e0d\u504f\u5206\u6563\n", + "\n", + "np.var(x, ddof=0) # \u6a19\u672c\u5206\u6563" + ], + "id": "906bde36-4465-453c-b33b-4d247d929a5a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "np.std(x, ddof=1) # \u221a\u4e0d\u504f\u5206\u6563\n", + "\n", + "np.std(x, ddof=0) # \u221a\u6a19\u672c\u5206\u6563" + ], + "id": "37c95c22-d736-4412-bbbf-056f3c82b3ae" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "np.std(x, ddof=1) / len(x)**0.5" + ], + "id": "1f826a97-cdae-48e0-8b66-713c81a4b63a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "my_df = pd.DataFrame({\n", + " 'name': ['A', 'B', 'C', 'D'],\n", + " 'english': [ 60, 90, 70, 90],\n", + " 'math': [ 70, 80, 90, 100],\n", + " 'gender': ['f', 'm', 'm', 'f']})" + ], + "id": "f0bf8cea-2067-4235-91ea-7f5d9aaf8e2d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df['english'].var(ddof=1)\n", + "# \u3042\u308b\u3044\u306f\n", + "np.var(my_df['english'], ddof=1)\n" + ], + "id": "18362c75-921e-45d6-a211-3617bbd0d255" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df.var()\n", + "# \u3042\u308b\u3044\u306f\n", + "my_df.apply('var')\n", + "# \u3042\u308b\u3044\u306f\n", + "my_df.iloc[:, [1, 2]].apply(\n", + " lambda x: np.var(x, ddof=1))\n" + ], + "id": "2fbdd1fb-c2d3-4ade-b585-4c74d5009725" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df.describe()" + ], + "id": "24e4ca47-7f86-4339-addd-3fec38dfdd31" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from collections import Counter\n", + "Counter(my_df.gender)\n", + "\n", + "# \u3042\u308b\u3044\u306f\n", + "\n", + "my_df.groupby('gender').apply(len)" + ], + "id": "51ed5b6b-e7ef-44e5-9ba3-f77030d7d584" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2 = my_df.assign(\n", + " excel=my_df.math >= 80)\n", + "pd.crosstab(my_df2.gender,\n", + " my_df2.excel)" + ], + "id": "faa17059-e702-443a-b542-2b0859042ced" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df.groupby('gender').mean()\n", + "# \u3042\u308b\u3044\u306f\n", + "my_df.groupby('gender').agg('mean')\n", + "# \u3042\u308b\u3044\u306f\n", + "my_df.groupby('gender').agg(np.mean)\n" + ], + "id": "7a6a8544-6a47-43bf-b4d8-f22099ef5539" + }, + { + "id": "5006e87e", + "cell_type": "markdown", + "source": "## 4.2 \u30c7\u30fc\u30bf\u306e\u53ef\u8996\u5316", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import statsmodels.api as sm\n", + "iris = sm.datasets.get_rdataset('iris', 'datasets').data\n", + "iris.head()" + ], + "id": "fe204e1c-2700-45d8-aca7-c9afba652f40" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "iris.hist('Sepal.Length')" + ], + "id": "c491098a-91fd-4de7-b855-826ea18e873a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df = pd.DataFrame(\n", + " {'x': [10, 20, 30]})\n", + "my_df.hist('x', bins=2) # \u968e\u7d1a\u6570\u306f2" + ], + "id": "712bf2c7-fe81-4640-8f98-520b8febb174" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = iris['Sepal.Length']\n", + "tmp = np.linspace(min(x), max(x), 10)\n", + "iris.hist('Sepal.Length',\n", + " bins=tmp.round(2))" + ], + "id": "08d1f068-391a-4bc5-b48b-15ff127b36f9" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "iris.plot('Sepal.Length',\n", + " 'Sepal.Width',\n", + " kind='scatter')" + ], + "id": "9e0cedfd-e9a8-47aa-9f18-02943408db62" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "iris.boxplot()" + ], + "id": "201be043-cd48-4275-8292-1b3eb2489689" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pd.options.display.float_format = (\n", + " '{:.2f}'.format)\n", + "my_df = (iris.describe().transpose()\n", + " [['mean', 'std']])\n", + "my_df['se'] = (my_df['std'] /\n", + " len(iris)**0.5)\n", + "my_df" + ], + "id": "9b241b1a-3789-4d9b-8bfb-a5c5ee912eb0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df.plot(y='mean', kind='bar', yerr='se', capsize=10)" + ], + "id": "3b1a714b-273a-4d74-a8cc-f9666cbd7533" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_group = iris.groupby('Species') # \u54c1\u7a2e\u3054\u3068\u306b\uff0c\n", + "my_df = my_group.agg('mean') # \u5404\u5909\u6570\u306e\uff0c\u5e73\u5747\u3068\n", + "my_se = my_group.agg(lambda x: x.std() / len(x)**0.5) # \u6a19\u6e96\u8aa4\u5dee\u3092\u6c42\u3081\u308b\uff0e\n", + "my_se" + ], + "id": "86e01a8c-69b0-4428-9cc9-9432c058887f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_group.agg('mean').plot(kind='bar', yerr=my_se, capsize=5)" + ], + "id": "1184e616-d6c8-4682-bbfb-97ffbeab1096" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from statsmodels.graphics.mosaicplot \\\n", + " import mosaic\n", + "\n", + "my_df = pd.DataFrame({\n", + " 'Species': iris.Species,\n", + " 'w_Sepal': iris['Sepal.Width'] > 3})\n", + "\n", + "my_table = pd.crosstab( # \u5206\u5272\u8868\n", + " my_df['Species'],\n", + " my_df['w_Sepal'])\n", + "my_table\n", + "\n", + "mosaic(my_df,\n", + " index=['Species', 'w_Sepal'])" + ], + "id": "96b38ac0-4874-4df4-961f-3add3427c367" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_table.columns = [str(x) for x in my_table.columns]\n", + "my_table.index = [str(x) for x in my_table.index]\n", + "mosaic(my_df, index=['Species', 'w_Sepal'], labelizer=lambda k: my_table.loc[k])" + ], + "id": "47db7fa6-cf2e-4a98-a78b-7b1ba12f4168" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "x = np.linspace(-2, 2, 100)\n", + "y = x**3 - x\n", + "plt.plot(x, y)" + ], + "id": "26050df6-c81b-40ec-898f-ce1f6660ab60" + }, + { + "id": "6eb754aa", + "cell_type": "markdown", + "source": "## 4.3 \u4e71\u6570", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "rng = np.random.default_rng()" + ], + "id": "322768e2-b62a-4454-bdb7-b27b757f31af" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = np.random.choice(\n", + " a=range(1, 7), # 1\u304b\u30896\n", + " size=10000, # \u4e71\u6570\u306e\u6570\n", + " replace=True) # \u91cd\u8907\u3042\u308a\n", + "# \u3042\u308b\u3044\u306f\n", + "x = np.random.randint(\n", + "# \u3042\u308b\u3044\u306f\n", + "#x = rng.integers(\n", + " low=1, # \u6700\u5c0f\n", + " high=7, # \u6700\u5927+1\n", + " size=10000) # \u4e71\u6570\u306e\u6570\n", + "\n", + "plt.hist(x, bins=6) # \u30d2\u30b9\u30c8\u30b0\u30e9\u30e0" + ], + "id": "35784622-40e4-4853-b8e4-f0e615a4993c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = np.random.random(size=1000)\n", + "# \u3042\u308b\u3044\u306f\n", + "x = rng.random(size=10000)\n", + "# \u3042\u308b\u3044\u306f\n", + "x = np.random.uniform(\n", + " low=0, # \u6700\u5c0f\n", + " high=1, # \u6700\u5927\n", + " size=1000) # \u4e71\u6570\u306e\u6570\n", + "plt.hist(x)" + ], + "id": "ff07da40-3255-469e-9bdb-93d5479f14f0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = np.random.uniform(\n", + " low=1, # \u6700\u5c0f\n", + " high=7, # \u6700\u5927 + 1\n", + " size=1000) # \u4e71\u6570\u306e\u6570\n", + "x = [int(k) for k in tmp]\n", + "plt.hist(x, bins=6) # \u7d50\u679c\u306f\u5272\u611b" + ], + "id": "c6174d84-e540-4f6d-86a4-5bf8f05fa947" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "n = 100\n", + "p = 0.5\n", + "r = 10000\n", + "x = np.random.binomial(\n", + "# \u3042\u308b\u3044\u306f\n", + "#x = rng.binomial(\n", + " n=n, # \u8a66\u884c\u56de\u6570\n", + " p=p, # \u78ba\u7387\n", + " size=r) # \u4e71\u6570\u306e\u6570\n", + "plt.hist(x, bins=max(x) - min(x))" + ], + "id": "fac1fbe9-c053-4e0e-8e06-0867694e6002" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "r = 10000\n", + "x = np.random.normal(\n", + "# \u3042\u308b\u3044\u306f\n", + "#x = rng.normal(\n", + " loc=50, # \u5e73\u5747\n", + " scale=5, # \u6a19\u6e96\u504f\u5dee\n", + " size=r) # \u4e71\u6570\u306e\u6570\n", + "plt.hist(x, bins=40)" + ], + "id": "9a0458e2-2df7-40de-b85a-b792b51d9716" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "def f(k):\n", + " n = 10000\n", + " tmp = [g(np.random.normal(size=k, scale=3)) for _ in range(n)]\n", + " return pd.Series([k,\n", + " np.mean(tmp), # \u5e73\u5747\n", + " np.std(tmp, ddof=1) / n**0.5], # \u6a19\u6e96\u8aa4\u5dee\n", + " index=['k', 'mean', 'se'])" + ], + "id": "194f5b5e-4d0c-4d2b-9aac-399b1b0ce00b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def g(x):\n", + " return np.var(x, ddof=1)\n", + "pd.Series([10, 20, 30]).apply(f)" + ], + "id": "5429e689-6913-422d-bfa3-e7e5936e4f49" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def g(x):\n", + " return np.std(x, ddof=1)\n", + "pd.Series([10, 20, 30]).apply(f)" + ], + "id": "8d8fb82a-7356-4e6e-8438-c2055b78d362" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from math import gamma\n", + "\n", + "def g(x):\n", + " n = len(x)\n", + " return (np.std(x, ddof=1) *\n", + " (np.sqrt((n - 1) / 2) *\n", + " gamma((n - 1) / 2) /\n", + " gamma(n / 2)))\n", + "pd.Series([10, 20, 30]).apply(f)" + ], + "id": "b54f12bd-77b3-4ccd-a56c-130c6d2a2be5" + }, + { + "id": "5d61b645", + "cell_type": "markdown", + "source": "## 4.4 \u7d71\u8a08\u7684\u63a8\u6e2c", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from statsmodels.stats.proportion import binom_test, proportion_confint\n", + "\n", + "binom_test(count=2, # \u5f53\u305f\u3063\u305f\u56de\u6570\n", + " nobs=15, # \u304f\u3058\u3092\u5f15\u3044\u305f\u56de\u6570\n", + " prop=4 / 10, # \u5f53\u305f\u308b\u78ba\u7387\uff08\u4eee\u8aac\uff09\n", + " alternative='two-sided') # \u4e21\u5074\u691c\u5b9a\uff08\u30c7\u30d5\u30a9\u30eb\u30c8\uff09\n", + " # \u5de6\u7247\u5074\u691c\u5b9a\u306a\u3089'smaller'\n", + " # \u53f3\u7247\u5074\u691c\u5b9a\u306a\u3089'larger'" + ], + "id": "1efe08a9-8f40-4dfb-a351-8c9d13e53d45" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from scipy import stats\n", + "\n", + "t = 4 / 10 # \u5f53\u305f\u308b\u78ba\u7387\n", + "n = 15 # \u304f\u3058\u3092\u5f15\u3044\u305f\u56de\u6570\n", + "x = np.array(range(0, n + 1)) # \u5f53\u305f\u3063\u305f\u56de\u6570\n", + "my_pr = stats.binom.pmf(x, n, t) # x\u56de\u5f53\u305f\u308b\u78ba\u7387\n", + "my_pr2 = stats.binom.pmf(2, n, t) # 2\u56de\u5f53\u305f\u308b\u78ba\u7387\n", + "\n", + "my_data = pd.DataFrame({'x': x, 'y1': my_pr, 'y2': my_pr})\n", + "my_data.loc[my_pr > my_pr2, 'y1'] = np.nan # \u5f53\u305f\u308b\u78ba\u7387\u304c\uff0c2\u56de\u5f53\u305f\u308b\u78ba\u7387\u8d85\u904e\n", + "my_data.loc[my_pr <= my_pr2, 'y2'] = np.nan # \u5f53\u305f\u308b\u78ba\u7387\u304c\uff0c2\u56de\u5f53\u305f\u308b\u78ba\u7387\u4ee5\u4e0b\n", + "ax = my_data.plot(x='x', style='o', ylabel='probability',\n", + " legend=False) # \u51e1\u4f8b\u3092\u8868\u793a\u3057\u306a\u3044\uff0e\n", + "ax.hlines(y=my_pr2, xmin=0, xmax=15) # \u6c34\u5e73\u7dda\n", + "ax.vlines(x=x, ymin=0, ymax=my_pr) # \u5782\u76f4\u7dda" + ], + "id": "3ea64a21-8188-4463-9bdb-827e89883656" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a = 0.05\n", + "proportion_confint(\n", + " count=2, # \u5f53\u305f\u3063\u305f\u56de\u6570\n", + " nobs=15, # \u304f\u3058\u3092\u5f15\u3044\u305f\u56de\u6570\n", + " alpha=a, # \u6709\u610f\u6c34\u6e96\uff08\u7701\u7565\u53ef\uff09\n", + " method='binom_test')" + ], + "id": "79d61da5-9c38-4310-9934-55dcb29d3c21" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a = 0.05 # \u6709\u610f\u6c34\u6e96\n", + "tmp = np.linspace(0, 1, 100)\n", + "\n", + "my_df = pd.DataFrame({\n", + " 't': tmp, # \u5f53\u305f\u308b\u78ba\u7387\n", + " 'q': a, # \u6c34\u5e73\u7dda\n", + " 'p': [binom_test(count=2, nobs=15, prop=t) for t in tmp]}) # p\u5024\n", + "\n", + "my_df.plot(x='t', legend=None, xlabel=r'$\\theta$', ylabel=r'p-value')" + ], + "id": "a808ccff-d85e-4ed0-866b-746ffd1a7d6a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from statsmodels.stats.weightstats import CompareMeans, DescrStatsW\n", + "\n", + "X = [32.1, 26.2, 27.5, 31.8, 32.1, 31.2, 30.1, 32.4, 32.3, 29.9,\n", + " 29.6, 26.6, 31.2, 30.9, 29.3]\n", + "Y = [35.4, 34.6, 31.1, 32.4, 33.3, 34.7, 35.3, 34.3, 32.1, 28.3,\n", + " 33.3, 30.5, 32.6, 33.3, 32.2]\n", + "\n", + "a = 0.05 # \u6709\u610f\u6c34\u6e96\uff08\u30c7\u30d5\u30a9\u30eb\u30c8\uff09 = 1 - \u4fe1\u983c\u4fc2\u6570\n", + "alt = 'two-sided' # \u4e21\u5074\u691c\u5b9a\uff08\u30c7\u30d5\u30a9\u30eb\u30c8\uff09\n", + " # \u5de6\u7247\u5074\u691c\u5b9a\u306a\u3089'smaller'\n", + " # \u53f3\u7247\u5074\u691c\u5b9a\u306a\u3089'larger'\n", + "\n", + "d = DescrStatsW(np.array(X) - np.array(Y)) # \u5bfe\u6a19\u672c\u306e\u5834\u5408\n", + "d.ttest_mean(alternative=alt)[1] # p\u5024\n", + "\n", + "d.tconfint_mean(alpha=a, alternative=alt) # \u4fe1\u983c\u533a\u9593" + ], + "id": "52fb2829-544a-4f05-b929-8c7ac1b99e6a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c = CompareMeans(DescrStatsW(X), DescrStatsW(Y)) # \u5bfe\u6a19\u672c\u3067\u306a\u3044\u5834\u5408\n", + "\n", + "ve = 'pooled' # \u7b49\u5206\u6563\u3092\u4eee\u5b9a\u3059\u308b\uff08\u30c7\u30d5\u30a9\u30eb\u30c8\uff09\uff0e\u4eee\u5b9a\u3057\u306a\u3044\u306a\u3089'unequal'\uff0e\n", + "c.ttest_ind(alternative=alt, usevar=ve)[1] # p\u5024\n", + "\n", + "c.tconfint_diff(alpha=a, alternative=alt, usevar=ve) # \u4fe1\u983c\u533a\u9593" + ], + "id": "d32041fe-8bfc-4293-95d0-bae53bcdb4f4" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", + " '/fromzero/master/data/smoker.csv')\n", + "my_data = pd.read_csv(my_url)" + ], + "id": "e4c749fa-4f1f-4536-acb7-5f9eae7fb3e2" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data.head()" + ], + "id": "f713abbe-f1f8-44ab-b690-fdada406fbfe" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_table = pd.crosstab(\n", + " my_data['alive'],\n", + " my_data['smoker'])\n", + "my_table" + ], + "id": "e2606a42-fb5b-4f4a-8066-c46d4c61f017" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from scipy.stats import chi2_contingency\n", + "chi2_contingency(my_table, correction=False)[1]" + ], + "id": "ab651d70-6ce3-4623-845f-9838bcb4f398" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "X = [0] * 13 + [1] * 2 # \u624b\u98061\n", + "X\n", + "\n", + "tmp = np.random.choice(X, 15, replace=True) # \u624b\u98062\n", + "tmp\n", + "\n", + "sum(tmp) # \u624b\u98063\n", + "\n", + "n = 10**5\n", + "result = [sum(np.random.choice(X, len(X), replace=True)) for _ in range(n)] # \u624b\u98064" + ], + "id": "bc659567-4de9-464a-bb10-f828600ec519" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "plt.hist(result, bins=range(0, 16))" + ], + "id": "763881f1-ddd4-4a7a-9980-3ca398bd1bc9" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "np.quantile(result, [0.025, 0.975])" + ], + "id": "3828f5eb-2419-4abb-a1bc-b5e1fe44289d" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + } +} \ No newline at end of file diff --git a/code/Python-notebook/python-05.ipynb b/code/Python-notebook/python-05.ipynb new file mode 100644 index 0000000..d35c289 --- /dev/null +++ b/code/Python-notebook/python-05.ipynb @@ -0,0 +1,343 @@ +{ + "cells": [ + { + "id": "6e3350aa", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)\n\n\n", + "metadata": {} + }, + { + "id": "e505f0a4", + "cell_type": "markdown", + "source": "## 5.1 \u30c7\u30fc\u30bf\u306e\u8aad\u307f\u8fbc\u307f", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!wget https://raw.githubusercontent.com/taroyabuki/fromzero/master/data/exam.csv" + ], + "id": "c556ed41-a048-4268-9427-341957b0a233" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "my_df = pd.read_csv('exam.csv')\n", + "my_df" + ], + "id": "f0de49d6-ca1d-4057-8a36-a151fe56ed89" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", + " '/fromzero/master/data/exam.csv')\n", + "my_df = pd.read_csv(my_url)" + ], + "id": "5c68ab84-96c6-45bb-b34c-cad0e9152569" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2 = pd.read_csv('exam.csv',\n", + " index_col='name')\n", + "my_df2" + ], + "id": "8a4eefdc-b03f-4258-9e10-62787632dd19" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df.to_csv('exam2.csv', index=False)" + ], + "id": "4f496308-d226-4ea8-88b8-3465e0b5e0aa" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2.to_csv('exam3.csv')" + ], + "id": "d064ce06-e23b-4afa-9cd2-b9e051166aed" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df = pd.read_csv('exam.csv',\n", + " encoding='UTF-8')" + ], + "id": "7411d9b3-caa5-464b-bbc0-7c10e74fde3e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df.to_csv('exam2.csv', index=False, encoding='UTF-8')" + ], + "id": "50c95471-eae9-4461-8e85-6b8b5df5b9a7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_url = 'https://taroyabuki.github.io/fromzero/exam.html'\n", + "my_tables = pd.read_html(my_url)" + ], + "id": "5f6b19b9-8cc9-4b50-86bd-a75b904f0b6b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_tables" + ], + "id": "557652bd-0b97-4e49-a42e-65f7f9ff62fe" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_tables[0]" + ], + "id": "9520f8cc-67b9-45d5-a0e9-fac4079be052" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# 1\u5217\u76ee\u4ee5\u964d\u3092\u53d6\u308a\u51fa\u3059\uff0e\n", + "my_data = my_tables[0].iloc[:, 1:]\n", + "my_data" + ], + "id": "916d8cb1-4056-4c35-b92b-3654c49ede3f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", + " '/fromzero/master/data/exam.json')\n", + "my_data = pd.read_json(my_url)\n", + "#my_data = pd.read_json('exam.json') # \uff08\u30d5\u30a1\u30a4\u30eb\u3092\u4f7f\u3046\u5834\u5408\uff09\n", + "my_data" + ], + "id": "44a8eed4-2ece-403d-ab74-2aa75547e25a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import xml.etree.ElementTree as ET\n", + "from urllib.request import urlopen\n", + "\n", + "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", + " '/fromzero/master/data/exam.xml')\n", + "with urlopen(my_url) as f:\n", + " my_tree = ET.parse(f) # XML\u30c7\u30fc\u30bf\u306e\u8aad\u307f\u8fbc\u307f\n", + "\n", + "#my_tree = ET.parse('exam.xml') # \uff08\u30d5\u30a1\u30a4\u30eb\u3092\u4f7f\u3046\u5834\u5408\uff09\n", + "my_ns = '{https://www.example.net/ns/1.0}' # \u540d\u524d\u7a7a\u9593" + ], + "id": "74426c3f-af69-44a3-ae93-652d0889f957" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_records = my_tree.findall(f'.//{my_ns}record')" + ], + "id": "339a54ca-bed3-4e7c-8d53-ca2a78b404c7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def f(record):\n", + " my_dic1 = record.attrib # \u5c5e\u6027\u3092\u53d6\u308a\u51fa\u3059\uff0e\n", + " # \u5b50\u8981\u7d20\u306e\u540d\u524d\u3068\u5185\u5bb9\u306e\u30da\u30a2\u3092\u8f9e\u66f8\u306b\u3059\u308b\uff0e\n", + " my_dic2 = {child.tag.replace(my_ns, ''): child.text for child in list(record)}\n", + " return {**my_dic1, **my_dic2} # \u8f9e\u66f8\u3092\u7d50\u5408\u3059\u308b\uff0e" + ], + "id": "5e102690-fd34-4f56-ad87-1beb0f6d47ea" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data = pd.DataFrame([f(record) for record in my_records])\n", + "my_data['english'] = pd.to_numeric(my_data['english'])\n", + "my_data['math'] = pd.to_numeric(my_data['math'])\n", + "my_data" + ], + "id": "abda4029-f581-4380-a57d-b010d6395838" + }, + { + "id": "f083057c", + "cell_type": "markdown", + "source": "## 5.2 \u30c7\u30fc\u30bf\u306e\u5909\u63db", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from scipy.stats import zscore\n", + "\n", + "x1 = [1, 2, 3]\n", + "\n", + "z1 = ((x1 - np.mean(x1)) /\n", + " np.std(x1, ddof=1))\n", + "# \u3042\u308b\u3044\u306f\n", + "z1 = zscore(x1, ddof=1)\n", + "\n", + "z1" + ], + "id": "dee44c8b-2524-46f5-ad8c-80b4c8c6f115" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "z1.mean(), np.std(z1, ddof=1)" + ], + "id": "f3ba4193-3c81-41f6-a4ab-6962deea5dc6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "z1 * np.std(x1, ddof=1) + np.mean(x1)" + ], + "id": "4e890f51-9074-46d7-a446-cbff9cbe0f20" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x2 = [1, 3, 5]\n", + "z2 = ((x2 - np.mean(x1)) /\n", + " np.std(x1, ddof=1))\n", + "z2.mean(), np.std(z2, ddof=1)" + ], + "id": "5e9ae29a-05de-4e63-ad78-0f771a99dc2e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "from sklearn.preprocessing import (\n", + " OneHotEncoder)\n", + "\n", + "my_df = pd.DataFrame({\n", + " 'id': [ 1 , 2 , 3 ],\n", + " 'class': ['A', 'B', 'C']})\n", + "\n", + "my_enc = OneHotEncoder()\n", + "tmp = my_enc.fit_transform(\n", + " my_df[['class']]).toarray()\n", + "my_names = my_enc.get_feature_names() \\\n", + "if hasattr(my_enc, 'get_feature_names') \\\n", + "else my_enc.get_feature_names_out()\n", + "pd.DataFrame(tmp, columns=my_names)" + ], + "id": "c47cedf2-fcdf-4a44-adda-e3059d48fad1" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2 = pd.DataFrame({\n", + " 'id': [ 4 , 5, 6 ],\n", + " 'class': ['B', 'C', 'B']})\n", + "tmp = my_enc.transform(\n", + " my_df2[['class']]).toarray()\n", + "pd.DataFrame(tmp, columns=my_names)" + ], + "id": "826a0bc5-cacf-41a1-b20e-f5dc61560da7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_enc = OneHotEncoder(drop='first')\n", + "\n", + "tmp = my_enc.fit_transform(\n", + " my_df[['class']]).toarray()\n", + "my_names = my_enc.get_feature_names() \\\n", + "if hasattr(my_enc, 'get_feature_names') \\\n", + "else my_enc.get_feature_names_out()\n", + "pd.DataFrame(tmp, columns=my_names)\n", + "\n", + "tmp = my_enc.transform(\n", + " my_df2[['class']]).toarray()\n", + "pd.DataFrame(tmp, columns=my_names)" + ], + "id": "bed83373-fe9d-447e-bdd6-8ee518261f39" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + } +} \ No newline at end of file diff --git a/code/Python-notebook/python-06.ipynb b/code/Python-notebook/python-06.ipynb new file mode 100644 index 0000000..6e09140 --- /dev/null +++ b/code/Python-notebook/python-06.ipynb @@ -0,0 +1,78 @@ +{ + "cells": [ + { + "id": "e9754de4", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)\n\n\n", + "metadata": {} + }, + { + "id": "d7548339", + "cell_type": "markdown", + "source": "## 6.1 \u6a5f\u68b0\u5b66\u7fd2\u306e\u76ee\u7684\uff08\u672c\u66f8\u306e\u5834\u5408\uff09\n\n\n", + "metadata": {} + }, + { + "id": "f5518ee4", + "cell_type": "markdown", + "source": "## 6.2 \u6a5f\u68b0\u5b66\u7fd2\u306e\u305f\u3081\u306e\u30c7\u30fc\u30bf", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import statsmodels.api as sm\n", + "iris = sm.datasets.get_rdataset('iris', 'datasets').data\n", + "iris.head()\n", + "# \u4ee5\u4e0b\u7701\u7565" + ], + "id": "0f86ba79-a242-4f7a-8d1c-f291233583f7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import seaborn as sns\n", + "iris = sns.load_dataset('iris')\n", + "iris.head()\n", + "# \u4ee5\u4e0b\u7701\u7565" + ], + "id": "9b3c3c64-8865-439e-8960-8223c1afbe7f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "from sklearn.datasets import load_iris\n", + "tmp = load_iris()\n", + "iris = pd.DataFrame(tmp.data, columns=tmp.feature_names)\n", + "iris['target'] = tmp.target_names[tmp.target]\n", + "iris.head()\n", + "# \u4ee5\u4e0b\u7701\u7565" + ], + "id": "e0f03577-b2f2-42b1-8773-380eb3fb3414" + }, + { + "id": "9323a92a", + "cell_type": "markdown", + "source": "## 6.3 \u6a5f\u68b0\u5b66\u7fd2\u306e\u305f\u3081\u306e\u624b\u6cd5", + "metadata": {} + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + } +} \ No newline at end of file diff --git a/code/Python-notebook/python-07.ipynb b/code/Python-notebook/python-07.ipynb new file mode 100644 index 0000000..2354158 --- /dev/null +++ b/code/Python-notebook/python-07.ipynb @@ -0,0 +1,757 @@ +{ + "cells": [ + { + "id": "814339b3", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)\n\n\n", + "metadata": {} + }, + { + "id": "3d0d9350", + "cell_type": "markdown", + "source": "## 7.1 \u81ea\u52d5\u8eca\u306e\u505c\u6b62\u8ddd\u96e2\n\n\n", + "metadata": {} + }, + { + "id": "756b7e2b", + "cell_type": "markdown", + "source": "## 7.2 \u30c7\u30fc\u30bf\u306e\u78ba\u8a8d", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import statsmodels.api as sm\n", + "my_data = sm.datasets.get_rdataset('cars', 'datasets').data" + ], + "id": "8cf39bb4-84c8-4663-81e5-f87318bff16a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data.shape" + ], + "id": "28b24fa4-c62b-44ec-9ff1-059cd5614c09" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data.head()" + ], + "id": "10d154d1-94e6-43a9-a3c0-426608b41cb4" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data.describe()" + ], + "id": "376313d0-db3d-48d3-a33f-61fe1bb18b11" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data.plot(x='speed', style='o')" + ], + "id": "7921a043-8ea3-4b6d-b46e-62923060cb44" + }, + { + "id": "29897b8f", + "cell_type": "markdown", + "source": "## 7.3 \u56de\u5e30\u5206\u6790", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import seaborn as sns\n", + "import statsmodels.api as sm\n", + "\n", + "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", + "ax = sns.regplot(x='speed', y='dist', data=my_data)\n", + "ax.vlines(x=21.5, ymin=-5, ymax=67, linestyles='dotted')\n", + "ax.hlines(y=67, xmin=4, xmax=21.5, linestyles='dotted')\n", + "ax.set_xlim(4, 25)\n", + "ax.set_ylim(-5, 125)" + ], + "id": "f329c1bb-20a9-4d1a-9bf9-d4d18252418b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import statsmodels.api as sm\n", + "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", + "X, y = my_data[['speed']], my_data['dist']" + ], + "id": "2c6f4748-cbbf-4d9b-af5a-b171faeb0415" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# \u30e2\u30c7\u30eb\u306e\u6307\u5b9a\n", + "from sklearn.linear_model import LinearRegression\n", + "my_model = LinearRegression()\n", + "\n", + "# \u8a13\u7df4\uff08\u30e2\u30c7\u30eb\u3092\u30c7\u30fc\u30bf\u306b\u30d5\u30a3\u30c3\u30c8\u3055\u305b\u308b\uff0e\uff09\n", + "my_model.fit(X, y)\n", + "\n", + "# \u307e\u3068\u3081\u3066\u5b9f\u884c\u3057\u3066\u3082\u3088\u3044\uff0e\n", + "# my_model = LinearRegression().fit(X, y)" + ], + "id": "56ac9cfc-337e-4551-8f8a-6984bcb2b147" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model.intercept_, my_model.coef_" + ], + "id": "a1ce373d-32da-46c3-b401-57d85799b1c2" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = [[21.5]]\n", + "my_model.predict(tmp)" + ], + "id": "86221ea3-acf8-4ae7-af5b-01bcb1a8e26f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "tmp = pd.DataFrame({'speed': np.linspace(min(my_data.speed),\n", + " max(my_data.speed),\n", + " 100)})\n", + "tmp['model'] = my_model.predict(tmp)" + ], + "id": "2d81de79-7452-42b2-b54e-50355cb116f6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pd.concat([my_data, tmp]).plot(\n", + " x='speed', style=['o', '-'])" + ], + "id": "bb796e13-660f-4d35-a0f0-a72201526b95" + }, + { + "id": "8d59bbe6", + "cell_type": "markdown", + "source": "## 7.4 \u5f53\u3066\u306f\u307e\u308a\u306e\u826f\u3055\u306e\u6307\u6a19", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import statsmodels.api as sm\n", + "from sklearn.linear_model import LinearRegression\n", + "from sklearn.metrics import mean_squared_error, r2_score\n", + "\n", + "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", + "X, y = my_data[['speed']], my_data['dist']\n", + "\n", + "my_model = LinearRegression()\n", + "my_model.fit(X, y)\n", + "y_ = my_model.predict(X)\n", + "my_data['y_'] = y_" + ], + "id": "3b917deb-d25c-4d24-a428-6f31d4051d2e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pd.options.display.float_format = (\n", + " '{:.2f}'.format)\n", + "my_data['residual'] = y - y_\n", + "my_data.head()" + ], + "id": "cb45fee8-2867-4ec4-8f05-edfe307b389e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ax = my_data.plot(x='speed', y='dist', style='o', legend=False)\n", + "my_data.plot(x='speed', y='y_', style='-', legend=False, ax=ax)\n", + "ax.vlines(x=X, ymin=y, ymax=y_, linestyles='dotted')" + ], + "id": "3339ba60-3231-48ff-8c52-2c26fd8e79b3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mean_squared_error(y, y_)**0.5\n", + "# \u3042\u308b\u3044\u306f\n", + "(my_data['residual']**2).mean()**0.5\n" + ], + "id": "b61b5d67-199e-441d-b029-3213f2b802cd" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model.score(X, y)\n", + "# \u3042\u308b\u3044\u306f\n", + "r2_score(y_true=y, y_pred=y_)" + ], + "id": "e0a654d8-405e-4d36-a10e-12d259ef6b23" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "np.corrcoef(y, y_)[0, 1]**2" + ], + "id": "4ccee95a-11bb-4244-b3f3-48b1ab9365c5" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_test = my_data[:3]\n", + "X = my_test[['speed']]\n", + "y = my_test['dist']\n", + "y_ = my_model.predict(X)\n", + "\n", + "my_model.score(X, y)\n", + "# \u3042\u308b\u3044\u306f\n", + "r2_score(y_true=y, y_pred=y_)\n", + "\n", + "np.corrcoef(y, y_)[0, 1]**2" + ], + "id": "2790ada7-124c-4290-8367-3eb45977a2b4" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import statsmodels.api as sm\n", + "from sklearn.linear_model import LinearRegression\n", + "from sklearn.preprocessing import PolynomialFeatures\n", + "\n", + "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", + "\n", + "my_idx = [1, 10, 26, 33, 38, 43]\n", + "my_sample = my_data.iloc[my_idx, ]\n", + "X, y = my_sample[['speed']], my_sample['dist']" + ], + "id": "0214a350-50c1-4682-a863-44cb709c6620" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "d = 5\n", + "X5 = PolynomialFeatures(d, include_bias=False).fit_transform(X) # X\u306e1\u4e57\u304b\u30895\u4e57\u306e\u5909\u6570\n", + "\n", + "my_model = LinearRegression()\n", + "my_model.fit(X5, y)\n", + "y_ = my_model.predict(X5)" + ], + "id": "fd8ac2bd-6540-4d3e-986d-82d8f4ecddd9" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "((y - y_)**2).mean()**0.5\n", + "\n", + "my_model.score(X5, y)\n", + "\n", + "np.corrcoef(y, y_)[0, 1]**2" + ], + "id": "fb03bb95-39bd-4218-ba93-33b53f6411d2" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = pd.DataFrame({'speed': np.linspace(min(my_data.speed),\n", + " max(my_data.speed),\n", + " 100)})\n", + "X5 = PolynomialFeatures(d, include_bias=False).fit_transform(tmp)\n", + "tmp['model'] = my_model.predict(X5)\n", + "\n", + "my_sample = my_sample.assign(sample=y)\n", + "my_df = pd.concat([my_data, my_sample, tmp])\n", + "my_df.plot(x='speed', style=['o', 'o', '-'], ylim=(0, 130))" + ], + "id": "fe81cbee-0076-40df-a036-5b1637765d7a" + }, + { + "id": "f87fcf88", + "cell_type": "markdown", + "source": "## 7.5 K\u6700\u8fd1\u508d\u6cd5", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# \u6e96\u5099\n", + "import numpy as np\n", + "import pandas as pd\n", + "import statsmodels.api as sm\n", + "from sklearn.neighbors import KNeighborsRegressor\n", + "\n", + "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", + "X, y = my_data[['speed']], my_data['dist']\n", + "\n", + "# \u8a13\u7df4\n", + "my_model = KNeighborsRegressor()\n", + "my_model.fit(X, y)\n", + "\n", + "# \u53ef\u8996\u5316\u306e\u6e96\u5099\n", + "tmp = pd.DataFrame({'speed': np.linspace(min(my_data.speed),\n", + " max(my_data.speed),\n", + " 100)})\n", + "tmp['model'] = my_model.predict(tmp)" + ], + "id": "e7d0c55e-95b3-46ea-8d84-b05d8a8e5aeb" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pd.concat([my_data, tmp]).plot(\n", + " x='speed', style=['o', '-'])" + ], + "id": "0e04dbe2-695a-4cdb-8ab0-af175c1fa213" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_ = my_model.predict(X)\n", + "\n", + "((y - y_)**2).mean()**0.5\n", + "\n", + "my_model.score(X, y)\n", + "\n", + "np.corrcoef(y, y_)[0, 1]**2" + ], + "id": "dd29ffe9-415e-474c-acc5-1aa19eab3ae7" + }, + { + "id": "c7677d3d", + "cell_type": "markdown", + "source": "## 7.6 \u691c\u8a3c", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import statsmodels.api as sm\n", + "from sklearn.linear_model import LinearRegression\n", + "from sklearn.model_selection import cross_val_score\n", + "\n", + "# \u30c7\u30fc\u30bf\u306e\u6e96\u5099\n", + "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", + "X, y = my_data[['speed']], my_data['dist']\n", + "\n", + "# \u30e2\u30c7\u30eb\u306e\u6307\u5b9a\n", + "my_model = LinearRegression()\n", + "\n", + "# \u691c\u8a3c\uff085\u5206\u5272\u4ea4\u5dee\u691c\u8a3c\uff09\n", + "my_scores = cross_val_score(my_model, X, y)\n", + "\n", + "# 5\u500b\u306e\u6c7a\u5b9a\u4fc2\u65701\u3092\u5f97\u308b\uff0e\n", + "my_scores\n", + "\n", + "# \u5e73\u5747\u3092\u6c7a\u5b9a\u4fc2\u65701\uff08\u691c\u8a3c\uff09\u3068\u3059\u308b\uff0e\n", + "my_scores.mean()" + ], + "id": "6f8eba71-444f-4139-960b-e3104f28a129" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_scores = cross_val_score(my_model, X, y,\n", + " scoring='neg_root_mean_squared_error')\n", + "-my_scores.mean()" + ], + "id": "4f22fd39-7dfe-4acc-a5bb-dbe4e86a7c88" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import statsmodels.api as sm\n", + "from sklearn.linear_model import LinearRegression\n", + "from sklearn.metrics import mean_squared_error, r2_score\n", + "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", + "\n", + "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", + "X, y = my_data[['speed']], my_data['dist']\n", + "my_model = LinearRegression().fit(X, y)\n", + "y_ = my_model.predict(X)" + ], + "id": "b8d9b4fd-04f9-442a-805c-831061df16c3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# RMSE\uff08\u8a13\u7df4\uff09\n", + "mean_squared_error(y, y_)**0.5\n", + "\n", + "# \u6c7a\u5b9a\u4fc2\u65701\uff08\u8a13\u7df4\uff09\n", + "my_model.score(X, y)\n", + "# \u3042\u308b\u3044\u306f\n", + "r2_score(y_true=y, y_pred=y_)\n", + "\n", + "# \u6c7a\u5b9a\u4fc2\u65706\uff08\u8a13\u7df4\uff09\n", + "np.corrcoef(y, y_)[0, 1]**2" + ], + "id": "8e55c9d3-33c5-4655-83a0-ce94aeac2e51" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_scores = cross_val_score(my_model, X, y,\n", + " scoring='neg_root_mean_squared_error')\n", + "-my_scores.mean()\n", + "\n", + "my_scores = cross_val_score(my_model, X, y, scoring='r2') # scoring='r2'\u306f\u7701\u7565\u53ef\n", + "my_scores.mean()" + ], + "id": "79610232-bc8e-4339-927e-575a91bbc1a9" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# \u65b9\u6cd51\n", + "my_scores1 = cross_val_score(my_model, X, y, cv=LeaveOneOut(),\n", + " scoring='neg_mean_squared_error')\n", + "(-my_scores1.mean())**0.5\n", + "\n", + "# \u65b9\u6cd52\n", + "my_scores2 = cross_val_score(my_model, X, y, cv=LeaveOneOut(),\n", + " scoring='neg_root_mean_squared_error')\n", + "(my_scores2**2).mean()**0.5" + ], + "id": "c80f9652-b278-4861-a01d-aa35bdbb0ecc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "-my_scores2.mean()" + ], + "id": "567b4607-3e44-42a1-9763-1aa9d719fb4e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import statsmodels.api as sm\n", + "from sklearn.linear_model import LinearRegression\n", + "from sklearn.metrics import mean_squared_error\n", + "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", + "from sklearn.neighbors import KNeighborsRegressor\n", + "\n", + "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", + "X, y = my_data[['speed']], my_data['dist']\n", + "\n", + "my_lm_scores = cross_val_score(\n", + " LinearRegression(),\n", + " X, y, cv=LeaveOneOut(), scoring='neg_mean_squared_error')\n", + "\n", + "my_knn_socres = cross_val_score(\n", + " KNeighborsRegressor(n_neighbors=5),\n", + " X, y, cv=LeaveOneOut(), scoring='neg_mean_squared_error')" + ], + "id": "10d8c917-6fcd-4a6d-a2ba-76fa4a95c807" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "(-my_lm_scores.mean())**0.5\n", + "\n", + "(-my_knn_socres.mean())**0.5" + ], + "id": "204d17c2-dc72-4d00-95ca-bc9c0167b54f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df = pd.DataFrame({\n", + " 'lm': -my_lm_scores,\n", + " 'knn': -my_knn_socres})\n", + "my_df.head()" + ], + "id": "264d9b2b-ba4b-4d3d-a798-20fff58dc4dc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df.boxplot().set_ylabel(\"$r^2$\")" + ], + "id": "95bf2677-bd7a-497e-9087-ba6f119729c4" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from statsmodels.stats.weightstats import DescrStatsW\n", + "d = DescrStatsW(my_df.lm - my_df.knn)\n", + "d.ttest_mean()[1] # p\u5024\n", + "\n", + "d.tconfint_mean(alpha=0.05, alternative='two-sided') # \u4fe1\u983c\u533a\u9593" + ], + "id": "d4114084-041e-433f-b7ab-e7113d135936" + }, + { + "id": "a303920b", + "cell_type": "markdown", + "source": "## 7.7 \u30d1\u30e9\u30e1\u30fc\u30bf\u30c1\u30e5\u30fc\u30cb\u30f3\u30b0", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import statsmodels.api as sm\n", + "from sklearn.metrics import mean_squared_error\n", + "from sklearn.model_selection import GridSearchCV, LeaveOneOut\n", + "from sklearn.neighbors import KNeighborsRegressor\n", + "\n", + "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", + "X, y = my_data[['speed']], my_data['dist']\n", + "\n", + "my_params = {'n_neighbors': range(1, 16)} # \u63a2\u7d22\u7bc4\u56f2\uff081\u4ee5\u4e0a16\u672a\u6e80\u306e\u6574\u6570\uff09\n", + "\n", + "my_search = GridSearchCV(estimator=KNeighborsRegressor(),\n", + " param_grid=my_params,\n", + " cv=LeaveOneOut(),\n", + " scoring='neg_mean_squared_error')\n", + "my_search.fit(X, y)" + ], + "id": "4c341837-95ae-48be-8183-76d9b143c397" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = my_search.cv_results_ # \u30c1\u30e5\u30fc\u30cb\u30f3\u30b0\u306e\u8a73\u7d30\n", + "my_scores = (-tmp['mean_test_score'])**0.5 # RMSE\n", + "my_results = pd.DataFrame(tmp['params']).assign(validation=my_scores)" + ], + "id": "b61730c1-130b-467d-82d4-a4516a476c5b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_results.head()" + ], + "id": "8bf2ca64-cb8f-4a6d-a008-7143c3771d49" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_results.plot(x='n_neighbors',\n", + " style='o-',\n", + " ylabel='RMSE')" + ], + "id": "4160bc00-791b-4095-a801-d486f3c764b0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_search.best_params_" + ], + "id": "0b95ca7e-c53d-4ae3-82ed-72551a42fda8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "(-my_search.best_score_)**0.5" + ], + "id": "af52f491-675b-464b-bf15-08c064430c11" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model = my_search.best_estimator_\n", + "y_ = my_model.predict(X)\n", + "mean_squared_error(y_, y)**0.5" + ], + "id": "2ffba036-eff4-41a1-9b31-94f2f4b3ec26" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import statsmodels.api as sm\n", + "from sklearn.metrics import mean_squared_error\n", + "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", + "from sklearn.neighbors import KNeighborsRegressor\n", + "\n", + "my_data = sm.datasets.get_rdataset('cars', 'datasets').data\n", + "X, y = my_data[['speed']], my_data['dist']\n", + "\n", + "def my_loocv(k):\n", + " my_model = KNeighborsRegressor(n_neighbors=k)\n", + " my_scores = cross_val_score(estimator=my_model, X=X, y=y,\n", + " cv=LeaveOneOut(),\n", + " scoring='neg_mean_squared_error')\n", + " y_ = my_model.fit(X, y).predict(X)\n", + " return pd.Series([k,\n", + " (-my_scores.mean())**0.5, # RMSE\uff08\u691c\u8a3c\uff09\n", + " mean_squared_error(y_, y)**0.5], # RMSE\uff08\u8a13\u7df4\uff09\n", + " index=['n_neighbors', 'validation', 'training'])\n", + "\n", + "my_results = pd.Series(range(1, 16)).apply(my_loocv)" + ], + "id": "0d2e8f5b-4ecc-4ea0-80bc-f7179a8d75a5" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_results.plot(x='n_neighbors',\n", + " style='o-',\n", + " ylabel='RMSE')" + ], + "id": "b9e20d43-6907-4706-a151-e3f32ef3e1bb" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + } +} \ No newline at end of file diff --git a/code/Python-notebook/python-08.ipynb b/code/Python-notebook/python-08.ipynb new file mode 100644 index 0000000..e7ebd8d --- /dev/null +++ b/code/Python-notebook/python-08.ipynb @@ -0,0 +1,598 @@ +{ + "cells": [ + { + "id": "ef0db241", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)\n\n\n", + "metadata": {} + }, + { + "id": "fca19532", + "cell_type": "markdown", + "source": "## 8.1 \u30d6\u30c9\u30a6\u306e\u751f\u80b2\u6761\u4ef6\u3068\u30ef\u30a4\u30f3\u306e\u4fa1\u683c", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "my_url = 'http://www.liquidasset.com/winedata.html'\n", + "tmp = pd.read_table(my_url, skiprows=62, nrows=38, sep='\\\\s+', na_values='.')\n", + "tmp.describe()\n", + "# \u4ee5\u4e0b\u7701\u7565" + ], + "id": "a937d2f9-1b46-4988-a763-49016ba492de" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data = tmp.iloc[:, 2:].dropna()\n", + "my_data.head()" + ], + "id": "0e49d596-19c9-40e3-bcd1-a0f9f45211d5" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data.shape" + ], + "id": "9cf673a5-9228-45ba-bd89-3a7e3cb33036" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data.to_csv('wine.csv',\n", + " index=False)" + ], + "id": "f5189f93-0559-4f98-ba25-02058c3c01e2" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#my_data = pd.read_csv('wine.csv') # \u4f5c\u3063\u305f\u30d5\u30a1\u30a4\u30eb\u3092\u4f7f\u3046\u5834\u5408\n", + "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", + " '/fromzero/master/data/wine.csv')\n", + "my_data = pd.read_csv(my_url)" + ], + "id": "fb120740-7810-4e7a-8d70-96fd65a14300" + }, + { + "id": "39587983", + "cell_type": "markdown", + "source": "## 8.2 \u91cd\u56de\u5e30\u5206\u6790", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from sklearn.linear_model import LinearRegression\n", + "from sklearn.metrics import mean_squared_error\n", + "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", + "\n", + "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", + " '/fromzero/master/data/wine.csv')\n", + "my_data = pd.read_csv(my_url)\n", + "X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2']\n", + "\n", + "my_model = LinearRegression().fit(X, y)" + ], + "id": "baa58938-12e1-4fe2-a1ee-c2657b252f72" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model.intercept_\n", + "\n", + "pd.Series(my_model.coef_,\n", + " index=X.columns)" + ], + "id": "42188792-ad47-439b-a18e-80f70c183ac6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_test = [[500, 17, 120, 2]]\n", + "my_model.predict(my_test)" + ], + "id": "35469121-e0ab-4522-92f5-e7a2071ff1fe" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_ = my_model.predict(X)\n", + "\n", + "mean_squared_error(y_, y)**0.5\n", + "\n", + "my_model.score(X, y)\n", + "\n", + "np.corrcoef(y, y_)[0, 1]**2" + ], + "id": "d6bc887a-8e03-4608-b5c7-ebec3b34da94" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_scores = cross_val_score(my_model, X, y,\n", + " cv=LeaveOneOut(),\n", + " scoring='neg_mean_squared_error')\n", + "(-my_scores.mean())**0.5" + ], + "id": "454e567f-b09c-4939-93c6-d4717d2400bd" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "M = np.matrix(X.assign(b0=1))\n", + "b = np.linalg.pinv(M) @ y\n", + "pd.Series(b,\n", + " index=list(X.columns) + ['b0'])" + ], + "id": "895710d7-7841-4844-95ce-10dccf34279d" + }, + { + "id": "6f0a9524", + "cell_type": "markdown", + "source": "## 8.3 \u6a19\u6e96\u5316", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "from sklearn.linear_model import LinearRegression\n", + "from sklearn.pipeline import Pipeline\n", + "from sklearn.preprocessing import StandardScaler\n", + "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", + " '/fromzero/master/data/wine.csv')\n", + "my_data = pd.read_csv(my_url)\n", + "X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2']\n", + "\n", + "# StandardScaler\u3067\u6a19\u6e96\u5316\u3057\u305f\u7d50\u679c\u3092\u30c7\u30fc\u30bf\u30d5\u30ec\u30fc\u30e0\u306b\u623b\u3057\u3066\u304b\u3089\u63cf\u753b\u3059\u308b\uff0e\n", + "pd.DataFrame(StandardScaler().fit_transform(X), columns=X.columns\n", + " ).boxplot(showmeans=True)" + ], + "id": "db42930e-9445-409b-b2ef-4628ed46d3e0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_pipeline = Pipeline([\n", + " ('sc', StandardScaler()),\n", + " ('lr', LinearRegression())])\n", + "my_pipeline.fit(X, y)" + ], + "id": "54e63664-d046-4f4b-83ea-ba3b0e18ed88" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# \u7dda\u5f62\u56de\u5e30\u306e\u90e8\u5206\u3060\u3051\u3092\u53d6\u308a\u51fa\u3059\uff0e\n", + "my_lr = my_pipeline.named_steps.lr\n", + "my_lr.intercept_\n", + "\n", + "pd.Series(my_lr.coef_,\n", + " index=X.columns)" + ], + "id": "bf4cf04f-a43f-46b8-97b5-ee3d413e16e6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_test = [[500, 17, 120, 2]]\n", + "my_pipeline.predict(my_test)" + ], + "id": "7e3c820b-6b42-4904-b7de-41b58aa98dd2" + }, + { + "id": "55719c87", + "cell_type": "markdown", + "source": "## 8.4 \u5165\u529b\u5909\u6570\u306e\u6570\u3068\u30e2\u30c7\u30eb\u306e\u826f\u3055", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "from sklearn.linear_model import LinearRegression\n", + "from sklearn.metrics import mean_squared_error\n", + "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", + "\n", + "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", + " '/fromzero/master/data/wine.csv')\n", + "my_data = pd.read_csv(my_url)\n", + "\n", + "n = len(my_data)\n", + "my_data2 = my_data.assign(v1=[i % 2 for i in range(n)],\n", + " v2=[i % 3 for i in range(n)])\n", + "my_data2.head()" + ], + "id": "42a49ec2-d496-4627-970d-7c0bb0f49ce3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "X, y = my_data2.drop(columns=['LPRICE2']), my_data2['LPRICE2']\n", + "my_model2 = LinearRegression().fit(X, y)\n", + "\n", + "y_ = my_model2.predict(X)\n", + "mean_squared_error(y_, y)**0.5\n", + "\n", + "my_scores = cross_val_score(my_model2, X, y,\n", + " cv=LeaveOneOut(),\n", + " scoring='neg_mean_squared_error')\n", + "(-my_scores.mean())**0.5" + ], + "id": "44a28503-c35a-4bf1-acf9-fef76cc770fd" + }, + { + "id": "e7bde378", + "cell_type": "markdown", + "source": "## 8.5 \u5909\u6570\u9078\u629e", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "from sklearn.feature_selection import SequentialFeatureSelector\n", + "from sklearn.linear_model import LinearRegression\n", + "from sklearn.model_selection import GridSearchCV, LeaveOneOut\n", + "from sklearn.pipeline import Pipeline\n", + "\n", + "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", + " '/fromzero/master/data/wine.csv')\n", + "my_data = pd.read_csv(my_url)\n", + "\n", + "n = len(my_data)\n", + "my_data2 = my_data.assign(v1=[i % 2 for i in range(n)],\n", + " v2=[i % 3 for i in range(n)])\n", + "X, y = my_data2.drop(columns=['LPRICE2']), my_data2['LPRICE2']" + ], + "id": "2b3e0ef3-4833-46d0-9676-0bb2ef4f26b0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_sfs = SequentialFeatureSelector(\n", + " estimator=LinearRegression(),\n", + " direction='forward', # \u5909\u6570\u5897\u52a0\u6cd5\n", + " cv=LeaveOneOut(),\n", + " scoring='neg_mean_squared_error')\n", + "\n", + "my_pipeline = Pipeline([ # \u5909\u6570\u9078\u629e\u306e\u5f8c\u3067\u518d\u8a13\u7df4\u3092\u884c\u3046\u3088\u3046\u306b\u3059\u308b\uff0e\n", + " ('sfs', my_sfs), # \u5909\u6570\u9078\u629e\n", + " ('lr', LinearRegression())]) # \u56de\u5e30\u5206\u6790\n", + "\n", + "my_params = {'sfs__n_features_to_select': range(1, 6)} # \u9078\u629e\u3059\u308b\u5909\u6570\u306e\u4e0a\u9650\n", + "my_search = GridSearchCV(estimator=my_pipeline,\n", + " param_grid=my_params,\n", + " cv=LeaveOneOut(),\n", + " scoring='neg_mean_squared_error',\n", + " n_jobs=-1).fit(X, y)\n", + "my_model = my_search.best_estimator_ # \u6700\u826f\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u3067\u518d\u8a13\u7df4\u3057\u305f\u30e2\u30c7\u30eb\n", + "my_search.best_estimator_.named_steps.sfs.get_support()" + ], + "id": "d39fe0ab-cee9-4b44-aa09-abb013d14ce3" + }, + { + "id": "6e104b12", + "cell_type": "markdown", + "source": "## 8.6 \u88dc\u8db3\uff1a\u6b63\u5247\u5316", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import warnings\n", + "from sklearn.exceptions import ConvergenceWarning\n", + "from sklearn.linear_model import ElasticNet, enet_path\n", + "from sklearn.model_selection import GridSearchCV, LeaveOneOut\n", + "from sklearn.pipeline import Pipeline\n", + "from sklearn.preprocessing import StandardScaler\n", + "from scipy.stats import zscore\n", + "warnings.simplefilter('ignore', ConvergenceWarning) # \u3053\u308c\u4ee5\u964d\uff0c\u8b66\u544a\u3092\u8868\u793a\u3057\u306a\u3044\uff0e\n", + "\n", + "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", + " '/fromzero/master/data/wine.csv')\n", + "my_data = pd.read_csv(my_url)\n", + "X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2']" + ], + "id": "ff05d1ad-204f-41f0-a2fd-d14a586264e8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "A = 2\n", + "B = 0.1\n", + "\n", + "my_pipeline = Pipeline([\n", + " ('sc', StandardScaler()),\n", + " ('enet', ElasticNet(\n", + " alpha=A,\n", + " l1_ratio=B))])\n", + "my_pipeline.fit(X, y)" + ], + "id": "3d310e99-02e8-4446-bf94-31a5098741e8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_enet = my_pipeline.named_steps.enet\n", + "my_enet.intercept_\n", + "\n", + "pd.Series(my_enet.coef_,\n", + " index=X.columns)" + ], + "id": "01507b97-a11b-4901-9731-2603a3be9765" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_test = pd.DataFrame(\n", + " [[500, 17, 120, 2]])\n", + "my_pipeline.predict(my_test)" + ], + "id": "159cb702-9919-4943-a9cf-8ce03be25753" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "As = np.e**np.arange(2, -5.5, -0.1)\n", + "B = 0.1\n", + "\n", + "_, my_path, _ = enet_path(\n", + " zscore(X), zscore(y),\n", + " alphas=As,\n", + " l1_ratio=B)\n", + "\n", + "pd.DataFrame(\n", + " my_path.T,\n", + " columns=X.columns,\n", + " index=np.log(As)\n", + ").plot(\n", + " xlabel='log A ( = log alpha)',\n", + " ylabel='Coefficients')" + ], + "id": "8274de19-d177-47a3-86f8-ef0c560a471c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "As = np.linspace(0, 0.1, 21)\n", + "Bs = np.linspace(0, 0.1, 6)\n", + "\n", + "my_pipeline = Pipeline([('sc', StandardScaler()),\n", + " ('enet', ElasticNet())])\n", + "my_search = GridSearchCV(\n", + " estimator=my_pipeline,\n", + " param_grid={'enet__alpha': As, 'enet__l1_ratio': Bs},\n", + " cv=LeaveOneOut(),\n", + " scoring='neg_mean_squared_error',\n", + " n_jobs=-1).fit(X, y)\n", + "my_model = my_search.best_estimator_ # \u6700\u826f\u30e2\u30c7\u30eb\n", + "\n", + "my_search.best_params_ # \u6700\u826f\u30d1\u30e9\u30e1\u30fc\u30bf" + ], + "id": "b500843a-b327-4431-a331-38a49fe76f8b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = my_search.cv_results_ # \u30c1\u30e5\u30fc\u30cb\u30f3\u30b0\u306e\u8a73\u7d30\n", + "my_scores = (-tmp['mean_test_score'])**0.5 # RMSE\n", + "\n", + "my_results = pd.DataFrame(tmp['params']).assign(RMSE=my_scores).pivot(\n", + " index='enet__alpha',\n", + " columns='enet__l1_ratio',\n", + " values='RMSE')\n", + "\n", + "my_results.plot(style='o-', xlabel='A ( = alpha)', ylabel='RMSE').legend(\n", + " title='B ( = l1_ratio)')" + ], + "id": "f4d84786-f702-4fb2-b50e-210b00043006" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "(-my_search.best_score_)**0.5" + ], + "id": "7fcedc2d-b3c0-4af0-b4fc-98afda960671" + }, + { + "id": "c83869f1", + "cell_type": "markdown", + "source": "## 8.7 \u30cb\u30e5\u30fc\u30e9\u30eb\u30cd\u30c3\u30c8\u30ef\u30fc\u30af", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "x = np.linspace(-6, 6, 100)\n", + "y = 1 / (1 + np.exp(-x))\n", + "plt.plot(x, y)" + ], + "id": "26273a0e-ad7c-4297-bd24-83372af1cff5" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import warnings\n", + "from sklearn.exceptions import ConvergenceWarning\n", + "from sklearn.neural_network import MLPRegressor\n", + "from sklearn.model_selection import cross_val_score, GridSearchCV, LeaveOneOut\n", + "from sklearn.pipeline import Pipeline\n", + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", + " '/fromzero/master/data/wine.csv')\n", + "my_data = pd.read_csv(my_url)\n", + "X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2']" + ], + "id": "2141ddd0-f440-4360-b879-f0f58b245e30" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "warnings.simplefilter(\"ignore\", ConvergenceWarning) # \u3053\u308c\u4ee5\u964d\uff0c\u8b66\u544a\u3092\u8868\u793a\u3057\u306a\u3044\uff0e\n", + "my_pipeline = Pipeline([('sc', StandardScaler()), # \u6a19\u6e96\u5316\n", + " ('mlp', MLPRegressor())]) # \u30cb\u30e5\u30fc\u30e9\u30eb\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\n", + "my_pipeline.fit(X, y) # \u8a13\u7df4\n", + "\n", + "my_scores = cross_val_score(my_pipeline, X, y, cv=LeaveOneOut(),\n", + " scoring='neg_mean_squared_error')\n", + "warnings.simplefilter(\"default\", ConvergenceWarning) # \u3053\u308c\u4ee5\u964d\uff0c\u8b66\u544a\u3092\u8868\u793a\u3059\u308b\uff0e" + ], + "id": "d90296e4-c1ca-4d12-b248-317a5dda75c8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "(-my_scores.mean())**0.5" + ], + "id": "ba66e33a-84b2-4358-90ad-1a1c94aeb56f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_pipeline = Pipeline([\n", + " ('sc', StandardScaler()),\n", + " ('mlp', MLPRegressor(tol=1e-5, # \u6539\u5584\u3057\u305f\u3068\u898b\u306a\u3059\u57fa\u6e96\n", + " max_iter=5000))]) # \u6539\u5584\u3057\u306a\u304f\u306a\u308b\u307e\u3067\u306e\u53cd\u5fa9\u6570\n", + "my_layers = (1, 3, 5, # \u96a0\u308c\u5c641\u5c64\u306e\u5834\u5408\n", + " (1, 1), (3, 1), (5, 1), (1, 2), (3, 2), (5, 2)) # \u96a0\u308c\u5c642\u5c64\u306e\u5834\u5408\n", + "my_params = {'mlp__hidden_layer_sizes': my_layers}\n", + "my_search = GridSearchCV(estimator=my_pipeline,\n", + " param_grid=my_params,\n", + " cv=LeaveOneOut(),\n", + " scoring='neg_mean_squared_error',\n", + " n_jobs=-1).fit(X, y)\n", + "my_model = my_search.best_estimator_ # \u6700\u826f\u30e2\u30c7\u30eb\n", + "\n", + "my_search.best_params_ # \u6700\u826f\u30d1\u30e9\u30e1\u30fc\u30bf" + ], + "id": "41250394-ca13-4ba3-9155-d359a8f596e5" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "(-my_search.best_score_)**0.5" + ], + "id": "232dbe2a-fb9e-4597-9f7e-812a4e5d0a74" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + } +} \ No newline at end of file diff --git a/code/Python-notebook/python-09.ipynb b/code/Python-notebook/python-09.ipynb new file mode 100644 index 0000000..2826ef7 --- /dev/null +++ b/code/Python-notebook/python-09.ipynb @@ -0,0 +1,408 @@ +{ + "cells": [ + { + "id": "c9d18c9f", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)\n\n\n", + "metadata": {} + }, + { + "id": "f6d8c4b7", + "cell_type": "markdown", + "source": "## 9.1 \u30a2\u30e4\u30e1\u306e\u30c7\u30fc\u30bf", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import statsmodels.api as sm\n", + "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", + "my_data.head()" + ], + "id": "d6df8abf-5fa5-41a4-8cd0-e670345e225b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data.describe()\n", + "# \u4ee5\u4e0b\u7701\u7565" + ], + "id": "33ac160a-7c32-4fc3-987e-56360331f1f9" + }, + { + "id": "82983ac8", + "cell_type": "markdown", + "source": "## 9.2 \u6728\u306b\u3088\u308b\u5206\u985e", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import graphviz\n", + "import pandas as pd\n", + "import statsmodels.api as sm\n", + "from sklearn import tree\n", + "\n", + "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", + "X, y = my_data.iloc[:, 0:4], my_data.Species\n", + "\n", + "my_model = tree.DecisionTreeClassifier(max_depth=2, random_state=0)\n", + "my_model.fit(X, y)" + ], + "id": "566d3e54-807f-4c3e-ae42-0b543bac75c3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_dot = tree.export_graphviz(\n", + " decision_tree=my_model,\n", + " out_file=None, # \u30d5\u30a1\u30a4\u30eb\u306b\u51fa\u529b\u3057\u306a\u3044\uff0e\n", + " feature_names=X.columns, # \u5909\u6570\u540d\n", + " class_names=my_model.classes_, # \u30ab\u30c6\u30b4\u30ea\u540d\n", + " filled=True) # \u8272\u3092\u5857\u308b\uff0e\n", + "graphviz.Source(my_dot)" + ], + "id": "db738ed7-250a-4c3d-a93b-34af9ed3a536" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_test = pd.DataFrame([[5.0, 3.5, 1.5, 0.5],\n", + " [6.5, 3.0, 5.0, 2.0]])\n", + "my_model.predict(my_test)" + ], + "id": "93644510-f970-43d2-9843-ee6da419bd78" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pd.DataFrame(\n", + " my_model.predict_proba(my_test),\n", + " columns=my_model.classes_)" + ], + "id": "d2bb87a4-53f9-4595-abc8-2308e3efd846" + }, + { + "id": "0b646067", + "cell_type": "markdown", + "source": "## 9.3 \u6b63\u89e3\u7387", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import graphviz\n", + "import pandas as pd\n", + "import statsmodels.api as sm\n", + "from sklearn import tree\n", + "from sklearn.metrics import confusion_matrix\n", + "from sklearn.model_selection import cross_val_score, GridSearchCV, LeaveOneOut\n", + "\n", + "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", + "X, y = my_data.iloc[:, 0:4], my_data.Species\n", + "\n", + "my_model = tree.DecisionTreeClassifier(max_depth=2, random_state=0).fit(X, y)\n", + "y_ = my_model.predict(X)\n", + "confusion_matrix(y_true=y, y_pred=y_)" + ], + "id": "6babbf8e-c4d3-46b0-8092-cc8477293fbe" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model.score(X, y)\n", + "# \u3042\u308b\u3044\u306f\n", + "y_ = my_model.predict(X)\n", + "(y_ == y).mean()\n" + ], + "id": "b1c39e62-929e-4bc4-aeca-40f2ff5a394c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cross_val_score(my_model, X, y, cv=LeaveOneOut()).mean()" + ], + "id": "fce4f9c7-bd9a-470c-bbc5-50fa3006ffcd" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_search = GridSearchCV(estimator=tree.DecisionTreeClassifier(random_state=0),\n", + " param_grid={'max_depth': range(1, 11)},\n", + " cv=LeaveOneOut(),\n", + " n_jobs=-1).fit(X, y)\n", + "my_search.best_params_, my_search.best_score_" + ], + "id": "af0691f9-80fd-4695-a218-dccf202a5058" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_params = {\n", + " 'max_depth': range(2, 6),\n", + " 'min_samples_split': [2, 20],\n", + " 'min_samples_leaf': range(1, 8)}\n", + "\n", + "my_search = GridSearchCV(\n", + " estimator=tree.DecisionTreeClassifier(min_impurity_decrease=0.01,\n", + " random_state=0),\n", + " param_grid=my_params,\n", + " cv=LeaveOneOut(),\n", + " n_jobs=-1).fit(X, y)\n", + "my_search.best_params_, my_search.best_score_\n", + "\n", + "tmp = my_search.cv_results_\n", + "my_results = pd.DataFrame(tmp['params']).assign(\n", + " Accuracy=tmp['mean_test_score'])\n", + "# \u6b63\u89e3\u7387\uff08\u691c\u8a3c\uff09\u306e\u6700\u5927\u5024\n", + "my_results[my_results.Accuracy == my_results.Accuracy.max()]" + ], + "id": "53f6bf8c-db80-4d7c-ac5f-2bd2d14ec43f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model = my_search.best_estimator_\n", + "my_dot = tree.export_graphviz(\n", + " decision_tree=my_model,\n", + " out_file=None,\n", + " feature_names=X.columns,\n", + " class_names=my_model.classes_,\n", + " filled=True)\n", + "graphviz.Source(my_dot)" + ], + "id": "990bc1c2-195d-4560-b9e9-b43c16e0c869" + }, + { + "id": "88bdbb58", + "cell_type": "markdown", + "source": "## 9.4 \u8907\u6570\u306e\u6728\u3092\u4f7f\u3046\u65b9\u6cd5", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import statsmodels.api as sm\n", + "import warnings\n", + "import xgboost\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.model_selection import GridSearchCV, LeaveOneOut\n", + "from sklearn.preprocessing import LabelEncoder\n", + "\n", + "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", + "X, y = my_data.iloc[:, 0:4], my_data.Species\n", + "label_encoder = LabelEncoder(); y = label_encoder.fit_transform(y)\n", + "\n", + "my_search = GridSearchCV(RandomForestClassifier(),\n", + " param_grid={'max_features': [2, 3, 4]},\n", + " cv=LeaveOneOut(),\n", + " n_jobs=-1).fit(X, y)\n", + "my_search.best_params_\n", + "\n", + "my_search.cv_results_['mean_test_score']" + ], + "id": "c12abad3-6992-4a9f-8c12-7b981ef83cb0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "warnings.simplefilter('ignore') # \u3053\u308c\u4ee5\u964d\uff0c\u8b66\u544a\u3092\u8868\u793a\u3057\u306a\u3044\uff0e\n", + "my_search = GridSearchCV(\n", + " xgboost.XGBClassifier(eval_metric='mlogloss'),\n", + " param_grid={'n_estimators' : [50, 100, 150],\n", + " 'max_depth' : [1, 2, 3],\n", + " 'learning_rate' : [0.3, 0.4],\n", + " 'gamma' : [0],\n", + " 'colsample_bytree': [0.6, 0.8],\n", + " 'min_child_weight': [1],\n", + " 'subsample' : [0.5, 0.75, 1]},\n", + " cv=5, # 5\u5206\u5272\u4ea4\u5dee\u691c\u8a3c\n", + " n_jobs=1).fit(X, y) # n_jobs=-1\u3067\u306f\u306a\u3044\uff0e\n", + "warnings.simplefilter('default') # \u3053\u308c\u4ee5\u964d\uff0c\u8b66\u544a\u3092\u8868\u793a\u3059\u308b\uff0e\n", + "\n", + "my_search.best_params_\n", + "\n", + "my_search.best_score_" + ], + "id": "f16bc88c-de25-45fd-99ae-07353bd34a6d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model = RandomForestClassifier().fit(X, y)\n", + "tmp = pd.Series(my_model.feature_importances_, index=X.columns)\n", + "tmp.sort_values().plot(kind='barh')" + ], + "id": "29212a7f-0767-43b2-9b56-97f324c12a67" + }, + { + "id": "fc300f9c", + "cell_type": "markdown", + "source": "## 9.5 \u6b20\u640d\u306e\u3042\u308b\u30c7\u30fc\u30bf\u3067\u306e\u5b66\u7fd2", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import statsmodels.api as sm\n", + "import warnings\n", + "import xgboost\n", + "from sklearn import tree\n", + "from sklearn.impute import SimpleImputer\n", + "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", + "from sklearn.pipeline import Pipeline\n", + "\n", + "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", + "\n", + "n = len(my_data)\n", + "my_data['Petal.Length'] = [np.nan if i % 10 == 0 else\n", + " my_data['Petal.Length'][i] for i in range(n)]\n", + "my_data['Petal.Width'] = [np.nan if i % 10 == 1 else\n", + " my_data['Petal.Width'][i] for i in range(n)]\n", + "\n", + "my_data.describe() # count\u306e\u5024\u304c135\u306e\u5909\u6570\u306b\uff0c150-135=15\u500b\u306e\u6b20\u640d\u304c\u3042\u308b\uff0e\n", + "# \u4ee5\u4e0b\u7701\u7565\n", + "\n", + "X, y = my_data.iloc[:, 0:4], my_data.Species" + ], + "id": "dc3d0646-ca8e-4cc4-b2b1-56b3a8bf7773" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_pipeline = Pipeline([\n", + " ('imputer', SimpleImputer(strategy='median')), # \u6b20\u640d\u3092\u4e2d\u592e\u5024\u3067\u57cb\u3081\u308b\uff0e\n", + " ('tree', tree.DecisionTreeClassifier(random_state=0))])\n", + "my_scores = cross_val_score(my_pipeline, X, y, cv=LeaveOneOut(), n_jobs=-1)\n", + "my_scores.mean()" + ], + "id": "b4f36167-4af4-4406-9d04-0946efc826ad" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.preprocessing import LabelEncoder\n", + "label_encoder = LabelEncoder()\n", + "y = label_encoder.fit_transform(y)\n", + "\n", + "warnings.simplefilter('ignore') # \u3053\u308c\u4ee5\u964d\uff0c\u8b66\u544a\u3092\u8868\u793a\u3057\u306a\u3044\uff0e\n", + "my_scores = cross_val_score(\n", + " xgboost.XGBClassifier(eval_metric='mlogloss'), X, y, cv=5)\n", + "warnings.simplefilter('default') # \u3053\u308c\u4ee5\u964d\uff0c\u8b66\u544a\u3092\u8868\u793a\u3059\u308b\uff0e\n", + "\n", + "my_scores.mean()" + ], + "id": "07051d50-6d4c-4b3a-9e18-6a8d8a0d1664" + }, + { + "id": "045f29ad", + "cell_type": "markdown", + "source": "## 9.6 \u4ed6\u306e\u5206\u985e\u624b\u6cd5", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import statsmodels.api as sm\n", + "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", + "from sklearn.neighbors import KNeighborsClassifier\n", + "\n", + "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", + "X, y = my_data.iloc[:, 0:4], my_data.Species\n", + "\n", + "my_scores = cross_val_score(KNeighborsClassifier(), X, y, cv=LeaveOneOut())\n", + "my_scores.mean()" + ], + "id": "cd214059-608a-49e1-85bd-f7eb812673a7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import statsmodels.api as sm\n", + "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", + "from sklearn.neural_network import MLPClassifier\n", + "from sklearn.pipeline import Pipeline\n", + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "my_data = sm.datasets.get_rdataset('iris', 'datasets').data\n", + "X, y = my_data.iloc[:, 0:4], my_data.Species\n", + "\n", + "my_pipeline = Pipeline([('sc', StandardScaler()), # \u6a19\u6e96\u5316\n", + " ('mlp', MLPClassifier(max_iter=1000))]) # \u30cb\u30e5\u30fc\u30e9\u30eb\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\n", + "my_scores = cross_val_score(my_pipeline, X, y, cv=LeaveOneOut(), n_jobs=-1)\n", + "my_scores.mean()" + ], + "id": "e1849eeb-6ea8-42f1-9a07-3457cdccdb2c" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + } +} \ No newline at end of file diff --git a/code/Python-notebook/python-10.ipynb b/code/Python-notebook/python-10.ipynb new file mode 100644 index 0000000..7ccc97b --- /dev/null +++ b/code/Python-notebook/python-10.ipynb @@ -0,0 +1,328 @@ +{ + "cells": [ + { + "id": "cb58a113", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)\n\n\n", + "metadata": {} + }, + { + "id": "ec7159e5", + "cell_type": "markdown", + "source": "## 10.1 2\u5024\u5206\u985e\u306e\u6027\u80fd\u6307\u6a19", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from sklearn.metrics import classification_report, confusion_matrix\n", + "\n", + "y = np.array([ 0, 1, 1, 0, 1, 0, 1, 0, 0, 1])\n", + "y_score = np.array([0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5])" + ], + "id": "f5f37e01-ff9c-492c-bc6b-2ed278224c33" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_ = np.array([1 if 0.5 <= p else 0 for p in y_score])\n", + "y_" + ], + "id": "096f24b8-ec94-488c-ac25-ff5ffb75f698" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "confusion_matrix(y_true=y, y_pred=y_)\n", + "\n", + "print(classification_report(y_true=y, y_pred=y_))" + ], + "id": "0b713878-a58b-434e-b788-a16486627922" + }, + { + "id": "e2ec4071", + "cell_type": "markdown", + "source": "## 10.2 \u30c8\u30ec\u30fc\u30c9\u30aa\u30d5", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from sklearn.metrics import (roc_curve, RocCurveDisplay,\n", + " precision_recall_curve, PrecisionRecallDisplay, auc)\n", + "\n", + "y = np.array([ 0, 1, 1, 0, 1, 0, 1, 0, 0, 1])\n", + "y_score = np.array([0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5])\n", + "y_ = np.array([1 if 0.5 <= p else 0 for p in y_score])\n", + "\n", + "[sum((y == 0) & (y_ == 1)) / sum(y == 0), # FPR\n", + " sum((y == 1) & (y_ == 1)) / sum(y == 1)] # TPR" + ], + "id": "1dabc51c-cd7d-4205-959b-048bb843c178" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_fpr, my_tpr, _ = roc_curve(y_true=y,\n", + " y_score=y_score,\n", + " pos_label=1) # 1\u304c\u967d\u6027\u3067\u3042\u308b\uff0e\n", + "RocCurveDisplay(fpr=my_fpr, tpr=my_tpr).plot()" + ], + "id": "0557e598-53c2-4317-b61e-246e851eb1a2" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "auc(x=my_fpr, y=my_tpr)" + ], + "id": "ae9d2889-a187-4ce5-8c3c-7b19563e4ddb" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "[sum((y == 1) & (y_ == 1)) / sum(y == 1), # Recall == TPR\n", + " sum((y == 1) & (y_ == 1)) / sum(y_ == 1)] # Precision" + ], + "id": "3da1c693-fe9a-47e5-abe7-46c304e16618" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_precision, my_recall, _ = precision_recall_curve(y_true=y,\n", + " probas_pred=y_score,\n", + " pos_label=1)\n", + "PrecisionRecallDisplay(precision=my_precision, recall=my_recall).plot()" + ], + "id": "c7762e14-5473-4458-8ea4-030404dbb764" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "auc(x=my_recall, y=my_precision)" + ], + "id": "a7faf537-a3e2-479a-82c6-9afe272b10ac" + }, + { + "id": "013d4fff", + "cell_type": "markdown", + "source": "## 10.3 \u30bf\u30a4\u30bf\u30cb\u30c3\u30af", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import graphviz\n", + "import pandas as pd\n", + "from sklearn import tree\n", + "from sklearn.metrics import roc_curve, RocCurveDisplay, auc\n", + "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", + "from sklearn.pipeline import Pipeline\n", + "from sklearn.preprocessing import OneHotEncoder\n", + "\n", + "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", + " '/fromzero/master/data/titanic.csv')\n", + "my_data = pd.read_csv(my_url)" + ], + "id": "53139119-01c2-4bcf-8a94-1eaf924c0519" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data.head()" + ], + "id": "ad27f676-af23-4e65-a663-0949cdc3de0e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "X, y = my_data.iloc[:, 0:3], my_data.Survived\n", + "\n", + "my_pipeline = Pipeline([\n", + " ('ohe', OneHotEncoder(drop='first')),\n", + " ('tree', tree.DecisionTreeClassifier(max_depth=2, random_state=0,\n", + " min_impurity_decrease=0.01))])\n", + "my_pipeline.fit(X, y)" + ], + "id": "fcdd6ff9-0bda-4383-8158-19f6c843c2a5" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_enc = my_pipeline.named_steps['ohe'] # \u30d1\u30a4\u30d7\u30e9\u30a4\u30f3\u304b\u3089\u30a8\u30f3\u30b3\u30fc\u30c0\u3092\u53d6\u308a\u51fa\u3059\uff0e\n", + "my_tree = my_pipeline.named_steps['tree'] # \u30d1\u30a4\u30d7\u30e9\u30a4\u30f3\u304b\u3089\u6728\u3092\u53d6\u308a\u51fa\u3059\uff0e\n", + "\n", + "my_dot = tree.export_graphviz(\n", + " decision_tree=my_tree,\n", + " out_file=None,\n", + " feature_names=my_enc.get_feature_names() \\\n", + " if hasattr(my_enc, 'get_feature_names') else my_enc.get_feature_names_out(),\n", + " class_names=my_pipeline.classes_,\n", + " filled=True)\n", + "graphviz.Source(my_dot)" + ], + "id": "f4115de4-aef5-4fd8-9c5c-52705e609ee0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_scores = cross_val_score(\n", + " my_pipeline, X, y,\n", + " cv=LeaveOneOut(),\n", + " n_jobs=-1)\n", + "my_scores.mean()" + ], + "id": "859edac8-e7f3-452d-99c8-96199ea7639c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = pd.DataFrame(\n", + " my_pipeline.predict_proba(X),\n", + " columns=my_pipeline.classes_)\n", + "y_score = tmp.Yes\n", + "\n", + "my_fpr, my_tpr, _ = roc_curve(y_true=y,\n", + " y_score=y_score,\n", + " pos_label='Yes')\n", + "my_auc = auc(x=my_fpr, y=my_tpr)\n", + "my_auc\n", + "\n", + "RocCurveDisplay(fpr=my_fpr, tpr=my_tpr, roc_auc=my_auc).plot()" + ], + "id": "87b6ea13-b19a-45d5-b570-f63712957b55" + }, + { + "id": "6898e59a", + "cell_type": "markdown", + "source": "## 10.4 \u30ed\u30b8\u30b9\u30c6\u30a3\u30c3\u30af\u56de\u5e30", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "x = np.arange(-6, 6, 0.1)\n", + "y = 1 / (1 + np.exp(-x))\n", + "plt.plot(x, y)" + ], + "id": "5a269350-29ac-4c8f-b72c-08bc2beb3086" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn.model_selection import cross_val_score, LeaveOneOut\n", + "from sklearn.pipeline import Pipeline\n", + "from sklearn.preprocessing import OneHotEncoder\n", + "\n", + "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", + " '/fromzero/master/data/titanic.csv')\n", + "my_data = pd.read_csv(my_url)\n", + "\n", + "X, y = my_data.iloc[:, 0:3], my_data.Survived\n", + "\n", + "my_pipeline = Pipeline([('ohe', OneHotEncoder(drop='first')),\n", + " ('lr', LogisticRegression(penalty='none'))])\n", + "my_pipeline.fit(X, y)" + ], + "id": "773b7e9e-6790-4f37-a501-353ea7c65db8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_ohe = my_pipeline.named_steps.ohe\n", + "my_lr = my_pipeline.named_steps.lr\n", + "\n", + "my_lr.intercept_[0]\n", + "\n", + "tmp = my_ohe.get_feature_names() \\\n", + "if hasattr(my_ohe, 'get_feature_names') \\\n", + "else my_ohe.get_feature_names_out()\n", + "pd.Series(my_lr.coef_[0],\n", + " index=tmp)" + ], + "id": "96c4c890-2e0b-40f9-a412-c23fdb2a5a83" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_scores = cross_val_score(\n", + " my_pipeline, X, y,\n", + " cv=LeaveOneOut(),\n", + " n_jobs=-1)\n", + "my_scores.mean()" + ], + "id": "49490009-03de-48bb-bc92-a1e53edda684" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + } +} \ No newline at end of file diff --git a/code/Python-notebook/python-11.ipynb b/code/Python-notebook/python-11.ipynb new file mode 100644 index 0000000..f8b2470 --- /dev/null +++ b/code/Python-notebook/python-11.ipynb @@ -0,0 +1,843 @@ +{ + "cells": [ + { + "id": "f475157e", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Google Colaboratory\u306e\u74b0\u5883\u8a2d\u5b9a\n", + "import os\n", + "if 'COLAB_GPU' in os.environ:\n", + " !python -m pip install h2o | tail -n 1" + ], + "id": "76f28522-bde4-4bd7-ba34-3d1ce478a925" + }, + { + "id": "3621b961", + "cell_type": "markdown", + "source": "## 11.1 Keras\u306b\u3088\u308b\u56de\u5e30", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "from keras import activations, callbacks, layers, models\n", + "from sklearn.preprocessing import StandardScaler\n", + "from sklearn.utils import shuffle\n", + "\n", + "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", + " '/fromzero/master/data/wine.csv')\n", + "tmp = pd.read_csv(my_url)" + ], + "id": "c7eb1115-1566-4c44-aed3-d5c801db0669" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data = shuffle(tmp)" + ], + "id": "bad796dc-65bb-47d1-8c14-b6b808fd473c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_scaler = StandardScaler()\n", + "X = my_scaler.fit_transform(\n", + " my_data.drop(columns=['LPRICE2']))\n", + "y = my_data['LPRICE2']" + ], + "id": "bf9cd9f0-260b-4ae6-af33-dfda45e80c0b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = np.linspace(-3, 3, 100)\n", + "plt.plot(x, activations.relu(x))\n", + "plt.xlabel('x')\n", + "plt.ylabel('ReLU(x)')" + ], + "id": "70d8c0e7-4720-4369-b270-ca876c31142e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model = models.Sequential()\n", + "my_model.add(layers.Dense(units=3, activation='relu', input_shape=[4]))\n", + "my_model.add(layers.Dense(units=1))\n", + "\n", + "my_model.summary() # \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u6982\u8981" + ], + "id": "20b299a3-a3a7-4b2c-8ee1-d5029ab7bb84" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model.compile(\n", + " loss='mse',\n", + " optimizer='rmsprop')" + ], + "id": "3c53592d-f926-4966-8050-72f642949690" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_cb = callbacks.EarlyStopping(\n", + " patience=20,\n", + " restore_best_weights=True)" + ], + "id": "68ee505a-ff77-419c-8840-bbe3680eff55" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_history = my_model.fit(\n", + " x=X,\n", + " y=y,\n", + " validation_split=0.25,\n", + " batch_size=10,\n", + " epochs=500,\n", + " callbacks=[my_cb],\n", + " verbose=0)" + ], + "id": "cbcbd802-441e-4c05-a9a6-51b0329cd55f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = pd.DataFrame(my_history.history)\n", + "tmp.plot(xlabel='epoch')" + ], + "id": "66940f93-5404-4ef0-ac7a-489ce21f4f50" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp.iloc[-1, ]" + ], + "id": "2aece778-c9f9-4381-89ee-a6963f2bbec8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_ = my_model.predict(X)\n", + "((y_.ravel() - y)**2).mean()" + ], + "id": "151beafb-25b9-4897-8229-bbe898c0f283" + }, + { + "id": "75d76590", + "cell_type": "markdown", + "source": "## 11.2 Keras\u306b\u3088\u308b\u5206\u985e", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import statsmodels.api as sm\n", + "from keras import callbacks, layers, losses, models\n", + "from sklearn.preprocessing import StandardScaler, LabelEncoder\n", + "from sklearn.utils import shuffle\n", + "\n", + "tmp = sm.datasets.get_rdataset('iris', 'datasets').data\n", + "my_data = shuffle(tmp)" + ], + "id": "de6c595c-f31a-4464-8996-e8047f57ee80" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_scaler = StandardScaler()\n", + "X = my_scaler.fit_transform(\n", + " my_data.drop(columns=['Species']))\n", + "my_enc = LabelEncoder()\n", + "y = my_enc.fit_transform(\n", + " my_data['Species'])" + ], + "id": "2520dd3a-e03b-4400-8923-204370b86e77" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model = models.Sequential()\n", + "my_model.add(layers.Dense(units=3, activation='relu', input_shape=[4]))\n", + "my_model.add(layers.Dense(units=3, activation='softmax'))" + ], + "id": "c1fcfd05-7625-41f6-82e2-a2f6a70d9cbd" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model.compile(loss='sparse_categorical_crossentropy',\n", + " optimizer='rmsprop',\n", + " metrics=['accuracy'])" + ], + "id": "2a0dea78-cb86-4197-ae6c-0b29a35c13b3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_cb = callbacks.EarlyStopping(\n", + " patience=20,\n", + " restore_best_weights=True)\n", + "\n", + "my_history = my_model.fit(\n", + " x=X,\n", + " y=y,\n", + " validation_split=0.25,\n", + " batch_size=10,\n", + " epochs=500,\n", + " callbacks=[my_cb],\n", + " verbose=0)\n", + "\n", + "tmp = pd.DataFrame(my_history.history)\n", + "tmp.plot(xlabel='epoch')" + ], + "id": "9062bdef-caf5-49f0-a7fc-32c7d3a97865" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp.iloc[-1, ]" + ], + "id": "1e5c97e9-13f9-4408-90c8-763e9f8c3014" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = my_model.predict(X)\n", + "y_ = np.argmax(tmp, axis=-1)\n", + "(y_ == y).mean()" + ], + "id": "207c5ffd-c03d-4e0e-84f1-2c9d7493e517" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "-np.log([0.8, 0.7, 0.3, 0.8]).mean()\n", + "\n", + "-np.log([0.7, 0.6, 0.2, 0.7]).mean()" + ], + "id": "f427ea71-d3ad-4a8e-bbf1-3e0696b6d7fc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y = [2, 1, 0, 1]\n", + "y_1 = [[0.1, 0.1, 0.8],\n", + " [0.1, 0.7, 0.2],\n", + " [0.3, 0.4, 0.3],\n", + " [0.1, 0.8, 0.1]]\n", + "y_2 = [[0.1, 0.2, 0.7],\n", + " [0.2, 0.6, 0.2],\n", + " [0.2, 0.5, 0.3],\n", + " [0.2, 0.7, 0.1]]" + ], + "id": "771ad4e2-a71c-4907-8606-25f6d3f761bc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "[losses.sparse_categorical_crossentropy(y_true=y, y_pred=y_1).numpy().mean(),\n", + " losses.sparse_categorical_crossentropy(y_true=y, y_pred=y_2).numpy().mean()]" + ], + "id": "d3eb32c5-6c7f-404c-860d-28e71fb98d82" + }, + { + "id": "79fe570e", + "cell_type": "markdown", + "source": "## 11.3 MNIST\uff1a\u624b\u66f8\u304d\u6570\u5b57\u306e\u5206\u985e", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "import tensorflow as tf\n", + "from random import sample\n", + "from keras import callbacks, layers, models\n", + "from sklearn.metrics import confusion_matrix\n", + "\n", + "(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()" + ], + "id": "421d470b-3b07-4be9-81ff-fba6ee4d8508" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x_train.shape" + ], + "id": "95f9497e-df90-4c20-a2f4-12fd3a98f069" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "np.set_printoptions(linewidth=170)\n", + "x_train[4, :, :]" + ], + "id": "7fbfb4d3-a8ea-4d3b-a3d4-a31e2500efb7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.matshow(x_train[4, :, :])" + ], + "id": "99c23b51-ddfa-40cb-b240-6ef9278917f4" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_train" + ], + "id": "6202e610-42b3-42f2-b620-6722740c89b2" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x_train.min(), x_train.max()" + ], + "id": "96fa1972-5840-4d01-b1ce-52f1c71ca6e6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x_train = x_train / 255\n", + "x_test = x_test / 255" + ], + "id": "caecf192-d2d6-4b1c-ba8f-81edd451ddc4" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_index = sample(range(60000), 6000)\n", + "x_train = x_train[my_index, :, :]\n", + "y_train = y_train[my_index]" + ], + "id": "2cca75bc-e6e2-47ff-af49-203247f3408f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model = models.Sequential()\n", + "my_model.add(layers.Flatten(input_shape=[28, 28]))\n", + "my_model.add(layers.Dense(units=256, activation=\"relu\"))\n", + "my_model.add(layers.Dense(units=10, activation=\"softmax\"))\n", + "\n", + "my_model.summary()\n", + "\n", + "my_model.compile(loss='sparse_categorical_crossentropy',\n", + " optimizer='rmsprop',\n", + " metrics=['accuracy'])\n", + "\n", + "my_cb = callbacks.EarlyStopping(patience=5, restore_best_weights=True)" + ], + "id": "c78e18ee-5a37-4bdc-84f7-fd99f890048d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_history = my_model.fit(\n", + " x=x_train,\n", + " y=y_train,\n", + " validation_split=0.2,\n", + " batch_size=128,\n", + " epochs=20,\n", + " callbacks=[my_cb],\n", + " verbose=0)\n", + "\n", + "tmp = pd.DataFrame(my_history.history)\n", + "tmp.plot(xlabel='epoch', style='o-')" + ], + "id": "c940040a-de6c-4f04-ab48-db90956356d2" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = my_model.predict(x_test)\n", + "y_ = np.argmax(tmp, axis=-1)\n", + "confusion_matrix(y_true=y_test,\n", + " y_pred=y_)" + ], + "id": "f6b8338e-e001-45dc-aaf5-5a4b5edd8f24" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [], + "id": "a6a69c51-fa45-4b93-a915-72395ac57a81" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "(y_ == y_test).mean()" + ], + "id": "33e075c8-529e-448d-8c29-5e852cc6f81f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model.evaluate(x=x_test, y=y_test)" + ], + "id": "06b65589-40dd-45d1-8230-c9bc81aefe81" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x_train2d = x_train.reshape(-1, 28, 28, 1)\n", + "x_test2d = x_test.reshape(-1, 28, 28, 1)" + ], + "id": "888e96fe-1951-4d56-a65f-63a6f4ec6a73" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model = models.Sequential()\n", + "my_model.add(layers.Conv2D(filters=32, kernel_size=3, # \u7573\u307f\u8fbc\u307f\u5c64\n", + " activation='relu',\n", + " input_shape=[28, 28, 1]))\n", + "my_model.add(layers.MaxPooling2D(pool_size=2)) # \u30d7\u30fc\u30ea\u30f3\u30b0\u5c64\n", + "my_model.add(layers.Flatten())\n", + "my_model.add(layers.Dense(128, activation='relu'))\n", + "my_model.add(layers.Dense(10, activation='softmax'))\n", + "\n", + "my_model.summary()\n", + "\n", + "my_model.compile(loss='sparse_categorical_crossentropy',\n", + " optimizer='rmsprop',\n", + " metrics=['accuracy'])\n", + "\n", + "from keras.callbacks import EarlyStopping\n", + "my_cb = EarlyStopping(patience=5,\n", + " restore_best_weights=True)" + ], + "id": "816343aa-548f-4cd3-8329-ce8e12a4f745" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_history = my_model.fit(\n", + " x=x_train2d,\n", + " y=y_train,\n", + " validation_split=0.2,\n", + " batch_size=128,\n", + " epochs=20,\n", + " callbacks=my_cb,\n", + " verbose=0)\n", + "\n", + "tmp = pd.DataFrame(my_history.history)\n", + "tmp.plot(xlabel='epoch', style='o-')" + ], + "id": "155c3521-2c38-448c-bad0-87871ae98246" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model.evaluate(x=x_test2d, y=y_test)" + ], + "id": "a518a13d-5747-47fb-af61-8dc0e48c7351" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model = models.Sequential()\n", + "my_model.add(layers.Conv2D(filters=20, kernel_size=5, activation='relu',\n", + " input_shape=(28, 28, 1)))\n", + "my_model.add(layers.MaxPooling2D(pool_size=2, strides=2))\n", + "my_model.add(layers.Conv2D(filters=20, kernel_size=5, activation='relu'))\n", + "my_model.add(layers.MaxPooling2D(pool_size=2, strides=2))\n", + "my_model.add(layers.Dropout(rate=0.25))\n", + "my_model.add(layers.Flatten())\n", + "my_model.add(layers.Dense(500, activation='relu'))\n", + "my_model.add(layers.Dropout(rate=0.5))\n", + "my_model.add(layers.Dense(10, activation='softmax'))\n", + "\n", + "my_model.compile(loss='sparse_categorical_crossentropy',\n", + " optimizer='rmsprop',\n", + " metrics=['accuracy'])\n", + "\n", + "my_cb = callbacks.EarlyStopping(patience=5,\n", + " restore_best_weights=True)" + ], + "id": "b5619b78-6e33-42a5-b616-5a6c97a3b412" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_history = my_model.fit(\n", + " x=x_train2d,\n", + " y=y_train,\n", + " validation_split=0.2,\n", + " batch_size=128,\n", + " epochs=20,\n", + " callbacks=my_cb,\n", + " verbose=0)\n", + "\n", + "tmp = pd.DataFrame(my_history.history)\n", + "tmp.plot(xlabel='epoch', style='o-')" + ], + "id": "bf421a0c-f653-4a74-90f9-c954b6f32ba0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model.evaluate(x=x_test2d, y=y_test)" + ], + "id": "67f5340a-e0dc-4800-b419-6b4ba06f3494" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_prob = my_model.predict(x_test2d) # \u30ab\u30c6\u30b4\u30ea\u306b\u5c5e\u3059\u308b\u78ba\u7387\n", + "\n", + "tmp = pd.DataFrame({\n", + " 'y_prob': np.max(y_prob, axis=1), # \u78ba\u7387\u306e\u6700\u5927\u5024\n", + " 'y_': np.argmax(y_prob, axis=1), # \u4e88\u6e2c\u30ab\u30c6\u30b4\u30ea\n", + " 'y': y_test, # \u6b63\u89e3\n", + " 'id': range(len(y_test))}) # \u756a\u53f7\n", + "\n", + "tmp = tmp[tmp.y_ != tmp.y] # \u4e88\u6e2c\u304c\u306f\u305a\u308c\u305f\u3082\u306e\u3092\u6b8b\u3059\n", + "my_result = tmp.sort_values('y_prob', ascending=False) # \u78ba\u7387\u306e\u5927\u304d\u3044\u9806\u306b\u4e26\u3073\u66ff\u3048\u308b" + ], + "id": "d79e2a31-9731-409e-88eb-ad7cacc335e2" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_result.head()" + ], + "id": "1997b83d-888c-4c38-9a58-ce7a4e241443" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for i in range(5):\n", + " plt.subplot(1, 5, i + 1)\n", + " ans = my_result['y'].iloc[i]\n", + " id = my_result['id'].iloc[i]\n", + " plt.title(f'{ans} ({id})')\n", + " plt.imshow(x_test[id])\n", + " plt.axis('off')" + ], + "id": "c6a83061-720d-4a12-8929-9102c64a8668" + }, + { + "id": "b15926e8", + "cell_type": "markdown", + "source": "## 11.4 AutoML", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import h2o\n", + "import pandas as pd\n", + "import tensorflow as tf\n", + "from h2o.automl import H2OAutoML\n", + "from random import sample\n", + "\n", + "h2o.init()\n", + "h2o.no_progress()\n", + "# h2o.cluster().shutdown() # \u505c\u6b62" + ], + "id": "05e8f52f-0b29-4ee0-a307-278afcb2af11" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_url = ('https://raw.githubusercontent.com/taroyabuki'\n", + " '/fromzero/master/data/wine.csv')\n", + "my_data = pd.read_csv(my_url)\n", + "my_frame = h2o.H2OFrame(my_data) # \u901a\u5e38\u306e\u30c7\u30fc\u30bf\u30d5\u30ec\u30fc\u30e0\u3092H2OFrame\u306b\u5909\u63db\u3059\u308b\uff0e\n", + "# \u3042\u308b\u3044\u306f\n", + "my_frame = h2o.import_file(my_url, header=1) # \u30c7\u30fc\u30bf\u3092\u8aad\u307f\u8fbc\u3080\uff0e" + ], + "id": "caafbde5-e075-4735-9c37-cd67035dddae" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_frame.head(5)\n", + "\n", + "# \u901a\u5e38\u306e\u30c7\u30fc\u30bf\u30d5\u30ec\u30fc\u30e0\u306b\u623b\u3059\uff0e\n", + "h2o.as_list(my_frame).head()\n", + "# \u7d50\u679c\u306f\u5272\u611b\uff08\u898b\u305f\u76ee\u306f\u540c\u3058\uff09" + ], + "id": "e5c62da6-eba8-46fa-85c2-4caa74ce1d06" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model = H2OAutoML(\n", + " max_runtime_secs=60)\n", + "my_model.train(\n", + " y='LPRICE2',\n", + " training_frame=my_frame)" + ], + "id": "5cdd74dd-e185-4c73-b016-e57b150f305d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model.leaderboard['rmse'].min()" + ], + "id": "b1a03aed-f1c0-4af7-b8b7-97ca35b04b0a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = h2o.as_list(\n", + " my_model.predict(my_frame))\n", + "\n", + "pd.DataFrame({\n", + " 'y': my_data['LPRICE2'],\n", + " 'y_': tmp['predict']}\n", + ").plot('y', 'y_', kind='scatter')" + ], + "id": "f05a4d38-4831-424d-a193-816129b960e0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()\n", + "my_index = sample(range(60000), 6000)\n", + "x_train = x_train[my_index, :, :]\n", + "y_train = y_train[my_index]" + ], + "id": "0fec2ce1-f0ff-4ec1-be66-0146642e2fd4" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = pd.DataFrame(\n", + " x_train.reshape(-1, 28 * 28))\n", + "y = 'y'\n", + "tmp[y] = y_train\n", + "my_train = h2o.H2OFrame(tmp)\n", + "my_train[y] = my_train[y].asfactor()\n", + "\n", + "tmp = pd.DataFrame(\n", + " x_test.reshape(-1, 28 * 28))\n", + "my_test = h2o.H2OFrame(tmp)" + ], + "id": "1b2ee246-6f2b-4df5-a593-52dd519f07a6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model = H2OAutoML(\n", + " max_runtime_secs=120)\n", + "my_model.train(\n", + " y=y,\n", + " training_frame=my_train)" + ], + "id": "84772f57-315c-4f51-9e5a-ffcb5774b182" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model.leaderboard[\n", + " 'mean_per_class_error'].min()" + ], + "id": "5cec46cb-aa21-4ce5-a00d-a0b862b1d54b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = h2o.as_list(\n", + " my_model.predict(my_test))\n", + "y_ = tmp.predict\n", + "\n", + "(y_ == y_test).mean()" + ], + "id": "2e6c8b13-ee1f-42fe-a718-a6e00100eb6e" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + } +} \ No newline at end of file diff --git a/code/Python-notebook/python-12.ipynb b/code/Python-notebook/python-12.ipynb new file mode 100644 index 0000000..e642f5a --- /dev/null +++ b/code/Python-notebook/python-12.ipynb @@ -0,0 +1,280 @@ +{ + "cells": [ + { + "id": "f929dbc4", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Google Colaboratory\u306e\u74b0\u5883\u8a2d\u5b9a\n", + "import os\n", + "if 'COLAB_GPU' in os.environ:\n", + " !python -m pip install pmdarima | tail -n 1" + ], + "id": "fee5c733-fa13-4091-b3b7-57ec2e49846c" + }, + { + "id": "93c783a7", + "cell_type": "markdown", + "source": "## 12.1 \u65e5\u6642\u3068\u65e5\u6642\u306e\u5217", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "pd.to_datetime('2020-01-01')" + ], + "id": "f6a3b489-3bdc-4f12-8ff6-c43a3cc4ac2f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pd.date_range(start='2021-01-01', end='2023-01-01', freq='1A')\n", + "\n", + "pd.date_range(start='2021-01-01', end='2023-01-01', freq='1AS')\n", + "\n", + "pd.date_range(start='2021-01-01', end='2021-03-01', freq='2M')\n", + "\n", + "pd.date_range(start='2021-01-01', end='2021-03-01', freq='2MS')\n", + "\n", + "pd.date_range(start='2021-01-01', end='2021-01-03', freq='1D')\n", + "\n", + "pd.date_range(start='2021-01-01 00:00:00', end='2021-01-01 03:00:00', freq='2H')" + ], + "id": "2eded528-7a9c-4388-87ea-ee894a8bb1c0" + }, + { + "id": "e81b3084", + "cell_type": "markdown", + "source": "## 12.2 \u6642\u7cfb\u5217\u30c7\u30fc\u30bf\u306e\u4e88\u6e2c", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import pandas as pd\n", + "from pmdarima.datasets import airpassengers\n", + "from sklearn.metrics import mean_squared_error\n", + "\n", + "my_data = airpassengers.load_airpassengers()" + ], + "id": "d286ffbe-5337-4857-9ec5-8f7268265d76" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "n = len(my_data) # \u30c7\u30fc\u30bf\u6570\uff08144\uff09\n", + "k = 108 # \u8a13\u7df4\u30c7\u30fc\u30bf\u6570" + ], + "id": "cfe5038c-2732-4f17-b96c-8d9ae9d28a29" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_ds = pd.date_range(\n", + " start='1949/01/01',\n", + " end='1960/12/01',\n", + " freq='MS')\n", + "my_df = pd.DataFrame({\n", + " 'ds': my_ds,\n", + " 'x': range(n),\n", + " 'y': my_data},\n", + " index=my_ds)\n", + "my_df.head()" + ], + "id": "76afb291-9fb7-45fb-9f37-616557159a46" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_train = my_df[ :k]\n", + "my_test = my_df[-(n - k): ]\n", + "y = my_test.y" + ], + "id": "a838edda-d409-4630-9630-678cd33dddd6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.plot(my_train.y, label='train')\n", + "plt.plot(my_test.y, label='test')\n", + "plt.legend()" + ], + "id": "ebba4a39-9a57-4e6b-9044-11e241129a84" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.linear_model import LinearRegression\n", + "\n", + "my_lm_model = LinearRegression()\n", + "my_lm_model.fit(my_train[['x']], my_train.y)\n", + "\n", + "X = my_test[['x']]\n", + "y_ = my_lm_model.predict(X)\n", + "mean_squared_error(y, y_)**0.5 # RMSE\uff08\u30c6\u30b9\u30c8\uff09" + ], + "id": "7be6bbe7-821e-44e6-94f7-914784b71925" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_ = my_lm_model.predict(my_df[['x']])\n", + "tmp = pd.DataFrame(y_,\n", + " index=my_df.index)\n", + "plt.plot(my_train.y, label='train')\n", + "plt.plot(my_test.y, label='test')\n", + "plt.plot(tmp, label='model')\n", + "plt.legend()" + ], + "id": "98d885be-785b-44a7-94c8-5962c9ab2db0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pmdarima as pm\n", + "my_arima_model = pm.auto_arima(my_train.y, m=12, trace=True)" + ], + "id": "2fd25f93-1408-4287-8c46-a92d68f26367" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_, my_ci = my_arima_model.predict(len(my_test), # \u671f\u9593\u306f\u30c6\u30b9\u30c8\u30c7\u30fc\u30bf\u3068\u540c\u3058\uff0e\n", + " alpha=0.05, # \u6709\u610f\u6c34\u6e96\uff08\u30c7\u30d5\u30a9\u30eb\u30c8\uff09\n", + " return_conf_int=True) # \u4fe1\u983c\u533a\u9593\u3092\u6c42\u3081\u308b\uff0e\n", + "tmp = pd.DataFrame({'y': y_,\n", + " 'Lo': my_ci[:, 0],\n", + " 'Hi': my_ci[:, 1]},\n", + " index=my_test.index)\n", + "tmp.head()" + ], + "id": "dea84574-351e-4486-bb78-7ea9e1b374be" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mean_squared_error(y, y_)**0.5" + ], + "id": "ca2e93c7-235d-48c8-830e-73c6089b0062" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.plot(my_train.y, label='train')\n", + "plt.plot(my_test.y, label='test')\n", + "plt.plot(tmp.y, label='model')\n", + "plt.fill_between(tmp.index,\n", + " tmp.Lo,\n", + " tmp.Hi,\n", + " alpha=0.25) # \u4e0d\u900f\u660e\u5ea6\n", + "plt.legend(loc='upper left')" + ], + "id": "9306bac7-d2bc-4c9a-a917-1a250dab51d4" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try: from fbprophet import Prophet\n", + "except ImportError: from prophet import Prophet\n", + "my_prophet_model = Prophet(seasonality_mode='multiplicative')\n", + "my_prophet_model.fit(my_train)" + ], + "id": "5f9d83e5-08aa-43f6-a36a-ae7b0add9178" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = my_prophet_model.predict(my_test)\n", + "tmp[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].head()" + ], + "id": "1296719f-77e5-4daa-a066-8e87e24daa60" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_ = tmp.yhat\n", + "mean_squared_error(y, y_)**0.5" + ], + "id": "a90ed86b-2359-48d3-801f-991ad627c7ad" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# my_prophet_model.plot(tmp) # \u4e88\u6e2c\u7d50\u679c\u306e\u307f\u3067\u3088\u3044\u5834\u5408\n", + "\n", + "fig = my_prophet_model.plot(tmp)\n", + "fig.axes[0].plot(my_train.ds, my_train.y)\n", + "fig.axes[0].plot(my_test.ds, my_test.y, color='red')" + ], + "id": "a8136524-b7aa-4843-9a96-a666aa3d3e16" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + } +} \ No newline at end of file diff --git a/code/Python-notebook/python-13.ipynb b/code/Python-notebook/python-13.ipynb new file mode 100644 index 0000000..92e7862 --- /dev/null +++ b/code/Python-notebook/python-13.ipynb @@ -0,0 +1,316 @@ +{ + "cells": [ + { + "id": "d586a5aa", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Google Colaboratory\u306e\u74b0\u5883\u8a2d\u5b9a\n", + "import os\n", + "if 'COLAB_GPU' in os.environ:\n", + " !python -m pip install pca | tail -n 1" + ], + "id": "7268a47c-b615-4c48-ae49-8bf891f2a368" + }, + { + "id": "35ce3428", + "cell_type": "markdown", + "source": "## 13.1 \u4e3b\u6210\u5206\u5206\u6790", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from pca import pca\n", + "from scipy.stats import zscore\n", + "\n", + "my_data = pd.DataFrame(\n", + " {'language': [ 0, 20, 20, 25, 22, 17],\n", + " 'english': [ 0, 20, 40, 20, 24, 18],\n", + " 'math': [100, 20, 5, 30, 17, 25],\n", + " 'science': [ 0, 20, 5, 25, 16, 23],\n", + " 'society': [ 0, 20, 30, 0, 21, 17]},\n", + " index= ['A', 'B', 'C', 'D', 'E', 'F'])\n", + "my_model = pca(n_components=5)\n", + "my_result = my_model.fit_transform(my_data) # \u4e3b\u6210\u5206\u5206\u6790\u306e\u5b9f\u884c" + ], + "id": "23443165-8c14-4406-83d9-247762c53a6b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_result['PC'] # \u4e3b\u6210\u5206\u30b9\u30b3\u30a2" + ], + "id": "c9f5b58c-1547-430a-a0b3-c63d3f36e717" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model.biplot(legend=False)" + ], + "id": "994967d5-7848-4b1d-b318-08c606e31e9f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_result['loadings']" + ], + "id": "271adc2d-e38f-48d3-90f4-cc53117b5f38" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_result['explained_var']" + ], + "id": "d029a293-6f5f-4e94-972c-a0627aafdcea" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = zscore(my_data, ddof=1) # \u6a19\u6e96\u5316\n", + "my_result = my_model.fit_transform(\n", + " tmp)\n", + "my_result['PC'] # \u4e3b\u6210\u5206\u30b9\u30b3\u30a2" + ], + "id": "bb7354df-54d3-40a8-81fb-97358accfaac" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = my_data - my_data.mean()\n", + "Z = np.matrix(tmp) # \u6a19\u6e96\u5316\u3057\u306a\u3044\u5834\u5408\n", + "#Z = np.matrix(tmp / my_data.std(ddof=1)) # \u221a\u4e0d\u504f\u5206\u6563\u3067\u6a19\u6e96\u5316\u3059\u308b\u5834\u5408\n", + "#Z = np.matrix(tmp / my_data.std(ddof=0)) # pca(normalize=True)\u306b\u5408\u308f\u305b\u308b\u5834\u5408\n", + "\n", + "n = len(my_data)\n", + "S = np.cov(Z, rowvar=0, ddof=0) # \u5206\u6563\u5171\u5206\u6563\u884c\u5217\n", + "#S = Z.T @ Z / n # \uff08\u540c\u3058\u7d50\u679c\uff09\n", + "vals, vecs = np.linalg.eig(S) # \u56fa\u6709\u5024\u3068\u56fa\u6709\u30d9\u30af\u30c8\u30eb\n", + "idx = np.argsort(-vals) # \u56fa\u6709\u5024\u306e\u5927\u304d\u3044\u9806\u306e\u756a\u53f7\n", + "vals, vecs = vals[idx], vecs[:, idx] # \u56fa\u6709\u5024\u306e\u5927\u304d\u3044\u9806\u3067\u306e\u4e26\u3079\u66ff\u3048\n", + "Z @ vecs # \u4e3b\u6210\u5206\u30b9\u30b3\u30a2\uff08\u7d50\u679c\u306f\u5272\u611b\uff09\n", + "vals.cumsum() / vals.sum() # \u7d2f\u7a4d\u5bc4\u4e0e\u7387" + ], + "id": "4fdd8a4c-d9b7-44b2-8d49-8812ca668508" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "U, d, V = np.linalg.svd(Z, full_matrices=False) # \u7279\u7570\u5024\u5206\u89e3\n", + "W = np.diag(d)\n", + "\n", + "[np.isclose(Z, U @ W @ V).all(), # \u78ba\u8a8d1\n", + " np.isclose(U.T @ U, np.identity(U.shape[1])).all(), # \u78ba\u8a8d2\n", + " np.isclose(V @ V.T, np.identity(V.shape[0])).all()] # \u78ba\u8a8d3\n", + "\n", + "U @ W # \u4e3b\u6210\u5206\u30b9\u30b3\u30a2\uff08\u7d50\u679c\u306f\u5272\u611b\uff09\n", + "\n", + "e = d ** 2 / n # \u5206\u6563\u5171\u5206\u6563\u884c\u5217\u306e\u56fa\u6709\u5024\n", + "e.cumsum() / e.sum() # \u7d2f\u7a4d\u5bc4\u4e0e\u7387" + ], + "id": "999335a6-cec8-45a9-a339-7f7b5f50c05f" + }, + { + "id": "0edd0543", + "cell_type": "markdown", + "source": "## 13.2 \u30af\u30e9\u30b9\u30bf\u5206\u6790", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "from scipy.cluster import hierarchy\n", + "\n", + "my_data = pd.DataFrame(\n", + " {'x': [ 0, -16, 10, 10],\n", + " 'y': [ 0, 0, 10, -15]},\n", + " index=['A', 'B', 'C', 'D'])\n", + "\n", + "my_result = hierarchy.linkage(\n", + " my_data,\n", + " metric='euclidean', # \u7701\u7565\u53ef\n", + " method='complete')" + ], + "id": "8191fa32-b362-4aaf-82fb-3ff7cf8b084e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "hierarchy.dendrogram(my_result,\n", + " labels=my_data.index)" + ], + "id": "404eeb42-ff9e-447a-9a1d-a8edab6a3e43" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "hierarchy.cut_tree(my_result, 3)\n", + "\n", + "# \u88dc\u8db3\uff08\u898b\u3084\u3059\u304f\u3059\u308b\uff09\n", + "my_data.assign(cluster=\n", + " hierarchy.cut_tree(my_result, 3))" + ], + "id": "1cf16f5b-6ad3-4263-94ee-5ed0a1be52e7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import seaborn as sns\n", + "\n", + "my_data = pd.DataFrame(\n", + " {'language': [ 0, 20, 20, 25, 22, 17],\n", + " 'english': [ 0, 20, 40, 20, 24, 18],\n", + " 'math': [100, 20, 5, 30, 17, 25],\n", + " 'science': [ 0, 20, 5, 25, 16, 23],\n", + " 'society': [ 0, 20, 30, 0, 21, 17]},\n", + " index= ['A', 'B', 'C', 'D', 'E', 'F'])\n", + "\n", + "sns.clustermap(my_data, z_score=1) # \u5217\u3054\u3068\u306e\u6a19\u6e96\u5316" + ], + "id": "8f02fa55-8739-4bcb-8cbd-3926a26357a7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "from sklearn.cluster import KMeans\n", + "\n", + "my_data = pd.DataFrame(\n", + " {'x': [ 0, -16, 10, 10],\n", + " 'y': [ 0, 0, 10, -15]},\n", + " index=['A', 'B', 'C', 'D'])\n", + "\n", + "my_result = KMeans(\n", + " n_clusters=3).fit(my_data)" + ], + "id": "9a0586d0-99a9-4adc-a037-ee51a3ef61d7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_result.labels_\n", + "\n", + "# \u88dc\u8db3\uff08\u898b\u3084\u3059\u304f\u3059\u308b\uff09\n", + "my_data.assign(\n", + " cluster=my_result.labels_)" + ], + "id": "9b4d930d-b857-417a-a3c3-0d9a56eac5bf" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import statsmodels.api as sm\n", + "from sklearn.cluster import KMeans\n", + "\n", + "iris = sm.datasets.get_rdataset('iris', 'datasets').data\n", + "my_data = iris.iloc[:, 0:4]\n", + "\n", + "k = range(1, 11)\n", + "my_df = pd.DataFrame({\n", + " 'k': k,\n", + " 'inertia': [KMeans(k).fit(my_data).inertia_ for k in range(1, 11)]})\n", + "my_df.plot(x='k', style='o-', legend=False)" + ], + "id": "e90bfa72-b22f-4376-ba79-92353f1f3324" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import seaborn as sns\n", + "import statsmodels.api as sm\n", + "from pca import pca\n", + "from scipy.cluster import hierarchy\n", + "from scipy.stats import zscore\n", + "from sklearn.cluster import KMeans\n", + "\n", + "iris = sm.datasets.get_rdataset('iris', 'datasets').data\n", + "my_data = zscore(iris.iloc[:, 0:4])\n", + "\n", + "my_model = pca() # \u4e3b\u6210\u5206\u5206\u6790\n", + "my_result = my_model.fit_transform(my_data)['PC']\n", + "my_result['Species'] = list(iris.Species)\n", + "\n", + "# \u975e\u968e\u5c64\u7684\u30af\u30e9\u30b9\u30bf\u5206\u6790\u306e\u5834\u5408\n", + "my_result['cluster'] = KMeans(n_clusters=3).fit(my_data).labels_\n", + "\n", + "# \u968e\u5c64\u7684\u30af\u30e9\u30b9\u30bf\u5206\u6790\u306e\u5834\u5408\n", + "#my_result['cluster'] = hierarchy.cut_tree(\n", + "# hierarchy.linkage(my_data, method='complete'), 3)[:,0]\n", + "\n", + "sns.scatterplot(x='PC1', y='PC2', data=my_result, legend=False,\n", + " hue='cluster', # \u8272\u3067\u30af\u30e9\u30b9\u30bf\u3092\u8868\u73fe\u3059\u308b\uff0e\n", + " style='Species', # \u5f62\u3067\u54c1\u7a2e\u3092\u8868\u73fe\u3059\u308b\uff0e\n", + " palette='bright')" + ], + "id": "28c4e73c-1d4d-454a-abef-42d9bb2bf7c2" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + } +} \ No newline at end of file diff --git a/code/R-notebook/README.md b/code/R-notebook/README.md index e0f7eb2..7204373 100644 --- a/code/R-notebook/README.md +++ b/code/R-notebook/README.md @@ -1,14 +1,15 @@ # Jupyter Notebooks for R + chapter|Open in Colab --|-- -03|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/ch03/03-colab.ipynb) -04|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/ch04/04-colab.ipynb) -05|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/ch05/05-colab.ipynb) -06|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/ch06/06-colab.ipynb) -07|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/ch07/07-colab.ipynb) -08|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/ch08/08-colab.ipynb) -09|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/ch09/09-colab.ipynb) -10|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/ch10/10-colab.ipynb) -11|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/ch11/11-colab.ipynb) -12|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/ch12/12-colab.ipynb) -13|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/ch13/13-colab.ipynb) +03|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/r-03.ipynb) +04|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/r-04.ipynb) +05|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/r-05.ipynb) +06|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/r-06.ipynb) +07|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/r-07.ipynb) +08|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/r-08.ipynb) +09|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/r-09.ipynb) +10|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/r-10.ipynb) +11|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/r-11.ipynb) +12|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/r-12.ipynb) +13|[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/taroyabuki/fromzero/blob/master/code/R-notebook/r-13.ipynb) diff --git a/code/R-notebook/ch03/03-colab.ipynb b/code/R-notebook/ch03/03-colab.ipynb deleted file mode 100644 index 185f606..0000000 --- a/code/R-notebook/ch03/03-colab.ipynb +++ /dev/null @@ -1,1847 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 03" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Google Colaboratoryの環境設定\n", - "options(Ncpus = 2)\n", - "install.packages(c(\"furrr\", \"keras\", \"proxy\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.1 入門\n", - "\n", - "### 3.1.1 数値" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "0x10\n", - "#> [1] 16" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1.23e5\n", - "#> [1] 123000" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "2 * 3\n", - "#> [1] 6" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "10 / 3\n", - "#> [1] 3.333333" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "10 %/% 3 # 商\n", - "#> [1] 3\n", - "\n", - "10 %% 3 # 余り\n", - "#> [1] 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.2 変数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- 2\n", - "y <- 3\n", - "x * y\n", - "#> [1] 6\n", - "\n", - "keras::`%<-%`(c(x, y), c(20, 30)) # まとめて名付け\n", - "x * y\n", - "#> [1] 600" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- 1 + 1\n", - "# この段階では結果は表示されない\n", - "\n", - "x # 変数名を評価する.\n", - "#> [1] 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.3 文字列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_s <- \"abcde\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "nchar(my_s)\n", - "#> [1] 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "str_c(\"This is \", \"a\", \" pen.\")\n", - "#> [1] \"This is a pen.\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "substr(x = my_s, start = 2, stop = 4)\n", - "#> [1] \"bcd\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- \"%s is %s.\"\n", - "sprintf(tmp, \"This\", \"a pen\")\n", - "#> [1] \"This is a pen.\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.4 論理値" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1 <= 2\n", - "#> [1] TRUE\n", - "\n", - "1 < 0\n", - "#> [1] FALSE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "0.1 + 0.1 + 0.1 == 0.3\n", - "#> [1] FALSE\n", - "\n", - "all.equal(0.1 + 0.1 + 0.1, 0.3)\n", - "#> [1] TRUE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "TRUE & FALSE # 論理積(かつ)\n", - "#> [1] FALSE\n", - "\n", - "TRUE | FALSE # 論理和(または)\n", - "#> [1] TRUE\n", - "\n", - "!TRUE # 否定(でない)\n", - "#> [1] FALSE" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.1.4.1 条件演算子" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ifelse(3 < 5, 0, 10)\n", - "#> 0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.5 作業ディレクトリ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "getwd()\n", - "#> '/home/jovyan/work'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "setwd(\"..\")\n", - "getwd()\n", - "#> '/home/jovyan'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.2 関数\n", - "\n", - "### 3.2.1 関数の利用" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sqrt(4)\n", - "#> [1] 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "log(100, 10)\n", - "#> [1] 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "log(100) # 自然対数\n", - "# あるいは\n", - "log(100, exp(1)) # 省略しない場合\n", - "\n", - "#> [1] 4.60517" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "log10(100) # 常用対数\n", - "#> [1] 2\n", - "\n", - "log2(1024) # 底が2の対数\n", - "#> [1] 10" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.1.1 パイプ(Rのみ)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "4 %>% sqrt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "exp(log(5)) # 通常の書き方\n", - "# あるいは\n", - "5 %>% log %>% exp # パイプを使う書き方\n", - "\n", - "#> 5" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.2.2 関数の定義" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(a, b) {\n", - " a - b\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f(3, 5)\n", - "#> [1] -2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.2.1 デフォルト引数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(a, b = 5) {\n", - " a - b\n", - "}\n", - "\n", - "f(3) # f(3, 5)と同じこと\n", - "#> [1] -2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.2.2 無名関数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(function(a, b) { a - b })(3, 5)\n", - "#> [1] -2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.3 コレクション\n", - "\n", - "### 3.3.1 1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(\"foo\", \"bar\", \"baz\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "length(x)\n", - "#> [1] 3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[2]\n", - "#> [1] \"bar\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[2] <- \"BAR\"\n", - "x # 結果の確認\n", - "#> [1] \"foo\" \"BAR\" \"baz\"\n", - "\n", - "x[2] <- \"bar\" # 元に戻す." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[-2]\n", - "#> [1] \"foo\" \"baz\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c(x, \"qux\")\n", - "#> [1] \"foo\" \"bar\" \"baz\" \"qux\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(x, \"qux\")\n", - "x # 結果の確認\n", - "#> [1] \"foo\" \"bar\" \"baz\" \"qux\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.1.1 等間隔の数値からなる1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1:5\n", - "#> [1] 1 2 3 4 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "seq(from = 0, to = 10, by = 2)\n", - "#> [1] 0 2 4 6 8 10" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "seq(from = 0, to = 1, by = 0.5)\n", - "#> [1] 0.0 0.5 1.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "seq(from = 0, to = 100, length.out = 5)\n", - "#> [1] 0 25 50 75 100" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rep(x = 10, times = 5)\n", - "#> [1] 10 10 10 10 10" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.1.2 ファクタ(Rのみ)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- c(\"グー\", \"パー\", \"グー\", \"パー\")\n", - "x <- factor(tmp, levels = c(\"グー\", \"チョキ\", \"パー\"))\n", - "x\n", - "#> [1] グー パー グー パー\n", - "#> Levels: グー チョキ パー" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.2 数値計算やデータ解析用の1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(2, 3, 5, 7)\n", - "\n", - "x + 10 # 加算\n", - "#> [1] 12 13 15 17\n", - "\n", - "x * 10 # 乗算\n", - "#> [1] 20 30 50 70" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(2, 3)\n", - "sin(x)\n", - "#> [1] 0.9092974 0.1411200" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(2, 3, 5, 7)\n", - "y <- c(1, 10, 100, 1000)\n", - "x + y\n", - "#> [1] 3 13 105 1007\n", - "\n", - "x * y\n", - "#> [1] 2 30 500 7000" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum(x * y)\n", - "#> [1] 7532" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(TRUE, FALSE)\n", - "y <- c(TRUE, TRUE)\n", - "x & y\n", - "#> [1] TRUE FALSE" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.2.1 1次元データ同士の比較" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "u <- c(1, 2, 3)\n", - "v <- c(1, 2, 3)\n", - "w <- c(1, 2, 4)\n", - "\n", - "identical(u, v) # 全体の比較\n", - "#> [1] TRUE\n", - "\n", - "identical(u, w) # 全体の比較\n", - "#> [1] FALSE\n", - "\n", - "u == v # 要素ごとの比較\n", - "#> [1] TRUE TRUE TRUE\n", - "\n", - "u == w # 要素ごとの比較\n", - "#> [1] TRUE TRUE FALSE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum(u == w) # 同じ要素の数\n", - "#> [1] 2\n", - "\n", - "mean(u == w) # 同じ要素の割合\n", - "#> [1] 0.6666667" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.3 複数種類のデータをひとまとめにする" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- list(1, \"two\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[[2]]\n", - "#> [1] \"two\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.4 文字列と値のペアのコレクション" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- list(\"apple\" = \"りんご\",\n", - " \"orange\" = \"みかん\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[[\"grape\"]] <- \"ぶどう\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x$apple\n", - "# あるいは\n", - "x$\"apple\"\n", - "# あるいは\n", - "x[[\"apple\"]]\n", - "# あるいは\n", - "tmp <- \"apple\"\n", - "x[[tmp]]\n", - "\n", - "#> [1] \"りんご\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.5 補足:コピーと参照" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(\"foo\", \"bar\", \"baz\")\n", - "y <- x\n", - "y[2] <- \"BAR\" # yを更新する.\n", - "y\n", - "#> [1] \"foo\" \"BAR\" \"baz\"\n", - "\n", - "x # xは変わらない.\n", - "#> [1] \"foo\" \"bar\" \"baz\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.4 データフレーム\n", - "\n", - "### 3.4.1 データフレームの作成" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.1 データを列ごとに記述する方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- data.frame(\n", - " name = c(\"A\", \"B\", \"C\", \"D\"),\n", - " english = c( 60, 90, 70, 90),\n", - " math = c( 70, 80, 90, 100),\n", - " gender = c(\"f\", \"m\", \"m\", \"f\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.2 データを見た目のとおりに記述する方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- tribble(\n", - " ~name, ~english, ~math, ~gender,\n", - " \"A\", 60, 70, \"f\",\n", - " \"B\", 90, 80, \"m\",\n", - " \"C\", 70, 90, \"m\",\n", - " \"D\", 90, 100, \"f\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_df)\n", - "# 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.3 データフレームのサイズ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "dim(my_df) # 行数と列数\n", - "#> [1] 4 4\n", - "\n", - "nrow(my_df) # 行数\n", - "#> [1] 4\n", - "\n", - "ncol(my_df) # 列数\n", - "#> [1] 4" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.4 組合せ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- expand.grid(\n", - " X = c(1, 2, 3),\n", - " Y = c(10, 100))\n", - "my_df2\n", - "#> X Y\n", - "#> 1 1 10\n", - "#> 2 2 10\n", - "#> 3 3 10\n", - "#> 4 1 100\n", - "#> 5 2 100\n", - "#> 6 3 100" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.5 列と行の名前" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "colnames(my_df2)\n", - "#> [1] \"X\" \"Y\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "colnames(my_df2) <- c(\"P\", \"Q\")\n", - "my_df2\n", - "#> P Q\n", - "#> 1 1 10\n", - "#> 2 2 10\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "row.names(my_df)\n", - "#> [1] \"1\" \"2\" \"3\" \"4\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "row.names(my_df2) <-\n", - " c(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\")\n", - "my_df2\n", - "#> P Q\n", - "#> a 1 10\n", - "#> b 2 10\n", - "#> c 3 10\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df3 <- data.frame(\n", - " english = c( 60, 90, 70, 90),\n", - " math = c( 70, 80, 90, 100),\n", - " gender = c(\"f\", \"m\", \"m\", \"f\"),\n", - " row.names = c(\"A\", \"B\", \"C\", \"D\"))\n", - "my_df3\n", - "#> english math gender\n", - "#> A 60 70 f\n", - "#> B 90 80 m\n", - "#> C 70 90 m\n", - "#> D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.2 データの追加\n", - "\n", - "#### 3.4.2.1 行の追加(データフレームの結合)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- data.frame(\n", - " name = \"E\",\n", - " english = 80,\n", - " math = 80,\n", - " gender = \"m\")\n", - "my_df2 <- rbind(my_df, tmp)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.2.2 列の追加" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- my_df %>%\n", - " mutate(id = c(1, 2, 3, 4))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df3 <- my_df # コピー\n", - "my_df3[\"id\"] <- c(1, 2, 3, 4) # 更新\n", - "my_df3 # 結果の確認(割愛)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.3 データの取り出し\n", - "\n", - "#### 3.4.3.1 観測値の取り出し" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df[1, 2]\n", - "#> [1] 60" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.2 1列の取り出し(結果は1次元データ)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[, 2]\n", - "# あるいは\n", - "x <- my_df$english\n", - "# あるいは\n", - "x <- my_df$\"english\"\n", - "# あるいは\n", - "x <- my_df[[\"english\"]]\n", - "# あるいは\n", - "tmp <- \"english\"\n", - "x <- my_df[[tmp]]\n", - "\n", - "x # 結果の確認(割愛)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.3 複数列の取り出し(結果はデータフレーム)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df %>% select(name, math)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[, c(1, 3)]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df %>%\n", - " select(-c(english, gender))\n", - "# あるいは\n", - "x <- my_df[, -c(2, 4)]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.4 複数行の取り出し(結果はデータフレーム)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[c(1, 3), ]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[-c(2, 4), ]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.5 検索" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[my_df$gender == \"m\", ]\n", - "# あるいは\n", - "x <- my_df %>% filter(gender == \"m\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[my_df$english > 80 & my_df$gender == \"m\", ]\n", - "# あるいは\n", - "x <- my_df %>% filter(english > 80 & gender == \"m\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[my_df$english == max(my_df$english), ]\n", - "# あるいは\n", - "x <- my_df %>% filter(english == max(my_df$english))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- my_df # コピー\n", - "my_df2[my_df$gender == \"m\", ]$gender <- \"M\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2\n", - "#> name english math gender\n", - "#> 1 A 60 70 f\n", - "#> 2 B 90 80 M\n", - "#> 3 C 70 90 M\n", - "#> 4 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.6 並べ替え" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df %>% arrange(english)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df %>% arrange(-english)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.4 補足:行列\n", - "\n", - "#### 3.4.4.1 行列の生成" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(2, 3, 5, 7, 11, 13, 17, 19, 23,\n", - " 29, 31, 37)\n", - "A <- matrix(\n", - " data = x, # 1次元データ\n", - " nrow = 3, # 行数\n", - " byrow = TRUE) # 行ごとの生成\n", - "A\n", - "#> [,1] [,2] [,3] [,4]\n", - "#> [1,] 2 3 5 7\n", - "#> [2,] 11 13 17 19\n", - "#> [3,] 23 29 31 37" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.2 データフレームと行列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A <- my_df[, c(2, 3)] %>% as.matrix\n", - "A\n", - "#> english math\n", - "#> [1,] 60 70\n", - "#> [2,] 90 80\n", - "#> [3,] 70 90\n", - "#> [4,] 90 100" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "as.data.frame(A)\n", - "#> english math\n", - "#> 1 60 70\n", - "#> 2 90 80\n", - "#> 3 70 90\n", - "#> 4 90 100" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.3 行列の変形" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "t(A)\n", - "#> [,1] [,2] [,3] [,4]\n", - "#> english 60 90 70 90\n", - "#> math 70 80 90 100" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.4 行列の積" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "t(A) %*% A\n", - "#> english math\n", - "#> english 24700 26700\n", - "#> math 26700 29400" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.5 縦型と横型" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_wider <- data.frame(\n", - " day = c(25, 26, 27),\n", - " min = c(20, 21, 15),\n", - " max = c(24, 27, 21))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_longer <- my_wider %>%\n", - " pivot_longer(-day)\n", - "my_longer\n", - "#> # A tibble: 6 x 3\n", - "#> day name value\n", - "#> \n", - "#> 1 25 min 20\n", - "#> 2 25 max 24\n", - "#> 3 26 min 21\n", - "#> 4 26 max 27\n", - "#> 5 27 min 15\n", - "#> 6 27 max 21" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_longer %>% pivot_wider()\n", - "#> # A tibble: 3 x 3\n", - "#> day min max\n", - "#> \n", - "#> 1 25 20 24\n", - "#> 2 26 21 27\n", - "#> 3 27 15 21" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_longer %>%\n", - " ggplot(aes(x = day, y = value,\n", - " color = name)) +\n", - " geom_point() +\n", - " geom_line() +\n", - " ylab(\"temperature\") + # y軸ラベル\n", - " scale_x_continuous(\n", - " breaks = my_longer$day) # x軸目盛り" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.5 1次元データの(非)類似度\n", - "\n", - "### 3.5.1 ユークリッド距離" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A <- c(3, 4, 5)\n", - "B <- c(3, 4, 29)\n", - "C <- c(9, -18, 8)\n", - "AB <- B - A\n", - "AC <- C - A\n", - "\n", - "sum(AB^2)^0.5\n", - "#> [1] 24\n", - "\n", - "sum(AC^2)^0.5\n", - "#> [1] 23" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.2 マンハッタン距離" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum(abs(AB))\n", - "#> [1] 24\n", - "\n", - "sum(abs(AC))\n", - "#> [1] 31" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.3 コサイン類似度" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum(A * B) /\n", - " sum(A * A)^0.5 / sum(B * B)^0.5\n", - "#> [1] 0.8169679\n", - "\n", - "sum(A * C) /\n", - " sum(A * A)^0.5 / sum(C * C)^0.5\n", - "#> [1] -0.03265116" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.4 相関係数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "cor(A, B)\n", - "#> [1] 0.8824975\n", - "\n", - "cor(A, C)\n", - "#> [1] -0.03266277" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.5.4.1 データフレームを使う方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "\n", - "\n", - "my_df <- data.frame(\n", - " x = c(3, 3, 9),\n", - " y = c(4, 4, -18),\n", - " z = c(5, 29, 8),\n", - " row.names = c(\"A\", \"B\", \"C\"))\n", - "\n", - "# ユークリッド距離\n", - "my_df %>% proxy::dist(\"Euclidean\")\n", - "#> A B\n", - "#> B 24\n", - "#> C 23 31\n", - "\n", - "\n", - "# マンハッタン距離\n", - "my_df %>% proxy::dist(\"Manhattan\")\n", - "#> A B\n", - "#> B 24\n", - "#> C 31 49\n", - "\n", - "\n", - "# コサイン類似度\n", - "my_df %>% proxy::simil(\"cosine\")\n", - "#> A B\n", - "#> B 0.81696786\n", - "#> C -0.03265116 0.29342441\n", - "\n", - "\n", - "# 相関係数\n", - "my_df %>% proxy::simil(\"correlation\")\n", - "#> A B\n", - "#> B 0.88249750\n", - "#> C -0.03266277 0.44124132" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.6 Rのパッケージ,Pythonのモジュール\n", - "\n", - "### 3.6.1 Rのパッケージ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.6.2 Pythonのモジュール\n", - "\n", - "## 3.7 反復処理" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.1 指定した回数→1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f1 <- function(x) {\n", - " tmp <- runif(x)\n", - " mean(tmp)\n", - "}\n", - "\n", - "f1(10) # 動作確認\n", - "#> [1] 0.5776604 # 結果の例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "replicate(n = 3, expr = f1(10))\n", - "#> [1] 0.4672766 0.4712016 0.5579449" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rep(x = f1(10), times = 3)\n", - "#> [1] 0.481329 0.481329 0.481329" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.2 1次元データ→1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v <- c(5, 10, 100)\n", - "v %>% map_dbl(f1)\n", - "#> [1] 0.4857329 0.5322183 0.5084124" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rep(x = 10, times = 3) %>% map_dbl(f1)\n", - "# 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.3 1次元データ→データフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f2 <- function(n) {\n", - " tmp <- runif(n)\n", - " list(x = n,\n", - " p = mean(tmp),\n", - " q = sd(tmp))\n", - "}\n", - "\n", - "f2(10) # 動作確認\n", - "#> $x\n", - "#> [1] 10\n", - "#>\n", - "#> $p\n", - "#> [1] 0.6840032 (平均の例)\n", - "#>\n", - "#> $q\n", - "#> [1] 0.3750788 (標準偏差の例)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v <- c(5, 10, 100)\n", - "v %>% map_dfr(f2)\n", - "#> x p q\n", - "#> \n", - "#> 1 5 0.560 0.320\n", - "#> 2 10 0.559 0.271\n", - "#> 3 100 0.507 0.283" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.4 データフレーム→データフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f3 <- function(x, y) {\n", - " tmp <- runif(x, min = 1,\n", - " max = y + 1) %>%\n", - " as.integer\n", - " list(x = x,\n", - " y = y,\n", - " p = mean(tmp),\n", - " q = sd(tmp))\n", - "}\n", - "\n", - "f3(x = 10, y = 6) # 動作確認\n", - "#> $x\n", - "#> [1] 10\n", - "#>\n", - "#> $y\n", - "#> [1] 6\n", - "#>\n", - "#> $p\n", - "#> [1] 3.2 (平均の例)\n", - "#>\n", - "#> $q\n", - "#> [1] 1.316561 (標準偏差の例)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- data.frame(\n", - " x = c(5, 10, 100, 5, 10, 100),\n", - " y = c(6, 6, 6, 12, 12, 12))\n", - "\n", - "my_df %>% pmap_dfr(f3)\n", - "#> x y p q\n", - "#> \n", - "#> 1 5 6 3 1.41\n", - "#> 2 10 6 3 1.49\n", - "#> 3 100 6 3.57 1.78\n", - "#> 4 5 12 7.6 5.22\n", - "#> 5 10 12 5.7 3.77\n", - "#> 6 100 12 6.36 3.59" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.5 補足:反復処理の並列化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(furrr)\n", - "plan(multisession) # 準備\n", - "\n", - "v <- c(5, 10, 100)\n", - "v %>% future_map_dbl(f1, .options =\n", - " furrr_options(seed = TRUE))\n", - "# 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.8 その他\n", - "\n", - "### 3.8.1 よく遭遇するエラーとその対処方法\n", - "\n", - "### 3.8.2 変数や関数についての調査" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- 123\n", - "typeof(x)\n", - "#> [1] \"double\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "?log\n", - "# あるいは\n", - "help(log)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.8.3 RのNA,Pythonのnan" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v <- c(1, NA, 3)\n", - "v\n", - "#> [1] 1 NA 3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "is.na(v[2])\n", - "#> [1] TRUE\n", - "\n", - "v[2] == NA # 誤り\n", - "#> [1] NA" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch03/03.01.ipynb b/code/R-notebook/ch03/03.01.ipynb deleted file mode 100644 index 88a2803..0000000 --- a/code/R-notebook/ch03/03.01.ipynb +++ /dev/null @@ -1,262 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.1 入門\n", - "\n", - "### 3.1.1 数値" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "0x10\n", - "#> [1] 16" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1.23e5\n", - "#> [1] 123000" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "2 * 3\n", - "#> [1] 6" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "10 / 3\n", - "#> [1] 3.333333" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "10 %/% 3 # 商\n", - "#> [1] 3\n", - "\n", - "10 %% 3 # 余り\n", - "#> [1] 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.2 変数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- 2\n", - "y <- 3\n", - "x * y\n", - "#> [1] 6\n", - "\n", - "keras::`%<-%`(c(x, y), c(20, 30)) # まとめて名付け\n", - "x * y\n", - "#> [1] 600" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- 1 + 1\n", - "# この段階では結果は表示されない\n", - "\n", - "x # 変数名を評価する.\n", - "#> [1] 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.3 文字列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_s <- \"abcde\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "nchar(my_s)\n", - "#> [1] 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "str_c(\"This is \", \"a\", \" pen.\")\n", - "#> [1] \"This is a pen.\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "substr(x = my_s, start = 2, stop = 4)\n", - "#> [1] \"bcd\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- \"%s is %s.\"\n", - "sprintf(tmp, \"This\", \"a pen\")\n", - "#> [1] \"This is a pen.\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.4 論理値" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1 <= 2\n", - "#> [1] TRUE\n", - "\n", - "1 < 0\n", - "#> [1] FALSE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "0.1 + 0.1 + 0.1 == 0.3\n", - "#> [1] FALSE\n", - "\n", - "all.equal(0.1 + 0.1 + 0.1, 0.3)\n", - "#> [1] TRUE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "TRUE & FALSE # 論理積(かつ)\n", - "#> [1] FALSE\n", - "\n", - "TRUE | FALSE # 論理和(または)\n", - "#> [1] TRUE\n", - "\n", - "!TRUE # 否定(でない)\n", - "#> [1] FALSE" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.1.4.1 条件演算子" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ifelse(3 < 5, 0, 10)\n", - "#> 0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.5 作業ディレクトリ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "getwd()\n", - "#> '/home/jovyan/work'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "setwd(\"..\")\n", - "getwd()\n", - "#> '/home/jovyan'" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch03/03.02.ipynb b/code/R-notebook/ch03/03.02.ipynb deleted file mode 100644 index 136ac36..0000000 --- a/code/R-notebook/ch03/03.02.ipynb +++ /dev/null @@ -1,163 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.2 関数\n", - "\n", - "### 3.2.1 関数の利用" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sqrt(4)\n", - "#> [1] 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "log(100, 10)\n", - "#> [1] 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "log(100) # 自然対数\n", - "# あるいは\n", - "log(100, exp(1)) # 省略しない場合\n", - "\n", - "#> [1] 4.60517" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "log10(100) # 常用対数\n", - "#> [1] 2\n", - "\n", - "log2(1024) # 底が2の対数\n", - "#> [1] 10" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.1.1 パイプ(Rのみ)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "4 %>% sqrt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "exp(log(5)) # 通常の書き方\n", - "# あるいは\n", - "5 %>% log %>% exp # パイプを使う書き方\n", - "\n", - "#> 5" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.2.2 関数の定義" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(a, b) {\n", - " a - b\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f(3, 5)\n", - "#> [1] -2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.2.1 デフォルト引数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(a, b = 5) {\n", - " a - b\n", - "}\n", - "\n", - "f(3) # f(3, 5)と同じこと\n", - "#> [1] -2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.2.2 無名関数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(function(a, b) { a - b })(3, 5)\n", - "#> [1] -2" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch03/03.03.ipynb b/code/R-notebook/ch03/03.03.ipynb deleted file mode 100644 index 3475ab7..0000000 --- a/code/R-notebook/ch03/03.03.ipynb +++ /dev/null @@ -1,377 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.3 コレクション\n", - "\n", - "### 3.3.1 1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(\"foo\", \"bar\", \"baz\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "length(x)\n", - "#> [1] 3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[2]\n", - "#> [1] \"bar\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[2] <- \"BAR\"\n", - "x # 結果の確認\n", - "#> [1] \"foo\" \"BAR\" \"baz\"\n", - "\n", - "x[2] <- \"bar\" # 元に戻す." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[-2]\n", - "#> [1] \"foo\" \"baz\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c(x, \"qux\")\n", - "#> [1] \"foo\" \"bar\" \"baz\" \"qux\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(x, \"qux\")\n", - "x # 結果の確認\n", - "#> [1] \"foo\" \"bar\" \"baz\" \"qux\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.1.1 等間隔の数値からなる1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1:5\n", - "#> [1] 1 2 3 4 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "seq(from = 0, to = 10, by = 2)\n", - "#> [1] 0 2 4 6 8 10" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "seq(from = 0, to = 1, by = 0.5)\n", - "#> [1] 0.0 0.5 1.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "seq(from = 0, to = 100, length.out = 5)\n", - "#> [1] 0 25 50 75 100" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rep(x = 10, times = 5)\n", - "#> [1] 10 10 10 10 10" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.1.2 ファクタ(Rのみ)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- c(\"グー\", \"パー\", \"グー\", \"パー\")\n", - "x <- factor(tmp, levels = c(\"グー\", \"チョキ\", \"パー\"))\n", - "x\n", - "#> [1] グー パー グー パー\n", - "#> Levels: グー チョキ パー" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.2 数値計算やデータ解析用の1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(2, 3, 5, 7)\n", - "\n", - "x + 10 # 加算\n", - "#> [1] 12 13 15 17\n", - "\n", - "x * 10 # 乗算\n", - "#> [1] 20 30 50 70" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(2, 3)\n", - "sin(x)\n", - "#> [1] 0.9092974 0.1411200" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(2, 3, 5, 7)\n", - "y <- c(1, 10, 100, 1000)\n", - "x + y\n", - "#> [1] 3 13 105 1007\n", - "\n", - "x * y\n", - "#> [1] 2 30 500 7000" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum(x * y)\n", - "#> [1] 7532" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(TRUE, FALSE)\n", - "y <- c(TRUE, TRUE)\n", - "x & y\n", - "#> [1] TRUE FALSE" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.2.1 1次元データ同士の比較" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "u <- c(1, 2, 3)\n", - "v <- c(1, 2, 3)\n", - "w <- c(1, 2, 4)\n", - "\n", - "identical(u, v) # 全体の比較\n", - "#> [1] TRUE\n", - "\n", - "identical(u, w) # 全体の比較\n", - "#> [1] FALSE\n", - "\n", - "u == v # 要素ごとの比較\n", - "#> [1] TRUE TRUE TRUE\n", - "\n", - "u == w # 要素ごとの比較\n", - "#> [1] TRUE TRUE FALSE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum(u == w) # 同じ要素の数\n", - "#> [1] 2\n", - "\n", - "mean(u == w) # 同じ要素の割合\n", - "#> [1] 0.6666667" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.3 複数種類のデータをひとまとめにする" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- list(1, \"two\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[[2]]\n", - "#> [1] \"two\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.4 文字列と値のペアのコレクション" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- list(\"apple\" = \"りんご\",\n", - " \"orange\" = \"みかん\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[[\"grape\"]] <- \"ぶどう\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x$apple\n", - "# あるいは\n", - "x$\"apple\"\n", - "# あるいは\n", - "x[[\"apple\"]]\n", - "# あるいは\n", - "tmp <- \"apple\"\n", - "x[[tmp]]\n", - "\n", - "#> [1] \"りんご\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.5 補足:コピーと参照" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(\"foo\", \"bar\", \"baz\")\n", - "y <- x\n", - "y[2] <- \"BAR\" # yを更新する.\n", - "y\n", - "#> [1] \"foo\" \"BAR\" \"baz\"\n", - "\n", - "x # xは変わらない.\n", - "#> [1] \"foo\" \"bar\" \"baz\"" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch03/03.04.ipynb b/code/R-notebook/ch03/03.04.ipynb deleted file mode 100644 index fc47943..0000000 --- a/code/R-notebook/ch03/03.04.ipynb +++ /dev/null @@ -1,626 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.4 データフレーム\n", - "\n", - "### 3.4.1 データフレームの作成" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.1 データを列ごとに記述する方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- data.frame(\n", - " name = c(\"A\", \"B\", \"C\", \"D\"),\n", - " english = c( 60, 90, 70, 90),\n", - " math = c( 70, 80, 90, 100),\n", - " gender = c(\"f\", \"m\", \"m\", \"f\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.2 データを見た目のとおりに記述する方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- tribble(\n", - " ~name, ~english, ~math, ~gender,\n", - " \"A\", 60, 70, \"f\",\n", - " \"B\", 90, 80, \"m\",\n", - " \"C\", 70, 90, \"m\",\n", - " \"D\", 90, 100, \"f\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_df)\n", - "# 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.3 データフレームのサイズ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "dim(my_df) # 行数と列数\n", - "#> [1] 4 4\n", - "\n", - "nrow(my_df) # 行数\n", - "#> [1] 4\n", - "\n", - "ncol(my_df) # 列数\n", - "#> [1] 4" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.4 組合せ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- expand.grid(\n", - " X = c(1, 2, 3),\n", - " Y = c(10, 100))\n", - "my_df2\n", - "#> X Y\n", - "#> 1 1 10\n", - "#> 2 2 10\n", - "#> 3 3 10\n", - "#> 4 1 100\n", - "#> 5 2 100\n", - "#> 6 3 100" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.5 列と行の名前" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "colnames(my_df2)\n", - "#> [1] \"X\" \"Y\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "colnames(my_df2) <- c(\"P\", \"Q\")\n", - "my_df2\n", - "#> P Q\n", - "#> 1 1 10\n", - "#> 2 2 10\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "row.names(my_df)\n", - "#> [1] \"1\" \"2\" \"3\" \"4\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "row.names(my_df2) <-\n", - " c(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\")\n", - "my_df2\n", - "#> P Q\n", - "#> a 1 10\n", - "#> b 2 10\n", - "#> c 3 10\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df3 <- data.frame(\n", - " english = c( 60, 90, 70, 90),\n", - " math = c( 70, 80, 90, 100),\n", - " gender = c(\"f\", \"m\", \"m\", \"f\"),\n", - " row.names = c(\"A\", \"B\", \"C\", \"D\"))\n", - "my_df3\n", - "#> english math gender\n", - "#> A 60 70 f\n", - "#> B 90 80 m\n", - "#> C 70 90 m\n", - "#> D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.2 データの追加\n", - "\n", - "#### 3.4.2.1 行の追加(データフレームの結合)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- data.frame(\n", - " name = \"E\",\n", - " english = 80,\n", - " math = 80,\n", - " gender = \"m\")\n", - "my_df2 <- rbind(my_df, tmp)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.2.2 列の追加" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- my_df %>%\n", - " mutate(id = c(1, 2, 3, 4))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df3 <- my_df # コピー\n", - "my_df3[\"id\"] <- c(1, 2, 3, 4) # 更新\n", - "my_df3 # 結果の確認(割愛)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.3 データの取り出し\n", - "\n", - "#### 3.4.3.1 観測値の取り出し" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df[1, 2]\n", - "#> [1] 60" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.2 1列の取り出し(結果は1次元データ)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[, 2]\n", - "# あるいは\n", - "x <- my_df$english\n", - "# あるいは\n", - "x <- my_df$\"english\"\n", - "# あるいは\n", - "x <- my_df[[\"english\"]]\n", - "# あるいは\n", - "tmp <- \"english\"\n", - "x <- my_df[[tmp]]\n", - "\n", - "x # 結果の確認(割愛)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.3 複数列の取り出し(結果はデータフレーム)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df %>% select(name, math)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[, c(1, 3)]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df %>%\n", - " select(-c(english, gender))\n", - "# あるいは\n", - "x <- my_df[, -c(2, 4)]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.4 複数行の取り出し(結果はデータフレーム)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[c(1, 3), ]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[-c(2, 4), ]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.5 検索" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[my_df$gender == \"m\", ]\n", - "# あるいは\n", - "x <- my_df %>% filter(gender == \"m\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[my_df$english > 80 & my_df$gender == \"m\", ]\n", - "# あるいは\n", - "x <- my_df %>% filter(english > 80 & gender == \"m\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[my_df$english == max(my_df$english), ]\n", - "# あるいは\n", - "x <- my_df %>% filter(english == max(my_df$english))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- my_df # コピー\n", - "my_df2[my_df$gender == \"m\", ]$gender <- \"M\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2\n", - "#> name english math gender\n", - "#> 1 A 60 70 f\n", - "#> 2 B 90 80 M\n", - "#> 3 C 70 90 M\n", - "#> 4 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.6 並べ替え" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df %>% arrange(english)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df %>% arrange(-english)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.4 補足:行列\n", - "\n", - "#### 3.4.4.1 行列の生成" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(2, 3, 5, 7, 11, 13, 17, 19, 23,\n", - " 29, 31, 37)\n", - "A <- matrix(\n", - " data = x, # 1次元データ\n", - " nrow = 3, # 行数\n", - " byrow = TRUE) # 行ごとの生成\n", - "A\n", - "#> [,1] [,2] [,3] [,4]\n", - "#> [1,] 2 3 5 7\n", - "#> [2,] 11 13 17 19\n", - "#> [3,] 23 29 31 37" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.2 データフレームと行列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A <- my_df[, c(2, 3)] %>% as.matrix\n", - "A\n", - "#> english math\n", - "#> [1,] 60 70\n", - "#> [2,] 90 80\n", - "#> [3,] 70 90\n", - "#> [4,] 90 100" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "as.data.frame(A)\n", - "#> english math\n", - "#> 1 60 70\n", - "#> 2 90 80\n", - "#> 3 70 90\n", - "#> 4 90 100" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.3 行列の変形" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "t(A)\n", - "#> [,1] [,2] [,3] [,4]\n", - "#> english 60 90 70 90\n", - "#> math 70 80 90 100" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.4 行列の積" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "t(A) %*% A\n", - "#> english math\n", - "#> english 24700 26700\n", - "#> math 26700 29400" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.5 縦型と横型" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_wider <- data.frame(\n", - " day = c(25, 26, 27),\n", - " min = c(20, 21, 15),\n", - " max = c(24, 27, 21))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_longer <- my_wider %>%\n", - " pivot_longer(-day)\n", - "my_longer\n", - "#> # A tibble: 6 x 3\n", - "#> day name value\n", - "#> \n", - "#> 1 25 min 20\n", - "#> 2 25 max 24\n", - "#> 3 26 min 21\n", - "#> 4 26 max 27\n", - "#> 5 27 min 15\n", - "#> 6 27 max 21" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_longer %>% pivot_wider()\n", - "#> # A tibble: 3 x 3\n", - "#> day min max\n", - "#> \n", - "#> 1 25 20 24\n", - "#> 2 26 21 27\n", - "#> 3 27 15 21" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_longer %>%\n", - " ggplot(aes(x = day, y = value,\n", - " color = name)) +\n", - " geom_point() +\n", - " geom_line() +\n", - " ylab(\"temperature\") + # y軸ラベル\n", - " scale_x_continuous(\n", - " breaks = my_longer$day) # x軸目盛り" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch03/03.05.ipynb b/code/R-notebook/ch03/03.05.ipynb deleted file mode 100644 index 58fddb5..0000000 --- a/code/R-notebook/ch03/03.05.ipynb +++ /dev/null @@ -1,153 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.5 1次元データの(非)類似度\n", - "\n", - "### 3.5.1 ユークリッド距離" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A <- c(3, 4, 5)\n", - "B <- c(3, 4, 29)\n", - "C <- c(9, -18, 8)\n", - "AB <- B - A\n", - "AC <- C - A\n", - "\n", - "sum(AB^2)^0.5\n", - "#> [1] 24\n", - "\n", - "sum(AC^2)^0.5\n", - "#> [1] 23" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.2 マンハッタン距離" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum(abs(AB))\n", - "#> [1] 24\n", - "\n", - "sum(abs(AC))\n", - "#> [1] 31" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.3 コサイン類似度" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum(A * B) /\n", - " sum(A * A)^0.5 / sum(B * B)^0.5\n", - "#> [1] 0.8169679\n", - "\n", - "sum(A * C) /\n", - " sum(A * A)^0.5 / sum(C * C)^0.5\n", - "#> [1] -0.03265116" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.4 相関係数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "cor(A, B)\n", - "#> [1] 0.8824975\n", - "\n", - "cor(A, C)\n", - "#> [1] -0.03266277" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.5.4.1 データフレームを使う方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "\n", - "\n", - "my_df <- data.frame(\n", - " x = c(3, 3, 9),\n", - " y = c(4, 4, -18),\n", - " z = c(5, 29, 8),\n", - " row.names = c(\"A\", \"B\", \"C\"))\n", - "\n", - "# ユークリッド距離\n", - "my_df %>% proxy::dist(\"Euclidean\")\n", - "#> A B\n", - "#> B 24\n", - "#> C 23 31\n", - "\n", - "\n", - "# マンハッタン距離\n", - "my_df %>% proxy::dist(\"Manhattan\")\n", - "#> A B\n", - "#> B 24\n", - "#> C 31 49\n", - "\n", - "\n", - "# コサイン類似度\n", - "my_df %>% proxy::simil(\"cosine\")\n", - "#> A B\n", - "#> B 0.81696786\n", - "#> C -0.03265116 0.29342441\n", - "\n", - "\n", - "# 相関係数\n", - "my_df %>% proxy::simil(\"correlation\")\n", - "#> A B\n", - "#> B 0.88249750\n", - "#> C -0.03266277 0.44124132" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch03/03.06.ipynb b/code/R-notebook/ch03/03.06.ipynb deleted file mode 100644 index e8638eb..0000000 --- a/code/R-notebook/ch03/03.06.ipynb +++ /dev/null @@ -1,37 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.6 Rのパッケージ,Pythonのモジュール\n", - "\n", - "### 3.6.1 Rのパッケージ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.6.2 Pythonのモジュール" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch03/03.07.ipynb b/code/R-notebook/ch03/03.07.ipynb deleted file mode 100644 index 465df16..0000000 --- a/code/R-notebook/ch03/03.07.ipynb +++ /dev/null @@ -1,224 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.7 反復処理" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.1 指定した回数→1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f1 <- function(x) {\n", - " tmp <- runif(x)\n", - " mean(tmp)\n", - "}\n", - "\n", - "f1(10) # 動作確認\n", - "#> [1] 0.5776604 # 結果の例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "replicate(n = 3, expr = f1(10))\n", - "#> [1] 0.4672766 0.4712016 0.5579449" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rep(x = f1(10), times = 3)\n", - "#> [1] 0.481329 0.481329 0.481329" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.2 1次元データ→1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v <- c(5, 10, 100)\n", - "v %>% map_dbl(f1)\n", - "#> [1] 0.4857329 0.5322183 0.5084124" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rep(x = 10, times = 3) %>% map_dbl(f1)\n", - "# 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.3 1次元データ→データフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f2 <- function(n) {\n", - " tmp <- runif(n)\n", - " list(x = n,\n", - " p = mean(tmp),\n", - " q = sd(tmp))\n", - "}\n", - "\n", - "f2(10) # 動作確認\n", - "#> $x\n", - "#> [1] 10\n", - "#>\n", - "#> $p\n", - "#> [1] 0.6840032 (平均の例)\n", - "#>\n", - "#> $q\n", - "#> [1] 0.3750788 (標準偏差の例)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v <- c(5, 10, 100)\n", - "v %>% map_dfr(f2)\n", - "#> x p q\n", - "#> \n", - "#> 1 5 0.560 0.320\n", - "#> 2 10 0.559 0.271\n", - "#> 3 100 0.507 0.283" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.4 データフレーム→データフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f3 <- function(x, y) {\n", - " tmp <- runif(x, min = 1,\n", - " max = y + 1) %>%\n", - " as.integer\n", - " list(x = x,\n", - " y = y,\n", - " p = mean(tmp),\n", - " q = sd(tmp))\n", - "}\n", - "\n", - "f3(x = 10, y = 6) # 動作確認\n", - "#> $x\n", - "#> [1] 10\n", - "#>\n", - "#> $y\n", - "#> [1] 6\n", - "#>\n", - "#> $p\n", - "#> [1] 3.2 (平均の例)\n", - "#>\n", - "#> $q\n", - "#> [1] 1.316561 (標準偏差の例)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- data.frame(\n", - " x = c(5, 10, 100, 5, 10, 100),\n", - " y = c(6, 6, 6, 12, 12, 12))\n", - "\n", - "my_df %>% pmap_dfr(f3)\n", - "#> x y p q\n", - "#> \n", - "#> 1 5 6 3 1.41\n", - "#> 2 10 6 3 1.49\n", - "#> 3 100 6 3.57 1.78\n", - "#> 4 5 12 7.6 5.22\n", - "#> 5 10 12 5.7 3.77\n", - "#> 6 100 12 6.36 3.59" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.5 補足:反復処理の並列化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(furrr)\n", - "plan(multisession) # 準備\n", - "\n", - "v <- c(5, 10, 100)\n", - "v %>% future_map_dbl(f1, .options =\n", - " furrr_options(seed = TRUE))\n", - "# 結果は割愛" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch03/03.08.ipynb b/code/R-notebook/ch03/03.08.ipynb deleted file mode 100644 index a6dea4a..0000000 --- a/code/R-notebook/ch03/03.08.ipynb +++ /dev/null @@ -1,76 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.8 その他\n", - "\n", - "### 3.8.1 よく遭遇するエラーとその対処方法\n", - "\n", - "### 3.8.2 変数や関数についての調査" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- 123\n", - "typeof(x)\n", - "#> [1] \"double\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "?log\n", - "# あるいは\n", - "help(log)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.8.3 RのNA,Pythonのnan" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v <- c(1, NA, 3)\n", - "v\n", - "#> [1] 1 NA 3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "is.na(v[2])\n", - "#> [1] TRUE\n", - "\n", - "v[2] == NA # 誤り\n", - "#> [1] NA" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch03/03.ipynb b/code/R-notebook/ch03/03.ipynb deleted file mode 100644 index 83cb6f0..0000000 --- a/code/R-notebook/ch03/03.ipynb +++ /dev/null @@ -1,1831 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 03\n", - "\n", - "## 3.1 入門\n", - "\n", - "### 3.1.1 数値" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "0x10\n", - "#> [1] 16" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1.23e5\n", - "#> [1] 123000" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "2 * 3\n", - "#> [1] 6" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "10 / 3\n", - "#> [1] 3.333333" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "10 %/% 3 # 商\n", - "#> [1] 3\n", - "\n", - "10 %% 3 # 余り\n", - "#> [1] 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.2 変数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- 2\n", - "y <- 3\n", - "x * y\n", - "#> [1] 6\n", - "\n", - "keras::`%<-%`(c(x, y), c(20, 30)) # まとめて名付け\n", - "x * y\n", - "#> [1] 600" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- 1 + 1\n", - "# この段階では結果は表示されない\n", - "\n", - "x # 変数名を評価する.\n", - "#> [1] 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.3 文字列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_s <- \"abcde\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "nchar(my_s)\n", - "#> [1] 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "str_c(\"This is \", \"a\", \" pen.\")\n", - "#> [1] \"This is a pen.\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "substr(x = my_s, start = 2, stop = 4)\n", - "#> [1] \"bcd\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- \"%s is %s.\"\n", - "sprintf(tmp, \"This\", \"a pen\")\n", - "#> [1] \"This is a pen.\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.4 論理値" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1 <= 2\n", - "#> [1] TRUE\n", - "\n", - "1 < 0\n", - "#> [1] FALSE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "0.1 + 0.1 + 0.1 == 0.3\n", - "#> [1] FALSE\n", - "\n", - "all.equal(0.1 + 0.1 + 0.1, 0.3)\n", - "#> [1] TRUE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "TRUE & FALSE # 論理積(かつ)\n", - "#> [1] FALSE\n", - "\n", - "TRUE | FALSE # 論理和(または)\n", - "#> [1] TRUE\n", - "\n", - "!TRUE # 否定(でない)\n", - "#> [1] FALSE" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.1.4.1 条件演算子" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ifelse(3 < 5, 0, 10)\n", - "#> 0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.1.5 作業ディレクトリ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "getwd()\n", - "#> '/home/jovyan/work'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "setwd(\"..\")\n", - "getwd()\n", - "#> '/home/jovyan'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.2 関数\n", - "\n", - "### 3.2.1 関数の利用" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sqrt(4)\n", - "#> [1] 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "log(100, 10)\n", - "#> [1] 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "log(100) # 自然対数\n", - "# あるいは\n", - "log(100, exp(1)) # 省略しない場合\n", - "\n", - "#> [1] 4.60517" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "log10(100) # 常用対数\n", - "#> [1] 2\n", - "\n", - "log2(1024) # 底が2の対数\n", - "#> [1] 10" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.1.1 パイプ(Rのみ)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "4 %>% sqrt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "exp(log(5)) # 通常の書き方\n", - "# あるいは\n", - "5 %>% log %>% exp # パイプを使う書き方\n", - "\n", - "#> 5" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.2.2 関数の定義" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(a, b) {\n", - " a - b\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f(3, 5)\n", - "#> [1] -2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.2.1 デフォルト引数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(a, b = 5) {\n", - " a - b\n", - "}\n", - "\n", - "f(3) # f(3, 5)と同じこと\n", - "#> [1] -2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.2.2.2 無名関数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(function(a, b) { a - b })(3, 5)\n", - "#> [1] -2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.3 コレクション\n", - "\n", - "### 3.3.1 1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(\"foo\", \"bar\", \"baz\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "length(x)\n", - "#> [1] 3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[2]\n", - "#> [1] \"bar\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[2] <- \"BAR\"\n", - "x # 結果の確認\n", - "#> [1] \"foo\" \"BAR\" \"baz\"\n", - "\n", - "x[2] <- \"bar\" # 元に戻す." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[-2]\n", - "#> [1] \"foo\" \"baz\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c(x, \"qux\")\n", - "#> [1] \"foo\" \"bar\" \"baz\" \"qux\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(x, \"qux\")\n", - "x # 結果の確認\n", - "#> [1] \"foo\" \"bar\" \"baz\" \"qux\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.1.1 等間隔の数値からなる1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1:5\n", - "#> [1] 1 2 3 4 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "seq(from = 0, to = 10, by = 2)\n", - "#> [1] 0 2 4 6 8 10" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "seq(from = 0, to = 1, by = 0.5)\n", - "#> [1] 0.0 0.5 1.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "seq(from = 0, to = 100, length.out = 5)\n", - "#> [1] 0 25 50 75 100" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rep(x = 10, times = 5)\n", - "#> [1] 10 10 10 10 10" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.1.2 ファクタ(Rのみ)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- c(\"グー\", \"パー\", \"グー\", \"パー\")\n", - "x <- factor(tmp, levels = c(\"グー\", \"チョキ\", \"パー\"))\n", - "x\n", - "#> [1] グー パー グー パー\n", - "#> Levels: グー チョキ パー" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.2 数値計算やデータ解析用の1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(2, 3, 5, 7)\n", - "\n", - "x + 10 # 加算\n", - "#> [1] 12 13 15 17\n", - "\n", - "x * 10 # 乗算\n", - "#> [1] 20 30 50 70" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(2, 3)\n", - "sin(x)\n", - "#> [1] 0.9092974 0.1411200" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(2, 3, 5, 7)\n", - "y <- c(1, 10, 100, 1000)\n", - "x + y\n", - "#> [1] 3 13 105 1007\n", - "\n", - "x * y\n", - "#> [1] 2 30 500 7000" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum(x * y)\n", - "#> [1] 7532" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(TRUE, FALSE)\n", - "y <- c(TRUE, TRUE)\n", - "x & y\n", - "#> [1] TRUE FALSE" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.3.2.1 1次元データ同士の比較" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "u <- c(1, 2, 3)\n", - "v <- c(1, 2, 3)\n", - "w <- c(1, 2, 4)\n", - "\n", - "identical(u, v) # 全体の比較\n", - "#> [1] TRUE\n", - "\n", - "identical(u, w) # 全体の比較\n", - "#> [1] FALSE\n", - "\n", - "u == v # 要素ごとの比較\n", - "#> [1] TRUE TRUE TRUE\n", - "\n", - "u == w # 要素ごとの比較\n", - "#> [1] TRUE TRUE FALSE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum(u == w) # 同じ要素の数\n", - "#> [1] 2\n", - "\n", - "mean(u == w) # 同じ要素の割合\n", - "#> [1] 0.6666667" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.3 複数種類のデータをひとまとめにする" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- list(1, \"two\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[[2]]\n", - "#> [1] \"two\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.4 文字列と値のペアのコレクション" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- list(\"apple\" = \"りんご\",\n", - " \"orange\" = \"みかん\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x[[\"grape\"]] <- \"ぶどう\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x$apple\n", - "# あるいは\n", - "x$\"apple\"\n", - "# あるいは\n", - "x[[\"apple\"]]\n", - "# あるいは\n", - "tmp <- \"apple\"\n", - "x[[tmp]]\n", - "\n", - "#> [1] \"りんご\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3.5 補足:コピーと参照" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(\"foo\", \"bar\", \"baz\")\n", - "y <- x\n", - "y[2] <- \"BAR\" # yを更新する.\n", - "y\n", - "#> [1] \"foo\" \"BAR\" \"baz\"\n", - "\n", - "x # xは変わらない.\n", - "#> [1] \"foo\" \"bar\" \"baz\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.4 データフレーム\n", - "\n", - "### 3.4.1 データフレームの作成" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.1 データを列ごとに記述する方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- data.frame(\n", - " name = c(\"A\", \"B\", \"C\", \"D\"),\n", - " english = c( 60, 90, 70, 90),\n", - " math = c( 70, 80, 90, 100),\n", - " gender = c(\"f\", \"m\", \"m\", \"f\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.2 データを見た目のとおりに記述する方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- tribble(\n", - " ~name, ~english, ~math, ~gender,\n", - " \"A\", 60, 70, \"f\",\n", - " \"B\", 90, 80, \"m\",\n", - " \"C\", 70, 90, \"m\",\n", - " \"D\", 90, 100, \"f\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_df)\n", - "# 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.3 データフレームのサイズ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "dim(my_df) # 行数と列数\n", - "#> [1] 4 4\n", - "\n", - "nrow(my_df) # 行数\n", - "#> [1] 4\n", - "\n", - "ncol(my_df) # 列数\n", - "#> [1] 4" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.4 組合せ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- expand.grid(\n", - " X = c(1, 2, 3),\n", - " Y = c(10, 100))\n", - "my_df2\n", - "#> X Y\n", - "#> 1 1 10\n", - "#> 2 2 10\n", - "#> 3 3 10\n", - "#> 4 1 100\n", - "#> 5 2 100\n", - "#> 6 3 100" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.1.5 列と行の名前" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "colnames(my_df2)\n", - "#> [1] \"X\" \"Y\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "colnames(my_df2) <- c(\"P\", \"Q\")\n", - "my_df2\n", - "#> P Q\n", - "#> 1 1 10\n", - "#> 2 2 10\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "row.names(my_df)\n", - "#> [1] \"1\" \"2\" \"3\" \"4\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "row.names(my_df2) <-\n", - " c(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\")\n", - "my_df2\n", - "#> P Q\n", - "#> a 1 10\n", - "#> b 2 10\n", - "#> c 3 10\n", - "# 以下省略" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df3 <- data.frame(\n", - " english = c( 60, 90, 70, 90),\n", - " math = c( 70, 80, 90, 100),\n", - " gender = c(\"f\", \"m\", \"m\", \"f\"),\n", - " row.names = c(\"A\", \"B\", \"C\", \"D\"))\n", - "my_df3\n", - "#> english math gender\n", - "#> A 60 70 f\n", - "#> B 90 80 m\n", - "#> C 70 90 m\n", - "#> D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.2 データの追加\n", - "\n", - "#### 3.4.2.1 行の追加(データフレームの結合)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- data.frame(\n", - " name = \"E\",\n", - " english = 80,\n", - " math = 80,\n", - " gender = \"m\")\n", - "my_df2 <- rbind(my_df, tmp)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.2.2 列の追加" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- my_df %>%\n", - " mutate(id = c(1, 2, 3, 4))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df3 <- my_df # コピー\n", - "my_df3[\"id\"] <- c(1, 2, 3, 4) # 更新\n", - "my_df3 # 結果の確認(割愛)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.3 データの取り出し\n", - "\n", - "#### 3.4.3.1 観測値の取り出し" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df[1, 2]\n", - "#> [1] 60" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.2 1列の取り出し(結果は1次元データ)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[, 2]\n", - "# あるいは\n", - "x <- my_df$english\n", - "# あるいは\n", - "x <- my_df$\"english\"\n", - "# あるいは\n", - "x <- my_df[[\"english\"]]\n", - "# あるいは\n", - "tmp <- \"english\"\n", - "x <- my_df[[tmp]]\n", - "\n", - "x # 結果の確認(割愛)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.3 複数列の取り出し(結果はデータフレーム)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df %>% select(name, math)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[, c(1, 3)]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df %>%\n", - " select(-c(english, gender))\n", - "# あるいは\n", - "x <- my_df[, -c(2, 4)]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.4 複数行の取り出し(結果はデータフレーム)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[c(1, 3), ]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[-c(2, 4), ]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.5 検索" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[my_df$gender == \"m\", ]\n", - "# あるいは\n", - "x <- my_df %>% filter(gender == \"m\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[my_df$english > 80 & my_df$gender == \"m\", ]\n", - "# あるいは\n", - "x <- my_df %>% filter(english > 80 & gender == \"m\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df[my_df$english == max(my_df$english), ]\n", - "# あるいは\n", - "x <- my_df %>% filter(english == max(my_df$english))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- my_df # コピー\n", - "my_df2[my_df$gender == \"m\", ]$gender <- \"M\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2\n", - "#> name english math gender\n", - "#> 1 A 60 70 f\n", - "#> 2 B 90 80 M\n", - "#> 3 C 70 90 M\n", - "#> 4 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.3.6 並べ替え" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df %>% arrange(english)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- my_df %>% arrange(-english)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.4 補足:行列\n", - "\n", - "#### 3.4.4.1 行列の生成" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(2, 3, 5, 7, 11, 13, 17, 19, 23,\n", - " 29, 31, 37)\n", - "A <- matrix(\n", - " data = x, # 1次元データ\n", - " nrow = 3, # 行数\n", - " byrow = TRUE) # 行ごとの生成\n", - "A\n", - "#> [,1] [,2] [,3] [,4]\n", - "#> [1,] 2 3 5 7\n", - "#> [2,] 11 13 17 19\n", - "#> [3,] 23 29 31 37" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.2 データフレームと行列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A <- my_df[, c(2, 3)] %>% as.matrix\n", - "A\n", - "#> english math\n", - "#> [1,] 60 70\n", - "#> [2,] 90 80\n", - "#> [3,] 70 90\n", - "#> [4,] 90 100" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "as.data.frame(A)\n", - "#> english math\n", - "#> 1 60 70\n", - "#> 2 90 80\n", - "#> 3 70 90\n", - "#> 4 90 100" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.3 行列の変形" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "t(A)\n", - "#> [,1] [,2] [,3] [,4]\n", - "#> english 60 90 70 90\n", - "#> math 70 80 90 100" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.4.4.4 行列の積" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "t(A) %*% A\n", - "#> english math\n", - "#> english 24700 26700\n", - "#> math 26700 29400" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4.5 縦型と横型" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_wider <- data.frame(\n", - " day = c(25, 26, 27),\n", - " min = c(20, 21, 15),\n", - " max = c(24, 27, 21))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_longer <- my_wider %>%\n", - " pivot_longer(-day)\n", - "my_longer\n", - "#> # A tibble: 6 x 3\n", - "#> day name value\n", - "#> \n", - "#> 1 25 min 20\n", - "#> 2 25 max 24\n", - "#> 3 26 min 21\n", - "#> 4 26 max 27\n", - "#> 5 27 min 15\n", - "#> 6 27 max 21" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_longer %>% pivot_wider()\n", - "#> # A tibble: 3 x 3\n", - "#> day min max\n", - "#> \n", - "#> 1 25 20 24\n", - "#> 2 26 21 27\n", - "#> 3 27 15 21" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_longer %>%\n", - " ggplot(aes(x = day, y = value,\n", - " color = name)) +\n", - " geom_point() +\n", - " geom_line() +\n", - " ylab(\"temperature\") + # y軸ラベル\n", - " scale_x_continuous(\n", - " breaks = my_longer$day) # x軸目盛り" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.5 1次元データの(非)類似度\n", - "\n", - "### 3.5.1 ユークリッド距離" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A <- c(3, 4, 5)\n", - "B <- c(3, 4, 29)\n", - "C <- c(9, -18, 8)\n", - "AB <- B - A\n", - "AC <- C - A\n", - "\n", - "sum(AB^2)^0.5\n", - "#> [1] 24\n", - "\n", - "sum(AC^2)^0.5\n", - "#> [1] 23" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.2 マンハッタン距離" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum(abs(AB))\n", - "#> [1] 24\n", - "\n", - "sum(abs(AC))\n", - "#> [1] 31" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.3 コサイン類似度" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum(A * B) /\n", - " sum(A * A)^0.5 / sum(B * B)^0.5\n", - "#> [1] 0.8169679\n", - "\n", - "sum(A * C) /\n", - " sum(A * A)^0.5 / sum(C * C)^0.5\n", - "#> [1] -0.03265116" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.5.4 相関係数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "cor(A, B)\n", - "#> [1] 0.8824975\n", - "\n", - "cor(A, C)\n", - "#> [1] -0.03266277" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3.5.4.1 データフレームを使う方法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "\n", - "\n", - "my_df <- data.frame(\n", - " x = c(3, 3, 9),\n", - " y = c(4, 4, -18),\n", - " z = c(5, 29, 8),\n", - " row.names = c(\"A\", \"B\", \"C\"))\n", - "\n", - "# ユークリッド距離\n", - "my_df %>% proxy::dist(\"Euclidean\")\n", - "#> A B\n", - "#> B 24\n", - "#> C 23 31\n", - "\n", - "\n", - "# マンハッタン距離\n", - "my_df %>% proxy::dist(\"Manhattan\")\n", - "#> A B\n", - "#> B 24\n", - "#> C 31 49\n", - "\n", - "\n", - "# コサイン類似度\n", - "my_df %>% proxy::simil(\"cosine\")\n", - "#> A B\n", - "#> B 0.81696786\n", - "#> C -0.03265116 0.29342441\n", - "\n", - "\n", - "# 相関係数\n", - "my_df %>% proxy::simil(\"correlation\")\n", - "#> A B\n", - "#> B 0.88249750\n", - "#> C -0.03266277 0.44124132" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.6 Rのパッケージ,Pythonのモジュール\n", - "\n", - "### 3.6.1 Rのパッケージ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.6.2 Pythonのモジュール\n", - "\n", - "## 3.7 反復処理" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.1 指定した回数→1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f1 <- function(x) {\n", - " tmp <- runif(x)\n", - " mean(tmp)\n", - "}\n", - "\n", - "f1(10) # 動作確認\n", - "#> [1] 0.5776604 # 結果の例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "replicate(n = 3, expr = f1(10))\n", - "#> [1] 0.4672766 0.4712016 0.5579449" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rep(x = f1(10), times = 3)\n", - "#> [1] 0.481329 0.481329 0.481329" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.2 1次元データ→1次元データ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v <- c(5, 10, 100)\n", - "v %>% map_dbl(f1)\n", - "#> [1] 0.4857329 0.5322183 0.5084124" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rep(x = 10, times = 3) %>% map_dbl(f1)\n", - "# 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.3 1次元データ→データフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f2 <- function(n) {\n", - " tmp <- runif(n)\n", - " list(x = n,\n", - " p = mean(tmp),\n", - " q = sd(tmp))\n", - "}\n", - "\n", - "f2(10) # 動作確認\n", - "#> $x\n", - "#> [1] 10\n", - "#>\n", - "#> $p\n", - "#> [1] 0.6840032 (平均の例)\n", - "#>\n", - "#> $q\n", - "#> [1] 0.3750788 (標準偏差の例)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v <- c(5, 10, 100)\n", - "v %>% map_dfr(f2)\n", - "#> x p q\n", - "#> \n", - "#> 1 5 0.560 0.320\n", - "#> 2 10 0.559 0.271\n", - "#> 3 100 0.507 0.283" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.4 データフレーム→データフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f3 <- function(x, y) {\n", - " tmp <- runif(x, min = 1,\n", - " max = y + 1) %>%\n", - " as.integer\n", - " list(x = x,\n", - " y = y,\n", - " p = mean(tmp),\n", - " q = sd(tmp))\n", - "}\n", - "\n", - "f3(x = 10, y = 6) # 動作確認\n", - "#> $x\n", - "#> [1] 10\n", - "#>\n", - "#> $y\n", - "#> [1] 6\n", - "#>\n", - "#> $p\n", - "#> [1] 3.2 (平均の例)\n", - "#>\n", - "#> $q\n", - "#> [1] 1.316561 (標準偏差の例)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- data.frame(\n", - " x = c(5, 10, 100, 5, 10, 100),\n", - " y = c(6, 6, 6, 12, 12, 12))\n", - "\n", - "my_df %>% pmap_dfr(f3)\n", - "#> x y p q\n", - "#> \n", - "#> 1 5 6 3 1.41\n", - "#> 2 10 6 3 1.49\n", - "#> 3 100 6 3.57 1.78\n", - "#> 4 5 12 7.6 5.22\n", - "#> 5 10 12 5.7 3.77\n", - "#> 6 100 12 6.36 3.59" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.7.5 補足:反復処理の並列化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(furrr)\n", - "plan(multisession) # 準備\n", - "\n", - "v <- c(5, 10, 100)\n", - "v %>% future_map_dbl(f1, .options =\n", - " furrr_options(seed = TRUE))\n", - "# 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.8 その他\n", - "\n", - "### 3.8.1 よく遭遇するエラーとその対処方法\n", - "\n", - "### 3.8.2 変数や関数についての調査" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- 123\n", - "typeof(x)\n", - "#> [1] \"double\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "?log\n", - "# あるいは\n", - "help(log)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.8.3 RのNA,Pythonのnan" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v <- c(1, NA, 3)\n", - "v\n", - "#> [1] 1 NA 3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "is.na(v[2])\n", - "#> [1] TRUE\n", - "\n", - "v[2] == NA # 誤り\n", - "#> [1] NA" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch04/04-colab.ipynb b/code/R-notebook/ch04/04-colab.ipynb deleted file mode 100644 index 29d6e76..0000000 --- a/code/R-notebook/ch04/04-colab.ipynb +++ /dev/null @@ -1,1123 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 04" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Google Colaboratoryの環境設定\n", - "options(Ncpus = 2)\n", - "install.packages(c(\"exactci\", \"ggmosaic\", \"pastecs\", \"psych\", \"vcd\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.1 記述統計\n", - "\n", - "### 4.1.1 平均・分散・標準偏差" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(165, 170, 175, 180, 185)\n", - "mean(x) # 平均\n", - "#> [1] 175" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n <- length(x) # サンプルサイズ\n", - "sum(x) / n\n", - "#> [1] 175" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- c(173, 174, 175, 176, 177)\n", - "mean(y)\n", - "#> [1] 175" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "var(x) # xの分散\n", - "#> [1] 62.5\n", - "\n", - "var(y) # yの分散\n", - "#> [1] 2.5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum((x - mean(x))^2) / (n - 1)\n", - "#> [1] 62.5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sd(x) # xの標準偏差\n", - "#> [1] 7.905694\n", - "\n", - "sd(y) # yの標準偏差\n", - "#> [1] 1.581139" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "var(x)**0.5 # xの標準偏差\n", - "#> [1] 7.905694" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "psych::describe(x)\n", - "#> vars n mean sd ...\n", - "#> X1 1 5 175 7.91 ...\n", - "\n", - "# あるいは\n", - "\n", - "pastecs::stat.desc(x)\n", - "#> nbr.val ... std.dev ...\n", - "#> 5.0000000 ... 7.9056942 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "quantile(x)\n", - "#> 0% 25% 50% 75% 100%\n", - "#> 165 170 175 180 185" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.1.1 不偏分散とその非負の平方根" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(165, 170, 175, 180, 185)\n", - "\n", - "var(x) # 不偏分散\n", - "#> [1] 62.5\n", - "\n", - "mean((x - mean(x))^2) # 標本分散\n", - "# あるいは\n", - "n <- length(x)\n", - "var(x) * (n - 1) / n # 標本分散\n", - "#> [1] 50" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sd(x) # √不偏分散\n", - "#> [1] 7.905694\n", - "\n", - "mean((x - mean(x))^2)^0.5 # √標本分散\n", - "# あるいは\n", - "sd(x) * sqrt((n - 1) / n) # √標本分散\n", - "#> [1] 7.071068" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sd(x) / length(x)**0.5\n", - "#> [1] 3.535534" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.1.2 データフレームの統計処理" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_df <- data.frame(\n", - " name = c(\"A\", \"B\", \"C\", \"D\"),\n", - " english = c( 60, 90, 70, 90),\n", - " math = c( 70, 80, 90, 100),\n", - " gender = c(\"f\", \"m\", \"m\", \"f\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.2.1 列ごとの集計" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "var(my_df$english)\n", - "#> [1] 225" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 結果はベクタ\n", - "my_df[, c(2, 3)] %>% sapply(var)\n", - "#> english math\n", - "#> 225.0000 166.6667\n", - "\n", - "# 結果はリスト\n", - "my_df[, c(2, 3)] %>% lapply(var)\n", - "#> $english\n", - "#> [1] 225\n", - "#>\n", - "#> $math\n", - "#> [1] 166.6667\n", - "\n", - "# 結果はデータフレーム\n", - "my_df[, c(2, 3)] %>% # 2, 3列目\n", - " summarize(across( # の\n", - " everything(), # 全ての\n", - " var)) # 不偏分散\n", - "# あるいは\n", - "my_df %>% # データフレーム\n", - " summarize(across( # の\n", - " where(is.numeric), # 数値の列の\n", - " var)) # 不偏分散\n", - "# あるいは\n", - "my_df %>% # データフレーム\n", - " summarize(across( # の\n", - " where(is.numeric), # 数値の列の\n", - " function(x) { var(x) })) # 不偏分散\n", - "\n", - "#> english math\n", - "#> 1 225 166.6667" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "psych::describe(my_df)\n", - "#> vars n mean sd ...\n", - "#> name* 1 4 2.5 1.29 ...\n", - "#> english 2 4 77.5 15.00 ...\n", - "#> math 3 4 85.0 12.91 ...\n", - "#> gender* 4 4 1.5 0.58 ...\n", - "\n", - "# あるいは\n", - "\n", - "pastecs::stat.desc(my_df)\n", - "#> name english ...\n", - "#> nbr.val NA 4.0000000 ...\n", - "#> nbr.null NA 0.0000000 ...\n", - "#> nbr.na NA 0.0000000 ...\n", - "#> min NA 60.0000000 ...\n", - "#> max NA 90.0000000 ...\n", - "# 以下省略" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.2.2 分割表とグループごとの集計" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "table(my_df$gender)\n", - "\n", - "#> f m\n", - "#> 2 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- data.frame(\n", - " gender = my_df$gender,\n", - " excel = my_df$math >= 80)\n", - "table(my_df2)\n", - "\n", - "#> excel\n", - "#> gender FALSE TRUE\n", - "#> f 1 1\n", - "#> m 0 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df %>% group_by(gender) %>%\n", - " summarize(across(\n", - " where(is.numeric), mean),\n", - " .groups = \"drop\") # グループ化解除\n", - "\n", - "#> # A tibble: 2 x 3\n", - "#> gender english math\n", - "#> \n", - "#> 1 f 75 85\n", - "#> 2 m 80 85" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.2 データの可視化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(iris)\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 1 5.1 3.5 1.4 0.2 setosa\n", - "#> 2 4.9 3.0 1.4 0.2 setosa\n", - "#> 3 4.7 3.2 1.3 0.2 setosa\n", - "#> 4 4.6 3.1 1.5 0.2 setosa\n", - "#> 5 5.0 3.6 1.4 0.2 setosa\n", - "#> 6 5.4 3.9 1.7 0.4 setosa" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.1 ヒストグラム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "hist(iris$Sepal.Length)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(10, 20, 30)\n", - "hist(x, breaks = 2) # 階級数は2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- iris$Sepal.Length\n", - "tmp <- seq(min(x), max(x),\n", - " length.out = 10)\n", - "hist(x, breaks = tmp, right = FALSE)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.2 散布図" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plot(iris$Sepal.Length,\n", - " iris$Sepal.Width)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.3 箱ひげ図" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "boxplot(iris[, -5])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.4 棒グラフとエラーバー" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "my_df <- psych::describe(iris[, -5])\n", - "my_df %>% select(mean, sd, se)\n", - "#> mean sd se\n", - "#> Sepal.Length 5.84 0.83 0.07\n", - "#> Sepal.Width 3.06 0.44 0.04\n", - "#> Petal.Length 3.76 1.77 0.14\n", - "#> Petal.Width 1.20 0.76 0.06" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- rownames(my_df)\n", - "my_df %>% ggplot(aes(x = factor(tmp, levels = tmp), y = mean)) +\n", - " geom_col() +\n", - " geom_errorbar(aes(ymin = mean - se, ymax = mean + se)) +\n", - " xlab(NULL)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_group <- iris %>% group_by(Species) # 品種ごとに,\n", - "\n", - "my_df <- my_group %>% # 各変数の,平均と\n", - " summarize(across(everything(), mean)) %>%\n", - " pivot_longer(-Species)\n", - "\n", - "tmp <- my_group %>% # 標準誤差を求める.\n", - " summarize(across(everything(), ~ sd(.) / length(.)**0.5)) %>%\n", - " pivot_longer(-Species)\n", - "\n", - "my_df$se <- tmp$value\n", - "head(my_df)\n", - "#> # A tibble: 6 x 4\n", - "#> Species name value se\n", - "#> \n", - "#> 1 setosa Sepal.Length 5.01 0.0498\n", - "#> 2 setosa Sepal.Width 3.43 0.0536\n", - "#> 3 setosa Petal.Length 1.46 0.0246\n", - "#> 4 setosa Petal.Width 0.246 0.0149\n", - "#> 5 versicolor Sepal.Length 5.94 0.0730\n", - "#> 6 versicolor Sepal.Width 2.77 0.0444" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df %>%\n", - " ggplot(aes(x = Species, y = value, fill = name)) +\n", - " geom_col(position = \"dodge\") +\n", - " geom_errorbar(aes(ymin = value - se, ymax = value + se), position = \"dodge\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 各変数の平均\n", - "iris %>% pivot_longer(-Species) %>%\n", - " ggplot(aes(x = name, y = value)) +\n", - " geom_bar(stat = \"summary\", fun = mean) +\n", - " stat_summary(geom = \"errorbar\", fun.data = mean_se) +\n", - " xlab(NULL)\n", - "\n", - "# 各変数の平均(品種ごと)\n", - "iris %>% pivot_longer(-Species) %>%\n", - " ggplot(aes(x = Species, y = value, fill = name)) +\n", - " geom_bar(stat = \"summary\", fun = mean, position = \"dodge\") +\n", - " stat_summary(geom = \"errorbar\", fun.data = mean_se, position = \"dodge\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.5 モザイクプロット" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- data.frame(\n", - " Species = iris$Species,\n", - " w_Sepal = iris$Sepal.Width > 3)\n", - "table(my_df) # 分割表\n", - "#> w_Sepal\n", - "#> Species FALSE TRUE\n", - "#> setosa 8 42\n", - "#> versicolor 42 8\n", - "#> virginica 33 17\n", - "\n", - "mosaicplot(\n", - " formula = ~ Species + w_Sepal,\n", - " data = my_df)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(vcd)\n", - "vcd::mosaic(formula = ~w_Sepal + Species, data = my_df,\n", - " labeling = labeling_values)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.6 関数のグラフ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "curve(x^3 - x, -2, 2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.7 ggplot2 (R)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- iris$Sepal.Length\n", - "tmp <- seq(min(x), max(x),\n", - " length.out = 10)\n", - "iris %>%\n", - " ggplot(aes(x = Sepal.Length)) +\n", - " geom_histogram(breaks = tmp,\n", - " closed = \"left\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris %>%\n", - " ggplot(aes(x = Sepal.Length,\n", - " y = Sepal.Width)) +\n", - " geom_point()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris %>%\n", - " pivot_longer(-Species) %>%\n", - " ggplot(aes(\n", - " x = factor(name,\n", - " levels = names(iris)),\n", - " y = value)) +\n", - " geom_boxplot() +\n", - " xlab(NULL)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(ggmosaic)\n", - "my_df <- data.frame(\n", - " Species = iris$Species,\n", - " w_Sepal = iris$Sepal.Width > 3)\n", - "my_df %>%\n", - " ggplot() +\n", - " geom_mosaic(\n", - " aes(x = product(w_Sepal, Species)))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(x) { x^3 - x }\n", - "data.frame(x = c(-2, 2)) %>%\n", - " ggplot(aes(x = x)) +\n", - " stat_function(fun = f)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.3 乱数\n", - "\n", - "### 4.3.1 一様乱数(離散)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- sample(x = 1:6, # 範囲\n", - " size = 10000, # 乱数の数\n", - " replace = TRUE) # 重複あり\n", - "hist(x, breaks = 0:6) # ヒストグラム" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.2 一様乱数(連続)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- runif(min = 0, # 最小\n", - " max = 1, # 最大\n", - " n = 1000) # 乱数の数\n", - "hist(x)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- as.integer( # 整数に変換\n", - " runif(min = 1, # 最小\n", - " max = 7, # 最大 + 1\n", - " n = 1000)) # 乱数の数\n", - "hist(x, breaks = 0:6) # 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.3 二項乱数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n <- 100\n", - "p <- 0.5\n", - "r <- 10000\n", - "x <- rbinom(size = n, # 試行回数\n", - " prob = p, # 確率\n", - " n = r) # 乱数の数\n", - "hist(x, breaks = max(x) - min(x))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.4 正規乱数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "r <- 10000\n", - "x <- rnorm(mean = 50, # 平均\n", - " sd = 5, # 標準偏差\n", - " n = r) # 乱数の数\n", - "hist(x, breaks = 40)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.3.4.1 補足:不偏性の具体例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "f <- function(k) {\n", - " n <- 10000\n", - " tmp <- replicate(n = n, expr = g(rnorm(n = k, sd = 3)))\n", - " list(k = k,\n", - " mean = mean(tmp), # 平均\n", - " se = sd(tmp) / sqrt(n)) # 標準誤差\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "g <- var\n", - "c(10, 20, 30) %>% map_dfr(f)\n", - "#> # A tibble: 3 x 3\n", - "#> k mean se\n", - "#> \n", - "#> 1 10 8.98 0.0427\n", - "#> 2 20 8.97 0.0288\n", - "#> 3 30 9.03 0.0233" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "g <- sd\n", - "c(5, 10, 15, 20) %>% map_dfr(f)\n", - "#> # A tibble: 3 x 3\n", - "#> k mean se\n", - "#> \n", - "#> 1 10 2.92 0.00701\n", - "#> 2 20 2.95 0.00481\n", - "#> 3 30 2.97 0.00394" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "g <- function(x) {\n", - " n <- length(x)\n", - " sd(x) *\n", - " sqrt((n - 1) / 2) *\n", - " gamma((n - 1) / 2) /\n", - " gamma(n / 2)\n", - "}\n", - "c(10, 20, 30) %>% map_dfr(f)\n", - "#> # A tibble: 3 x 3\n", - "#> k mean se\n", - "#> \n", - "#> 1 10 3.00 0.00717\n", - "#> 2 20 2.99 0.00488\n", - "#> 3 30 3.00 0.00396" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.4 統計的推測\n", - "\n", - "### 4.4.1 検定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(exactci)\n", - "library(tidyverse)\n", - "\n", - "a <- 0.05 # 有意水準\n", - "binom.exact(x = 2, # 当たった回数\n", - " n = 15, # くじを引いた回数\n", - " p = 4 / 10, # 当たる確率(仮説)\n", - " plot = TRUE, # p値の描画(結果は次項に掲載)\n", - " conf.level = 1 - a, # 信頼係数(デフォルト)\n", - " tsmethod = \"minlike\", # p値の定義\n", - " alternative = \"two.sided\") # 両側検定(デフォルト)\n", - " # 左片側検定なら'less'\n", - " # 右片側検定なら'greater'\n", - "\n", - "#> Exact two-sided binomial test (central method)\n", - "#>\n", - "#> data: 2 and 15\n", - "#> number of successes = 2, number of trials = 15,\n", - "#> p-value = 0.03646\n", - "#> alternative hypothesis: true probability of success is not equal to 0.4\n", - "#> 95 percent confidence interval:\n", - "#> 0.0242 0.3967\n", - "#> sample estimates:\n", - "#> probability of success\n", - "#> 0.1333333" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.4.1.1 補足:p値とは何か" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "t <- 4 / 10 # 当たる確率\n", - "n <- 15 # くじを引いた回数\n", - "x <- 0:n # 当たった回数\n", - "my_pr <- dbinom(x, n, t) # x回当たる確率\n", - "my_pr2 <- dbinom(2, n, t) # 2回当たる確率\n", - "\n", - "my_data <- data.frame(x = x,\n", - " probability = my_pr,\n", - " color = my_pr <= my_pr2) # 当たる確率が,2回当たる確率以下\n", - "\n", - "my_data %>% ggplot(aes(x = x, y = probability, color = color)) +\n", - " geom_point(size = 3) +\n", - " geom_linerange(aes(ymin = 0, ymax = probability), ) + # 垂直線\n", - " geom_hline(yintercept = my_pr2) + # 水平線\n", - " theme(legend.position = \"none\") # 凡例を表示しない." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.2 推定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 前項の結果(再掲)\n", - "#> 95 percent confidence interval:\n", - "#> 0.0242 0.3967" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 前項冒頭のコード" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.3 平均の差の検定と推定(t検定)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X <- c(32.1, 26.2, 27.5, 31.8, 32.1, 31.2, 30.1, 32.4, 32.3, 29.9,\n", - " 29.6, 26.6, 31.2, 30.9, 29.3)\n", - "Y <- c(35.4, 34.6, 31.1, 32.4, 33.3, 34.7, 35.3, 34.3, 32.1, 28.3,\n", - " 33.3, 30.5, 32.6, 33.3, 32.2)\n", - "\n", - "t.test(x = X, y = Y,\n", - " conf.level = 0.95, # 信頼係数(デフォルト)\n", - " paired = TRUE, # 対標本である.\n", - " alternative = \"two.sided\") # 両側検定(デフォルト)\n", - " # 左片側検定なら'less'\n", - " # 右片側検定なら'greater'\n", - "\n", - "#> Paired t-test\n", - "#>\n", - "#> data: X and Y\n", - "#> t = -4.3694, df = 14, p-value = 0.0006416\n", - "#> alternative hypothesis: true difference in means is not equal to 0\n", - "#> 95 percent confidence interval:\n", - "#> -3.995525 -1.364475\n", - "#> sample estimates:\n", - "#> mean of the differences\n", - "#> -2.68" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "t.test(x = X, y = Y,\n", - " paired = FALSE, # 対標本ではない(デフォルト).\n", - " var.equal = TRUE, # 等分散を仮定する.仮定しないならFALSE(デフォルト).\n", - " alternative = \"two.sided\",\n", - " conf.level = 0.95)\n", - "\n", - "#> Two Sample t-test\n", - "#>\n", - "#> data: X and Y\n", - "#> t = -3.6821, df = 28, p-value = 0.0009785\n", - "#> alternative hypothesis: true difference in means is not equal to 0\n", - "#> 95 percent confidence interval:\n", - "#> -4.170906 -1.189094\n", - "#> sample estimates:\n", - "#> mean of x mean of y\n", - "#> 30.21333 32.89333" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.4 独立性の検定(カイ2乗検定)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/smoker.csv\")\n", - "my_data <- read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_data)\n", - "#> alive smoker\n", - "#> 1 Yes No\n", - "#> 2 Yes No\n", - "#> 3 Yes No\n", - "#> 4 Yes No\n", - "#> 5 Yes No\n", - "#> 6 Yes No" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_table <- table(my_data)\n", - "my_table\n", - "#> smoker\n", - "#> alive No Yes\n", - "#> No 117 54\n", - "#> Yes 950 348" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "chisq.test(my_table, correct = FALSE)\n", - "\n", - "#> Pearson's Chi-squared test\n", - "#>\n", - "#> data: my_data\n", - "#> X-squared = 1.7285, df = 1, p-value = 0.1886" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.5 ブートストラップ\n", - "\n", - "#### 4.4.5.1 15回引いて2回当たったくじ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X <- rep(0:1, c(13, 2)) # 手順1\n", - "X\n", - "#> [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1\n", - "\n", - "tmp <- sample(X, size = length(X), replace = TRUE) # 手順2\n", - "tmp\n", - "#> [1] 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0\n", - "\n", - "sum(tmp) # 手順3\n", - "#> [1] 2\n", - "\n", - "n <- 10^5\n", - "result <- replicate(n, sum(sample(X, size = length(X), replace = TRUE))) # 手順4" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "hist(x = result, breaks = 0:15,\n", - " right = FALSE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "quantile(result, c(0.025, 0.975))\n", - "#> 2.5% 97.5%\n", - "#> 0 5" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch04/04.01.ipynb b/code/R-notebook/ch04/04.01.ipynb deleted file mode 100644 index 8c6ddd6..0000000 --- a/code/R-notebook/ch04/04.01.ipynb +++ /dev/null @@ -1,335 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.1 記述統計\n", - "\n", - "### 4.1.1 平均・分散・標準偏差" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(165, 170, 175, 180, 185)\n", - "mean(x) # 平均\n", - "#> [1] 175" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n <- length(x) # サンプルサイズ\n", - "sum(x) / n\n", - "#> [1] 175" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- c(173, 174, 175, 176, 177)\n", - "mean(y)\n", - "#> [1] 175" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "var(x) # xの分散\n", - "#> [1] 62.5\n", - "\n", - "var(y) # yの分散\n", - "#> [1] 2.5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum((x - mean(x))^2) / (n - 1)\n", - "#> [1] 62.5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sd(x) # xの標準偏差\n", - "#> [1] 7.905694\n", - "\n", - "sd(y) # yの標準偏差\n", - "#> [1] 1.581139" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "var(x)**0.5 # xの標準偏差\n", - "#> [1] 7.905694" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "psych::describe(x)\n", - "#> vars n mean sd ...\n", - "#> X1 1 5 175 7.91 ...\n", - "\n", - "# あるいは\n", - "\n", - "pastecs::stat.desc(x)\n", - "#> nbr.val ... std.dev ...\n", - "#> 5.0000000 ... 7.9056942 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "quantile(x)\n", - "#> 0% 25% 50% 75% 100%\n", - "#> 165 170 175 180 185" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.1.1 不偏分散とその非負の平方根" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(165, 170, 175, 180, 185)\n", - "\n", - "var(x) # 不偏分散\n", - "#> [1] 62.5\n", - "\n", - "mean((x - mean(x))^2) # 標本分散\n", - "# あるいは\n", - "n <- length(x)\n", - "var(x) * (n - 1) / n # 標本分散\n", - "#> [1] 50" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sd(x) # √不偏分散\n", - "#> [1] 7.905694\n", - "\n", - "mean((x - mean(x))^2)^0.5 # √標本分散\n", - "# あるいは\n", - "sd(x) * sqrt((n - 1) / n) # √標本分散\n", - "#> [1] 7.071068" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sd(x) / length(x)**0.5\n", - "#> [1] 3.535534" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.1.2 データフレームの統計処理" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_df <- data.frame(\n", - " name = c(\"A\", \"B\", \"C\", \"D\"),\n", - " english = c( 60, 90, 70, 90),\n", - " math = c( 70, 80, 90, 100),\n", - " gender = c(\"f\", \"m\", \"m\", \"f\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.2.1 列ごとの集計" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "var(my_df$english)\n", - "#> [1] 225" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 結果はベクタ\n", - "my_df[, c(2, 3)] %>% sapply(var)\n", - "#> english math\n", - "#> 225.0000 166.6667\n", - "\n", - "# 結果はリスト\n", - "my_df[, c(2, 3)] %>% lapply(var)\n", - "#> $english\n", - "#> [1] 225\n", - "#>\n", - "#> $math\n", - "#> [1] 166.6667\n", - "\n", - "# 結果はデータフレーム\n", - "my_df[, c(2, 3)] %>% # 2, 3列目\n", - " summarize(across( # の\n", - " everything(), # 全ての\n", - " var)) # 不偏分散\n", - "# あるいは\n", - "my_df %>% # データフレーム\n", - " summarize(across( # の\n", - " where(is.numeric), # 数値の列の\n", - " var)) # 不偏分散\n", - "# あるいは\n", - "my_df %>% # データフレーム\n", - " summarize(across( # の\n", - " where(is.numeric), # 数値の列の\n", - " function(x) { var(x) })) # 不偏分散\n", - "\n", - "#> english math\n", - "#> 1 225 166.6667" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "psych::describe(my_df)\n", - "#> vars n mean sd ...\n", - "#> name* 1 4 2.5 1.29 ...\n", - "#> english 2 4 77.5 15.00 ...\n", - "#> math 3 4 85.0 12.91 ...\n", - "#> gender* 4 4 1.5 0.58 ...\n", - "\n", - "# あるいは\n", - "\n", - "pastecs::stat.desc(my_df)\n", - "#> name english ...\n", - "#> nbr.val NA 4.0000000 ...\n", - "#> nbr.null NA 0.0000000 ...\n", - "#> nbr.na NA 0.0000000 ...\n", - "#> min NA 60.0000000 ...\n", - "#> max NA 90.0000000 ...\n", - "# 以下省略" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.2.2 分割表とグループごとの集計" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "table(my_df$gender)\n", - "\n", - "#> f m\n", - "#> 2 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- data.frame(\n", - " gender = my_df$gender,\n", - " excel = my_df$math >= 80)\n", - "table(my_df2)\n", - "\n", - "#> excel\n", - "#> gender FALSE TRUE\n", - "#> f 1 1\n", - "#> m 0 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df %>% group_by(gender) %>%\n", - " summarize(across(\n", - " where(is.numeric), mean),\n", - " .groups = \"drop\") # グループ化解除\n", - "\n", - "#> # A tibble: 2 x 3\n", - "#> gender english math\n", - "#> \n", - "#> 1 f 75 85\n", - "#> 2 m 80 85" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch04/04.02.ipynb b/code/R-notebook/ch04/04.02.ipynb deleted file mode 100644 index 7685912..0000000 --- a/code/R-notebook/ch04/04.02.ipynb +++ /dev/null @@ -1,336 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.2 データの可視化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(iris)\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 1 5.1 3.5 1.4 0.2 setosa\n", - "#> 2 4.9 3.0 1.4 0.2 setosa\n", - "#> 3 4.7 3.2 1.3 0.2 setosa\n", - "#> 4 4.6 3.1 1.5 0.2 setosa\n", - "#> 5 5.0 3.6 1.4 0.2 setosa\n", - "#> 6 5.4 3.9 1.7 0.4 setosa" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.1 ヒストグラム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "hist(iris$Sepal.Length)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(10, 20, 30)\n", - "hist(x, breaks = 2) # 階級数は2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- iris$Sepal.Length\n", - "tmp <- seq(min(x), max(x),\n", - " length.out = 10)\n", - "hist(x, breaks = tmp, right = FALSE)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.2 散布図" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plot(iris$Sepal.Length,\n", - " iris$Sepal.Width)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.3 箱ひげ図" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "boxplot(iris[, -5])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.4 棒グラフとエラーバー" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "my_df <- psych::describe(iris[, -5])\n", - "my_df %>% select(mean, sd, se)\n", - "#> mean sd se\n", - "#> Sepal.Length 5.84 0.83 0.07\n", - "#> Sepal.Width 3.06 0.44 0.04\n", - "#> Petal.Length 3.76 1.77 0.14\n", - "#> Petal.Width 1.20 0.76 0.06" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- rownames(my_df)\n", - "my_df %>% ggplot(aes(x = factor(tmp, levels = tmp), y = mean)) +\n", - " geom_col() +\n", - " geom_errorbar(aes(ymin = mean - se, ymax = mean + se)) +\n", - " xlab(NULL)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_group <- iris %>% group_by(Species) # 品種ごとに,\n", - "\n", - "my_df <- my_group %>% # 各変数の,平均と\n", - " summarize(across(everything(), mean)) %>%\n", - " pivot_longer(-Species)\n", - "\n", - "tmp <- my_group %>% # 標準誤差を求める.\n", - " summarize(across(everything(), ~ sd(.) / length(.)**0.5)) %>%\n", - " pivot_longer(-Species)\n", - "\n", - "my_df$se <- tmp$value\n", - "head(my_df)\n", - "#> # A tibble: 6 x 4\n", - "#> Species name value se\n", - "#> \n", - "#> 1 setosa Sepal.Length 5.01 0.0498\n", - "#> 2 setosa Sepal.Width 3.43 0.0536\n", - "#> 3 setosa Petal.Length 1.46 0.0246\n", - "#> 4 setosa Petal.Width 0.246 0.0149\n", - "#> 5 versicolor Sepal.Length 5.94 0.0730\n", - "#> 6 versicolor Sepal.Width 2.77 0.0444" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df %>%\n", - " ggplot(aes(x = Species, y = value, fill = name)) +\n", - " geom_col(position = \"dodge\") +\n", - " geom_errorbar(aes(ymin = value - se, ymax = value + se), position = \"dodge\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 各変数の平均\n", - "iris %>% pivot_longer(-Species) %>%\n", - " ggplot(aes(x = name, y = value)) +\n", - " geom_bar(stat = \"summary\", fun = mean) +\n", - " stat_summary(geom = \"errorbar\", fun.data = mean_se) +\n", - " xlab(NULL)\n", - "\n", - "# 各変数の平均(品種ごと)\n", - "iris %>% pivot_longer(-Species) %>%\n", - " ggplot(aes(x = Species, y = value, fill = name)) +\n", - " geom_bar(stat = \"summary\", fun = mean, position = \"dodge\") +\n", - " stat_summary(geom = \"errorbar\", fun.data = mean_se, position = \"dodge\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.5 モザイクプロット" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- data.frame(\n", - " Species = iris$Species,\n", - " w_Sepal = iris$Sepal.Width > 3)\n", - "table(my_df) # 分割表\n", - "#> w_Sepal\n", - "#> Species FALSE TRUE\n", - "#> setosa 8 42\n", - "#> versicolor 42 8\n", - "#> virginica 33 17\n", - "\n", - "mosaicplot(\n", - " formula = ~ Species + w_Sepal,\n", - " data = my_df)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(vcd)\n", - "vcd::mosaic(formula = ~w_Sepal + Species, data = my_df,\n", - " labeling = labeling_values)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.6 関数のグラフ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "curve(x^3 - x, -2, 2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.7 ggplot2 (R)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- iris$Sepal.Length\n", - "tmp <- seq(min(x), max(x),\n", - " length.out = 10)\n", - "iris %>%\n", - " ggplot(aes(x = Sepal.Length)) +\n", - " geom_histogram(breaks = tmp,\n", - " closed = \"left\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris %>%\n", - " ggplot(aes(x = Sepal.Length,\n", - " y = Sepal.Width)) +\n", - " geom_point()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris %>%\n", - " pivot_longer(-Species) %>%\n", - " ggplot(aes(\n", - " x = factor(name,\n", - " levels = names(iris)),\n", - " y = value)) +\n", - " geom_boxplot() +\n", - " xlab(NULL)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(ggmosaic)\n", - "my_df <- data.frame(\n", - " Species = iris$Species,\n", - " w_Sepal = iris$Sepal.Width > 3)\n", - "my_df %>%\n", - " ggplot() +\n", - " geom_mosaic(\n", - " aes(x = product(w_Sepal, Species)))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(x) { x^3 - x }\n", - "data.frame(x = c(-2, 2)) %>%\n", - " ggplot(aes(x = x)) +\n", - " stat_function(fun = f)" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch04/04.03.ipynb b/code/R-notebook/ch04/04.03.ipynb deleted file mode 100644 index 3505f29..0000000 --- a/code/R-notebook/ch04/04.03.ipynb +++ /dev/null @@ -1,185 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.3 乱数\n", - "\n", - "### 4.3.1 一様乱数(離散)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- sample(x = 1:6, # 範囲\n", - " size = 10000, # 乱数の数\n", - " replace = TRUE) # 重複あり\n", - "hist(x, breaks = 0:6) # ヒストグラム" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.2 一様乱数(連続)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- runif(min = 0, # 最小\n", - " max = 1, # 最大\n", - " n = 1000) # 乱数の数\n", - "hist(x)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- as.integer( # 整数に変換\n", - " runif(min = 1, # 最小\n", - " max = 7, # 最大 + 1\n", - " n = 1000)) # 乱数の数\n", - "hist(x, breaks = 0:6) # 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.3 二項乱数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n <- 100\n", - "p <- 0.5\n", - "r <- 10000\n", - "x <- rbinom(size = n, # 試行回数\n", - " prob = p, # 確率\n", - " n = r) # 乱数の数\n", - "hist(x, breaks = max(x) - min(x))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.4 正規乱数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "r <- 10000\n", - "x <- rnorm(mean = 50, # 平均\n", - " sd = 5, # 標準偏差\n", - " n = r) # 乱数の数\n", - "hist(x, breaks = 40)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.3.4.1 補足:不偏性の具体例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "f <- function(k) {\n", - " n <- 10000\n", - " tmp <- replicate(n = n, expr = g(rnorm(n = k, sd = 3)))\n", - " list(k = k,\n", - " mean = mean(tmp), # 平均\n", - " se = sd(tmp) / sqrt(n)) # 標準誤差\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "g <- var\n", - "c(10, 20, 30) %>% map_dfr(f)\n", - "#> # A tibble: 3 x 3\n", - "#> k mean se\n", - "#> \n", - "#> 1 10 8.98 0.0427\n", - "#> 2 20 8.97 0.0288\n", - "#> 3 30 9.03 0.0233" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "g <- sd\n", - "c(5, 10, 15, 20) %>% map_dfr(f)\n", - "#> # A tibble: 3 x 3\n", - "#> k mean se\n", - "#> \n", - "#> 1 10 2.92 0.00701\n", - "#> 2 20 2.95 0.00481\n", - "#> 3 30 2.97 0.00394" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "g <- function(x) {\n", - " n <- length(x)\n", - " sd(x) *\n", - " sqrt((n - 1) / 2) *\n", - " gamma((n - 1) / 2) /\n", - " gamma(n / 2)\n", - "}\n", - "c(10, 20, 30) %>% map_dfr(f)\n", - "#> # A tibble: 3 x 3\n", - "#> k mean se\n", - "#> \n", - "#> 1 10 3.00 0.00717\n", - "#> 2 20 2.99 0.00488\n", - "#> 3 30 3.00 0.00396" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch04/04.04.ipynb b/code/R-notebook/ch04/04.04.ipynb deleted file mode 100644 index 7162373..0000000 --- a/code/R-notebook/ch04/04.04.ipynb +++ /dev/null @@ -1,285 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.4 統計的推測\n", - "\n", - "### 4.4.1 検定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(exactci)\n", - "library(tidyverse)\n", - "\n", - "a <- 0.05 # 有意水準\n", - "binom.exact(x = 2, # 当たった回数\n", - " n = 15, # くじを引いた回数\n", - " p = 4 / 10, # 当たる確率(仮説)\n", - " plot = TRUE, # p値の描画(結果は次項に掲載)\n", - " conf.level = 1 - a, # 信頼係数(デフォルト)\n", - " tsmethod = \"minlike\", # p値の定義\n", - " alternative = \"two.sided\") # 両側検定(デフォルト)\n", - " # 左片側検定なら'less'\n", - " # 右片側検定なら'greater'\n", - "\n", - "#> Exact two-sided binomial test (central method)\n", - "#>\n", - "#> data: 2 and 15\n", - "#> number of successes = 2, number of trials = 15,\n", - "#> p-value = 0.03646\n", - "#> alternative hypothesis: true probability of success is not equal to 0.4\n", - "#> 95 percent confidence interval:\n", - "#> 0.0242 0.3967\n", - "#> sample estimates:\n", - "#> probability of success\n", - "#> 0.1333333" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.4.1.1 補足:p値とは何か" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "t <- 4 / 10 # 当たる確率\n", - "n <- 15 # くじを引いた回数\n", - "x <- 0:n # 当たった回数\n", - "my_pr <- dbinom(x, n, t) # x回当たる確率\n", - "my_pr2 <- dbinom(2, n, t) # 2回当たる確率\n", - "\n", - "my_data <- data.frame(x = x,\n", - " probability = my_pr,\n", - " color = my_pr <= my_pr2) # 当たる確率が,2回当たる確率以下\n", - "\n", - "my_data %>% ggplot(aes(x = x, y = probability, color = color)) +\n", - " geom_point(size = 3) +\n", - " geom_linerange(aes(ymin = 0, ymax = probability), ) + # 垂直線\n", - " geom_hline(yintercept = my_pr2) + # 水平線\n", - " theme(legend.position = \"none\") # 凡例を表示しない." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.2 推定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 前項の結果(再掲)\n", - "#> 95 percent confidence interval:\n", - "#> 0.0242 0.3967" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 前項冒頭のコード" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.3 平均の差の検定と推定(t検定)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X <- c(32.1, 26.2, 27.5, 31.8, 32.1, 31.2, 30.1, 32.4, 32.3, 29.9,\n", - " 29.6, 26.6, 31.2, 30.9, 29.3)\n", - "Y <- c(35.4, 34.6, 31.1, 32.4, 33.3, 34.7, 35.3, 34.3, 32.1, 28.3,\n", - " 33.3, 30.5, 32.6, 33.3, 32.2)\n", - "\n", - "t.test(x = X, y = Y,\n", - " conf.level = 0.95, # 信頼係数(デフォルト)\n", - " paired = TRUE, # 対標本である.\n", - " alternative = \"two.sided\") # 両側検定(デフォルト)\n", - " # 左片側検定なら'less'\n", - " # 右片側検定なら'greater'\n", - "\n", - "#> Paired t-test\n", - "#>\n", - "#> data: X and Y\n", - "#> t = -4.3694, df = 14, p-value = 0.0006416\n", - "#> alternative hypothesis: true difference in means is not equal to 0\n", - "#> 95 percent confidence interval:\n", - "#> -3.995525 -1.364475\n", - "#> sample estimates:\n", - "#> mean of the differences\n", - "#> -2.68" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "t.test(x = X, y = Y,\n", - " paired = FALSE, # 対標本ではない(デフォルト).\n", - " var.equal = TRUE, # 等分散を仮定する.仮定しないならFALSE(デフォルト).\n", - " alternative = \"two.sided\",\n", - " conf.level = 0.95)\n", - "\n", - "#> Two Sample t-test\n", - "#>\n", - "#> data: X and Y\n", - "#> t = -3.6821, df = 28, p-value = 0.0009785\n", - "#> alternative hypothesis: true difference in means is not equal to 0\n", - "#> 95 percent confidence interval:\n", - "#> -4.170906 -1.189094\n", - "#> sample estimates:\n", - "#> mean of x mean of y\n", - "#> 30.21333 32.89333" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.4 独立性の検定(カイ2乗検定)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/smoker.csv\")\n", - "my_data <- read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_data)\n", - "#> alive smoker\n", - "#> 1 Yes No\n", - "#> 2 Yes No\n", - "#> 3 Yes No\n", - "#> 4 Yes No\n", - "#> 5 Yes No\n", - "#> 6 Yes No" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_table <- table(my_data)\n", - "my_table\n", - "#> smoker\n", - "#> alive No Yes\n", - "#> No 117 54\n", - "#> Yes 950 348" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "chisq.test(my_table, correct = FALSE)\n", - "\n", - "#> Pearson's Chi-squared test\n", - "#>\n", - "#> data: my_data\n", - "#> X-squared = 1.7285, df = 1, p-value = 0.1886" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.5 ブートストラップ\n", - "\n", - "#### 4.4.5.1 15回引いて2回当たったくじ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X <- rep(0:1, c(13, 2)) # 手順1\n", - "X\n", - "#> [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1\n", - "\n", - "tmp <- sample(X, size = length(X), replace = TRUE) # 手順2\n", - "tmp\n", - "#> [1] 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0\n", - "\n", - "sum(tmp) # 手順3\n", - "#> [1] 2\n", - "\n", - "n <- 10^5\n", - "result <- replicate(n, sum(sample(X, size = length(X), replace = TRUE))) # 手順4" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "hist(x = result, breaks = 0:15,\n", - " right = FALSE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "quantile(result, c(0.025, 0.975))\n", - "#> 2.5% 97.5%\n", - "#> 0 5" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch04/04.ipynb b/code/R-notebook/ch04/04.ipynb deleted file mode 100644 index 00ee156..0000000 --- a/code/R-notebook/ch04/04.ipynb +++ /dev/null @@ -1,1107 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 04\n", - "\n", - "## 4.1 記述統計\n", - "\n", - "### 4.1.1 平均・分散・標準偏差" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(165, 170, 175, 180, 185)\n", - "mean(x) # 平均\n", - "#> [1] 175" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n <- length(x) # サンプルサイズ\n", - "sum(x) / n\n", - "#> [1] 175" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- c(173, 174, 175, 176, 177)\n", - "mean(y)\n", - "#> [1] 175" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "var(x) # xの分散\n", - "#> [1] 62.5\n", - "\n", - "var(y) # yの分散\n", - "#> [1] 2.5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sum((x - mean(x))^2) / (n - 1)\n", - "#> [1] 62.5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sd(x) # xの標準偏差\n", - "#> [1] 7.905694\n", - "\n", - "sd(y) # yの標準偏差\n", - "#> [1] 1.581139" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "var(x)**0.5 # xの標準偏差\n", - "#> [1] 7.905694" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "psych::describe(x)\n", - "#> vars n mean sd ...\n", - "#> X1 1 5 175 7.91 ...\n", - "\n", - "# あるいは\n", - "\n", - "pastecs::stat.desc(x)\n", - "#> nbr.val ... std.dev ...\n", - "#> 5.0000000 ... 7.9056942 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "quantile(x)\n", - "#> 0% 25% 50% 75% 100%\n", - "#> 165 170 175 180 185" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.1.1 不偏分散とその非負の平方根" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(165, 170, 175, 180, 185)\n", - "\n", - "var(x) # 不偏分散\n", - "#> [1] 62.5\n", - "\n", - "mean((x - mean(x))^2) # 標本分散\n", - "# あるいは\n", - "n <- length(x)\n", - "var(x) * (n - 1) / n # 標本分散\n", - "#> [1] 50" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sd(x) # √不偏分散\n", - "#> [1] 7.905694\n", - "\n", - "mean((x - mean(x))^2)^0.5 # √標本分散\n", - "# あるいは\n", - "sd(x) * sqrt((n - 1) / n) # √標本分散\n", - "#> [1] 7.071068" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sd(x) / length(x)**0.5\n", - "#> [1] 3.535534" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.1.2 データフレームの統計処理" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_df <- data.frame(\n", - " name = c(\"A\", \"B\", \"C\", \"D\"),\n", - " english = c( 60, 90, 70, 90),\n", - " math = c( 70, 80, 90, 100),\n", - " gender = c(\"f\", \"m\", \"m\", \"f\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.2.1 列ごとの集計" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "var(my_df$english)\n", - "#> [1] 225" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 結果はベクタ\n", - "my_df[, c(2, 3)] %>% sapply(var)\n", - "#> english math\n", - "#> 225.0000 166.6667\n", - "\n", - "# 結果はリスト\n", - "my_df[, c(2, 3)] %>% lapply(var)\n", - "#> $english\n", - "#> [1] 225\n", - "#>\n", - "#> $math\n", - "#> [1] 166.6667\n", - "\n", - "# 結果はデータフレーム\n", - "my_df[, c(2, 3)] %>% # 2, 3列目\n", - " summarize(across( # の\n", - " everything(), # 全ての\n", - " var)) # 不偏分散\n", - "# あるいは\n", - "my_df %>% # データフレーム\n", - " summarize(across( # の\n", - " where(is.numeric), # 数値の列の\n", - " var)) # 不偏分散\n", - "# あるいは\n", - "my_df %>% # データフレーム\n", - " summarize(across( # の\n", - " where(is.numeric), # 数値の列の\n", - " function(x) { var(x) })) # 不偏分散\n", - "\n", - "#> english math\n", - "#> 1 225 166.6667" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "psych::describe(my_df)\n", - "#> vars n mean sd ...\n", - "#> name* 1 4 2.5 1.29 ...\n", - "#> english 2 4 77.5 15.00 ...\n", - "#> math 3 4 85.0 12.91 ...\n", - "#> gender* 4 4 1.5 0.58 ...\n", - "\n", - "# あるいは\n", - "\n", - "pastecs::stat.desc(my_df)\n", - "#> name english ...\n", - "#> nbr.val NA 4.0000000 ...\n", - "#> nbr.null NA 0.0000000 ...\n", - "#> nbr.na NA 0.0000000 ...\n", - "#> min NA 60.0000000 ...\n", - "#> max NA 90.0000000 ...\n", - "# 以下省略" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.1.2.2 分割表とグループごとの集計" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "table(my_df$gender)\n", - "\n", - "#> f m\n", - "#> 2 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- data.frame(\n", - " gender = my_df$gender,\n", - " excel = my_df$math >= 80)\n", - "table(my_df2)\n", - "\n", - "#> excel\n", - "#> gender FALSE TRUE\n", - "#> f 1 1\n", - "#> m 0 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df %>% group_by(gender) %>%\n", - " summarize(across(\n", - " where(is.numeric), mean),\n", - " .groups = \"drop\") # グループ化解除\n", - "\n", - "#> # A tibble: 2 x 3\n", - "#> gender english math\n", - "#> \n", - "#> 1 f 75 85\n", - "#> 2 m 80 85" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.2 データの可視化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(iris)\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 1 5.1 3.5 1.4 0.2 setosa\n", - "#> 2 4.9 3.0 1.4 0.2 setosa\n", - "#> 3 4.7 3.2 1.3 0.2 setosa\n", - "#> 4 4.6 3.1 1.5 0.2 setosa\n", - "#> 5 5.0 3.6 1.4 0.2 setosa\n", - "#> 6 5.4 3.9 1.7 0.4 setosa" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.1 ヒストグラム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "hist(iris$Sepal.Length)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- c(10, 20, 30)\n", - "hist(x, breaks = 2) # 階級数は2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- iris$Sepal.Length\n", - "tmp <- seq(min(x), max(x),\n", - " length.out = 10)\n", - "hist(x, breaks = tmp, right = FALSE)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.2 散布図" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plot(iris$Sepal.Length,\n", - " iris$Sepal.Width)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.3 箱ひげ図" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "boxplot(iris[, -5])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.4 棒グラフとエラーバー" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "my_df <- psych::describe(iris[, -5])\n", - "my_df %>% select(mean, sd, se)\n", - "#> mean sd se\n", - "#> Sepal.Length 5.84 0.83 0.07\n", - "#> Sepal.Width 3.06 0.44 0.04\n", - "#> Petal.Length 3.76 1.77 0.14\n", - "#> Petal.Width 1.20 0.76 0.06" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- rownames(my_df)\n", - "my_df %>% ggplot(aes(x = factor(tmp, levels = tmp), y = mean)) +\n", - " geom_col() +\n", - " geom_errorbar(aes(ymin = mean - se, ymax = mean + se)) +\n", - " xlab(NULL)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_group <- iris %>% group_by(Species) # 品種ごとに,\n", - "\n", - "my_df <- my_group %>% # 各変数の,平均と\n", - " summarize(across(everything(), mean)) %>%\n", - " pivot_longer(-Species)\n", - "\n", - "tmp <- my_group %>% # 標準誤差を求める.\n", - " summarize(across(everything(), ~ sd(.) / length(.)**0.5)) %>%\n", - " pivot_longer(-Species)\n", - "\n", - "my_df$se <- tmp$value\n", - "head(my_df)\n", - "#> # A tibble: 6 x 4\n", - "#> Species name value se\n", - "#> \n", - "#> 1 setosa Sepal.Length 5.01 0.0498\n", - "#> 2 setosa Sepal.Width 3.43 0.0536\n", - "#> 3 setosa Petal.Length 1.46 0.0246\n", - "#> 4 setosa Petal.Width 0.246 0.0149\n", - "#> 5 versicolor Sepal.Length 5.94 0.0730\n", - "#> 6 versicolor Sepal.Width 2.77 0.0444" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df %>%\n", - " ggplot(aes(x = Species, y = value, fill = name)) +\n", - " geom_col(position = \"dodge\") +\n", - " geom_errorbar(aes(ymin = value - se, ymax = value + se), position = \"dodge\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 各変数の平均\n", - "iris %>% pivot_longer(-Species) %>%\n", - " ggplot(aes(x = name, y = value)) +\n", - " geom_bar(stat = \"summary\", fun = mean) +\n", - " stat_summary(geom = \"errorbar\", fun.data = mean_se) +\n", - " xlab(NULL)\n", - "\n", - "# 各変数の平均(品種ごと)\n", - "iris %>% pivot_longer(-Species) %>%\n", - " ggplot(aes(x = Species, y = value, fill = name)) +\n", - " geom_bar(stat = \"summary\", fun = mean, position = \"dodge\") +\n", - " stat_summary(geom = \"errorbar\", fun.data = mean_se, position = \"dodge\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.5 モザイクプロット" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- data.frame(\n", - " Species = iris$Species,\n", - " w_Sepal = iris$Sepal.Width > 3)\n", - "table(my_df) # 分割表\n", - "#> w_Sepal\n", - "#> Species FALSE TRUE\n", - "#> setosa 8 42\n", - "#> versicolor 42 8\n", - "#> virginica 33 17\n", - "\n", - "mosaicplot(\n", - " formula = ~ Species + w_Sepal,\n", - " data = my_df)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(vcd)\n", - "vcd::mosaic(formula = ~w_Sepal + Species, data = my_df,\n", - " labeling = labeling_values)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.6 関数のグラフ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "curve(x^3 - x, -2, 2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.2.7 ggplot2 (R)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- iris$Sepal.Length\n", - "tmp <- seq(min(x), max(x),\n", - " length.out = 10)\n", - "iris %>%\n", - " ggplot(aes(x = Sepal.Length)) +\n", - " geom_histogram(breaks = tmp,\n", - " closed = \"left\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris %>%\n", - " ggplot(aes(x = Sepal.Length,\n", - " y = Sepal.Width)) +\n", - " geom_point()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris %>%\n", - " pivot_longer(-Species) %>%\n", - " ggplot(aes(\n", - " x = factor(name,\n", - " levels = names(iris)),\n", - " y = value)) +\n", - " geom_boxplot() +\n", - " xlab(NULL)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(ggmosaic)\n", - "my_df <- data.frame(\n", - " Species = iris$Species,\n", - " w_Sepal = iris$Sepal.Width > 3)\n", - "my_df %>%\n", - " ggplot() +\n", - " geom_mosaic(\n", - " aes(x = product(w_Sepal, Species)))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(x) { x^3 - x }\n", - "data.frame(x = c(-2, 2)) %>%\n", - " ggplot(aes(x = x)) +\n", - " stat_function(fun = f)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.3 乱数\n", - "\n", - "### 4.3.1 一様乱数(離散)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- sample(x = 1:6, # 範囲\n", - " size = 10000, # 乱数の数\n", - " replace = TRUE) # 重複あり\n", - "hist(x, breaks = 0:6) # ヒストグラム" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.2 一様乱数(連続)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- runif(min = 0, # 最小\n", - " max = 1, # 最大\n", - " n = 1000) # 乱数の数\n", - "hist(x)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x <- as.integer( # 整数に変換\n", - " runif(min = 1, # 最小\n", - " max = 7, # 最大 + 1\n", - " n = 1000)) # 乱数の数\n", - "hist(x, breaks = 0:6) # 結果は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.3 二項乱数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n <- 100\n", - "p <- 0.5\n", - "r <- 10000\n", - "x <- rbinom(size = n, # 試行回数\n", - " prob = p, # 確率\n", - " n = r) # 乱数の数\n", - "hist(x, breaks = max(x) - min(x))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.3.4 正規乱数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "r <- 10000\n", - "x <- rnorm(mean = 50, # 平均\n", - " sd = 5, # 標準偏差\n", - " n = r) # 乱数の数\n", - "hist(x, breaks = 40)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.3.4.1 補足:不偏性の具体例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "f <- function(k) {\n", - " n <- 10000\n", - " tmp <- replicate(n = n, expr = g(rnorm(n = k, sd = 3)))\n", - " list(k = k,\n", - " mean = mean(tmp), # 平均\n", - " se = sd(tmp) / sqrt(n)) # 標準誤差\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "g <- var\n", - "c(10, 20, 30) %>% map_dfr(f)\n", - "#> # A tibble: 3 x 3\n", - "#> k mean se\n", - "#> \n", - "#> 1 10 8.98 0.0427\n", - "#> 2 20 8.97 0.0288\n", - "#> 3 30 9.03 0.0233" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "g <- sd\n", - "c(5, 10, 15, 20) %>% map_dfr(f)\n", - "#> # A tibble: 3 x 3\n", - "#> k mean se\n", - "#> \n", - "#> 1 10 2.92 0.00701\n", - "#> 2 20 2.95 0.00481\n", - "#> 3 30 2.97 0.00394" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "g <- function(x) {\n", - " n <- length(x)\n", - " sd(x) *\n", - " sqrt((n - 1) / 2) *\n", - " gamma((n - 1) / 2) /\n", - " gamma(n / 2)\n", - "}\n", - "c(10, 20, 30) %>% map_dfr(f)\n", - "#> # A tibble: 3 x 3\n", - "#> k mean se\n", - "#> \n", - "#> 1 10 3.00 0.00717\n", - "#> 2 20 2.99 0.00488\n", - "#> 3 30 3.00 0.00396" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4.4 統計的推測\n", - "\n", - "### 4.4.1 検定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(exactci)\n", - "library(tidyverse)\n", - "\n", - "a <- 0.05 # 有意水準\n", - "binom.exact(x = 2, # 当たった回数\n", - " n = 15, # くじを引いた回数\n", - " p = 4 / 10, # 当たる確率(仮説)\n", - " plot = TRUE, # p値の描画(結果は次項に掲載)\n", - " conf.level = 1 - a, # 信頼係数(デフォルト)\n", - " tsmethod = \"minlike\", # p値の定義\n", - " alternative = \"two.sided\") # 両側検定(デフォルト)\n", - " # 左片側検定なら'less'\n", - " # 右片側検定なら'greater'\n", - "\n", - "#> Exact two-sided binomial test (central method)\n", - "#>\n", - "#> data: 2 and 15\n", - "#> number of successes = 2, number of trials = 15,\n", - "#> p-value = 0.03646\n", - "#> alternative hypothesis: true probability of success is not equal to 0.4\n", - "#> 95 percent confidence interval:\n", - "#> 0.0242 0.3967\n", - "#> sample estimates:\n", - "#> probability of success\n", - "#> 0.1333333" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4.4.1.1 補足:p値とは何か" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "t <- 4 / 10 # 当たる確率\n", - "n <- 15 # くじを引いた回数\n", - "x <- 0:n # 当たった回数\n", - "my_pr <- dbinom(x, n, t) # x回当たる確率\n", - "my_pr2 <- dbinom(2, n, t) # 2回当たる確率\n", - "\n", - "my_data <- data.frame(x = x,\n", - " probability = my_pr,\n", - " color = my_pr <= my_pr2) # 当たる確率が,2回当たる確率以下\n", - "\n", - "my_data %>% ggplot(aes(x = x, y = probability, color = color)) +\n", - " geom_point(size = 3) +\n", - " geom_linerange(aes(ymin = 0, ymax = probability), ) + # 垂直線\n", - " geom_hline(yintercept = my_pr2) + # 水平線\n", - " theme(legend.position = \"none\") # 凡例を表示しない." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.2 推定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 前項の結果(再掲)\n", - "#> 95 percent confidence interval:\n", - "#> 0.0242 0.3967" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 前項冒頭のコード" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.3 平均の差の検定と推定(t検定)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X <- c(32.1, 26.2, 27.5, 31.8, 32.1, 31.2, 30.1, 32.4, 32.3, 29.9,\n", - " 29.6, 26.6, 31.2, 30.9, 29.3)\n", - "Y <- c(35.4, 34.6, 31.1, 32.4, 33.3, 34.7, 35.3, 34.3, 32.1, 28.3,\n", - " 33.3, 30.5, 32.6, 33.3, 32.2)\n", - "\n", - "t.test(x = X, y = Y,\n", - " conf.level = 0.95, # 信頼係数(デフォルト)\n", - " paired = TRUE, # 対標本である.\n", - " alternative = \"two.sided\") # 両側検定(デフォルト)\n", - " # 左片側検定なら'less'\n", - " # 右片側検定なら'greater'\n", - "\n", - "#> Paired t-test\n", - "#>\n", - "#> data: X and Y\n", - "#> t = -4.3694, df = 14, p-value = 0.0006416\n", - "#> alternative hypothesis: true difference in means is not equal to 0\n", - "#> 95 percent confidence interval:\n", - "#> -3.995525 -1.364475\n", - "#> sample estimates:\n", - "#> mean of the differences\n", - "#> -2.68" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "t.test(x = X, y = Y,\n", - " paired = FALSE, # 対標本ではない(デフォルト).\n", - " var.equal = TRUE, # 等分散を仮定する.仮定しないならFALSE(デフォルト).\n", - " alternative = \"two.sided\",\n", - " conf.level = 0.95)\n", - "\n", - "#> Two Sample t-test\n", - "#>\n", - "#> data: X and Y\n", - "#> t = -3.6821, df = 28, p-value = 0.0009785\n", - "#> alternative hypothesis: true difference in means is not equal to 0\n", - "#> 95 percent confidence interval:\n", - "#> -4.170906 -1.189094\n", - "#> sample estimates:\n", - "#> mean of x mean of y\n", - "#> 30.21333 32.89333" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.4 独立性の検定(カイ2乗検定)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/smoker.csv\")\n", - "my_data <- read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_data)\n", - "#> alive smoker\n", - "#> 1 Yes No\n", - "#> 2 Yes No\n", - "#> 3 Yes No\n", - "#> 4 Yes No\n", - "#> 5 Yes No\n", - "#> 6 Yes No" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_table <- table(my_data)\n", - "my_table\n", - "#> smoker\n", - "#> alive No Yes\n", - "#> No 117 54\n", - "#> Yes 950 348" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "chisq.test(my_table, correct = FALSE)\n", - "\n", - "#> Pearson's Chi-squared test\n", - "#>\n", - "#> data: my_data\n", - "#> X-squared = 1.7285, df = 1, p-value = 0.1886" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 4.4.5 ブートストラップ\n", - "\n", - "#### 4.4.5.1 15回引いて2回当たったくじ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X <- rep(0:1, c(13, 2)) # 手順1\n", - "X\n", - "#> [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1\n", - "\n", - "tmp <- sample(X, size = length(X), replace = TRUE) # 手順2\n", - "tmp\n", - "#> [1] 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0\n", - "\n", - "sum(tmp) # 手順3\n", - "#> [1] 2\n", - "\n", - "n <- 10^5\n", - "result <- replicate(n, sum(sample(X, size = length(X), replace = TRUE))) # 手順4" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "hist(x = result, breaks = 0:15,\n", - " right = FALSE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "quantile(result, c(0.025, 0.975))\n", - "#> 2.5% 97.5%\n", - "#> 0 5" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch05/05-colab.ipynb b/code/R-notebook/ch05/05-colab.ipynb deleted file mode 100644 index 2ecb3de..0000000 --- a/code/R-notebook/ch05/05-colab.ipynb +++ /dev/null @@ -1,462 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 05" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Google Colaboratoryの環境設定\n", - "options(Ncpus = 2)\n", - "install.packages(\"caret\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 5.1 データの読み込み\n", - "\n", - "### 5.1.1 CSV" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "system(str_c(\"wget https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/exam.csv\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.1.1 CSVの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- read_csv(\"exam.csv\")\n", - "# あるいは\n", - "my_df <- read.csv(\"exam.csv\",\n", - " stringsAsFactors = FALSE)\n", - "\n", - "my_df\n", - "#> name english math gender\n", - "#> 1 A 60 70 f\n", - "#> 2 B 90 80 m\n", - "#> 3 C 70 90 m\n", - "#> 4 D 90 100 f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/exam.csv\")\n", - "my_df <- read_csv(my_url)\n", - "# あるいは\n", - "my_df <- read.csv(my_url, stringsAsFactors = FALSE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- read.csv(\n", - " file = \"exam.csv\",\n", - " stringsAsFactors = FALSE,\n", - " row.names = 1)\n", - "my_df2\n", - "#> english math gender\n", - "#> A 60 70 f\n", - "#> B 90 80 m\n", - "#> C 70 90 m\n", - "#> D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.1.2 CSVファイルへの書き出し" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df %>% write_csv(\"exam2.csv\")\n", - "# あるいは\n", - "my_df %>% write.csv(\n", - " file = \"exam2.csv\",\n", - " row.names = FALSE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 %>% write.csv(\"exam3.csv\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.2 文字コード" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- read_csv(file = \"exam.csv\",\n", - " locale = locale(encoding = \"UTF-8\"))\n", - "# あるいは\n", - "my_df <- read.csv(file = \"exam.csv\",\n", - " stringsAsFactors = FALSE,\n", - " fileEncoding = \"UTF-8\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df %>% write_csv(\"exam2.csv\")\n", - "# あるいは\n", - "my_df %>% write.csv(file = \"exam2.csv\", row.names = FALSE,\n", - " fileEncoding = \"UTF-8\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.3 ウェブ上の表" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url <- \"https://taroyabuki.github.io/fromzero/exam.html\"\n", - "my_tables <- xml2::read_html(my_url) %>% rvest::html_table()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_tables\n", - "#> [[1]]\n", - "#> X1 X2 X3 X4 X5\n", - "#> 1 NA name english math gender\n", - "#> 2 NA A 60 70 f\n", - "#> 3 NA B 90 80 m\n", - "#> 4 NA C 70 90 m\n", - "#> 5 NA D 90 100 f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_tables[[1]]\n", - "tmp\n", - "#> X1 X2 X3 X4 X5\n", - "#> 1 NA name english math gender\n", - "#> 2 NA A 60 70 f\n", - "#> 3 NA B 90 80 m\n", - "#> 4 NA C 70 90 m\n", - "#> 5 NA D 90 100 f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 1行目のデータを使って列の名前を付け直す.\n", - "colnames(tmp) <- tmp[1, ]\n", - "\n", - "# 1行目と1列目を削除する.\n", - "my_data <- tmp[-1, -1]\n", - "my_data\n", - "#> name english math gender\n", - "#> 2 A 60 70 f\n", - "#> 3 B 90 80 m\n", - "#> 4 C 70 90 m\n", - "#> 5 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.4 JSONとXML\n", - "\n", - "#### 5.1.4.1 JSONデータの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(jsonlite)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/exam.json\")\n", - "my_data <- fromJSON(my_url)\n", - "#my_data <- fromJSON(\"exam.json\") # (ファイルを使う場合)\n", - "my_data\n", - "#> name english math gender\n", - "#> 1 A 60 70 f\n", - "#> 2 B 90 80 m\n", - "#> 3 C 70 90 m\n", - "#> 4 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.4.2 XMLデータの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(xml2)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/exam.xml\")\n", - "my_xml <- read_xml(my_url) # XMLデータの読み込み\n", - "#my_xml <- read_xml(\"exam.xml\") # (ファイルを使う場合)\n", - "xml_ns(my_xml) # 名前空間の確認(d1)\n", - "#> d1 <-> https://www.example.net/ns/1.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_records <- xml_find_all(my_xml, \".//d1:record\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(record) {\n", - " tmp <- xml_attrs(record) # 属性を全て取り出し,\n", - " xml_children(record) %>% walk(function(e) {\n", - " tmp[xml_name(e)] <<- xml_text(e) # 子要素の名前と内容を追加する.\n", - " })\n", - " tmp\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data <- my_records %>% map_dfr(f)\n", - "my_data$english <- as.numeric(my_data$english)\n", - "my_data$math <- as.numeric(my_data$math)\n", - "my_data\n", - "#> english math gender name\n", - "#> \n", - "#> 1 60 70 f A\n", - "#> 2 90 80 m B\n", - "#> 3 70 90 m C\n", - "#> 4 90 100 f D" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 5.2 データの変換\n", - "\n", - "### 5.2.1 標準化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x1 <- c(1, 2, 3)\n", - "\n", - "z1 <- scale(x1)\n", - "# あるいは\n", - "z1 <- (x1 - mean(x1)) / sd(x1)\n", - "\n", - "z1\n", - "#> [1] -1 0 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c(mean(z1), sd(z1))\n", - "#> [1] 0 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "z1 * sd(x1) + mean(x1)\n", - "#> [1] 1 2 3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x2 <- c(1, 3, 5)\n", - "z2 <- (x2 - mean(x1)) / sd(x1)\n", - "c(mean(z2), sd(z2))\n", - "#> [1] 1 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.2.2 ワンホットエンコーディング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "\n", - "my_df <- data.frame(\n", - " id = c(1, 2, 3),\n", - " class = as.factor(\n", - " c(\"A\", \"B\", \"C\")))\n", - "\n", - "my_enc <- my_df %>%\n", - " dummyVars(formula = ~ .)\n", - "\n", - "my_enc %>% predict(my_df)\n", - "#> id class.A class.B class.C\n", - "#> 1 1 1 0 0\n", - "#> 2 2 0 1 0\n", - "#> 3 3 0 0 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- data.frame(\n", - " id = c( 4 , 5 , 6 ),\n", - " class = c(\"B\", \"C\", \"B\"))\n", - "my_enc %>% predict(my_df2)\n", - "#> id class.A class.B class.C\n", - "#> 1 4 0 1 0\n", - "#> 2 5 0 0 1\n", - "#> 3 6 0 1 0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.2.2.1 補足:冗長性の排除" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_enc <- my_df %>%\n", - " dummyVars(formula = ~ .,\n", - " fullRank = TRUE)\n", - "my_enc %>% predict(my_df)\n", - "#> id class.B class.C\n", - "#> 1 1 0 0\n", - "#> 2 2 1 0\n", - "#> 3 3 0 1\n", - "\n", - "my_enc %>% predict(my_df2)\n", - "#> id class.B class.C\n", - "#> 1 4 1 0\n", - "#> 2 5 0 1\n", - "#> 3 6 1 0" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch05/05.01.ipynb b/code/R-notebook/ch05/05.01.ipynb deleted file mode 100644 index 62ef36e..0000000 --- a/code/R-notebook/ch05/05.01.ipynb +++ /dev/null @@ -1,311 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 5.1 データの読み込み\n", - "\n", - "### 5.1.1 CSV" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "system(str_c(\"wget https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/exam.csv\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.1.1 CSVの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- read_csv(\"exam.csv\")\n", - "# あるいは\n", - "my_df <- read.csv(\"exam.csv\",\n", - " stringsAsFactors = FALSE)\n", - "\n", - "my_df\n", - "#> name english math gender\n", - "#> 1 A 60 70 f\n", - "#> 2 B 90 80 m\n", - "#> 3 C 70 90 m\n", - "#> 4 D 90 100 f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/exam.csv\")\n", - "my_df <- read_csv(my_url)\n", - "# あるいは\n", - "my_df <- read.csv(my_url, stringsAsFactors = FALSE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- read.csv(\n", - " file = \"exam.csv\",\n", - " stringsAsFactors = FALSE,\n", - " row.names = 1)\n", - "my_df2\n", - "#> english math gender\n", - "#> A 60 70 f\n", - "#> B 90 80 m\n", - "#> C 70 90 m\n", - "#> D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.1.2 CSVファイルへの書き出し" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df %>% write_csv(\"exam2.csv\")\n", - "# あるいは\n", - "my_df %>% write.csv(\n", - " file = \"exam2.csv\",\n", - " row.names = FALSE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 %>% write.csv(\"exam3.csv\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.2 文字コード" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- read_csv(file = \"exam.csv\",\n", - " locale = locale(encoding = \"UTF-8\"))\n", - "# あるいは\n", - "my_df <- read.csv(file = \"exam.csv\",\n", - " stringsAsFactors = FALSE,\n", - " fileEncoding = \"UTF-8\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df %>% write_csv(\"exam2.csv\")\n", - "# あるいは\n", - "my_df %>% write.csv(file = \"exam2.csv\", row.names = FALSE,\n", - " fileEncoding = \"UTF-8\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.3 ウェブ上の表" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url <- \"https://taroyabuki.github.io/fromzero/exam.html\"\n", - "my_tables <- xml2::read_html(my_url) %>% rvest::html_table()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_tables\n", - "#> [[1]]\n", - "#> X1 X2 X3 X4 X5\n", - "#> 1 NA name english math gender\n", - "#> 2 NA A 60 70 f\n", - "#> 3 NA B 90 80 m\n", - "#> 4 NA C 70 90 m\n", - "#> 5 NA D 90 100 f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_tables[[1]]\n", - "tmp\n", - "#> X1 X2 X3 X4 X5\n", - "#> 1 NA name english math gender\n", - "#> 2 NA A 60 70 f\n", - "#> 3 NA B 90 80 m\n", - "#> 4 NA C 70 90 m\n", - "#> 5 NA D 90 100 f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 1行目のデータを使って列の名前を付け直す.\n", - "colnames(tmp) <- tmp[1, ]\n", - "\n", - "# 1行目と1列目を削除する.\n", - "my_data <- tmp[-1, -1]\n", - "my_data\n", - "#> name english math gender\n", - "#> 2 A 60 70 f\n", - "#> 3 B 90 80 m\n", - "#> 4 C 70 90 m\n", - "#> 5 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.4 JSONとXML\n", - "\n", - "#### 5.1.4.1 JSONデータの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(jsonlite)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/exam.json\")\n", - "my_data <- fromJSON(my_url)\n", - "#my_data <- fromJSON(\"exam.json\") # (ファイルを使う場合)\n", - "my_data\n", - "#> name english math gender\n", - "#> 1 A 60 70 f\n", - "#> 2 B 90 80 m\n", - "#> 3 C 70 90 m\n", - "#> 4 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.4.2 XMLデータの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(xml2)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/exam.xml\")\n", - "my_xml <- read_xml(my_url) # XMLデータの読み込み\n", - "#my_xml <- read_xml(\"exam.xml\") # (ファイルを使う場合)\n", - "xml_ns(my_xml) # 名前空間の確認(d1)\n", - "#> d1 <-> https://www.example.net/ns/1.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_records <- xml_find_all(my_xml, \".//d1:record\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(record) {\n", - " tmp <- xml_attrs(record) # 属性を全て取り出し,\n", - " xml_children(record) %>% walk(function(e) {\n", - " tmp[xml_name(e)] <<- xml_text(e) # 子要素の名前と内容を追加する.\n", - " })\n", - " tmp\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data <- my_records %>% map_dfr(f)\n", - "my_data$english <- as.numeric(my_data$english)\n", - "my_data$math <- as.numeric(my_data$math)\n", - "my_data\n", - "#> english math gender name\n", - "#> \n", - "#> 1 60 70 f A\n", - "#> 2 90 80 m B\n", - "#> 3 70 90 m C\n", - "#> 4 90 100 f D" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch05/05.02.ipynb b/code/R-notebook/ch05/05.02.ipynb deleted file mode 100644 index 4ea7b81..0000000 --- a/code/R-notebook/ch05/05.02.ipynb +++ /dev/null @@ -1,145 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 5.2 データの変換\n", - "\n", - "### 5.2.1 標準化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x1 <- c(1, 2, 3)\n", - "\n", - "z1 <- scale(x1)\n", - "# あるいは\n", - "z1 <- (x1 - mean(x1)) / sd(x1)\n", - "\n", - "z1\n", - "#> [1] -1 0 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c(mean(z1), sd(z1))\n", - "#> [1] 0 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "z1 * sd(x1) + mean(x1)\n", - "#> [1] 1 2 3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x2 <- c(1, 3, 5)\n", - "z2 <- (x2 - mean(x1)) / sd(x1)\n", - "c(mean(z2), sd(z2))\n", - "#> [1] 1 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.2.2 ワンホットエンコーディング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "\n", - "my_df <- data.frame(\n", - " id = c(1, 2, 3),\n", - " class = as.factor(\n", - " c(\"A\", \"B\", \"C\")))\n", - "\n", - "my_enc <- my_df %>%\n", - " dummyVars(formula = ~ .)\n", - "\n", - "my_enc %>% predict(my_df)\n", - "#> id class.A class.B class.C\n", - "#> 1 1 1 0 0\n", - "#> 2 2 0 1 0\n", - "#> 3 3 0 0 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- data.frame(\n", - " id = c( 4 , 5 , 6 ),\n", - " class = c(\"B\", \"C\", \"B\"))\n", - "my_enc %>% predict(my_df2)\n", - "#> id class.A class.B class.C\n", - "#> 1 4 0 1 0\n", - "#> 2 5 0 0 1\n", - "#> 3 6 0 1 0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.2.2.1 補足:冗長性の排除" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_enc <- my_df %>%\n", - " dummyVars(formula = ~ .,\n", - " fullRank = TRUE)\n", - "my_enc %>% predict(my_df)\n", - "#> id class.B class.C\n", - "#> 1 1 0 0\n", - "#> 2 2 1 0\n", - "#> 3 3 0 1\n", - "\n", - "my_enc %>% predict(my_df2)\n", - "#> id class.B class.C\n", - "#> 1 4 1 0\n", - "#> 2 5 0 1\n", - "#> 3 6 1 0" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch05/05.ipynb b/code/R-notebook/ch05/05.ipynb deleted file mode 100644 index 9ed6081..0000000 --- a/code/R-notebook/ch05/05.ipynb +++ /dev/null @@ -1,446 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 05\n", - "\n", - "## 5.1 データの読み込み\n", - "\n", - "### 5.1.1 CSV" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "system(str_c(\"wget https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/exam.csv\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.1.1 CSVの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- read_csv(\"exam.csv\")\n", - "# あるいは\n", - "my_df <- read.csv(\"exam.csv\",\n", - " stringsAsFactors = FALSE)\n", - "\n", - "my_df\n", - "#> name english math gender\n", - "#> 1 A 60 70 f\n", - "#> 2 B 90 80 m\n", - "#> 3 C 70 90 m\n", - "#> 4 D 90 100 f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/exam.csv\")\n", - "my_df <- read_csv(my_url)\n", - "# あるいは\n", - "my_df <- read.csv(my_url, stringsAsFactors = FALSE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- read.csv(\n", - " file = \"exam.csv\",\n", - " stringsAsFactors = FALSE,\n", - " row.names = 1)\n", - "my_df2\n", - "#> english math gender\n", - "#> A 60 70 f\n", - "#> B 90 80 m\n", - "#> C 70 90 m\n", - "#> D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.1.2 CSVファイルへの書き出し" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df %>% write_csv(\"exam2.csv\")\n", - "# あるいは\n", - "my_df %>% write.csv(\n", - " file = \"exam2.csv\",\n", - " row.names = FALSE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 %>% write.csv(\"exam3.csv\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.2 文字コード" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df <- read_csv(file = \"exam.csv\",\n", - " locale = locale(encoding = \"UTF-8\"))\n", - "# あるいは\n", - "my_df <- read.csv(file = \"exam.csv\",\n", - " stringsAsFactors = FALSE,\n", - " fileEncoding = \"UTF-8\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df %>% write_csv(\"exam2.csv\")\n", - "# あるいは\n", - "my_df %>% write.csv(file = \"exam2.csv\", row.names = FALSE,\n", - " fileEncoding = \"UTF-8\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.3 ウェブ上の表" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url <- \"https://taroyabuki.github.io/fromzero/exam.html\"\n", - "my_tables <- xml2::read_html(my_url) %>% rvest::html_table()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_tables\n", - "#> [[1]]\n", - "#> X1 X2 X3 X4 X5\n", - "#> 1 NA name english math gender\n", - "#> 2 NA A 60 70 f\n", - "#> 3 NA B 90 80 m\n", - "#> 4 NA C 70 90 m\n", - "#> 5 NA D 90 100 f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_tables[[1]]\n", - "tmp\n", - "#> X1 X2 X3 X4 X5\n", - "#> 1 NA name english math gender\n", - "#> 2 NA A 60 70 f\n", - "#> 3 NA B 90 80 m\n", - "#> 4 NA C 70 90 m\n", - "#> 5 NA D 90 100 f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 1行目のデータを使って列の名前を付け直す.\n", - "colnames(tmp) <- tmp[1, ]\n", - "\n", - "# 1行目と1列目を削除する.\n", - "my_data <- tmp[-1, -1]\n", - "my_data\n", - "#> name english math gender\n", - "#> 2 A 60 70 f\n", - "#> 3 B 90 80 m\n", - "#> 4 C 70 90 m\n", - "#> 5 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.1.4 JSONとXML\n", - "\n", - "#### 5.1.4.1 JSONデータの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(jsonlite)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/exam.json\")\n", - "my_data <- fromJSON(my_url)\n", - "#my_data <- fromJSON(\"exam.json\") # (ファイルを使う場合)\n", - "my_data\n", - "#> name english math gender\n", - "#> 1 A 60 70 f\n", - "#> 2 B 90 80 m\n", - "#> 3 C 70 90 m\n", - "#> 4 D 90 100 f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.1.4.2 XMLデータの読み込み" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(xml2)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/exam.xml\")\n", - "my_xml <- read_xml(my_url) # XMLデータの読み込み\n", - "#my_xml <- read_xml(\"exam.xml\") # (ファイルを使う場合)\n", - "xml_ns(my_xml) # 名前空間の確認(d1)\n", - "#> d1 <-> https://www.example.net/ns/1.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_records <- xml_find_all(my_xml, \".//d1:record\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(record) {\n", - " tmp <- xml_attrs(record) # 属性を全て取り出し,\n", - " xml_children(record) %>% walk(function(e) {\n", - " tmp[xml_name(e)] <<- xml_text(e) # 子要素の名前と内容を追加する.\n", - " })\n", - " tmp\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data <- my_records %>% map_dfr(f)\n", - "my_data$english <- as.numeric(my_data$english)\n", - "my_data$math <- as.numeric(my_data$math)\n", - "my_data\n", - "#> english math gender name\n", - "#> \n", - "#> 1 60 70 f A\n", - "#> 2 90 80 m B\n", - "#> 3 70 90 m C\n", - "#> 4 90 100 f D" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 5.2 データの変換\n", - "\n", - "### 5.2.1 標準化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x1 <- c(1, 2, 3)\n", - "\n", - "z1 <- scale(x1)\n", - "# あるいは\n", - "z1 <- (x1 - mean(x1)) / sd(x1)\n", - "\n", - "z1\n", - "#> [1] -1 0 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c(mean(z1), sd(z1))\n", - "#> [1] 0 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "z1 * sd(x1) + mean(x1)\n", - "#> [1] 1 2 3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x2 <- c(1, 3, 5)\n", - "z2 <- (x2 - mean(x1)) / sd(x1)\n", - "c(mean(z2), sd(z2))\n", - "#> [1] 1 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 5.2.2 ワンホットエンコーディング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "\n", - "my_df <- data.frame(\n", - " id = c(1, 2, 3),\n", - " class = as.factor(\n", - " c(\"A\", \"B\", \"C\")))\n", - "\n", - "my_enc <- my_df %>%\n", - " dummyVars(formula = ~ .)\n", - "\n", - "my_enc %>% predict(my_df)\n", - "#> id class.A class.B class.C\n", - "#> 1 1 1 0 0\n", - "#> 2 2 0 1 0\n", - "#> 3 3 0 0 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_df2 <- data.frame(\n", - " id = c( 4 , 5 , 6 ),\n", - " class = c(\"B\", \"C\", \"B\"))\n", - "my_enc %>% predict(my_df2)\n", - "#> id class.A class.B class.C\n", - "#> 1 4 0 1 0\n", - "#> 2 5 0 0 1\n", - "#> 3 6 0 1 0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 5.2.2.1 補足:冗長性の排除" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_enc <- my_df %>%\n", - " dummyVars(formula = ~ .,\n", - " fullRank = TRUE)\n", - "my_enc %>% predict(my_df)\n", - "#> id class.B class.C\n", - "#> 1 1 0 0\n", - "#> 2 2 1 0\n", - "#> 3 3 0 1\n", - "\n", - "my_enc %>% predict(my_df2)\n", - "#> id class.B class.C\n", - "#> 1 4 1 0\n", - "#> 2 5 0 1\n", - "#> 3 6 1 0" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch06/06-colab.ipynb b/code/R-notebook/ch06/06-colab.ipynb deleted file mode 100644 index 519ad12..0000000 --- a/code/R-notebook/ch06/06-colab.ipynb +++ /dev/null @@ -1,60 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 06\n", - "\n", - "## 6.1 機械学習の目的(本書の場合)\n", - "\n", - "## 6.2 機械学習のためのデータ\n", - "\n", - "### 6.2.1 機械学習を学ぶのに使うデータセット\n", - "\n", - "#### 6.2.1.1 教師データあり\n", - "\n", - "#### 6.2.1.2 時系列データ(第\\\\ref{時系列予測\n", - "\n", - "#### 6.2.1.3 教師データなし(第\\\\ref{教師なし学習\n", - "\n", - "### 6.2.2 補足:アヤメのデータ\n", - "\n", - "#### 6.2.2.1 R" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 1 5.1 3.5 1.4 0.2 setosa\n", - "# 以下省略" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 6.2.2.2 Python\n", - "\n", - "## 6.3 機械学習のための手法\n", - "\n", - "### 6.3.1 教師あり学習のためのフレームワーク\n", - "\n", - "### 6.3.2 本書で勧める手法とデータセットの組合せ" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch06/06.01.ipynb b/code/R-notebook/ch06/06.01.ipynb deleted file mode 100644 index 3f35b18..0000000 --- a/code/R-notebook/ch06/06.01.ipynb +++ /dev/null @@ -1,19 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 6.1 機械学習の目的(本書の場合)" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch06/06.02.ipynb b/code/R-notebook/ch06/06.02.ipynb deleted file mode 100644 index e27c193..0000000 --- a/code/R-notebook/ch06/06.02.ipynb +++ /dev/null @@ -1,50 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 6.2 機械学習のためのデータ\n", - "\n", - "### 6.2.1 機械学習を学ぶのに使うデータセット\n", - "\n", - "#### 6.2.1.1 教師データあり\n", - "\n", - "#### 6.2.1.2 時系列データ(第\\\\ref{時系列予測\n", - "\n", - "#### 6.2.1.3 教師データなし(第\\\\ref{教師なし学習\n", - "\n", - "### 6.2.2 補足:アヤメのデータ\n", - "\n", - "#### 6.2.2.1 R" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 1 5.1 3.5 1.4 0.2 setosa\n", - "# 以下省略" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 6.2.2.2 Python" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch06/06.03.ipynb b/code/R-notebook/ch06/06.03.ipynb deleted file mode 100644 index 4bdf6ff..0000000 --- a/code/R-notebook/ch06/06.03.ipynb +++ /dev/null @@ -1,23 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 6.3 機械学習のための手法\n", - "\n", - "### 6.3.1 教師あり学習のためのフレームワーク\n", - "\n", - "### 6.3.2 本書で勧める手法とデータセットの組合せ" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch06/06.ipynb b/code/R-notebook/ch06/06.ipynb deleted file mode 100644 index 519ad12..0000000 --- a/code/R-notebook/ch06/06.ipynb +++ /dev/null @@ -1,60 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 06\n", - "\n", - "## 6.1 機械学習の目的(本書の場合)\n", - "\n", - "## 6.2 機械学習のためのデータ\n", - "\n", - "### 6.2.1 機械学習を学ぶのに使うデータセット\n", - "\n", - "#### 6.2.1.1 教師データあり\n", - "\n", - "#### 6.2.1.2 時系列データ(第\\\\ref{時系列予測\n", - "\n", - "#### 6.2.1.3 教師データなし(第\\\\ref{教師なし学習\n", - "\n", - "### 6.2.2 補足:アヤメのデータ\n", - "\n", - "#### 6.2.2.1 R" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "iris\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 1 5.1 3.5 1.4 0.2 setosa\n", - "# 以下省略" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 6.2.2.2 Python\n", - "\n", - "## 6.3 機械学習のための手法\n", - "\n", - "### 6.3.1 教師あり学習のためのフレームワーク\n", - "\n", - "### 6.3.2 本書で勧める手法とデータセットの組合せ" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch07/07-colab.ipynb b/code/R-notebook/ch07/07-colab.ipynb deleted file mode 100644 index c7ea61a..0000000 --- a/code/R-notebook/ch07/07-colab.ipynb +++ /dev/null @@ -1,925 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 07" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Google Colaboratoryの環境設定\n", - "options(Ncpus = 2)\n", - "install.packages(c(\"caret\", \"doParallel\", \"pastecs\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.1 自動車の停止距離\n", - "\n", - "## 7.2 データの確認" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "dim(my_data)\n", - "#> [1] 50 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_data)\n", - "#> speed dist\n", - "#> 1 4 2\n", - "#> 2 4 10\n", - "#> 3 7 4\n", - "#> 4 7 22\n", - "#> 5 8 16\n", - "#> 6 9 10" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "options(digits = 3)\n", - "pastecs::stat.desc(my_data)\n", - "#> speed dist\n", - "#> nbr.val 50.000 50.00\n", - "#> nbr.null 0.000 0.00\n", - "#> nbr.na 0.000 0.00\n", - "#> min 4.000 2.00\n", - "#> max 25.000 120.00\n", - "#> range 21.000 118.00\n", - "#> sum 770.000 2149.00\n", - "#> median 15.000 36.00\n", - "#> mean 15.400 42.98\n", - "#> SE.mean 0.748 3.64\n", - "#> CI.mean.0.95 1.503 7.32\n", - "#> var 27.959 664.06\n", - "#> std.dev 5.288 25.77\n", - "#> coef.var 0.343 0.60" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data %>%\n", - " ggplot(aes(x = speed, y = dist)) +\n", - " geom_point()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.3 回帰分析\n", - "\n", - "### 7.3.1 回帰分析とは何か\n", - "\n", - "### 7.3.2 線形単回帰分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_data <- cars\n", - "tmp <- data.frame(speed = 21.5, dist = 67)\n", - "my_data %>% ggplot(aes(x = speed, y = dist)) +\n", - " coord_cartesian(xlim = c(4, 25), ylim = c(0, 120)) +\n", - " geom_point() +\n", - " stat_smooth(formula = y ~ x, method = \"lm\") +\n", - " geom_pointrange(data = tmp, aes(ymin = -9, ymax = dist), linetype = \"dotted\") +\n", - " geom_pointrange(data = tmp, aes(xmin = 0, xmax = speed), linetype = \"dotted\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.3.3 回帰分析の実践\n", - "\n", - "#### 7.3.3.1 データの用意" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.2 訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = dist ~ speed, # モデル式(出力変数と入力変数の関係)\n", - " data = my_data, # データ\n", - " method = \"lm\") # 手法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "coef(my_model$finalModel)\n", - "#> (Intercept) speed\n", - "#> -17.579095 3.932409" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.3 予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- data.frame(speed = 21.5)\n", - "my_model %>% predict(tmp)\n", - "#> 1\n", - "#> 66.96769" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.4 モデルの可視化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(x) { my_model %>% predict(data.frame(speed = x)) }" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data %>%\n", - " ggplot(aes(x = speed, y = dist,\n", - " color = \"data\")) +\n", - " geom_point() +\n", - " stat_function(\n", - " fun = f,\n", - " mapping = aes(color = \"model\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.4 当てはまりの良さの指標\n", - "\n", - "### 7.4.1 RMSE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\")\n", - "\n", - "y <- my_data$dist\n", - "y_ <- my_model %>% predict(my_data)\n", - "my_data$y_ <- y_" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data$residual <- y - y_\n", - "head(my_data)\n", - "#> speed dist y_ residual\n", - "#> 1 4 2 -1.849460 3.849460\n", - "#> 2 4 10 -1.849460 11.849460\n", - "#> 3 7 4 9.947766 -5.947766\n", - "#> 4 7 22 9.947766 12.052234\n", - "#> 5 8 16 13.880175 2.119825\n", - "#> 6 9 10 17.812584 -7.812584" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data %>%\n", - " ggplot(aes(x = speed, y = dist)) +\n", - " geom_point() +\n", - " geom_line(aes(x = speed, y = y_)) +\n", - " geom_linerange(mapping = aes(ymin = y_, ymax = dist), linetype = \"dotted\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "RMSE(y_, y)\n", - "# あるいは\n", - "mean((my_data$residual^2))**0.5\n", - "\n", - "#> [1] 15.06886" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.4.2 決定係数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] 0.6510794" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "# あるいは\n", - "summary(my_model$finalModel)$r.squared\n", - "#> [1] 0.6510794" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test <- my_data[1:3, ]\n", - "y <- my_test$dist\n", - "y_ <- my_model %>% predict(my_test)\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] -4.498191 # 決定係数1\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "#> [1] 0.07692308 # 決定係数6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.4.3 当てはまりの良さの指標の問題点" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "my_idx <- c(2, 11, 27, 34, 39, 44)\n", - "my_sample <- my_data[my_idx, ]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "options(warn = -1) # これ以降,警告を表示しない.\n", - "my_model <- train(form = dist ~ poly(speed, degree = 5, raw = TRUE),\n", - " data = my_sample,\n", - " method = \"lm\")\n", - "options(warn = 0) # これ以降,警告を表示する.\n", - "\n", - "y <- my_sample$dist\n", - "y_ <- my_model %>% predict(my_sample)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "RMSE(y_, y)\n", - "#> [1] 1.042275e-10 # RMSE\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] 1 # 決定係数1\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "#> [1] 1 # 決定係数6" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(x) { my_model %>% predict(data.frame(speed = x)) }\n", - "\n", - "my_data %>%\n", - " ggplot(aes(x = speed, y = dist, color = \"data\")) +\n", - " geom_point() +\n", - " geom_point(data = my_sample, mapping = aes(color = \"sample\")) +\n", - " stat_function(fun = f, mapping = aes(color = \"model\")) +\n", - " coord_cartesian(ylim = c(0, 120))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.5 K最近傍法\n", - "\n", - "### 7.5.1 K最近傍法とは何か\n", - "\n", - "### 7.5.2 K最近傍法の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 準備\n", - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "\n", - "# 訓練\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\")\n", - "\n", - "# 可視化の準備\n", - "f <- function(x) { my_model %>% predict(data.frame(speed = x))}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data %>%\n", - " ggplot(aes(x = speed,\n", - " y = dist,\n", - " color = \"data\")) +\n", - " geom_point() +\n", - " stat_function(\n", - " fun = f,\n", - " mapping = aes(color = \"model\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$dist\n", - "y_ <- my_model %>% predict(my_data)\n", - "\n", - "RMSE(y_, y)\n", - "#> [1] 13.96845 # RMSE\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] 0.7001789 # 決定係数1\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "#> [1] 0.7017314 # 決定係数6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.6 検証\n", - "\n", - "### 7.6.1 訓練データ・検証データ・テストデータ\n", - "\n", - "### 7.6.2 検証とは何か\n", - "\n", - "### 7.6.3 検証の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\")\n", - "\n", - "my_model$results\n", - "#> intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD\n", - "#> 1 TRUE 16.0206 0.6662176 12.14701 2.518604 0.09249158 1.920564" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\",\n", - " trControl = trainControl(method = \"cv\", number = 5))\n", - "my_model$results\n", - "#> intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD\n", - "#> 1 TRUE 15.06708 0.6724501 12.12448 4.75811 0.1848932 3.052435" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "my_model$results\n", - "#> intercept RMSE Rsquared MAE\n", - "#> 1 TRUE 15.69731 0.6217139 12.05918" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.6.4 検証の並列化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(doParallel)\n", - "cl <- makeCluster(detectCores())\n", - "registerDoParallel(cl)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.6.5 指標のまとめ\n", - "\n", - "#### 7.6.5.1 準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\")\n", - "y <- my_data$dist\n", - "y_ <- my_model %>% predict(my_data)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.2 当てはまりの良さの指標" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# RMSE(訓練)\n", - "RMSE(y_, y)\n", - "#> [1] 15.06886\n", - "\n", - "# 決定係数1(訓練)\n", - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] 0.6510794\n", - "\n", - "# 決定係数6(訓練)\n", - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "#> [1] 0.6510794" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "postResample(pred = y_, obs = y)\n", - "#> RMSE Rsquared MAE\n", - "#> 15.0688560 0.6510794 11.5801191" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.3 予測性能の指標(簡単に求められるもの)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\")\n", - "my_model$results\n", - "#> intercept RMSE Rsquared MAE ...\n", - "#> 1 TRUE 14.88504 0.6700353 11.59226 ...\n", - "# 左から,RMSE(検証),決定係数6(検証),MAE(検証)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.4 予測性能の指標(RとPythonで同じ結果を得る)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "\n", - "# 方法1\n", - "my_model$results\n", - "#> intercept RMSE Rsquared MAE\n", - "#> 1 TRUE 15.69731 0.6217139 12.05918\n", - "\n", - "# 方法2\n", - "y <- my_model$pred$obs\n", - "y_ <- my_model$pred$pred\n", - "mean((y - y_)^2)**0.5\n", - "#> [1] 15.69731" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mean(((y - y_)^2)**0.5)\n", - "#> [1] 12.05918" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.6.6 補足:検証による手法の比較" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "\n", - "my_lm_model <- train(form = dist ~ speed, data = my_data, method = \"lm\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "\n", - "my_knn_model <- train(form = dist ~ speed, data = my_data, method = \"knn\",\n", - " tuneGrid = data.frame(k = 5),\n", - " trControl = trainControl(method = \"LOOCV\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_lm_model$results$RMSE\n", - "#> [1] 15.69731 # 線形回帰分析\n", - "\n", - "my_knn_model$results$RMSE\n", - "#> [1] 15.79924 # K最近傍法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$dist\n", - "y_lm <- my_lm_model$pred$pred\n", - "y_knn <- my_knn_model$pred$pred\n", - "\n", - "my_df <- data.frame(\n", - " lm = (y - y_lm)^2,\n", - " knn = (y - y_knn)^2)\n", - "\n", - "head(my_df)\n", - "#> lm knn\n", - "#> 1 18.913720 108.1600\n", - "#> 2 179.215044 0.6400\n", - "#> 3 41.034336 175.5625\n", - "#> 4 168.490212 49.0000\n", - "#> 5 5.085308 9.0000\n", - "#> 6 67.615888 112.8906" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "boxplot(my_df, ylab = \"r^2\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "t.test(x = my_df$lm, y = my_df$knn,\n", - " conf.level = 0.95,\n", - " paired = TRUE,\n", - " alternative = \"two.sided\")\n", - "\n", - "#> Paired t-test\n", - "#>\n", - "#> data: my_df$lm and my_df$knn\n", - "#> t = -0.12838, df = 49, p-value = 0.8984\n", - "#> alternative hypothesis: true difference in means is not equal to 0\n", - "#> 95 percent confidence interval:\n", - "#> -53.46930 47.04792\n", - "#> sample estimates:\n", - "#> mean of the differences\n", - "#> -3.210688" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.7 パラメータチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\")\n", - "my_model$results\n", - "#> k RMSE Rsquared MAE RMSESD RsquaredSD MAESD\n", - "#> 1 5 15.72114 0.6615765 12.54588 3.013243 0.11043907 2.372245\n", - "#> 2 7 16.19047 0.6601173 12.68464 3.165330 0.09990158 2.329326\n", - "#> 3 9 16.30276 0.6556700 12.84811 3.367423 0.09645747 2.471620" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_params <- expand.grid(k = 1:15)\n", - "\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\",\n", - " tuneGrid = my_params,\n", - " trControl = trainControl(method = \"LOOCV\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_model$results)\n", - "#> k RMSE Rsquared MAE\n", - "#> 1 1 17.22299 0.5777197 13.84900\n", - "#> 2 2 16.81462 0.5936438 13.03469\n", - "#> 3 3 16.32874 0.6218866 12.74524\n", - "#> 4 4 15.98970 0.6086993 12.27888\n", - "#> 5 5 15.79924 0.6169267 11.96067\n", - "#> 6 6 15.98720 0.6079396 12.26667" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ggplot(my_model)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$bestTune\n", - "#> k\n", - "#> 5 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results %>%\n", - " filter(RMSE == min(RMSE))\n", - "#> k RMSE Rsquared MAE\n", - "#> 1 5 15.79924 0.6169267 11.96067" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$dist\n", - "y_ <- my_model %>% predict(my_data)\n", - "RMSE(y_, y)\n", - "#> [1] 13.96845" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.7.1 補足:ハイパーパラメータとRMSE(訓練)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "\n", - "my_loocv <- function(k) {\n", - " my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\",\n", - " tuneGrid = data.frame(k = k),\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - " y <- my_data$dist\n", - " y_ <- my_model %>% predict(my_data)\n", - " list(k = k,\n", - " training = RMSE(y_, y), # RMSE(訓練)\n", - " validation = my_model$results$RMSE) # RMSE(検証)\n", - "}\n", - "\n", - "my_results <- 1:15 %>% map_dfr(my_loocv)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_results %>%\n", - " pivot_longer(-k) %>%\n", - " ggplot(aes(x = k, y = value,\n", - " color = name)) +\n", - " geom_line() + geom_point() +\n", - " xlab(\"#Neighbors\") + ylab(\"RMSE\") +\n", - " theme(legend.position = c(1, 0),\n", - " legend.justification = c(1, 0))" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch07/07.01.ipynb b/code/R-notebook/ch07/07.01.ipynb deleted file mode 100644 index 77b5e21..0000000 --- a/code/R-notebook/ch07/07.01.ipynb +++ /dev/null @@ -1,19 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.1 自動車の停止距離" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch07/07.02.ipynb b/code/R-notebook/ch07/07.02.ipynb deleted file mode 100644 index cfa131e..0000000 --- a/code/R-notebook/ch07/07.02.ipynb +++ /dev/null @@ -1,92 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.2 データの確認" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "dim(my_data)\n", - "#> [1] 50 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_data)\n", - "#> speed dist\n", - "#> 1 4 2\n", - "#> 2 4 10\n", - "#> 3 7 4\n", - "#> 4 7 22\n", - "#> 5 8 16\n", - "#> 6 9 10" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "options(digits = 3)\n", - "pastecs::stat.desc(my_data)\n", - "#> speed dist\n", - "#> nbr.val 50.000 50.00\n", - "#> nbr.null 0.000 0.00\n", - "#> nbr.na 0.000 0.00\n", - "#> min 4.000 2.00\n", - "#> max 25.000 120.00\n", - "#> range 21.000 118.00\n", - "#> sum 770.000 2149.00\n", - "#> median 15.000 36.00\n", - "#> mean 15.400 42.98\n", - "#> SE.mean 0.748 3.64\n", - "#> CI.mean.0.95 1.503 7.32\n", - "#> var 27.959 664.06\n", - "#> std.dev 5.288 25.77\n", - "#> coef.var 0.343 0.60" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data %>%\n", - " ggplot(aes(x = speed, y = dist)) +\n", - " geom_point()" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch07/07.03.ipynb b/code/R-notebook/ch07/07.03.ipynb deleted file mode 100644 index 01726f3..0000000 --- a/code/R-notebook/ch07/07.03.ipynb +++ /dev/null @@ -1,140 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.3 回帰分析\n", - "\n", - "### 7.3.1 回帰分析とは何か\n", - "\n", - "### 7.3.2 線形単回帰分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_data <- cars\n", - "tmp <- data.frame(speed = 21.5, dist = 67)\n", - "my_data %>% ggplot(aes(x = speed, y = dist)) +\n", - " coord_cartesian(xlim = c(4, 25), ylim = c(0, 120)) +\n", - " geom_point() +\n", - " stat_smooth(formula = y ~ x, method = \"lm\") +\n", - " geom_pointrange(data = tmp, aes(ymin = -9, ymax = dist), linetype = \"dotted\") +\n", - " geom_pointrange(data = tmp, aes(xmin = 0, xmax = speed), linetype = \"dotted\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.3.3 回帰分析の実践\n", - "\n", - "#### 7.3.3.1 データの用意" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.2 訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = dist ~ speed, # モデル式(出力変数と入力変数の関係)\n", - " data = my_data, # データ\n", - " method = \"lm\") # 手法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "coef(my_model$finalModel)\n", - "#> (Intercept) speed\n", - "#> -17.579095 3.932409" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.3 予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- data.frame(speed = 21.5)\n", - "my_model %>% predict(tmp)\n", - "#> 1\n", - "#> 66.96769" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.4 モデルの可視化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(x) { my_model %>% predict(data.frame(speed = x)) }" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data %>%\n", - " ggplot(aes(x = speed, y = dist,\n", - " color = \"data\")) +\n", - " geom_point() +\n", - " stat_function(\n", - " fun = f,\n", - " mapping = aes(color = \"model\"))" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch07/07.04.ipynb b/code/R-notebook/ch07/07.04.ipynb deleted file mode 100644 index 9815058..0000000 --- a/code/R-notebook/ch07/07.04.ipynb +++ /dev/null @@ -1,200 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.4 当てはまりの良さの指標\n", - "\n", - "### 7.4.1 RMSE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\")\n", - "\n", - "y <- my_data$dist\n", - "y_ <- my_model %>% predict(my_data)\n", - "my_data$y_ <- y_" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data$residual <- y - y_\n", - "head(my_data)\n", - "#> speed dist y_ residual\n", - "#> 1 4 2 -1.849460 3.849460\n", - "#> 2 4 10 -1.849460 11.849460\n", - "#> 3 7 4 9.947766 -5.947766\n", - "#> 4 7 22 9.947766 12.052234\n", - "#> 5 8 16 13.880175 2.119825\n", - "#> 6 9 10 17.812584 -7.812584" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data %>%\n", - " ggplot(aes(x = speed, y = dist)) +\n", - " geom_point() +\n", - " geom_line(aes(x = speed, y = y_)) +\n", - " geom_linerange(mapping = aes(ymin = y_, ymax = dist), linetype = \"dotted\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "RMSE(y_, y)\n", - "# あるいは\n", - "mean((my_data$residual^2))**0.5\n", - "\n", - "#> [1] 15.06886" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.4.2 決定係数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] 0.6510794" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "# あるいは\n", - "summary(my_model$finalModel)$r.squared\n", - "#> [1] 0.6510794" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test <- my_data[1:3, ]\n", - "y <- my_test$dist\n", - "y_ <- my_model %>% predict(my_test)\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] -4.498191 # 決定係数1\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "#> [1] 0.07692308 # 決定係数6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.4.3 当てはまりの良さの指標の問題点" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "my_idx <- c(2, 11, 27, 34, 39, 44)\n", - "my_sample <- my_data[my_idx, ]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "options(warn = -1) # これ以降,警告を表示しない.\n", - "my_model <- train(form = dist ~ poly(speed, degree = 5, raw = TRUE),\n", - " data = my_sample,\n", - " method = \"lm\")\n", - "options(warn = 0) # これ以降,警告を表示する.\n", - "\n", - "y <- my_sample$dist\n", - "y_ <- my_model %>% predict(my_sample)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "RMSE(y_, y)\n", - "#> [1] 1.042275e-10 # RMSE\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] 1 # 決定係数1\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "#> [1] 1 # 決定係数6" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(x) { my_model %>% predict(data.frame(speed = x)) }\n", - "\n", - "my_data %>%\n", - " ggplot(aes(x = speed, y = dist, color = \"data\")) +\n", - " geom_point() +\n", - " geom_point(data = my_sample, mapping = aes(color = \"sample\")) +\n", - " stat_function(fun = f, mapping = aes(color = \"model\")) +\n", - " coord_cartesian(ylim = c(0, 120))" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch07/07.05.ipynb b/code/R-notebook/ch07/07.05.ipynb deleted file mode 100644 index e4c5217..0000000 --- a/code/R-notebook/ch07/07.05.ipynb +++ /dev/null @@ -1,78 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.5 K最近傍法\n", - "\n", - "### 7.5.1 K最近傍法とは何か\n", - "\n", - "### 7.5.2 K最近傍法の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 準備\n", - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "\n", - "# 訓練\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\")\n", - "\n", - "# 可視化の準備\n", - "f <- function(x) { my_model %>% predict(data.frame(speed = x))}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data %>%\n", - " ggplot(aes(x = speed,\n", - " y = dist,\n", - " color = \"data\")) +\n", - " geom_point() +\n", - " stat_function(\n", - " fun = f,\n", - " mapping = aes(color = \"model\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$dist\n", - "y_ <- my_model %>% predict(my_data)\n", - "\n", - "RMSE(y_, y)\n", - "#> [1] 13.96845 # RMSE\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] 0.7001789 # 決定係数1\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "#> [1] 0.7017314 # 決定係数6" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch07/07.06.ipynb b/code/R-notebook/ch07/07.06.ipynb deleted file mode 100644 index 0b5eab3..0000000 --- a/code/R-notebook/ch07/07.06.ipynb +++ /dev/null @@ -1,299 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.6 検証\n", - "\n", - "### 7.6.1 訓練データ・検証データ・テストデータ\n", - "\n", - "### 7.6.2 検証とは何か\n", - "\n", - "### 7.6.3 検証の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\")\n", - "\n", - "my_model$results\n", - "#> intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD\n", - "#> 1 TRUE 16.0206 0.6662176 12.14701 2.518604 0.09249158 1.920564" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\",\n", - " trControl = trainControl(method = \"cv\", number = 5))\n", - "my_model$results\n", - "#> intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD\n", - "#> 1 TRUE 15.06708 0.6724501 12.12448 4.75811 0.1848932 3.052435" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "my_model$results\n", - "#> intercept RMSE Rsquared MAE\n", - "#> 1 TRUE 15.69731 0.6217139 12.05918" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.6.4 検証の並列化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(doParallel)\n", - "cl <- makeCluster(detectCores())\n", - "registerDoParallel(cl)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.6.5 指標のまとめ\n", - "\n", - "#### 7.6.5.1 準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\")\n", - "y <- my_data$dist\n", - "y_ <- my_model %>% predict(my_data)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.2 当てはまりの良さの指標" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# RMSE(訓練)\n", - "RMSE(y_, y)\n", - "#> [1] 15.06886\n", - "\n", - "# 決定係数1(訓練)\n", - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] 0.6510794\n", - "\n", - "# 決定係数6(訓練)\n", - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "#> [1] 0.6510794" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "postResample(pred = y_, obs = y)\n", - "#> RMSE Rsquared MAE\n", - "#> 15.0688560 0.6510794 11.5801191" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.3 予測性能の指標(簡単に求められるもの)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\")\n", - "my_model$results\n", - "#> intercept RMSE Rsquared MAE ...\n", - "#> 1 TRUE 14.88504 0.6700353 11.59226 ...\n", - "# 左から,RMSE(検証),決定係数6(検証),MAE(検証)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.4 予測性能の指標(RとPythonで同じ結果を得る)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "\n", - "# 方法1\n", - "my_model$results\n", - "#> intercept RMSE Rsquared MAE\n", - "#> 1 TRUE 15.69731 0.6217139 12.05918\n", - "\n", - "# 方法2\n", - "y <- my_model$pred$obs\n", - "y_ <- my_model$pred$pred\n", - "mean((y - y_)^2)**0.5\n", - "#> [1] 15.69731" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mean(((y - y_)^2)**0.5)\n", - "#> [1] 12.05918" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.6.6 補足:検証による手法の比較" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "\n", - "my_lm_model <- train(form = dist ~ speed, data = my_data, method = \"lm\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "\n", - "my_knn_model <- train(form = dist ~ speed, data = my_data, method = \"knn\",\n", - " tuneGrid = data.frame(k = 5),\n", - " trControl = trainControl(method = \"LOOCV\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_lm_model$results$RMSE\n", - "#> [1] 15.69731 # 線形回帰分析\n", - "\n", - "my_knn_model$results$RMSE\n", - "#> [1] 15.79924 # K最近傍法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$dist\n", - "y_lm <- my_lm_model$pred$pred\n", - "y_knn <- my_knn_model$pred$pred\n", - "\n", - "my_df <- data.frame(\n", - " lm = (y - y_lm)^2,\n", - " knn = (y - y_knn)^2)\n", - "\n", - "head(my_df)\n", - "#> lm knn\n", - "#> 1 18.913720 108.1600\n", - "#> 2 179.215044 0.6400\n", - "#> 3 41.034336 175.5625\n", - "#> 4 168.490212 49.0000\n", - "#> 5 5.085308 9.0000\n", - "#> 6 67.615888 112.8906" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "boxplot(my_df, ylab = \"r^2\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "t.test(x = my_df$lm, y = my_df$knn,\n", - " conf.level = 0.95,\n", - " paired = TRUE,\n", - " alternative = \"two.sided\")\n", - "\n", - "#> Paired t-test\n", - "#>\n", - "#> data: my_df$lm and my_df$knn\n", - "#> t = -0.12838, df = 49, p-value = 0.8984\n", - "#> alternative hypothesis: true difference in means is not equal to 0\n", - "#> 95 percent confidence interval:\n", - "#> -53.46930 47.04792\n", - "#> sample estimates:\n", - "#> mean of the differences\n", - "#> -3.210688" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch07/07.07.ipynb b/code/R-notebook/ch07/07.07.ipynb deleted file mode 100644 index 1a9e91a..0000000 --- a/code/R-notebook/ch07/07.07.ipynb +++ /dev/null @@ -1,156 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.7 パラメータチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\")\n", - "my_model$results\n", - "#> k RMSE Rsquared MAE RMSESD RsquaredSD MAESD\n", - "#> 1 5 15.72114 0.6615765 12.54588 3.013243 0.11043907 2.372245\n", - "#> 2 7 16.19047 0.6601173 12.68464 3.165330 0.09990158 2.329326\n", - "#> 3 9 16.30276 0.6556700 12.84811 3.367423 0.09645747 2.471620" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_params <- expand.grid(k = 1:15)\n", - "\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\",\n", - " tuneGrid = my_params,\n", - " trControl = trainControl(method = \"LOOCV\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_model$results)\n", - "#> k RMSE Rsquared MAE\n", - "#> 1 1 17.22299 0.5777197 13.84900\n", - "#> 2 2 16.81462 0.5936438 13.03469\n", - "#> 3 3 16.32874 0.6218866 12.74524\n", - "#> 4 4 15.98970 0.6086993 12.27888\n", - "#> 5 5 15.79924 0.6169267 11.96067\n", - "#> 6 6 15.98720 0.6079396 12.26667" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ggplot(my_model)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$bestTune\n", - "#> k\n", - "#> 5 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results %>%\n", - " filter(RMSE == min(RMSE))\n", - "#> k RMSE Rsquared MAE\n", - "#> 1 5 15.79924 0.6169267 11.96067" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$dist\n", - "y_ <- my_model %>% predict(my_data)\n", - "RMSE(y_, y)\n", - "#> [1] 13.96845" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.7.1 補足:ハイパーパラメータとRMSE(訓練)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "\n", - "my_loocv <- function(k) {\n", - " my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\",\n", - " tuneGrid = data.frame(k = k),\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - " y <- my_data$dist\n", - " y_ <- my_model %>% predict(my_data)\n", - " list(k = k,\n", - " training = RMSE(y_, y), # RMSE(訓練)\n", - " validation = my_model$results$RMSE) # RMSE(検証)\n", - "}\n", - "\n", - "my_results <- 1:15 %>% map_dfr(my_loocv)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_results %>%\n", - " pivot_longer(-k) %>%\n", - " ggplot(aes(x = k, y = value,\n", - " color = name)) +\n", - " geom_line() + geom_point() +\n", - " xlab(\"#Neighbors\") + ylab(\"RMSE\") +\n", - " theme(legend.position = c(1, 0),\n", - " legend.justification = c(1, 0))" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch07/07.ipynb b/code/R-notebook/ch07/07.ipynb deleted file mode 100644 index 77bb8f5..0000000 --- a/code/R-notebook/ch07/07.ipynb +++ /dev/null @@ -1,909 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 07\n", - "\n", - "## 7.1 自動車の停止距離\n", - "\n", - "## 7.2 データの確認" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "dim(my_data)\n", - "#> [1] 50 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_data)\n", - "#> speed dist\n", - "#> 1 4 2\n", - "#> 2 4 10\n", - "#> 3 7 4\n", - "#> 4 7 22\n", - "#> 5 8 16\n", - "#> 6 9 10" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "options(digits = 3)\n", - "pastecs::stat.desc(my_data)\n", - "#> speed dist\n", - "#> nbr.val 50.000 50.00\n", - "#> nbr.null 0.000 0.00\n", - "#> nbr.na 0.000 0.00\n", - "#> min 4.000 2.00\n", - "#> max 25.000 120.00\n", - "#> range 21.000 118.00\n", - "#> sum 770.000 2149.00\n", - "#> median 15.000 36.00\n", - "#> mean 15.400 42.98\n", - "#> SE.mean 0.748 3.64\n", - "#> CI.mean.0.95 1.503 7.32\n", - "#> var 27.959 664.06\n", - "#> std.dev 5.288 25.77\n", - "#> coef.var 0.343 0.60" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data %>%\n", - " ggplot(aes(x = speed, y = dist)) +\n", - " geom_point()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.3 回帰分析\n", - "\n", - "### 7.3.1 回帰分析とは何か\n", - "\n", - "### 7.3.2 線形単回帰分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_data <- cars\n", - "tmp <- data.frame(speed = 21.5, dist = 67)\n", - "my_data %>% ggplot(aes(x = speed, y = dist)) +\n", - " coord_cartesian(xlim = c(4, 25), ylim = c(0, 120)) +\n", - " geom_point() +\n", - " stat_smooth(formula = y ~ x, method = \"lm\") +\n", - " geom_pointrange(data = tmp, aes(ymin = -9, ymax = dist), linetype = \"dotted\") +\n", - " geom_pointrange(data = tmp, aes(xmin = 0, xmax = speed), linetype = \"dotted\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.3.3 回帰分析の実践\n", - "\n", - "#### 7.3.3.1 データの用意" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.2 訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = dist ~ speed, # モデル式(出力変数と入力変数の関係)\n", - " data = my_data, # データ\n", - " method = \"lm\") # 手法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "coef(my_model$finalModel)\n", - "#> (Intercept) speed\n", - "#> -17.579095 3.932409" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.3 予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- data.frame(speed = 21.5)\n", - "my_model %>% predict(tmp)\n", - "#> 1\n", - "#> 66.96769" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.3.3.4 モデルの可視化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(x) { my_model %>% predict(data.frame(speed = x)) }" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data %>%\n", - " ggplot(aes(x = speed, y = dist,\n", - " color = \"data\")) +\n", - " geom_point() +\n", - " stat_function(\n", - " fun = f,\n", - " mapping = aes(color = \"model\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.4 当てはまりの良さの指標\n", - "\n", - "### 7.4.1 RMSE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\")\n", - "\n", - "y <- my_data$dist\n", - "y_ <- my_model %>% predict(my_data)\n", - "my_data$y_ <- y_" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data$residual <- y - y_\n", - "head(my_data)\n", - "#> speed dist y_ residual\n", - "#> 1 4 2 -1.849460 3.849460\n", - "#> 2 4 10 -1.849460 11.849460\n", - "#> 3 7 4 9.947766 -5.947766\n", - "#> 4 7 22 9.947766 12.052234\n", - "#> 5 8 16 13.880175 2.119825\n", - "#> 6 9 10 17.812584 -7.812584" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data %>%\n", - " ggplot(aes(x = speed, y = dist)) +\n", - " geom_point() +\n", - " geom_line(aes(x = speed, y = y_)) +\n", - " geom_linerange(mapping = aes(ymin = y_, ymax = dist), linetype = \"dotted\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "RMSE(y_, y)\n", - "# あるいは\n", - "mean((my_data$residual^2))**0.5\n", - "\n", - "#> [1] 15.06886" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.4.2 決定係数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] 0.6510794" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "# あるいは\n", - "summary(my_model$finalModel)$r.squared\n", - "#> [1] 0.6510794" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test <- my_data[1:3, ]\n", - "y <- my_test$dist\n", - "y_ <- my_model %>% predict(my_test)\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] -4.498191 # 決定係数1\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "#> [1] 0.07692308 # 決定係数6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.4.3 当てはまりの良さの指標の問題点" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "my_idx <- c(2, 11, 27, 34, 39, 44)\n", - "my_sample <- my_data[my_idx, ]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "options(warn = -1) # これ以降,警告を表示しない.\n", - "my_model <- train(form = dist ~ poly(speed, degree = 5, raw = TRUE),\n", - " data = my_sample,\n", - " method = \"lm\")\n", - "options(warn = 0) # これ以降,警告を表示する.\n", - "\n", - "y <- my_sample$dist\n", - "y_ <- my_model %>% predict(my_sample)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "RMSE(y_, y)\n", - "#> [1] 1.042275e-10 # RMSE\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] 1 # 決定係数1\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "#> [1] 1 # 決定係数6" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f <- function(x) { my_model %>% predict(data.frame(speed = x)) }\n", - "\n", - "my_data %>%\n", - " ggplot(aes(x = speed, y = dist, color = \"data\")) +\n", - " geom_point() +\n", - " geom_point(data = my_sample, mapping = aes(color = \"sample\")) +\n", - " stat_function(fun = f, mapping = aes(color = \"model\")) +\n", - " coord_cartesian(ylim = c(0, 120))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.5 K最近傍法\n", - "\n", - "### 7.5.1 K最近傍法とは何か\n", - "\n", - "### 7.5.2 K最近傍法の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 準備\n", - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "\n", - "# 訓練\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\")\n", - "\n", - "# 可視化の準備\n", - "f <- function(x) { my_model %>% predict(data.frame(speed = x))}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data %>%\n", - " ggplot(aes(x = speed,\n", - " y = dist,\n", - " color = \"data\")) +\n", - " geom_point() +\n", - " stat_function(\n", - " fun = f,\n", - " mapping = aes(color = \"model\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$dist\n", - "y_ <- my_model %>% predict(my_data)\n", - "\n", - "RMSE(y_, y)\n", - "#> [1] 13.96845 # RMSE\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] 0.7001789 # 決定係数1\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "#> [1] 0.7017314 # 決定係数6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.6 検証\n", - "\n", - "### 7.6.1 訓練データ・検証データ・テストデータ\n", - "\n", - "### 7.6.2 検証とは何か\n", - "\n", - "### 7.6.3 検証の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\")\n", - "\n", - "my_model$results\n", - "#> intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD\n", - "#> 1 TRUE 16.0206 0.6662176 12.14701 2.518604 0.09249158 1.920564" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\",\n", - " trControl = trainControl(method = \"cv\", number = 5))\n", - "my_model$results\n", - "#> intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD\n", - "#> 1 TRUE 15.06708 0.6724501 12.12448 4.75811 0.1848932 3.052435" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "my_model$results\n", - "#> intercept RMSE Rsquared MAE\n", - "#> 1 TRUE 15.69731 0.6217139 12.05918" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.6.4 検証の並列化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(doParallel)\n", - "cl <- makeCluster(detectCores())\n", - "registerDoParallel(cl)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.6.5 指標のまとめ\n", - "\n", - "#### 7.6.5.1 準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\")\n", - "y <- my_data$dist\n", - "y_ <- my_model %>% predict(my_data)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.2 当てはまりの良さの指標" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# RMSE(訓練)\n", - "RMSE(y_, y)\n", - "#> [1] 15.06886\n", - "\n", - "# 決定係数1(訓練)\n", - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] 0.6510794\n", - "\n", - "# 決定係数6(訓練)\n", - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "#> [1] 0.6510794" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "postResample(pred = y_, obs = y)\n", - "#> RMSE Rsquared MAE\n", - "#> 15.0688560 0.6510794 11.5801191" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.3 予測性能の指標(簡単に求められるもの)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\")\n", - "my_model$results\n", - "#> intercept RMSE Rsquared MAE ...\n", - "#> 1 TRUE 14.88504 0.6700353 11.59226 ...\n", - "# 左から,RMSE(検証),決定係数6(検証),MAE(検証)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 7.6.5.4 予測性能の指標(RとPythonで同じ結果を得る)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "\n", - "# 方法1\n", - "my_model$results\n", - "#> intercept RMSE Rsquared MAE\n", - "#> 1 TRUE 15.69731 0.6217139 12.05918\n", - "\n", - "# 方法2\n", - "y <- my_model$pred$obs\n", - "y_ <- my_model$pred$pred\n", - "mean((y - y_)^2)**0.5\n", - "#> [1] 15.69731" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mean(((y - y_)^2)**0.5)\n", - "#> [1] 12.05918" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.6.6 補足:検証による手法の比較" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "\n", - "my_lm_model <- train(form = dist ~ speed, data = my_data, method = \"lm\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "\n", - "my_knn_model <- train(form = dist ~ speed, data = my_data, method = \"knn\",\n", - " tuneGrid = data.frame(k = 5),\n", - " trControl = trainControl(method = \"LOOCV\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_lm_model$results$RMSE\n", - "#> [1] 15.69731 # 線形回帰分析\n", - "\n", - "my_knn_model$results$RMSE\n", - "#> [1] 15.79924 # K最近傍法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$dist\n", - "y_lm <- my_lm_model$pred$pred\n", - "y_knn <- my_knn_model$pred$pred\n", - "\n", - "my_df <- data.frame(\n", - " lm = (y - y_lm)^2,\n", - " knn = (y - y_knn)^2)\n", - "\n", - "head(my_df)\n", - "#> lm knn\n", - "#> 1 18.913720 108.1600\n", - "#> 2 179.215044 0.6400\n", - "#> 3 41.034336 175.5625\n", - "#> 4 168.490212 49.0000\n", - "#> 5 5.085308 9.0000\n", - "#> 6 67.615888 112.8906" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "boxplot(my_df, ylab = \"r^2\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "t.test(x = my_df$lm, y = my_df$knn,\n", - " conf.level = 0.95,\n", - " paired = TRUE,\n", - " alternative = \"two.sided\")\n", - "\n", - "#> Paired t-test\n", - "#>\n", - "#> data: my_df$lm and my_df$knn\n", - "#> t = -0.12838, df = 49, p-value = 0.8984\n", - "#> alternative hypothesis: true difference in means is not equal to 0\n", - "#> 95 percent confidence interval:\n", - "#> -53.46930 47.04792\n", - "#> sample estimates:\n", - "#> mean of the differences\n", - "#> -3.210688" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 7.7 パラメータチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\")\n", - "my_model$results\n", - "#> k RMSE Rsquared MAE RMSESD RsquaredSD MAESD\n", - "#> 1 5 15.72114 0.6615765 12.54588 3.013243 0.11043907 2.372245\n", - "#> 2 7 16.19047 0.6601173 12.68464 3.165330 0.09990158 2.329326\n", - "#> 3 9 16.30276 0.6556700 12.84811 3.367423 0.09645747 2.471620" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_params <- expand.grid(k = 1:15)\n", - "\n", - "my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\",\n", - " tuneGrid = my_params,\n", - " trControl = trainControl(method = \"LOOCV\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_model$results)\n", - "#> k RMSE Rsquared MAE\n", - "#> 1 1 17.22299 0.5777197 13.84900\n", - "#> 2 2 16.81462 0.5936438 13.03469\n", - "#> 3 3 16.32874 0.6218866 12.74524\n", - "#> 4 4 15.98970 0.6086993 12.27888\n", - "#> 5 5 15.79924 0.6169267 11.96067\n", - "#> 6 6 15.98720 0.6079396 12.26667" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ggplot(my_model)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$bestTune\n", - "#> k\n", - "#> 5 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results %>%\n", - " filter(RMSE == min(RMSE))\n", - "#> k RMSE Rsquared MAE\n", - "#> 1 5 15.79924 0.6169267 11.96067" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$dist\n", - "y_ <- my_model %>% predict(my_data)\n", - "RMSE(y_, y)\n", - "#> [1] 13.96845" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 7.7.1 補足:ハイパーパラメータとRMSE(訓練)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- cars\n", - "\n", - "my_loocv <- function(k) {\n", - " my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\",\n", - " tuneGrid = data.frame(k = k),\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - " y <- my_data$dist\n", - " y_ <- my_model %>% predict(my_data)\n", - " list(k = k,\n", - " training = RMSE(y_, y), # RMSE(訓練)\n", - " validation = my_model$results$RMSE) # RMSE(検証)\n", - "}\n", - "\n", - "my_results <- 1:15 %>% map_dfr(my_loocv)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_results %>%\n", - " pivot_longer(-k) %>%\n", - " ggplot(aes(x = k, y = value,\n", - " color = name)) +\n", - " geom_line() + geom_point() +\n", - " xlab(\"#Neighbors\") + ylab(\"RMSE\") +\n", - " theme(legend.position = c(1, 0),\n", - " legend.justification = c(1, 0))" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch08/08-colab.ipynb b/code/R-notebook/ch08/08-colab.ipynb deleted file mode 100644 index 4ba249e..0000000 --- a/code/R-notebook/ch08/08-colab.ipynb +++ /dev/null @@ -1,645 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 08" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Google Colaboratoryの環境設定\n", - "options(Ncpus = 2)\n", - "install.packages(c(\"caret\", \"ggfortify\", \"glmnet\", \"glmnetUtils\", \"leaps\", \"neuralnet\", \"psych\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.1 ブドウの生育条件とワインの価格" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "my_url <- \"http://www.liquidasset.com/winedata.html\"\n", - "tmp <- read.table(file = my_url, # 読み込む対象\n", - " header = TRUE, # 1行目は変数名\n", - " na.string = \".\", # 欠損値を表す文字列\n", - " skip = 62, # 読み飛ばす行数\n", - " nrows = 38) # 読み込む行数\n", - "psych::describe(tmp)\n", - "#> vars n mean sd median trimmed mad min max ...\n", - "#> OBS 1 38 19.50 11.11 19.50 19.50 14.08 1.00 38.00 ...\n", - "#> VINT 2 38 1970.50 11.11 1970.50 1970.50 14.08 1952.00 1989.00 ...\n", - "#> LPRICE2 3 27 -1.45 0.63 -1.51 -1.49 0.72 -2.29 0.00 ...\n", - "#> WRAIN 4 38 605.00 135.28 586.50 603.06 174.95 376.00 845.00 ...\n", - "#> DEGREES 5 37 16.52 0.66 16.53 16.55 0.67 14.98 17.65 ...\n", - "#> HRAIN 6 38 137.00 66.74 120.50 132.19 59.30 38.00 292.00 ...\n", - "#> TIME_SV 7 38 12.50 11.11 12.50 12.50 14.08 -6.00 31.00 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data <- na.omit(tmp[, -c(1, 2)])\n", - "head(my_data)\n", - "#> LPRICE2 WRAIN DEGREES ...\n", - "#> 1 -0.99868 600 17.1167 ...\n", - "#> 2 -0.45440 690 16.7333 ...\n", - "#> 4 -0.80796 502 17.1500 ...\n", - "#> 6 -1.50926 420 16.1333 ...\n", - "#> 7 -1.71655 582 16.4167 ...\n", - "#> 8 -0.41800 485 17.4833 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "dim(my_data)\n", - "#> [1] 27 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data %>% write_csv(\"wine.csv\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#my_data <- read_csv(\"wine.csv\") # 作ったファイルを使う場合\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.2 重回帰分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)\n", - "\n", - "my_model <- train(form = LPRICE2 ~ WRAIN + DEGREES + HRAIN + TIME_SV,\n", - " data = my_data,\n", - " method = \"lm\",\n", - " trControl = trainControl(method = \"LOOCV\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "coef(my_model$finalModel) %>%\n", - " as.data.frame\n", - "#> .\n", - "#> (Intercept) -12.145333577\n", - "#> WRAIN 0.001166782\n", - "#> DEGREES 0.616392441\n", - "#> HRAIN -0.003860554\n", - "#> TIME_SV 0.023847413" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test <- data.frame(\n", - " WRAIN = 500, DEGREES = 17,\n", - " HRAIN = 120, TIME_SV = 2)\n", - "my_model %>% predict(my_test)\n", - "#> 1\n", - "#> -1.498843" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$LPRICE2\n", - "y_ <- my_model %>% predict(my_data)\n", - "\n", - "RMSE(y_, y)\n", - "#> [1] 0.2586167 # RMSE(訓練)\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] 0.8275278 # 決定係数1(訓練)\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "#> [1] 0.8275278 # 決定係数6(訓練)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results\n", - "#> intercept RMSE Rsquared MAE\n", - "#> 1 TRUE 0.3230043 0.7361273 0.2767282" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.2.1 補足:行列計算による再現" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M <- my_data[, -1] %>%\n", - " mutate(b0 = 1) %>% as.matrix\n", - "b <- MASS::ginv(M) %*% y\n", - "matrix(b,\n", - " dimnames = list(colnames(M)))\n", - "#> [,1]\n", - "#> WRAIN 0.001166782\n", - "#> DEGREES 0.616392441\n", - "#> HRAIN -0.003860554\n", - "#> TIME_SV 0.023847413\n", - "#> b0 -12.145333577" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.3 標準化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)\n", - "\n", - "my_data %>%\n", - " mutate_if(is.numeric, scale) %>% # 数値の列の標準化\n", - " pivot_longer(-LPRICE2) %>%\n", - " ggplot(aes(x = name, y = value)) +\n", - " geom_boxplot() +\n", - " stat_summary(fun = mean, geom = \"point\", size = 3) +\n", - " xlab(NULL)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(\n", - " form = LPRICE2 ~ .,\n", - " data = my_data,\n", - " method = \"lm\",\n", - " preProcess = c(\"center\", \"scale\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "coef(my_model$finalModel) %>%\n", - " as.data.frame\n", - "#> .\n", - "#> (Intercept) -1.4517652\n", - "#> WRAIN 0.1505557\n", - "#> DEGREES 0.4063194\n", - "#> HRAIN -0.2820746\n", - "#> TIME_SV 0.1966549" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test <- data.frame(\n", - " WRAIN = 500, DEGREES = 17,\n", - " HRAIN = 120, TIME_SV = 2)\n", - "my_model %>% predict(my_test)\n", - "#> 1\n", - "#> -1.498843" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.4 入力変数の数とモデルの良さ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)\n", - "\n", - "n <- nrow(my_data)\n", - "my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2,\n", - " v2 = 0:(n - 1) %% 3)\n", - "head(my_data2)\n", - "#> # A tibble: 6 x 7\n", - "#> LPRICE2 WRAIN DEGREES HRAIN TIME_SV v1 v2\n", - "#> \n", - "#> 1 -0.999 600 17.1 160 31 0 0\n", - "#> 2 -0.454 690 16.7 80 30 1 1\n", - "#> 3 -0.808 502 17.2 130 28 0 2\n", - "#> 4 -1.51 420 16.1 110 26 1 0\n", - "#> 5 -1.72 582 16.4 187 25 0 1\n", - "#> 6 -0.418 485 17.5 187 24 1 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model2 <- train(form = LPRICE2 ~ ., data = my_data2, method = \"lm\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "y <- my_data2$LPRICE2\n", - "y_ <- my_model2 %>% predict(my_data2)\n", - "\n", - "RMSE(y_, y)\n", - "#> [1] 0.256212 # RMSE(訓練)\n", - "\n", - "my_model2$results$RMSE\n", - "#> [1] 0.3569918 # RMSE(検証)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.5 変数選択" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)\n", - "n <- nrow(my_data)\n", - "my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2,\n", - " v2 = 0:(n - 1) %% 3)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = LPRICE2 ~ .,\n", - " data = my_data2,\n", - " method = \"leapForward\", # 変数増加法\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " tuneGrid = data.frame(nvmax = 1:6)) # 選択する変数の上限\n", - "summary(my_model$finalModel)$outmat\n", - "#> WRAIN DEGREES HRAIN TIME_SV v1 v2\n", - "#> 1 ( 1 ) \" \" \"*\" \" \" \" \" \" \" \" \"\n", - "#> 2 ( 1 ) \" \" \"*\" \"*\" \" \" \" \" \" \"\n", - "#> 3 ( 1 ) \" \" \"*\" \"*\" \"*\" \" \" \" \"\n", - "#> 4 ( 1 ) \"*\" \"*\" \"*\" \"*\" \" \" \" \"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.6 補足:正則化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.1 正則化の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A <- 2\n", - "B <- 0.1\n", - "\n", - "my_model <- train(\n", - " form = LPRICE2 ~ .,\n", - " data = my_data,\n", - " method = \"glmnet\",\n", - " standardize = TRUE,\n", - " tuneGrid = data.frame(\n", - " lambda = A,\n", - " alpha = B))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "coef(my_model$finalModel, A)\n", - "#> 1\n", - "#> (Intercept) -2.8015519302\n", - "#> WRAIN .\n", - "#> DEGREES 0.0832910512\n", - "#> HRAIN -0.0004147386\n", - "#> TIME_SV 0.0023104647" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test <- data.frame(\n", - " WRAIN = 500, DEGREES = 17,\n", - " HRAIN = 120, TIME_SV = 2)\n", - "my_model %>% predict(my_test)\n", - "#> [1] -1.430752" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.2 ペナルティの強さと係数の関係" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(ggfortify)\n", - "library(glmnetUtils)\n", - "\n", - "my_data2 <- my_data %>% scale %>%\n", - " as.data.frame\n", - "\n", - "B <- 0.1\n", - "\n", - "glmnet(\n", - " form = LPRICE2 ~ .,\n", - " data = my_data2,\n", - " alpha = B) %>%\n", - " autoplot(xvar = \"lambda\") +\n", - " xlab(\"log A ( = log lambda)\") +\n", - " theme(legend.position = c(0.15, 0.25))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.3 パラメータの決定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "As <- seq(0, 0.1, length.out = 21)\n", - "Bs <- seq(0, 0.1, length.out = 6)\n", - "\n", - "my_model <- train(\n", - " form = LPRICE2 ~ ., data = my_data, method = \"glmnet\", standardize = TRUE,\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " tuneGrid = expand.grid(lambda = As, alpha = Bs))\n", - "\n", - "my_model$bestTune\n", - "#> alpha lambda\n", - "#> 8 0 0.035" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- \"B ( = alpha)\"\n", - "ggplot(my_model) +\n", - " theme(legend.position = c(0, 1), legend.justification = c(0, 1)) +\n", - " xlab(\"A ( = lambda)\") +\n", - " guides(shape = guide_legend(tmp), color = guide_legend(tmp))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results %>%\n", - " filter(RMSE == min(RMSE))\n", - "#> alpha lambda RMSE ...\n", - "#> 1 0 0.0595 0.3117092 ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.4 補足:RとPythonで結果を同じにする方法\n", - "\n", - "## 8.7 ニューラルネットワーク\n", - "\n", - "### 8.7.1 ニューラルネットワークとは何か" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "curve(1 / (1 + exp(-x)), -6, 6)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.7.2 ニューラルネットワークの訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = LPRICE2 ~ .,\n", - " data = my_data,\n", - " method = \"neuralnet\", # ニューラルネットワーク\n", - " preProcess = c(\"center\", \"scale\"), # 標準化\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "plot(my_model$finalModel) # 訓練済ネットワークの描画" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results\n", - "#> layer1 layer2 layer3 RMSE ...\n", - "#> 1 1 0 0 0.3504016 ...\n", - "#> 2 3 0 0 0.4380399 ...\n", - "#> 3 5 0 0 0.4325535 ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.7.3 ニューラルネットワークのチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(\n", - " form = LPRICE2 ~ .,\n", - " data = my_data,\n", - " method = \"neuralnet\",\n", - " preProcess = c(\"center\", \"scale\"),\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " tuneGrid = expand.grid(layer1 = 1:5,\n", - " layer2 = 0:2,\n", - " layer3 = 0))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results %>%\n", - " filter(RMSE == min(RMSE))\n", - "#> layer1 layer2 layer3 RMSE ...\n", - "#> 1 2 0 0 0.3165704 ..." - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch08/08.01.ipynb b/code/R-notebook/ch08/08.01.ipynb deleted file mode 100644 index 0fe22a7..0000000 --- a/code/R-notebook/ch08/08.01.ipynb +++ /dev/null @@ -1,91 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.1 ブドウの生育条件とワインの価格" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "my_url <- \"http://www.liquidasset.com/winedata.html\"\n", - "tmp <- read.table(file = my_url, # 読み込む対象\n", - " header = TRUE, # 1行目は変数名\n", - " na.string = \".\", # 欠損値を表す文字列\n", - " skip = 62, # 読み飛ばす行数\n", - " nrows = 38) # 読み込む行数\n", - "psych::describe(tmp)\n", - "#> vars n mean sd median trimmed mad min max ...\n", - "#> OBS 1 38 19.50 11.11 19.50 19.50 14.08 1.00 38.00 ...\n", - "#> VINT 2 38 1970.50 11.11 1970.50 1970.50 14.08 1952.00 1989.00 ...\n", - "#> LPRICE2 3 27 -1.45 0.63 -1.51 -1.49 0.72 -2.29 0.00 ...\n", - "#> WRAIN 4 38 605.00 135.28 586.50 603.06 174.95 376.00 845.00 ...\n", - "#> DEGREES 5 37 16.52 0.66 16.53 16.55 0.67 14.98 17.65 ...\n", - "#> HRAIN 6 38 137.00 66.74 120.50 132.19 59.30 38.00 292.00 ...\n", - "#> TIME_SV 7 38 12.50 11.11 12.50 12.50 14.08 -6.00 31.00 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data <- na.omit(tmp[, -c(1, 2)])\n", - "head(my_data)\n", - "#> LPRICE2 WRAIN DEGREES ...\n", - "#> 1 -0.99868 600 17.1167 ...\n", - "#> 2 -0.45440 690 16.7333 ...\n", - "#> 4 -0.80796 502 17.1500 ...\n", - "#> 6 -1.50926 420 16.1333 ...\n", - "#> 7 -1.71655 582 16.4167 ...\n", - "#> 8 -0.41800 485 17.4833 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "dim(my_data)\n", - "#> [1] 27 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data %>% write_csv(\"wine.csv\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#my_data <- read_csv(\"wine.csv\") # 作ったファイルを使う場合\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch08/08.02.ipynb b/code/R-notebook/ch08/08.02.ipynb deleted file mode 100644 index 60d2235..0000000 --- a/code/R-notebook/ch08/08.02.ipynb +++ /dev/null @@ -1,125 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.2 重回帰分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)\n", - "\n", - "my_model <- train(form = LPRICE2 ~ WRAIN + DEGREES + HRAIN + TIME_SV,\n", - " data = my_data,\n", - " method = \"lm\",\n", - " trControl = trainControl(method = \"LOOCV\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "coef(my_model$finalModel) %>%\n", - " as.data.frame\n", - "#> .\n", - "#> (Intercept) -12.145333577\n", - "#> WRAIN 0.001166782\n", - "#> DEGREES 0.616392441\n", - "#> HRAIN -0.003860554\n", - "#> TIME_SV 0.023847413" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test <- data.frame(\n", - " WRAIN = 500, DEGREES = 17,\n", - " HRAIN = 120, TIME_SV = 2)\n", - "my_model %>% predict(my_test)\n", - "#> 1\n", - "#> -1.498843" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$LPRICE2\n", - "y_ <- my_model %>% predict(my_data)\n", - "\n", - "RMSE(y_, y)\n", - "#> [1] 0.2586167 # RMSE(訓練)\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] 0.8275278 # 決定係数1(訓練)\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "#> [1] 0.8275278 # 決定係数6(訓練)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results\n", - "#> intercept RMSE Rsquared MAE\n", - "#> 1 TRUE 0.3230043 0.7361273 0.2767282" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.2.1 補足:行列計算による再現" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M <- my_data[, -1] %>%\n", - " mutate(b0 = 1) %>% as.matrix\n", - "b <- MASS::ginv(M) %*% y\n", - "matrix(b,\n", - " dimnames = list(colnames(M)))\n", - "#> [,1]\n", - "#> WRAIN 0.001166782\n", - "#> DEGREES 0.616392441\n", - "#> HRAIN -0.003860554\n", - "#> TIME_SV 0.023847413\n", - "#> b0 -12.145333577" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch08/08.03.ipynb b/code/R-notebook/ch08/08.03.ipynb deleted file mode 100644 index a4ad7d6..0000000 --- a/code/R-notebook/ch08/08.03.ipynb +++ /dev/null @@ -1,83 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.3 標準化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)\n", - "\n", - "my_data %>%\n", - " mutate_if(is.numeric, scale) %>% # 数値の列の標準化\n", - " pivot_longer(-LPRICE2) %>%\n", - " ggplot(aes(x = name, y = value)) +\n", - " geom_boxplot() +\n", - " stat_summary(fun = mean, geom = \"point\", size = 3) +\n", - " xlab(NULL)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(\n", - " form = LPRICE2 ~ .,\n", - " data = my_data,\n", - " method = \"lm\",\n", - " preProcess = c(\"center\", \"scale\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "coef(my_model$finalModel) %>%\n", - " as.data.frame\n", - "#> .\n", - "#> (Intercept) -1.4517652\n", - "#> WRAIN 0.1505557\n", - "#> DEGREES 0.4063194\n", - "#> HRAIN -0.2820746\n", - "#> TIME_SV 0.1966549" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test <- data.frame(\n", - " WRAIN = 500, DEGREES = 17,\n", - " HRAIN = 120, TIME_SV = 2)\n", - "my_model %>% predict(my_test)\n", - "#> 1\n", - "#> -1.498843" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch08/08.04.ipynb b/code/R-notebook/ch08/08.04.ipynb deleted file mode 100644 index 0b3abc5..0000000 --- a/code/R-notebook/ch08/08.04.ipynb +++ /dev/null @@ -1,64 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.4 入力変数の数とモデルの良さ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)\n", - "\n", - "n <- nrow(my_data)\n", - "my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2,\n", - " v2 = 0:(n - 1) %% 3)\n", - "head(my_data2)\n", - "#> # A tibble: 6 x 7\n", - "#> LPRICE2 WRAIN DEGREES HRAIN TIME_SV v1 v2\n", - "#> \n", - "#> 1 -0.999 600 17.1 160 31 0 0\n", - "#> 2 -0.454 690 16.7 80 30 1 1\n", - "#> 3 -0.808 502 17.2 130 28 0 2\n", - "#> 4 -1.51 420 16.1 110 26 1 0\n", - "#> 5 -1.72 582 16.4 187 25 0 1\n", - "#> 6 -0.418 485 17.5 187 24 1 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model2 <- train(form = LPRICE2 ~ ., data = my_data2, method = \"lm\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "y <- my_data2$LPRICE2\n", - "y_ <- my_model2 %>% predict(my_data2)\n", - "\n", - "RMSE(y_, y)\n", - "#> [1] 0.256212 # RMSE(訓練)\n", - "\n", - "my_model2$results$RMSE\n", - "#> [1] 0.3569918 # RMSE(検証)" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch08/08.05.ipynb b/code/R-notebook/ch08/08.05.ipynb deleted file mode 100644 index 1dba9e5..0000000 --- a/code/R-notebook/ch08/08.05.ipynb +++ /dev/null @@ -1,54 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.5 変数選択" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)\n", - "n <- nrow(my_data)\n", - "my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2,\n", - " v2 = 0:(n - 1) %% 3)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = LPRICE2 ~ .,\n", - " data = my_data2,\n", - " method = \"leapForward\", # 変数増加法\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " tuneGrid = data.frame(nvmax = 1:6)) # 選択する変数の上限\n", - "summary(my_model$finalModel)$outmat\n", - "#> WRAIN DEGREES HRAIN TIME_SV v1 v2\n", - "#> 1 ( 1 ) \" \" \"*\" \" \" \" \" \" \" \" \"\n", - "#> 2 ( 1 ) \" \" \"*\" \"*\" \" \" \" \" \" \"\n", - "#> 3 ( 1 ) \" \" \"*\" \"*\" \"*\" \" \" \" \"\n", - "#> 4 ( 1 ) \"*\" \"*\" \"*\" \"*\" \" \" \" \"" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch08/08.06.ipynb b/code/R-notebook/ch08/08.06.ipynb deleted file mode 100644 index e7a201c..0000000 --- a/code/R-notebook/ch08/08.06.ipynb +++ /dev/null @@ -1,174 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.6 補足:正則化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.1 正則化の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A <- 2\n", - "B <- 0.1\n", - "\n", - "my_model <- train(\n", - " form = LPRICE2 ~ .,\n", - " data = my_data,\n", - " method = \"glmnet\",\n", - " standardize = TRUE,\n", - " tuneGrid = data.frame(\n", - " lambda = A,\n", - " alpha = B))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "coef(my_model$finalModel, A)\n", - "#> 1\n", - "#> (Intercept) -2.8015519302\n", - "#> WRAIN .\n", - "#> DEGREES 0.0832910512\n", - "#> HRAIN -0.0004147386\n", - "#> TIME_SV 0.0023104647" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test <- data.frame(\n", - " WRAIN = 500, DEGREES = 17,\n", - " HRAIN = 120, TIME_SV = 2)\n", - "my_model %>% predict(my_test)\n", - "#> [1] -1.430752" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.2 ペナルティの強さと係数の関係" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(ggfortify)\n", - "library(glmnetUtils)\n", - "\n", - "my_data2 <- my_data %>% scale %>%\n", - " as.data.frame\n", - "\n", - "B <- 0.1\n", - "\n", - "glmnet(\n", - " form = LPRICE2 ~ .,\n", - " data = my_data2,\n", - " alpha = B) %>%\n", - " autoplot(xvar = \"lambda\") +\n", - " xlab(\"log A ( = log lambda)\") +\n", - " theme(legend.position = c(0.15, 0.25))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.3 パラメータの決定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "As <- seq(0, 0.1, length.out = 21)\n", - "Bs <- seq(0, 0.1, length.out = 6)\n", - "\n", - "my_model <- train(\n", - " form = LPRICE2 ~ ., data = my_data, method = \"glmnet\", standardize = TRUE,\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " tuneGrid = expand.grid(lambda = As, alpha = Bs))\n", - "\n", - "my_model$bestTune\n", - "#> alpha lambda\n", - "#> 8 0 0.035" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- \"B ( = alpha)\"\n", - "ggplot(my_model) +\n", - " theme(legend.position = c(0, 1), legend.justification = c(0, 1)) +\n", - " xlab(\"A ( = lambda)\") +\n", - " guides(shape = guide_legend(tmp), color = guide_legend(tmp))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results %>%\n", - " filter(RMSE == min(RMSE))\n", - "#> alpha lambda RMSE ...\n", - "#> 1 0 0.0595 0.3117092 ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.4 補足:RとPythonで結果を同じにする方法" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch08/08.07.ipynb b/code/R-notebook/ch08/08.07.ipynb deleted file mode 100644 index 03d4abf..0000000 --- a/code/R-notebook/ch08/08.07.ipynb +++ /dev/null @@ -1,113 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.7 ニューラルネットワーク\n", - "\n", - "### 8.7.1 ニューラルネットワークとは何か" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "curve(1 / (1 + exp(-x)), -6, 6)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.7.2 ニューラルネットワークの訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = LPRICE2 ~ .,\n", - " data = my_data,\n", - " method = \"neuralnet\", # ニューラルネットワーク\n", - " preProcess = c(\"center\", \"scale\"), # 標準化\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "plot(my_model$finalModel) # 訓練済ネットワークの描画" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results\n", - "#> layer1 layer2 layer3 RMSE ...\n", - "#> 1 1 0 0 0.3504016 ...\n", - "#> 2 3 0 0 0.4380399 ...\n", - "#> 3 5 0 0 0.4325535 ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.7.3 ニューラルネットワークのチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(\n", - " form = LPRICE2 ~ .,\n", - " data = my_data,\n", - " method = \"neuralnet\",\n", - " preProcess = c(\"center\", \"scale\"),\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " tuneGrid = expand.grid(layer1 = 1:5,\n", - " layer2 = 0:2,\n", - " layer3 = 0))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results %>%\n", - " filter(RMSE == min(RMSE))\n", - "#> layer1 layer2 layer3 RMSE ...\n", - "#> 1 2 0 0 0.3165704 ..." - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch08/08.ipynb b/code/R-notebook/ch08/08.ipynb deleted file mode 100644 index 26ed163..0000000 --- a/code/R-notebook/ch08/08.ipynb +++ /dev/null @@ -1,629 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 08\n", - "\n", - "## 8.1 ブドウの生育条件とワインの価格" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "my_url <- \"http://www.liquidasset.com/winedata.html\"\n", - "tmp <- read.table(file = my_url, # 読み込む対象\n", - " header = TRUE, # 1行目は変数名\n", - " na.string = \".\", # 欠損値を表す文字列\n", - " skip = 62, # 読み飛ばす行数\n", - " nrows = 38) # 読み込む行数\n", - "psych::describe(tmp)\n", - "#> vars n mean sd median trimmed mad min max ...\n", - "#> OBS 1 38 19.50 11.11 19.50 19.50 14.08 1.00 38.00 ...\n", - "#> VINT 2 38 1970.50 11.11 1970.50 1970.50 14.08 1952.00 1989.00 ...\n", - "#> LPRICE2 3 27 -1.45 0.63 -1.51 -1.49 0.72 -2.29 0.00 ...\n", - "#> WRAIN 4 38 605.00 135.28 586.50 603.06 174.95 376.00 845.00 ...\n", - "#> DEGREES 5 37 16.52 0.66 16.53 16.55 0.67 14.98 17.65 ...\n", - "#> HRAIN 6 38 137.00 66.74 120.50 132.19 59.30 38.00 292.00 ...\n", - "#> TIME_SV 7 38 12.50 11.11 12.50 12.50 14.08 -6.00 31.00 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data <- na.omit(tmp[, -c(1, 2)])\n", - "head(my_data)\n", - "#> LPRICE2 WRAIN DEGREES ...\n", - "#> 1 -0.99868 600 17.1167 ...\n", - "#> 2 -0.45440 690 16.7333 ...\n", - "#> 4 -0.80796 502 17.1500 ...\n", - "#> 6 -1.50926 420 16.1333 ...\n", - "#> 7 -1.71655 582 16.4167 ...\n", - "#> 8 -0.41800 485 17.4833 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "dim(my_data)\n", - "#> [1] 27 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data %>% write_csv(\"wine.csv\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#my_data <- read_csv(\"wine.csv\") # 作ったファイルを使う場合\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.2 重回帰分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)\n", - "\n", - "my_model <- train(form = LPRICE2 ~ WRAIN + DEGREES + HRAIN + TIME_SV,\n", - " data = my_data,\n", - " method = \"lm\",\n", - " trControl = trainControl(method = \"LOOCV\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "coef(my_model$finalModel) %>%\n", - " as.data.frame\n", - "#> .\n", - "#> (Intercept) -12.145333577\n", - "#> WRAIN 0.001166782\n", - "#> DEGREES 0.616392441\n", - "#> HRAIN -0.003860554\n", - "#> TIME_SV 0.023847413" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test <- data.frame(\n", - " WRAIN = 500, DEGREES = 17,\n", - " HRAIN = 120, TIME_SV = 2)\n", - "my_model %>% predict(my_test)\n", - "#> 1\n", - "#> -1.498843" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$LPRICE2\n", - "y_ <- my_model %>% predict(my_data)\n", - "\n", - "RMSE(y_, y)\n", - "#> [1] 0.2586167 # RMSE(訓練)\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"traditional\")\n", - "#> [1] 0.8275278 # 決定係数1(訓練)\n", - "\n", - "R2(pred = y_, obs = y,\n", - " form = \"corr\")\n", - "#> [1] 0.8275278 # 決定係数6(訓練)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results\n", - "#> intercept RMSE Rsquared MAE\n", - "#> 1 TRUE 0.3230043 0.7361273 0.2767282" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.2.1 補足:行列計算による再現" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "M <- my_data[, -1] %>%\n", - " mutate(b0 = 1) %>% as.matrix\n", - "b <- MASS::ginv(M) %*% y\n", - "matrix(b,\n", - " dimnames = list(colnames(M)))\n", - "#> [,1]\n", - "#> WRAIN 0.001166782\n", - "#> DEGREES 0.616392441\n", - "#> HRAIN -0.003860554\n", - "#> TIME_SV 0.023847413\n", - "#> b0 -12.145333577" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.3 標準化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)\n", - "\n", - "my_data %>%\n", - " mutate_if(is.numeric, scale) %>% # 数値の列の標準化\n", - " pivot_longer(-LPRICE2) %>%\n", - " ggplot(aes(x = name, y = value)) +\n", - " geom_boxplot() +\n", - " stat_summary(fun = mean, geom = \"point\", size = 3) +\n", - " xlab(NULL)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(\n", - " form = LPRICE2 ~ .,\n", - " data = my_data,\n", - " method = \"lm\",\n", - " preProcess = c(\"center\", \"scale\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "coef(my_model$finalModel) %>%\n", - " as.data.frame\n", - "#> .\n", - "#> (Intercept) -1.4517652\n", - "#> WRAIN 0.1505557\n", - "#> DEGREES 0.4063194\n", - "#> HRAIN -0.2820746\n", - "#> TIME_SV 0.1966549" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test <- data.frame(\n", - " WRAIN = 500, DEGREES = 17,\n", - " HRAIN = 120, TIME_SV = 2)\n", - "my_model %>% predict(my_test)\n", - "#> 1\n", - "#> -1.498843" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.4 入力変数の数とモデルの良さ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)\n", - "\n", - "n <- nrow(my_data)\n", - "my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2,\n", - " v2 = 0:(n - 1) %% 3)\n", - "head(my_data2)\n", - "#> # A tibble: 6 x 7\n", - "#> LPRICE2 WRAIN DEGREES HRAIN TIME_SV v1 v2\n", - "#> \n", - "#> 1 -0.999 600 17.1 160 31 0 0\n", - "#> 2 -0.454 690 16.7 80 30 1 1\n", - "#> 3 -0.808 502 17.2 130 28 0 2\n", - "#> 4 -1.51 420 16.1 110 26 1 0\n", - "#> 5 -1.72 582 16.4 187 25 0 1\n", - "#> 6 -0.418 485 17.5 187 24 1 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model2 <- train(form = LPRICE2 ~ ., data = my_data2, method = \"lm\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "y <- my_data2$LPRICE2\n", - "y_ <- my_model2 %>% predict(my_data2)\n", - "\n", - "RMSE(y_, y)\n", - "#> [1] 0.256212 # RMSE(訓練)\n", - "\n", - "my_model2$results$RMSE\n", - "#> [1] 0.3569918 # RMSE(検証)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.5 変数選択" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)\n", - "n <- nrow(my_data)\n", - "my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2,\n", - " v2 = 0:(n - 1) %% 3)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = LPRICE2 ~ .,\n", - " data = my_data2,\n", - " method = \"leapForward\", # 変数増加法\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " tuneGrid = data.frame(nvmax = 1:6)) # 選択する変数の上限\n", - "summary(my_model$finalModel)$outmat\n", - "#> WRAIN DEGREES HRAIN TIME_SV v1 v2\n", - "#> 1 ( 1 ) \" \" \"*\" \" \" \" \" \" \" \" \"\n", - "#> 2 ( 1 ) \" \" \"*\" \"*\" \" \" \" \" \" \"\n", - "#> 3 ( 1 ) \" \" \"*\" \"*\" \"*\" \" \" \" \"\n", - "#> 4 ( 1 ) \"*\" \"*\" \"*\" \"*\" \" \" \" \"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 8.6 補足:正則化" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.1 正則化の実践" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A <- 2\n", - "B <- 0.1\n", - "\n", - "my_model <- train(\n", - " form = LPRICE2 ~ .,\n", - " data = my_data,\n", - " method = \"glmnet\",\n", - " standardize = TRUE,\n", - " tuneGrid = data.frame(\n", - " lambda = A,\n", - " alpha = B))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "coef(my_model$finalModel, A)\n", - "#> 1\n", - "#> (Intercept) -2.8015519302\n", - "#> WRAIN .\n", - "#> DEGREES 0.0832910512\n", - "#> HRAIN -0.0004147386\n", - "#> TIME_SV 0.0023104647" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test <- data.frame(\n", - " WRAIN = 500, DEGREES = 17,\n", - " HRAIN = 120, TIME_SV = 2)\n", - "my_model %>% predict(my_test)\n", - "#> [1] -1.430752" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.2 ペナルティの強さと係数の関係" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(ggfortify)\n", - "library(glmnetUtils)\n", - "\n", - "my_data2 <- my_data %>% scale %>%\n", - " as.data.frame\n", - "\n", - "B <- 0.1\n", - "\n", - "glmnet(\n", - " form = LPRICE2 ~ .,\n", - " data = my_data2,\n", - " alpha = B) %>%\n", - " autoplot(xvar = \"lambda\") +\n", - " xlab(\"log A ( = log lambda)\") +\n", - " theme(legend.position = c(0.15, 0.25))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.3 パラメータの決定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "As <- seq(0, 0.1, length.out = 21)\n", - "Bs <- seq(0, 0.1, length.out = 6)\n", - "\n", - "my_model <- train(\n", - " form = LPRICE2 ~ ., data = my_data, method = \"glmnet\", standardize = TRUE,\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " tuneGrid = expand.grid(lambda = As, alpha = Bs))\n", - "\n", - "my_model$bestTune\n", - "#> alpha lambda\n", - "#> 8 0 0.035" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- \"B ( = alpha)\"\n", - "ggplot(my_model) +\n", - " theme(legend.position = c(0, 1), legend.justification = c(0, 1)) +\n", - " xlab(\"A ( = lambda)\") +\n", - " guides(shape = guide_legend(tmp), color = guide_legend(tmp))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results %>%\n", - " filter(RMSE == min(RMSE))\n", - "#> alpha lambda RMSE ...\n", - "#> 1 0 0.0595 0.3117092 ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.6.4 補足:RとPythonで結果を同じにする方法\n", - "\n", - "## 8.7 ニューラルネットワーク\n", - "\n", - "### 8.7.1 ニューラルネットワークとは何か" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "curve(1 / (1 + exp(-x)), -6, 6)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.7.2 ニューラルネットワークの訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = LPRICE2 ~ .,\n", - " data = my_data,\n", - " method = \"neuralnet\", # ニューラルネットワーク\n", - " preProcess = c(\"center\", \"scale\"), # 標準化\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "plot(my_model$finalModel) # 訓練済ネットワークの描画" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results\n", - "#> layer1 layer2 layer3 RMSE ...\n", - "#> 1 1 0 0 0.3504016 ...\n", - "#> 2 3 0 0 0.4380399 ...\n", - "#> 3 5 0 0 0.4325535 ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 8.7.3 ニューラルネットワークのチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(\n", - " form = LPRICE2 ~ .,\n", - " data = my_data,\n", - " method = \"neuralnet\",\n", - " preProcess = c(\"center\", \"scale\"),\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " tuneGrid = expand.grid(layer1 = 1:5,\n", - " layer2 = 0:2,\n", - " layer3 = 0))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results %>%\n", - " filter(RMSE == min(RMSE))\n", - "#> layer1 layer2 layer3 RMSE ...\n", - "#> 1 2 0 0 0.3165704 ..." - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch09/09-colab.ipynb b/code/R-notebook/ch09/09-colab.ipynb deleted file mode 100644 index 6ecd7af..0000000 --- a/code/R-notebook/ch09/09-colab.ipynb +++ /dev/null @@ -1,516 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 09" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Google Colaboratoryの環境設定\n", - "options(Ncpus = 2)\n", - "install.packages(c(\"caret\", \"e1071\", \"furrr\", \"psych\", \"randomForest\", \"rpart.plot\", \"xgboost\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.1 アヤメのデータ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data <- iris\n", - "head(my_data)\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 1 5.1 3.5 1.4 0.2 setosa\n", - "#> 2 4.9 3.0 1.4 0.2 setosa\n", - "#> 3 4.7 3.2 1.3 0.2 setosa\n", - "#> 4 4.6 3.1 1.5 0.2 setosa\n", - "#> 5 5.0 3.6 1.4 0.2 setosa\n", - "#> 6 5.4 3.9 1.7 0.4 setosa" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "psych::describe(my_data)\n", - "#> vars n mean sd median trimmed mad min max range ...\n", - "#> Sepal.Length 1 150 5.84 0.83 5.80 5.81 1.04 4.3 7.9 3.6 ...\n", - "#> Sepal.Width 2 150 3.06 0.44 3.00 3.04 0.44 2.0 4.4 2.4 ...\n", - "#> Petal.Length 3 150 3.76 1.77 4.35 3.76 1.85 1.0 6.9 5.9 ...\n", - "#> Petal.Width 4 150 1.20 0.76 1.30 1.18 1.04 0.1 2.5 2.4 ...\n", - "#> Species* 5 150 2.00 0.82 2.00 2.00 1.48 1.0 3.0 2.0 ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.2 木による分類\n", - "\n", - "### 9.2.1 分類木の作成と利用" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rpart.plot::rpart.plot(my_model$finalModel, extra = 1)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test <- tribble(\n", - "~Sepal.Length, ~Sepal.Width, ~Petal.Length, ~Petal.Width,\n", - " 5.0, 3.5, 1.5, 0.5,\n", - " 6.5, 3.0, 5.0, 2.0)\n", - "\n", - "my_model %>% predict(my_test)\n", - "#> [1] setosa virginica\n", - "#> Levels: setosa versicolor virginica" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>% predict(my_test,\n", - " type = \"prob\")\n", - "#> setosa versicolor virginica\n", - "#> 1 1 0.00000000 0.0000000\n", - "#> 2 0 0.02173913 0.9782609" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.3 正解率\n", - "\n", - "### 9.3.1 混同行列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\")\n", - "\n", - "y <- my_data$Species\n", - "y_ <- my_model %>% predict(my_data)\n", - "confusionMatrix(data = y_, reference = y)\n", - "#> Confusion Matrix and Statistics\n", - "#>\n", - "#> Reference\n", - "#> Prediction setosa versicolor virginica\n", - "#> setosa 50 0 0\n", - "#> versicolor 0 49 1\n", - "#> virginica 0 5 45\n", - "# 以下は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.2 正解率(訓練)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$Species\n", - "y_ <- my_model %>% predict(my_data)\n", - "mean(y_ == y)\n", - "#> [1] 0.96" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.3 正解率(検証)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "my_model$results\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 1 0.3333333 0.00\n", - "#> 2 2 0.9533333 0.93" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.4 パラメータチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\",\n", - " tuneGrid = data.frame(maxdepth = 1:10),\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "my_model$results %>% filter(Accuracy == max(Accuracy))\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 2 0.9533333 0.93" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.5 補足:木の複雑さの制限" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# パラメータを与えると正解率(LOOCV)を返す関数\n", - "my_loocv <- function(maxdepth, minbucket, minsplit) {\n", - " my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\",\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " tuneGrid = data.frame(maxdepth = maxdepth),\n", - " control = rpart::rpart.control(cp = 0.01,\n", - " minbucket = minbucket,\n", - " minsplit = minsplit))\n", - " list(maxdepth = maxdepth,\n", - " minbucket = minbucket,\n", - " minsplit = minsplit,\n", - " Accuracy = my_model$results$Accuracy)\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_params <- expand.grid(\n", - " maxdepth = 2:5,\n", - " minbucket = 1:7,\n", - " minsplit = c(2, 20))\n", - "\n", - "library(furrr)\n", - "plan(multisession) # 並列処理の準備\n", - "my_results <- my_params %>% future_pmap_dfr(my_loocv, # 実行\n", - " .options = furrr_options(seed = TRUE))\n", - "\n", - "my_results %>% filter(Accuracy == max(Accuracy)) # 正解率(検証)の最大値\n", - "#> maxdepth minbucket minsplit Accuracy\n", - "#> \n", - "#> 1 3 5 2 0.973\n", - "#> 2 4 5 2 0.973\n", - "#> 3 5 5 2 0.973\n", - "#> 4 3 5 20 0.973\n", - "#> 5 4 5 20 0.973\n", - "#> 6 5 5 20 0.973" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\",\n", - " trControl = trainControl(method = \"none\"),\n", - " tuneGrid = data.frame(maxdepth = 3),\n", - " control = rpart::rpart.control(cp = 0.01,\n", - " minbucket = 5,\n", - " minsplit = 2))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rpart.plot::rpart.plot(\n", - " my_model$finalModel, extra = 1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.4 複数の木を使う方法\n", - "\n", - "### 9.4.1 ランダムフォレスト" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "\n", - "my_model <- train(form = Species ~ ., data = my_data, method = \"rf\",\n", - " tuneGrid = data.frame(mtry = 2:4), # 省略可\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "my_model$results\n", - "#> mtry Accuracy Kappa\n", - "#> 1 2 0.96 0.94\n", - "#> 2 3 0.96 0.94\n", - "#> 3 4 0.96 0.94" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.4.2 ブースティング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(\n", - " form = Species ~ ., data = my_data, method = \"xgbTree\",\n", - " tuneGrid = expand.grid(\n", - " nrounds = c(50, 100, 150),\n", - " max_depth = c(1, 2, 3),\n", - " eta = c(0.3, 0.4),\n", - " gamma = 0,\n", - " colsample_bytree = c(0.6, 0.8),\n", - " min_child_weight = 1,\n", - " subsample = c(0.5, 0.75, 1)),\n", - " trControl = trainControl(method = \"cv\", number = 5)) # 5分割交差検証\n", - "my_model$results %>% filter(Accuracy == max(Accuracy)) %>% head(5) %>% t\n", - "#> 1 2 3 4 5\n", - "#> eta 0.30000000 0.30000000 0.30000000 0.40000000 0.30000000\n", - "#> max_depth 1.00000000 1.00000000 1.00000000 1.00000000 3.00000000\n", - "#> gamma 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000\n", - "#> colsample_bytree 0.60000000 0.60000000 0.80000000 0.60000000 0.80000000\n", - "#> min_child_weight 1.00000000 1.00000000 1.00000000 1.00000000 1.00000000\n", - "#> subsample 0.50000000 0.75000000 0.75000000 0.50000000 0.50000000\n", - "#> nrounds 50.00000000 50.00000000 50.00000000 50.00000000 50.00000000\n", - "#> Accuracy 0.96000000 0.96000000 0.96000000 0.96000000 0.96000000\n", - "#> Kappa 0.94000000 0.94000000 0.94000000 0.94000000 0.94000000\n", - "#> AccuracySD 0.02788867 0.02788867 0.02788867 0.01490712 0.01490712\n", - "#> KappaSD 0.04183300 0.04183300 0.04183300 0.02236068 0.02236068" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.4.3 入力変数の重要度" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Species ~ ., data = my_data, method = \"rf\")\n", - "ggplot(varImp(my_model))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.5 欠損のあるデータでの学習\n", - "\n", - "### 9.5.1 欠損のあるデータの準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "\n", - "n <- nrow(my_data)\n", - "my_data$Petal.Length[0:(n - 1) %% 10 == 0] <- NA\n", - "my_data$Petal.Width[ 0:(n - 1) %% 10 == 1] <- NA\n", - "\n", - "psych::describe(my_data) # nの値が135の変数に,150 - 135 = 15個の欠損がある.\n", - "#> vars n mean sd median trimmed mad min max range ...\n", - "#> Sepal.Length 1 150 5.84 0.83 5.8 5.81 1.04 4.3 7.9 3.6 ...\n", - "#> Sepal.Width 2 150 3.06 0.44 3.0 3.04 0.44 2.0 4.4 2.4 ...\n", - "#> Petal.Length 3 135 3.75 1.76 4.3 3.75 1.78 1.0 6.9 5.9 ...\n", - "#> Petal.Width 4 135 1.20 0.77 1.3 1.18 1.04 0.1 2.5 2.4 ...\n", - "#> Species* 5 150 2.00 0.82 2.0 2.00 1.48 1.0 3.0 2.0 ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.5.2 方針1:欠損を埋めて学習する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(\n", - " form = Species ~ ., data = my_data, method = \"rpart2\",\n", - " na.action = na.pass, # 欠損があっても学習を止めない.\n", - " preProcess = \"medianImpute\", # 欠損を中央値で埋める.\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " tuneGrid = data.frame(maxdepth = 20), # 木の高さの上限\n", - " control = rpart::rpart.control(minsplit = 2, # 分岐の条件\n", - " minbucket = 1)) # 終端ノードの条件\n", - "max(my_model$results$Accuracy)\n", - "#> [1] 0.9266667" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.5.3 方針2:欠損があっても使える手法で学習する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Species ~ ., data = my_data, method = \"xgbTree\",\n", - " na.action = na.pass,\n", - " trControl = trainControl(method = \"cv\", number = 5))\n", - "max(my_model$results$Accuracy)\n", - "#> [1] 0.966666666666667" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.6 他の分類手法\n", - "\n", - "### 9.6.1 K最近傍法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "\n", - "my_model <- train(form = Species ~ ., data = my_data, method = \"knn\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "my_model$results %>% filter(Accuracy == max(Accuracy))\n", - "#> k Accuracy Kappa\n", - "#> 1 9 0.9733333 0.96" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.6.2 ニューラルネットワーク" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "\n", - "my_model <- train(form = Species ~ ., data = my_data, method = \"nnet\",\n", - " preProcess = c(\"center\", \"scale\"), # 標準化\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " trace = FALSE) # 途中経過を表示しない\n", - "my_model$results %>% filter(Accuracy == max(Accuracy))\n", - "#> size decay Accuracy Kappa\n", - "#> 1 3 0.1 0.9733333 0.96\n", - "#> 2 5 0.1 0.9733333 0.96" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch09/09.01.ipynb b/code/R-notebook/ch09/09.01.ipynb deleted file mode 100644 index cdd9619..0000000 --- a/code/R-notebook/ch09/09.01.ipynb +++ /dev/null @@ -1,51 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.1 アヤメのデータ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data <- iris\n", - "head(my_data)\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 1 5.1 3.5 1.4 0.2 setosa\n", - "#> 2 4.9 3.0 1.4 0.2 setosa\n", - "#> 3 4.7 3.2 1.3 0.2 setosa\n", - "#> 4 4.6 3.1 1.5 0.2 setosa\n", - "#> 5 5.0 3.6 1.4 0.2 setosa\n", - "#> 6 5.4 3.9 1.7 0.4 setosa" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "psych::describe(my_data)\n", - "#> vars n mean sd median trimmed mad min max range ...\n", - "#> Sepal.Length 1 150 5.84 0.83 5.80 5.81 1.04 4.3 7.9 3.6 ...\n", - "#> Sepal.Width 2 150 3.06 0.44 3.00 3.04 0.44 2.0 4.4 2.4 ...\n", - "#> Petal.Length 3 150 3.76 1.77 4.35 3.76 1.85 1.0 6.9 5.9 ...\n", - "#> Petal.Width 4 150 1.20 0.76 1.30 1.18 1.04 0.1 2.5 2.4 ...\n", - "#> Species* 5 150 2.00 0.82 2.00 2.00 1.48 1.0 3.0 2.0 ..." - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch09/09.02.ipynb b/code/R-notebook/ch09/09.02.ipynb deleted file mode 100644 index 00752fd..0000000 --- a/code/R-notebook/ch09/09.02.ipynb +++ /dev/null @@ -1,71 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.2 木による分類\n", - "\n", - "### 9.2.1 分類木の作成と利用" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rpart.plot::rpart.plot(my_model$finalModel, extra = 1)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test <- tribble(\n", - "~Sepal.Length, ~Sepal.Width, ~Petal.Length, ~Petal.Width,\n", - " 5.0, 3.5, 1.5, 0.5,\n", - " 6.5, 3.0, 5.0, 2.0)\n", - "\n", - "my_model %>% predict(my_test)\n", - "#> [1] setosa virginica\n", - "#> Levels: setosa versicolor virginica" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>% predict(my_test,\n", - " type = \"prob\")\n", - "#> setosa versicolor virginica\n", - "#> 1 1 0.00000000 0.0000000\n", - "#> 2 0 0.02173913 0.9782609" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch09/09.03.ipynb b/code/R-notebook/ch09/09.03.ipynb deleted file mode 100644 index 0067af2..0000000 --- a/code/R-notebook/ch09/09.03.ipynb +++ /dev/null @@ -1,185 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.3 正解率\n", - "\n", - "### 9.3.1 混同行列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\")\n", - "\n", - "y <- my_data$Species\n", - "y_ <- my_model %>% predict(my_data)\n", - "confusionMatrix(data = y_, reference = y)\n", - "#> Confusion Matrix and Statistics\n", - "#>\n", - "#> Reference\n", - "#> Prediction setosa versicolor virginica\n", - "#> setosa 50 0 0\n", - "#> versicolor 0 49 1\n", - "#> virginica 0 5 45\n", - "# 以下は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.2 正解率(訓練)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$Species\n", - "y_ <- my_model %>% predict(my_data)\n", - "mean(y_ == y)\n", - "#> [1] 0.96" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.3 正解率(検証)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "my_model$results\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 1 0.3333333 0.00\n", - "#> 2 2 0.9533333 0.93" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.4 パラメータチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\",\n", - " tuneGrid = data.frame(maxdepth = 1:10),\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "my_model$results %>% filter(Accuracy == max(Accuracy))\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 2 0.9533333 0.93" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.5 補足:木の複雑さの制限" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# パラメータを与えると正解率(LOOCV)を返す関数\n", - "my_loocv <- function(maxdepth, minbucket, minsplit) {\n", - " my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\",\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " tuneGrid = data.frame(maxdepth = maxdepth),\n", - " control = rpart::rpart.control(cp = 0.01,\n", - " minbucket = minbucket,\n", - " minsplit = minsplit))\n", - " list(maxdepth = maxdepth,\n", - " minbucket = minbucket,\n", - " minsplit = minsplit,\n", - " Accuracy = my_model$results$Accuracy)\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_params <- expand.grid(\n", - " maxdepth = 2:5,\n", - " minbucket = 1:7,\n", - " minsplit = c(2, 20))\n", - "\n", - "library(furrr)\n", - "plan(multisession) # 並列処理の準備\n", - "my_results <- my_params %>% future_pmap_dfr(my_loocv, # 実行\n", - " .options = furrr_options(seed = TRUE))\n", - "\n", - "my_results %>% filter(Accuracy == max(Accuracy)) # 正解率(検証)の最大値\n", - "#> maxdepth minbucket minsplit Accuracy\n", - "#> \n", - "#> 1 3 5 2 0.973\n", - "#> 2 4 5 2 0.973\n", - "#> 3 5 5 2 0.973\n", - "#> 4 3 5 20 0.973\n", - "#> 5 4 5 20 0.973\n", - "#> 6 5 5 20 0.973" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\",\n", - " trControl = trainControl(method = \"none\"),\n", - " tuneGrid = data.frame(maxdepth = 3),\n", - " control = rpart::rpart.control(cp = 0.01,\n", - " minbucket = 5,\n", - " minsplit = 2))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rpart.plot::rpart.plot(\n", - " my_model$finalModel, extra = 1)" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch09/09.04.ipynb b/code/R-notebook/ch09/09.04.ipynb deleted file mode 100644 index 6b068ce..0000000 --- a/code/R-notebook/ch09/09.04.ipynb +++ /dev/null @@ -1,97 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.4 複数の木を使う方法\n", - "\n", - "### 9.4.1 ランダムフォレスト" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "\n", - "my_model <- train(form = Species ~ ., data = my_data, method = \"rf\",\n", - " tuneGrid = data.frame(mtry = 2:4), # 省略可\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "my_model$results\n", - "#> mtry Accuracy Kappa\n", - "#> 1 2 0.96 0.94\n", - "#> 2 3 0.96 0.94\n", - "#> 3 4 0.96 0.94" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.4.2 ブースティング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(\n", - " form = Species ~ ., data = my_data, method = \"xgbTree\",\n", - " tuneGrid = expand.grid(\n", - " nrounds = c(50, 100, 150),\n", - " max_depth = c(1, 2, 3),\n", - " eta = c(0.3, 0.4),\n", - " gamma = 0,\n", - " colsample_bytree = c(0.6, 0.8),\n", - " min_child_weight = 1,\n", - " subsample = c(0.5, 0.75, 1)),\n", - " trControl = trainControl(method = \"cv\", number = 5)) # 5分割交差検証\n", - "my_model$results %>% filter(Accuracy == max(Accuracy)) %>% head(5) %>% t\n", - "#> 1 2 3 4 5\n", - "#> eta 0.30000000 0.30000000 0.30000000 0.40000000 0.30000000\n", - "#> max_depth 1.00000000 1.00000000 1.00000000 1.00000000 3.00000000\n", - "#> gamma 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000\n", - "#> colsample_bytree 0.60000000 0.60000000 0.80000000 0.60000000 0.80000000\n", - "#> min_child_weight 1.00000000 1.00000000 1.00000000 1.00000000 1.00000000\n", - "#> subsample 0.50000000 0.75000000 0.75000000 0.50000000 0.50000000\n", - "#> nrounds 50.00000000 50.00000000 50.00000000 50.00000000 50.00000000\n", - "#> Accuracy 0.96000000 0.96000000 0.96000000 0.96000000 0.96000000\n", - "#> Kappa 0.94000000 0.94000000 0.94000000 0.94000000 0.94000000\n", - "#> AccuracySD 0.02788867 0.02788867 0.02788867 0.01490712 0.01490712\n", - "#> KappaSD 0.04183300 0.04183300 0.04183300 0.02236068 0.02236068" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.4.3 入力変数の重要度" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Species ~ ., data = my_data, method = \"rf\")\n", - "ggplot(varImp(my_model))" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch09/09.05.ipynb b/code/R-notebook/ch09/09.05.ipynb deleted file mode 100644 index 2ef1be5..0000000 --- a/code/R-notebook/ch09/09.05.ipynb +++ /dev/null @@ -1,89 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.5 欠損のあるデータでの学習\n", - "\n", - "### 9.5.1 欠損のあるデータの準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "\n", - "n <- nrow(my_data)\n", - "my_data$Petal.Length[0:(n - 1) %% 10 == 0] <- NA\n", - "my_data$Petal.Width[ 0:(n - 1) %% 10 == 1] <- NA\n", - "\n", - "psych::describe(my_data) # nの値が135の変数に,150 - 135 = 15個の欠損がある.\n", - "#> vars n mean sd median trimmed mad min max range ...\n", - "#> Sepal.Length 1 150 5.84 0.83 5.8 5.81 1.04 4.3 7.9 3.6 ...\n", - "#> Sepal.Width 2 150 3.06 0.44 3.0 3.04 0.44 2.0 4.4 2.4 ...\n", - "#> Petal.Length 3 135 3.75 1.76 4.3 3.75 1.78 1.0 6.9 5.9 ...\n", - "#> Petal.Width 4 135 1.20 0.77 1.3 1.18 1.04 0.1 2.5 2.4 ...\n", - "#> Species* 5 150 2.00 0.82 2.0 2.00 1.48 1.0 3.0 2.0 ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.5.2 方針1:欠損を埋めて学習する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(\n", - " form = Species ~ ., data = my_data, method = \"rpart2\",\n", - " na.action = na.pass, # 欠損があっても学習を止めない.\n", - " preProcess = \"medianImpute\", # 欠損を中央値で埋める.\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " tuneGrid = data.frame(maxdepth = 20), # 木の高さの上限\n", - " control = rpart::rpart.control(minsplit = 2, # 分岐の条件\n", - " minbucket = 1)) # 終端ノードの条件\n", - "max(my_model$results$Accuracy)\n", - "#> [1] 0.9266667" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.5.3 方針2:欠損があっても使える手法で学習する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Species ~ ., data = my_data, method = \"xgbTree\",\n", - " na.action = na.pass,\n", - " trControl = trainControl(method = \"cv\", number = 5))\n", - "max(my_model$results$Accuracy)\n", - "#> [1] 0.966666666666667" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch09/09.06.ipynb b/code/R-notebook/ch09/09.06.ipynb deleted file mode 100644 index 0a42901..0000000 --- a/code/R-notebook/ch09/09.06.ipynb +++ /dev/null @@ -1,65 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.6 他の分類手法\n", - "\n", - "### 9.6.1 K最近傍法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "\n", - "my_model <- train(form = Species ~ ., data = my_data, method = \"knn\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "my_model$results %>% filter(Accuracy == max(Accuracy))\n", - "#> k Accuracy Kappa\n", - "#> 1 9 0.9733333 0.96" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.6.2 ニューラルネットワーク" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "\n", - "my_model <- train(form = Species ~ ., data = my_data, method = \"nnet\",\n", - " preProcess = c(\"center\", \"scale\"), # 標準化\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " trace = FALSE) # 途中経過を表示しない\n", - "my_model$results %>% filter(Accuracy == max(Accuracy))\n", - "#> size decay Accuracy Kappa\n", - "#> 1 3 0.1 0.9733333 0.96\n", - "#> 2 5 0.1 0.9733333 0.96" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch09/09.ipynb b/code/R-notebook/ch09/09.ipynb deleted file mode 100644 index e71bc5b..0000000 --- a/code/R-notebook/ch09/09.ipynb +++ /dev/null @@ -1,500 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 09\n", - "\n", - "## 9.1 アヤメのデータ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data <- iris\n", - "head(my_data)\n", - "#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species\n", - "#> 1 5.1 3.5 1.4 0.2 setosa\n", - "#> 2 4.9 3.0 1.4 0.2 setosa\n", - "#> 3 4.7 3.2 1.3 0.2 setosa\n", - "#> 4 4.6 3.1 1.5 0.2 setosa\n", - "#> 5 5.0 3.6 1.4 0.2 setosa\n", - "#> 6 5.4 3.9 1.7 0.4 setosa" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "psych::describe(my_data)\n", - "#> vars n mean sd median trimmed mad min max range ...\n", - "#> Sepal.Length 1 150 5.84 0.83 5.80 5.81 1.04 4.3 7.9 3.6 ...\n", - "#> Sepal.Width 2 150 3.06 0.44 3.00 3.04 0.44 2.0 4.4 2.4 ...\n", - "#> Petal.Length 3 150 3.76 1.77 4.35 3.76 1.85 1.0 6.9 5.9 ...\n", - "#> Petal.Width 4 150 1.20 0.76 1.30 1.18 1.04 0.1 2.5 2.4 ...\n", - "#> Species* 5 150 2.00 0.82 2.00 2.00 1.48 1.0 3.0 2.0 ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.2 木による分類\n", - "\n", - "### 9.2.1 分類木の作成と利用" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rpart.plot::rpart.plot(my_model$finalModel, extra = 1)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_test <- tribble(\n", - "~Sepal.Length, ~Sepal.Width, ~Petal.Length, ~Petal.Width,\n", - " 5.0, 3.5, 1.5, 0.5,\n", - " 6.5, 3.0, 5.0, 2.0)\n", - "\n", - "my_model %>% predict(my_test)\n", - "#> [1] setosa virginica\n", - "#> Levels: setosa versicolor virginica" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>% predict(my_test,\n", - " type = \"prob\")\n", - "#> setosa versicolor virginica\n", - "#> 1 1 0.00000000 0.0000000\n", - "#> 2 0 0.02173913 0.9782609" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.3 正解率\n", - "\n", - "### 9.3.1 混同行列" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\")\n", - "\n", - "y <- my_data$Species\n", - "y_ <- my_model %>% predict(my_data)\n", - "confusionMatrix(data = y_, reference = y)\n", - "#> Confusion Matrix and Statistics\n", - "#>\n", - "#> Reference\n", - "#> Prediction setosa versicolor virginica\n", - "#> setosa 50 0 0\n", - "#> versicolor 0 49 1\n", - "#> virginica 0 5 45\n", - "# 以下は割愛" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.2 正解率(訓練)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$Species\n", - "y_ <- my_model %>% predict(my_data)\n", - "mean(y_ == y)\n", - "#> [1] 0.96" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.3 正解率(検証)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "my_model$results\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 1 0.3333333 0.00\n", - "#> 2 2 0.9533333 0.93" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.4 パラメータチューニング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\",\n", - " tuneGrid = data.frame(maxdepth = 1:10),\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "my_model$results %>% filter(Accuracy == max(Accuracy))\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 2 0.9533333 0.93" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.3.5 補足:木の複雑さの制限" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# パラメータを与えると正解率(LOOCV)を返す関数\n", - "my_loocv <- function(maxdepth, minbucket, minsplit) {\n", - " my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\",\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " tuneGrid = data.frame(maxdepth = maxdepth),\n", - " control = rpart::rpart.control(cp = 0.01,\n", - " minbucket = minbucket,\n", - " minsplit = minsplit))\n", - " list(maxdepth = maxdepth,\n", - " minbucket = minbucket,\n", - " minsplit = minsplit,\n", - " Accuracy = my_model$results$Accuracy)\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_params <- expand.grid(\n", - " maxdepth = 2:5,\n", - " minbucket = 1:7,\n", - " minsplit = c(2, 20))\n", - "\n", - "library(furrr)\n", - "plan(multisession) # 並列処理の準備\n", - "my_results <- my_params %>% future_pmap_dfr(my_loocv, # 実行\n", - " .options = furrr_options(seed = TRUE))\n", - "\n", - "my_results %>% filter(Accuracy == max(Accuracy)) # 正解率(検証)の最大値\n", - "#> maxdepth minbucket minsplit Accuracy\n", - "#> \n", - "#> 1 3 5 2 0.973\n", - "#> 2 4 5 2 0.973\n", - "#> 3 5 5 2 0.973\n", - "#> 4 3 5 20 0.973\n", - "#> 5 4 5 20 0.973\n", - "#> 6 5 5 20 0.973" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\",\n", - " trControl = trainControl(method = \"none\"),\n", - " tuneGrid = data.frame(maxdepth = 3),\n", - " control = rpart::rpart.control(cp = 0.01,\n", - " minbucket = 5,\n", - " minsplit = 2))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rpart.plot::rpart.plot(\n", - " my_model$finalModel, extra = 1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.4 複数の木を使う方法\n", - "\n", - "### 9.4.1 ランダムフォレスト" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "\n", - "my_model <- train(form = Species ~ ., data = my_data, method = \"rf\",\n", - " tuneGrid = data.frame(mtry = 2:4), # 省略可\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "my_model$results\n", - "#> mtry Accuracy Kappa\n", - "#> 1 2 0.96 0.94\n", - "#> 2 3 0.96 0.94\n", - "#> 3 4 0.96 0.94" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.4.2 ブースティング" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(\n", - " form = Species ~ ., data = my_data, method = \"xgbTree\",\n", - " tuneGrid = expand.grid(\n", - " nrounds = c(50, 100, 150),\n", - " max_depth = c(1, 2, 3),\n", - " eta = c(0.3, 0.4),\n", - " gamma = 0,\n", - " colsample_bytree = c(0.6, 0.8),\n", - " min_child_weight = 1,\n", - " subsample = c(0.5, 0.75, 1)),\n", - " trControl = trainControl(method = \"cv\", number = 5)) # 5分割交差検証\n", - "my_model$results %>% filter(Accuracy == max(Accuracy)) %>% head(5) %>% t\n", - "#> 1 2 3 4 5\n", - "#> eta 0.30000000 0.30000000 0.30000000 0.40000000 0.30000000\n", - "#> max_depth 1.00000000 1.00000000 1.00000000 1.00000000 3.00000000\n", - "#> gamma 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000\n", - "#> colsample_bytree 0.60000000 0.60000000 0.80000000 0.60000000 0.80000000\n", - "#> min_child_weight 1.00000000 1.00000000 1.00000000 1.00000000 1.00000000\n", - "#> subsample 0.50000000 0.75000000 0.75000000 0.50000000 0.50000000\n", - "#> nrounds 50.00000000 50.00000000 50.00000000 50.00000000 50.00000000\n", - "#> Accuracy 0.96000000 0.96000000 0.96000000 0.96000000 0.96000000\n", - "#> Kappa 0.94000000 0.94000000 0.94000000 0.94000000 0.94000000\n", - "#> AccuracySD 0.02788867 0.02788867 0.02788867 0.01490712 0.01490712\n", - "#> KappaSD 0.04183300 0.04183300 0.04183300 0.02236068 0.02236068" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.4.3 入力変数の重要度" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Species ~ ., data = my_data, method = \"rf\")\n", - "ggplot(varImp(my_model))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.5 欠損のあるデータでの学習\n", - "\n", - "### 9.5.1 欠損のあるデータの準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "\n", - "n <- nrow(my_data)\n", - "my_data$Petal.Length[0:(n - 1) %% 10 == 0] <- NA\n", - "my_data$Petal.Width[ 0:(n - 1) %% 10 == 1] <- NA\n", - "\n", - "psych::describe(my_data) # nの値が135の変数に,150 - 135 = 15個の欠損がある.\n", - "#> vars n mean sd median trimmed mad min max range ...\n", - "#> Sepal.Length 1 150 5.84 0.83 5.8 5.81 1.04 4.3 7.9 3.6 ...\n", - "#> Sepal.Width 2 150 3.06 0.44 3.0 3.04 0.44 2.0 4.4 2.4 ...\n", - "#> Petal.Length 3 135 3.75 1.76 4.3 3.75 1.78 1.0 6.9 5.9 ...\n", - "#> Petal.Width 4 135 1.20 0.77 1.3 1.18 1.04 0.1 2.5 2.4 ...\n", - "#> Species* 5 150 2.00 0.82 2.0 2.00 1.48 1.0 3.0 2.0 ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.5.2 方針1:欠損を埋めて学習する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(\n", - " form = Species ~ ., data = my_data, method = \"rpart2\",\n", - " na.action = na.pass, # 欠損があっても学習を止めない.\n", - " preProcess = \"medianImpute\", # 欠損を中央値で埋める.\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " tuneGrid = data.frame(maxdepth = 20), # 木の高さの上限\n", - " control = rpart::rpart.control(minsplit = 2, # 分岐の条件\n", - " minbucket = 1)) # 終端ノードの条件\n", - "max(my_model$results$Accuracy)\n", - "#> [1] 0.9266667" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.5.3 方針2:欠損があっても使える手法で学習する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Species ~ ., data = my_data, method = \"xgbTree\",\n", - " na.action = na.pass,\n", - " trControl = trainControl(method = \"cv\", number = 5))\n", - "max(my_model$results$Accuracy)\n", - "#> [1] 0.966666666666667" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 9.6 他の分類手法\n", - "\n", - "### 9.6.1 K最近傍法" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "\n", - "my_model <- train(form = Species ~ ., data = my_data, method = \"knn\",\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "my_model$results %>% filter(Accuracy == max(Accuracy))\n", - "#> k Accuracy Kappa\n", - "#> 1 9 0.9733333 0.96" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 9.6.2 ニューラルネットワーク" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(tidyverse)\n", - "my_data <- iris\n", - "\n", - "my_model <- train(form = Species ~ ., data = my_data, method = \"nnet\",\n", - " preProcess = c(\"center\", \"scale\"), # 標準化\n", - " trControl = trainControl(method = \"LOOCV\"),\n", - " trace = FALSE) # 途中経過を表示しない\n", - "my_model$results %>% filter(Accuracy == max(Accuracy))\n", - "#> size decay Accuracy Kappa\n", - "#> 1 3 0.1 0.9733333 0.96\n", - "#> 2 5 0.1 0.9733333 0.96" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch10/10-colab.ipynb b/code/R-notebook/ch10/10-colab.ipynb deleted file mode 100644 index 9726b7b..0000000 --- a/code/R-notebook/ch10/10-colab.ipynb +++ /dev/null @@ -1,436 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 10" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Google Colaboratoryの環境設定\n", - "options(Ncpus = 2)\n", - "install.packages(c(\"caret\", \"e1071\", \"PRROC\", \"rpart.plot\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.1 2値分類の性能指標\n", - "\n", - "### 10.1.1 陽性と陰性" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1)\n", - "y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ <- ifelse(0.5 <= y_score, 1, 0)\n", - "y_\n", - "#> [1] 1 1 0 0 1 1 1 0 0 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "confusionMatrix(data = as.factor(y_), # 予測\n", - " reference = as.factor(y), # 正解\n", - " positive = \"1\", # 「1」を陽性とする.\n", - " mode = \"everything\") # 全ての指標を求める.\n", - "#> Confusion Matrix and Statistics\n", - "#>\n", - "#> Reference\n", - "#> Prediction 0 1\n", - "#> 0 3 1\n", - "#> 1 2 4\n", - "#>\n", - "#> Accuracy : 0.7\n", - "#> 95% CI : (0.3475, 0.9333)\n", - "#> No Information Rate : 0.5\n", - "#> P-Value [Acc > NIR] : 0.1719\n", - "#>\n", - "#> Kappa : 0.4\n", - "#>\n", - "#> Mcnemar's Test P-Value : 1.0000\n", - "#>\n", - "#> Sensitivity : 0.8000\n", - "#> Specificity : 0.6000\n", - "#> Pos Pred Value : 0.6667\n", - "#> Neg Pred Value : 0.7500\n", - "#> Precision : 0.6667\n", - "#> Recall : 0.8000\n", - "#> F1 : 0.7273\n", - "#> Prevalence : 0.5000\n", - "#> Detection Rate : 0.4000\n", - "#> Detection Prevalence : 0.6000\n", - "#> Balanced Accuracy : 0.7000\n", - "#>\n", - "#> 'Positive' Class : 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.2 トレードオフ\n", - "\n", - "### 10.2.1 偽陽性率と真陽性率のトレードオフ(ROC曲線)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(PRROC)\n", - "library(tidyverse)\n", - "\n", - "y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1)\n", - "y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5)\n", - "y_ <- ifelse(0.5 <= y_score, 1, 0)\n", - "\n", - "c(sum((y == 0) & (y_ == 1)) / sum(y == 0), # FPR\n", - " sum((y == 1) & (y_ == 1)) / sum(y == 1)) # TPR\n", - "#> [1] 0.4 0.8" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_roc <- roc.curve(scores.class0 = y_score[y == 1], # 答えが1のもののスコア\n", - " scores.class1 = y_score[y == 0], # 答えが0のもののスコア\n", - " curve = TRUE)\n", - "my_roc %>% plot(xlab = \"False Positive Rate\",\n", - " ylab = \"True Positive Rate\",\n", - " legend = FALSE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_roc$auc\n", - "#> [1] 0.8" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.2.2 再現率と精度のトレードオフ(PR曲線)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c(sum((y == 1) & (y_ == 1)) / sum(y == 1), # Recall == TPR\n", - " sum((y == 1) & (y_ == 1)) / sum(y_ == 1)) # Precision\n", - "#> [1] 0.8000000 0.6666667" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_pr <- pr.curve(scores.class0 = y_score[y == 1],\n", - " scores.class1 = y_score[y == 0],\n", - " curve = TRUE)\n", - "my_pr %>% plot(xlab = \"Recall\",\n", - " ylab = \"Precision\",\n", - " legend = FALSE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_pr$auc.integral\n", - "#> [1] 0.8469525" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.3 タイタニック" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(PRROC)\n", - "library(tidyverse)\n", - "\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/titanic.csv\")\n", - "my_data <- read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_data)\n", - "#> # A tibble: 6 x 4\n", - "#> Class Sex Age Survived\n", - "#> \n", - "#> 1 1st Male Child Yes\n", - "#> 2 1st Male Child Yes\n", - "#> 3 1st Male Child Yes\n", - "#> 4 1st Male Child Yes\n", - "#> 5 1st Male Child Yes\n", - "#> 6 1st Male Adult No" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.1 質的入力変数の扱い方\n", - "\n", - "### 10.3.2 決定木の訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Survived ~ ., data = my_data, method = \"rpart2\",\n", - " tuneGrid = data.frame(maxdepth = 2),\n", - " trControl = trainControl(method = \"LOOCV\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.3 決定木の描画" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rpart.plot::rpart.plot(my_model$finalModel, extra = 1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.4 決定木の評価" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 2 0.7832803 0.4096365" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$Survived\n", - "tmp <- my_model %>% predict(newdata = my_data, type = \"prob\")\n", - "y_score <- tmp$Yes\n", - "\n", - "my_roc <- roc.curve(scores.class0 = y_score[y == \"Yes\"],\n", - " scores.class1 = y_score[y == \"No\"],\n", - " curve = TRUE)\n", - "my_roc$auc\n", - "#> [1] 0.7114887\n", - "\n", - "my_roc %>% plot(xlab = \"False Positive Rate\",\n", - " ylab = \"True Positive Rate\",\n", - " legend = FALSE)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.5 補足:質的入力変数の扱い" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X <- my_data %>% select(Class) # 質的入力変数\n", - "y <- my_data$Survived # 出力変数\n", - "\n", - "options(warn = -1) # これ以降,警告を表示しない.\n", - "my_model1 <- train(x = X, y = y, method = \"rpart2\",\n", - " tuneGrid = data.frame(maxdepth = 2),\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "options(warn = 0) # これ以降,警告を表示する.\n", - "\n", - "rpart.plot::rpart.plot(my_model1$finalModel, extra = 1)\n", - "my_model1$results\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 2 0.7137665 0.2373133" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_enc <- my_data %>% dummyVars(formula = Survived ~ Class)\n", - "my_data2 <- my_enc %>%\n", - " predict(my_data) %>%\n", - " as.data.frame %>%\n", - " mutate(Survived = my_data$Survived)\n", - "\n", - "my_model2 <- train(form = Survived ~ ., data = my_data2, method = \"rpart2\",\n", - " tuneGrid = data.frame(maxdepth = 2),\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "rpart.plot::rpart.plot(my_model2$finalModel, extra = 1)\n", - "my_model2$results\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 2 0.7137665 0.2373133" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model3 <- train(form = Survived ~ Class, data = my_data, method = \"rpart2\",\n", - " tuneGrid = data.frame(maxdepth = 2),\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "rpart.plot::rpart.plot(my_model3$finalModel, extra = 1)\n", - "my_model3$results\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 2 0.6915039 0.2674485" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.4 ロジスティック回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "curve(1 / (1 + exp(-x)), -6, 6)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(PRROC)\n", - "library(tidyverse)\n", - "\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/titanic.csv\")\n", - "my_data <- read_csv(my_url)\n", - "\n", - "my_model <- train(form = Survived ~ ., data = my_data, method = \"glm\",\n", - " trControl = trainControl(method = \"LOOCV\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "coef(my_model$finalModel) %>%\n", - " as.data.frame\n", - "#> .\n", - "#> (Intercept) 2.0438374\n", - "#> Class2nd -1.0180950\n", - "#> Class3rd -1.7777622\n", - "#> ClassCrew -0.8576762\n", - "#> SexMale -2.4200603\n", - "#> AgeChild 1.0615424" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results\n", - "#> parameter Accuracy Kappa\n", - "#> 1 none 0.7782826 0.4448974" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch10/10.01.ipynb b/code/R-notebook/ch10/10.01.ipynb deleted file mode 100644 index 7494100..0000000 --- a/code/R-notebook/ch10/10.01.ipynb +++ /dev/null @@ -1,84 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.1 2値分類の性能指標\n", - "\n", - "### 10.1.1 陽性と陰性" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1)\n", - "y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ <- ifelse(0.5 <= y_score, 1, 0)\n", - "y_\n", - "#> [1] 1 1 0 0 1 1 1 0 0 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "confusionMatrix(data = as.factor(y_), # 予測\n", - " reference = as.factor(y), # 正解\n", - " positive = \"1\", # 「1」を陽性とする.\n", - " mode = \"everything\") # 全ての指標を求める.\n", - "#> Confusion Matrix and Statistics\n", - "#>\n", - "#> Reference\n", - "#> Prediction 0 1\n", - "#> 0 3 1\n", - "#> 1 2 4\n", - "#>\n", - "#> Accuracy : 0.7\n", - "#> 95% CI : (0.3475, 0.9333)\n", - "#> No Information Rate : 0.5\n", - "#> P-Value [Acc > NIR] : 0.1719\n", - "#>\n", - "#> Kappa : 0.4\n", - "#>\n", - "#> Mcnemar's Test P-Value : 1.0000\n", - "#>\n", - "#> Sensitivity : 0.8000\n", - "#> Specificity : 0.6000\n", - "#> Pos Pred Value : 0.6667\n", - "#> Neg Pred Value : 0.7500\n", - "#> Precision : 0.6667\n", - "#> Recall : 0.8000\n", - "#> F1 : 0.7273\n", - "#> Prevalence : 0.5000\n", - "#> Detection Rate : 0.4000\n", - "#> Detection Prevalence : 0.6000\n", - "#> Balanced Accuracy : 0.7000\n", - "#>\n", - "#> 'Positive' Class : 1" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch10/10.02.ipynb b/code/R-notebook/ch10/10.02.ipynb deleted file mode 100644 index cb539de..0000000 --- a/code/R-notebook/ch10/10.02.ipynb +++ /dev/null @@ -1,105 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.2 トレードオフ\n", - "\n", - "### 10.2.1 偽陽性率と真陽性率のトレードオフ(ROC曲線)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(PRROC)\n", - "library(tidyverse)\n", - "\n", - "y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1)\n", - "y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5)\n", - "y_ <- ifelse(0.5 <= y_score, 1, 0)\n", - "\n", - "c(sum((y == 0) & (y_ == 1)) / sum(y == 0), # FPR\n", - " sum((y == 1) & (y_ == 1)) / sum(y == 1)) # TPR\n", - "#> [1] 0.4 0.8" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_roc <- roc.curve(scores.class0 = y_score[y == 1], # 答えが1のもののスコア\n", - " scores.class1 = y_score[y == 0], # 答えが0のもののスコア\n", - " curve = TRUE)\n", - "my_roc %>% plot(xlab = \"False Positive Rate\",\n", - " ylab = \"True Positive Rate\",\n", - " legend = FALSE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_roc$auc\n", - "#> [1] 0.8" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.2.2 再現率と精度のトレードオフ(PR曲線)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c(sum((y == 1) & (y_ == 1)) / sum(y == 1), # Recall == TPR\n", - " sum((y == 1) & (y_ == 1)) / sum(y_ == 1)) # Precision\n", - "#> [1] 0.8000000 0.6666667" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_pr <- pr.curve(scores.class0 = y_score[y == 1],\n", - " scores.class1 = y_score[y == 0],\n", - " curve = TRUE)\n", - "my_pr %>% plot(xlab = \"Recall\",\n", - " ylab = \"Precision\",\n", - " legend = FALSE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_pr$auc.integral\n", - "#> [1] 0.8469525" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch10/10.03.ipynb b/code/R-notebook/ch10/10.03.ipynb deleted file mode 100644 index c250eae..0000000 --- a/code/R-notebook/ch10/10.03.ipynb +++ /dev/null @@ -1,191 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.3 タイタニック" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(PRROC)\n", - "library(tidyverse)\n", - "\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/titanic.csv\")\n", - "my_data <- read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_data)\n", - "#> # A tibble: 6 x 4\n", - "#> Class Sex Age Survived\n", - "#> \n", - "#> 1 1st Male Child Yes\n", - "#> 2 1st Male Child Yes\n", - "#> 3 1st Male Child Yes\n", - "#> 4 1st Male Child Yes\n", - "#> 5 1st Male Child Yes\n", - "#> 6 1st Male Adult No" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.1 質的入力変数の扱い方\n", - "\n", - "### 10.3.2 決定木の訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Survived ~ ., data = my_data, method = \"rpart2\",\n", - " tuneGrid = data.frame(maxdepth = 2),\n", - " trControl = trainControl(method = \"LOOCV\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.3 決定木の描画" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rpart.plot::rpart.plot(my_model$finalModel, extra = 1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.4 決定木の評価" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 2 0.7832803 0.4096365" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$Survived\n", - "tmp <- my_model %>% predict(newdata = my_data, type = \"prob\")\n", - "y_score <- tmp$Yes\n", - "\n", - "my_roc <- roc.curve(scores.class0 = y_score[y == \"Yes\"],\n", - " scores.class1 = y_score[y == \"No\"],\n", - " curve = TRUE)\n", - "my_roc$auc\n", - "#> [1] 0.7114887\n", - "\n", - "my_roc %>% plot(xlab = \"False Positive Rate\",\n", - " ylab = \"True Positive Rate\",\n", - " legend = FALSE)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.5 補足:質的入力変数の扱い" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X <- my_data %>% select(Class) # 質的入力変数\n", - "y <- my_data$Survived # 出力変数\n", - "\n", - "options(warn = -1) # これ以降,警告を表示しない.\n", - "my_model1 <- train(x = X, y = y, method = \"rpart2\",\n", - " tuneGrid = data.frame(maxdepth = 2),\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "options(warn = 0) # これ以降,警告を表示する.\n", - "\n", - "rpart.plot::rpart.plot(my_model1$finalModel, extra = 1)\n", - "my_model1$results\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 2 0.7137665 0.2373133" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_enc <- my_data %>% dummyVars(formula = Survived ~ Class)\n", - "my_data2 <- my_enc %>%\n", - " predict(my_data) %>%\n", - " as.data.frame %>%\n", - " mutate(Survived = my_data$Survived)\n", - "\n", - "my_model2 <- train(form = Survived ~ ., data = my_data2, method = \"rpart2\",\n", - " tuneGrid = data.frame(maxdepth = 2),\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "rpart.plot::rpart.plot(my_model2$finalModel, extra = 1)\n", - "my_model2$results\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 2 0.7137665 0.2373133" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model3 <- train(form = Survived ~ Class, data = my_data, method = \"rpart2\",\n", - " tuneGrid = data.frame(maxdepth = 2),\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "rpart.plot::rpart.plot(my_model3$finalModel, extra = 1)\n", - "my_model3$results\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 2 0.6915039 0.2674485" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch10/10.04.ipynb b/code/R-notebook/ch10/10.04.ipynb deleted file mode 100644 index ef8c4e1..0000000 --- a/code/R-notebook/ch10/10.04.ipynb +++ /dev/null @@ -1,74 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.4 ロジスティック回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "curve(1 / (1 + exp(-x)), -6, 6)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(PRROC)\n", - "library(tidyverse)\n", - "\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/titanic.csv\")\n", - "my_data <- read_csv(my_url)\n", - "\n", - "my_model <- train(form = Survived ~ ., data = my_data, method = \"glm\",\n", - " trControl = trainControl(method = \"LOOCV\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "coef(my_model$finalModel) %>%\n", - " as.data.frame\n", - "#> .\n", - "#> (Intercept) 2.0438374\n", - "#> Class2nd -1.0180950\n", - "#> Class3rd -1.7777622\n", - "#> ClassCrew -0.8576762\n", - "#> SexMale -2.4200603\n", - "#> AgeChild 1.0615424" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results\n", - "#> parameter Accuracy Kappa\n", - "#> 1 none 0.7782826 0.4448974" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch10/10.ipynb b/code/R-notebook/ch10/10.ipynb deleted file mode 100644 index 5081ec0..0000000 --- a/code/R-notebook/ch10/10.ipynb +++ /dev/null @@ -1,420 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 10\n", - "\n", - "## 10.1 2値分類の性能指標\n", - "\n", - "### 10.1.1 陽性と陰性" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1)\n", - "y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ <- ifelse(0.5 <= y_score, 1, 0)\n", - "y_\n", - "#> [1] 1 1 0 0 1 1 1 0 0 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "confusionMatrix(data = as.factor(y_), # 予測\n", - " reference = as.factor(y), # 正解\n", - " positive = \"1\", # 「1」を陽性とする.\n", - " mode = \"everything\") # 全ての指標を求める.\n", - "#> Confusion Matrix and Statistics\n", - "#>\n", - "#> Reference\n", - "#> Prediction 0 1\n", - "#> 0 3 1\n", - "#> 1 2 4\n", - "#>\n", - "#> Accuracy : 0.7\n", - "#> 95% CI : (0.3475, 0.9333)\n", - "#> No Information Rate : 0.5\n", - "#> P-Value [Acc > NIR] : 0.1719\n", - "#>\n", - "#> Kappa : 0.4\n", - "#>\n", - "#> Mcnemar's Test P-Value : 1.0000\n", - "#>\n", - "#> Sensitivity : 0.8000\n", - "#> Specificity : 0.6000\n", - "#> Pos Pred Value : 0.6667\n", - "#> Neg Pred Value : 0.7500\n", - "#> Precision : 0.6667\n", - "#> Recall : 0.8000\n", - "#> F1 : 0.7273\n", - "#> Prevalence : 0.5000\n", - "#> Detection Rate : 0.4000\n", - "#> Detection Prevalence : 0.6000\n", - "#> Balanced Accuracy : 0.7000\n", - "#>\n", - "#> 'Positive' Class : 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.2 トレードオフ\n", - "\n", - "### 10.2.1 偽陽性率と真陽性率のトレードオフ(ROC曲線)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(PRROC)\n", - "library(tidyverse)\n", - "\n", - "y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1)\n", - "y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5)\n", - "y_ <- ifelse(0.5 <= y_score, 1, 0)\n", - "\n", - "c(sum((y == 0) & (y_ == 1)) / sum(y == 0), # FPR\n", - " sum((y == 1) & (y_ == 1)) / sum(y == 1)) # TPR\n", - "#> [1] 0.4 0.8" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_roc <- roc.curve(scores.class0 = y_score[y == 1], # 答えが1のもののスコア\n", - " scores.class1 = y_score[y == 0], # 答えが0のもののスコア\n", - " curve = TRUE)\n", - "my_roc %>% plot(xlab = \"False Positive Rate\",\n", - " ylab = \"True Positive Rate\",\n", - " legend = FALSE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_roc$auc\n", - "#> [1] 0.8" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.2.2 再現率と精度のトレードオフ(PR曲線)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c(sum((y == 1) & (y_ == 1)) / sum(y == 1), # Recall == TPR\n", - " sum((y == 1) & (y_ == 1)) / sum(y_ == 1)) # Precision\n", - "#> [1] 0.8000000 0.6666667" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_pr <- pr.curve(scores.class0 = y_score[y == 1],\n", - " scores.class1 = y_score[y == 0],\n", - " curve = TRUE)\n", - "my_pr %>% plot(xlab = \"Recall\",\n", - " ylab = \"Precision\",\n", - " legend = FALSE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_pr$auc.integral\n", - "#> [1] 0.8469525" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.3 タイタニック" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(PRROC)\n", - "library(tidyverse)\n", - "\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/titanic.csv\")\n", - "my_data <- read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_data)\n", - "#> # A tibble: 6 x 4\n", - "#> Class Sex Age Survived\n", - "#> \n", - "#> 1 1st Male Child Yes\n", - "#> 2 1st Male Child Yes\n", - "#> 3 1st Male Child Yes\n", - "#> 4 1st Male Child Yes\n", - "#> 5 1st Male Child Yes\n", - "#> 6 1st Male Adult No" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.1 質的入力変数の扱い方\n", - "\n", - "### 10.3.2 決定木の訓練" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- train(form = Survived ~ ., data = my_data, method = \"rpart2\",\n", - " tuneGrid = data.frame(maxdepth = 2),\n", - " trControl = trainControl(method = \"LOOCV\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.3 決定木の描画" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rpart.plot::rpart.plot(my_model$finalModel, extra = 1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.4 決定木の評価" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 2 0.7832803 0.4096365" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- my_data$Survived\n", - "tmp <- my_model %>% predict(newdata = my_data, type = \"prob\")\n", - "y_score <- tmp$Yes\n", - "\n", - "my_roc <- roc.curve(scores.class0 = y_score[y == \"Yes\"],\n", - " scores.class1 = y_score[y == \"No\"],\n", - " curve = TRUE)\n", - "my_roc$auc\n", - "#> [1] 0.7114887\n", - "\n", - "my_roc %>% plot(xlab = \"False Positive Rate\",\n", - " ylab = \"True Positive Rate\",\n", - " legend = FALSE)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 10.3.5 補足:質的入力変数の扱い" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X <- my_data %>% select(Class) # 質的入力変数\n", - "y <- my_data$Survived # 出力変数\n", - "\n", - "options(warn = -1) # これ以降,警告を表示しない.\n", - "my_model1 <- train(x = X, y = y, method = \"rpart2\",\n", - " tuneGrid = data.frame(maxdepth = 2),\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "options(warn = 0) # これ以降,警告を表示する.\n", - "\n", - "rpart.plot::rpart.plot(my_model1$finalModel, extra = 1)\n", - "my_model1$results\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 2 0.7137665 0.2373133" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_enc <- my_data %>% dummyVars(formula = Survived ~ Class)\n", - "my_data2 <- my_enc %>%\n", - " predict(my_data) %>%\n", - " as.data.frame %>%\n", - " mutate(Survived = my_data$Survived)\n", - "\n", - "my_model2 <- train(form = Survived ~ ., data = my_data2, method = \"rpart2\",\n", - " tuneGrid = data.frame(maxdepth = 2),\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "rpart.plot::rpart.plot(my_model2$finalModel, extra = 1)\n", - "my_model2$results\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 2 0.7137665 0.2373133" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model3 <- train(form = Survived ~ Class, data = my_data, method = \"rpart2\",\n", - " tuneGrid = data.frame(maxdepth = 2),\n", - " trControl = trainControl(method = \"LOOCV\"))\n", - "rpart.plot::rpart.plot(my_model3$finalModel, extra = 1)\n", - "my_model3$results\n", - "#> maxdepth Accuracy Kappa\n", - "#> 1 2 0.6915039 0.2674485" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 10.4 ロジスティック回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "curve(1 / (1 + exp(-x)), -6, 6)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "library(PRROC)\n", - "library(tidyverse)\n", - "\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/titanic.csv\")\n", - "my_data <- read_csv(my_url)\n", - "\n", - "my_model <- train(form = Survived ~ ., data = my_data, method = \"glm\",\n", - " trControl = trainControl(method = \"LOOCV\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "coef(my_model$finalModel) %>%\n", - " as.data.frame\n", - "#> .\n", - "#> (Intercept) 2.0438374\n", - "#> Class2nd -1.0180950\n", - "#> Class3rd -1.7777622\n", - "#> ClassCrew -0.8576762\n", - "#> SexMale -2.4200603\n", - "#> AgeChild 1.0615424" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model$results\n", - "#> parameter Accuracy Kappa\n", - "#> 1 none 0.7782826 0.4448974" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch11/11-colab.ipynb b/code/R-notebook/ch11/11-colab.ipynb deleted file mode 100644 index 3b25c75..0000000 --- a/code/R-notebook/ch11/11-colab.ipynb +++ /dev/null @@ -1,908 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 11" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Google Colaboratoryの環境設定(GPUを使う場合)\n", - "# GPUを使おうとするとセッションがクラッシュする問題への対策\n", - "# https://github.com/googlecolab/colabtools/issues/2486#issuecomment-1010747044\n", - "# 1. ランタイム→ランタイムのタイプを変更で,ハードウェアアクセラレータを「GPU」にする.\n", - "# 2. このセルを実行する.\n", - "system(\"sed -i -e 's,R_LD_LIBRARY_PATH}:${LD_LIBRARY,LD_LIBRARY_PATH}:${R_LD_LIBRARY,' /usr/lib/R/etc/ldpaths\")\n", - "# 3. ランタイム→ランタイムを再起動.つまり,次に進む前にランタイムを再起動する." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Google Colaboratoryの環境設定(共通)\n", - "options(Ncpus = 2)\n", - "install.packages(c(\"h2o\", \"keras\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.1 Kerasによる回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(keras)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "tmp <- read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data <- tmp[sample(nrow(tmp)), ]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X <- my_data %>%\n", - " select(-LPRICE2) %>% scale\n", - "y <- my_data$LPRICE2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "curve(activation_relu(x), -3, 3)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- keras_model_sequential() %>%\n", - " layer_dense(units = 3, activation = \"relu\", input_shape = c(4)) %>%\n", - " layer_dense(units = 1)\n", - "\n", - "summary(my_model) # ネットワークの概要\n", - "# 割愛(Pythonの結果を参照)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>% compile(\n", - " loss = \"mse\",\n", - " optimizer = \"rmsprop\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_cb <- callback_early_stopping(\n", - " patience = 20,\n", - " restore_best_weights = TRUE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history <- my_model %>% fit(\n", - " x = X,\n", - " y = y,\n", - " validation_split = 0.25,\n", - " batch_size = 10,\n", - " epochs = 500,\n", - " callbacks = list(my_cb),\n", - " verbose = 0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plot(my_history)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history\n", - "#> Final epoch (plot to see history):\n", - "#> loss: 0.06124\n", - "#> val_loss: 0.1132" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ <- my_model %>% predict(X)\n", - "mean((y_ - y)^2)**0.5\n", - "#> [1] 0.2724372" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.2 Kerasによる分類" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(keras)\n", - "library(tidyverse)\n", - "my_data <- iris[sample(nrow(iris)), ]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X <- my_data %>%\n", - " select(-Species) %>% scale\n", - "y <- as.integer(my_data$Species) - 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- keras_model_sequential() %>%\n", - " layer_dense(units = 3, activation = \"relu\", input_shape = c(4)) %>%\n", - " layer_dense(units = 3, activation = \"softmax\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>% compile(loss = \"sparse_categorical_crossentropy\",\n", - " optimizer = \"rmsprop\",\n", - " metrics = c(\"accuracy\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_cb <- callback_early_stopping(\n", - " patience = 20,\n", - " restore_best_weights = TRUE)\n", - "\n", - "my_history <- my_model %>%\n", - " fit(x = X,\n", - " y = y,\n", - " validation_split = 0.25,\n", - " batch_size = 10,\n", - " epochs = 500,\n", - " callbacks = list(my_cb),\n", - " verbose = 0)\n", - "\n", - "plot(my_history)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history\n", - "#> Final epoch (plot to see history):\n", - "#> loss: 0.06206\n", - "#> accuracy: 0.9732\n", - "#> val_loss: 0.1269\n", - "#> val_accuracy: 0.9211" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_model %>% predict(X)\n", - "y_ <- apply(tmp, 1, which.max) - 1\n", - "mean(y_ == y)\n", - "#> [1] 0.9666667" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.2.1 交差エントロピー" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "-mean(log(c(0.8, 0.7, 0.3, 0.8)))\n", - "#> 0.5017337\n", - "\n", - "-mean(log(c(0.7, 0.6, 0.2, 0.7)))\n", - "#> 0.7084034" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- c(2, 1, 0, 1)\n", - "y_1 <- list(c(0.1, 0.1, 0.8),\n", - " c(0.1, 0.7, 0.2),\n", - " c(0.3, 0.4, 0.3),\n", - " c(0.1, 0.8, 0.1))\n", - "y_2 <- list(c(0.1, 0.2, 0.7),\n", - " c(0.2, 0.6, 0.2),\n", - " c(0.2, 0.5, 0.3),\n", - " c(0.2, 0.7, 0.1))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c(mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_1))),\n", - " mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_2))))\n", - "#> [1] 0.5017337 0.7084033" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.3 MNIST:手書き数字の分類\n", - "\n", - "### 11.3.1 データの形式" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(keras)\n", - "library(tidyverse)\n", - "keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist())" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "dim(x_train)\n", - "#> [1] 60000 28 28" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train[5, , ]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plot(as.raster(x = x_train[5, , ],\n", - " max = max(x_train)))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(y_train)\n", - "#> [1] 5 0 4 1 9 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c(min(x_train), max(x_train))\n", - "#> [1] 0 255" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train <- x_train / 255\n", - "x_test <- x_test / 255" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_index <- sample(1:60000, 6000)\n", - "x_train <- x_train[my_index, , ]\n", - "y_train <- y_train[my_index]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.3.2 多層パーセプトロン" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- keras_model_sequential() %>%\n", - " layer_flatten(input_shape = c(28, 28)) %>%\n", - " layer_dense(units = 256, activation = \"relu\") %>%\n", - " layer_dense(units = 10, activation = \"softmax\")\n", - "summary(my_model)\n", - "# 割愛(Pythonの結果を参照)\n", - "\n", - "my_model %>% compile(loss = \"sparse_categorical_crossentropy\",\n", - " optimizer = \"rmsprop\",\n", - " metrics = c(\"accuracy\"))\n", - "\n", - "my_cb <- callback_early_stopping(patience = 5,\n", - " restore_best_weights = TRUE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history <- my_model %>%\n", - " fit(x = x_train,\n", - " y = y_train,\n", - " validation_split = 0.2,\n", - " batch_size = 128,\n", - " epochs = 20,\n", - " callbacks = list(my_cb),\n", - " verbose = 0)\n", - "\n", - "plot(my_history)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_model %>% predict(x_test)\n", - "y_ <- apply(tmp, 1, which.max) - 1\n", - "table(y_, y_test)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#> y_test\n", - "#> y_ 0 1 2 3 4 5 6 7 8 9\n", - "#> 0 962 0 8 2 0 6 11 0 8 11\n", - "#> 1 0 1110 1 0 3 1 3 8 2 4\n", - "#> 2 0 5 959 13 4 4 2 16 6 1\n", - "#> 3 1 1 22 958 1 27 0 7 33 13\n", - "#> 4 2 0 6 1 905 8 6 6 3 14\n", - "#> 5 5 2 0 12 1 809 9 1 15 4\n", - "#> 6 6 3 8 0 8 11 922 0 5 1\n", - "#> 7 1 1 7 7 1 2 0 963 4 8\n", - "#> 8 2 13 19 13 4 16 5 0 890 5\n", - "#> 9 1 0 2 4 55 8 0 27 8 948" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mean(y_ == y_test)\n", - "#> [1] 0.9426000" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>%\n", - " evaluate(x = x_test, y = y_test)\n", - "#> loss accuracy\n", - "#> 0.2071411 0.9426000" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.3.3 畳み込みニューラルネットワーク(CNN)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train2d <- x_train %>% array_reshape(c(-1, 28, 28, 1))\n", - "x_test2d <- x_test %>% array_reshape(c(-1, 28, 28, 1))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.1 単純なCNN" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- keras_model_sequential() %>%\n", - " layer_conv_2d(filters = 32, kernel_size = 3, # 畳み込み層\n", - " activation = \"relu\",\n", - " input_shape = c(28, 28, 1)) %>%\n", - " layer_max_pooling_2d(pool_size = 2) %>% # プーリング層\n", - " layer_flatten() %>%\n", - " layer_dense(units = 128, activation = \"relu\") %>%\n", - " layer_dense(units = 10, activation = \"softmax\")\n", - "\n", - "summary(my_model)\n", - "# 割愛(Python の結果を参照)\n", - "\n", - "my_model %>% compile(loss = \"sparse_categorical_crossentropy\",\n", - " optimizer = \"rmsprop\",\n", - " metrics = c(\"accuracy\"))\n", - "\n", - "my_cb <- callback_early_stopping(patience = 5,\n", - " restore_best_weights = TRUE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history <- my_model %>%\n", - " fit(x = x_train2d,\n", - " y = y_train,\n", - " validation_split = 0.2,\n", - " batch_size = 128,\n", - " epochs = 20,\n", - " callbacks = list(my_cb),\n", - " verbose = 0)\n", - "\n", - "plot(my_history)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>%\n", - " evaluate(x = x_test2d, y = y_test)\n", - "#> loss accuracy\n", - "#> 0.1392894 0.9607000" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.2 LeNet" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- keras_model_sequential() %>%\n", - " layer_conv_2d(filters = 20, kernel_size = 5, activation = \"relu\",\n", - " input_shape = c(28, 28, 1)) %>%\n", - " layer_max_pooling_2d(pool_size = 2, strides = 2) %>%\n", - " layer_conv_2d(filters = 50, kernel_size = 5, activation = \"relu\") %>%\n", - " layer_max_pooling_2d(pool_size = 2, strides = 2) %>%\n", - " layer_dropout(rate = 0.25) %>%\n", - " layer_flatten() %>%\n", - " layer_dense(units = 500, activation = \"relu\") %>%\n", - " layer_dropout(rate = 0.5) %>%\n", - " layer_dense(units = 10, activation = \"softmax\")\n", - "\n", - "my_model %>% compile(\n", - " loss = \"sparse_categorical_crossentropy\",\n", - " optimizer = \"rmsprop\",\n", - " metrics = c(\"accuracy\"))\n", - "\n", - "my_cb <- callback_early_stopping(patience = 5,\n", - " restore_best_weights = TRUE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history <- my_model %>%\n", - " fit(x = x_train2d,\n", - " y = y_train,\n", - " validation_split = 0.2,\n", - " batch_size = 128,\n", - " epochs = 20,\n", - " callbacks = list(my_cb),\n", - " verbose = 0)\n", - "\n", - "plot(my_history)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>%\n", - " evaluate(x = x_test2d, y = y_test)\n", - "#> loss accuracy\n", - "#> 0.07309694 0.98060000" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.3 補足:LeNetが自信満々で間違う例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_prob <- my_model %>% predict(x_test2d) # カテゴリに属する確率\n", - "\n", - "my_result <- data.frame(\n", - " y_prob = apply(y_prob, 1, max), # 確率の最大値\n", - " y_ = apply(y_prob, 1, which.max) - 1, # 予測カテゴリ\n", - " y = y_test, # 正解\n", - " id = seq_len(length(y_test))) %>% # 番号\n", - " filter(y_ != y) %>% # 予測がはずれたものを残す\n", - " arrange(desc(y_prob)) # 確率の大きい順に並び替える" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_result)\n", - "#> y_prob y_ y id\n", - "#> 1 0.9998116 9 4 2131\n", - "#> 2 0.9988768 6 5 9730\n", - "#> 3 0.9986107 3 5 2598\n", - "#> 4 0.9971705 3 5 2036\n", - "#> 5 0.9888211 1 6 2655\n", - "#> 6 0.9857675 0 6 2119" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_result[1:5, ]$id\n", - "my_labels <- sprintf(\"%s (%s)\",\n", - " my_result[1:5, ]$y, tmp)\n", - "my_fig <- expand.grid(\n", - " label = my_labels,\n", - " y = 28:1,\n", - " x = 1:28)\n", - "my_fig$z <- as.vector(\n", - " x_test[tmp, , ])\n", - "\n", - "my_fig %>% ggplot(\n", - " aes(x = x, y = y, fill = z)) +\n", - " geom_raster() +\n", - " coord_fixed() +\n", - " theme_void() +\n", - " theme(legend.position = \"none\") +\n", - " facet_grid(. ~ label)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.4 AutoML\n", - "\n", - "### 11.4.1 H2Oの起動と停止" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(h2o)\n", - "library(keras)\n", - "library(tidyverse)\n", - "\n", - "h2o.init()\n", - "h2o.no_progress()\n", - "# h2o.shutdown(prompt = FALSE) # 停止" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.2 H2Oのデータフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)\n", - "my_frame <- as.h2o(my_data) # 通常のデータフレームをH2OFrameに変換する.\n", - "# あるいは\n", - "my_frame <- h2o.importFile(my_url, header = TRUE) # データを読み込む." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_frame\n", - "#> LPRICE2 WRAIN DEGREES HRAIN ...\n", - "#> 1 -0.99868 600 17.1167 160 ...\n", - "#> 2 -0.45440 690 16.7333 80 ...\n", - "#> 3 -0.80796 502 17.1500 130 ...\n", - "#> 4 -1.50926 420 16.1333 110 ...\n", - "#> 5 -1.71655 582 16.4167 187 ...\n", - "#> 6 -0.41800 485 17.4833 187 ...\n", - "#>\n", - "#> [27 rows x 5 columns]\n", - "\n", - "# 通常のデータフレームに戻す.\n", - "my_frame %>% as.data.frame %>% head\n", - "# 結果は割愛(見た目は同じ)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.3 AutoMLによる回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- h2o.automl(\n", - " y = \"LPRICE2\",\n", - " training_frame = my_frame,\n", - " max_runtime_secs = 60)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "min(my_model@leaderboard$rmse)\n", - "#> [1] 0.2922861" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_model %>%\n", - " predict(my_frame) %>%\n", - " as.data.frame\n", - "y_ <- tmp$predict\n", - "y <- my_data$LPRICE2\n", - "\n", - "plot(y, y_)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.4 AutoMLによる分類" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist())\n", - "my_index <- sample(1:60000, 6000)\n", - "x_train <- x_train[my_index, , ]\n", - "y_train <- y_train[my_index]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- x_train %>%\n", - " array_reshape(c(-1, 28 * 28)) %>%\n", - " as.data.frame\n", - "tmp$y <- as.factor(y_train)\n", - "my_train <- as.h2o(tmp)\n", - "\n", - "tmp <- x_test %>%\n", - " array_reshape(c(-1, 28 * 28)) %>%\n", - " as.data.frame\n", - "my_test <- as.h2o(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- h2o.automl(\n", - " y = \"y\",\n", - " training_frame = my_train,\n", - " max_runtime_secs = 120)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "min(my_model@leaderboard$\n", - " mean_per_class_error)\n", - "#> [1] 0.0806190885648608" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_model %>%\n", - " predict(my_test) %>% as.data.frame\n", - "y_ <- tmp$predict\n", - "\n", - "mean(y_ == y_test)\n", - "#> [1] 0.9306" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch11/11.01.ipynb b/code/R-notebook/ch11/11.01.ipynb deleted file mode 100644 index fb15b1f..0000000 --- a/code/R-notebook/ch11/11.01.ipynb +++ /dev/null @@ -1,145 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.1 Kerasによる回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(keras)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "tmp <- read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data <- tmp[sample(nrow(tmp)), ]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X <- my_data %>%\n", - " select(-LPRICE2) %>% scale\n", - "y <- my_data$LPRICE2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "curve(activation_relu(x), -3, 3)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- keras_model_sequential() %>%\n", - " layer_dense(units = 3, activation = \"relu\", input_shape = c(4)) %>%\n", - " layer_dense(units = 1)\n", - "\n", - "summary(my_model) # ネットワークの概要\n", - "# 割愛(Pythonの結果を参照)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>% compile(\n", - " loss = \"mse\",\n", - " optimizer = \"rmsprop\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_cb <- callback_early_stopping(\n", - " patience = 20,\n", - " restore_best_weights = TRUE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history <- my_model %>% fit(\n", - " x = X,\n", - " y = y,\n", - " validation_split = 0.25,\n", - " batch_size = 10,\n", - " epochs = 500,\n", - " callbacks = list(my_cb),\n", - " verbose = 0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plot(my_history)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history\n", - "#> Final epoch (plot to see history):\n", - "#> loss: 0.06124\n", - "#> val_loss: 0.1132" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ <- my_model %>% predict(X)\n", - "mean((y_ - y)^2)**0.5\n", - "#> [1] 0.2724372" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch11/11.02.ipynb b/code/R-notebook/ch11/11.02.ipynb deleted file mode 100644 index bfb9725..0000000 --- a/code/R-notebook/ch11/11.02.ipynb +++ /dev/null @@ -1,159 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.2 Kerasによる分類" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(keras)\n", - "library(tidyverse)\n", - "my_data <- iris[sample(nrow(iris)), ]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X <- my_data %>%\n", - " select(-Species) %>% scale\n", - "y <- as.integer(my_data$Species) - 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- keras_model_sequential() %>%\n", - " layer_dense(units = 3, activation = \"relu\", input_shape = c(4)) %>%\n", - " layer_dense(units = 3, activation = \"softmax\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>% compile(loss = \"sparse_categorical_crossentropy\",\n", - " optimizer = \"rmsprop\",\n", - " metrics = c(\"accuracy\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_cb <- callback_early_stopping(\n", - " patience = 20,\n", - " restore_best_weights = TRUE)\n", - "\n", - "my_history <- my_model %>%\n", - " fit(x = X,\n", - " y = y,\n", - " validation_split = 0.25,\n", - " batch_size = 10,\n", - " epochs = 500,\n", - " callbacks = list(my_cb),\n", - " verbose = 0)\n", - "\n", - "plot(my_history)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history\n", - "#> Final epoch (plot to see history):\n", - "#> loss: 0.06206\n", - "#> accuracy: 0.9732\n", - "#> val_loss: 0.1269\n", - "#> val_accuracy: 0.9211" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_model %>% predict(X)\n", - "y_ <- apply(tmp, 1, which.max) - 1\n", - "mean(y_ == y)\n", - "#> [1] 0.9666667" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.2.1 交差エントロピー" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "-mean(log(c(0.8, 0.7, 0.3, 0.8)))\n", - "#> 0.5017337\n", - "\n", - "-mean(log(c(0.7, 0.6, 0.2, 0.7)))\n", - "#> 0.7084034" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- c(2, 1, 0, 1)\n", - "y_1 <- list(c(0.1, 0.1, 0.8),\n", - " c(0.1, 0.7, 0.2),\n", - " c(0.3, 0.4, 0.3),\n", - " c(0.1, 0.8, 0.1))\n", - "y_2 <- list(c(0.1, 0.2, 0.7),\n", - " c(0.2, 0.6, 0.2),\n", - " c(0.2, 0.5, 0.3),\n", - " c(0.2, 0.7, 0.1))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c(mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_1))),\n", - " mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_2))))\n", - "#> [1] 0.5017337 0.7084033" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch11/11.03.ipynb b/code/R-notebook/ch11/11.03.ipynb deleted file mode 100644 index 9002a78..0000000 --- a/code/R-notebook/ch11/11.03.ipynb +++ /dev/null @@ -1,410 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.3 MNIST:手書き数字の分類\n", - "\n", - "### 11.3.1 データの形式" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(keras)\n", - "library(tidyverse)\n", - "keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist())" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "dim(x_train)\n", - "#> [1] 60000 28 28" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train[5, , ]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plot(as.raster(x = x_train[5, , ],\n", - " max = max(x_train)))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(y_train)\n", - "#> [1] 5 0 4 1 9 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c(min(x_train), max(x_train))\n", - "#> [1] 0 255" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train <- x_train / 255\n", - "x_test <- x_test / 255" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_index <- sample(1:60000, 6000)\n", - "x_train <- x_train[my_index, , ]\n", - "y_train <- y_train[my_index]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.3.2 多層パーセプトロン" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- keras_model_sequential() %>%\n", - " layer_flatten(input_shape = c(28, 28)) %>%\n", - " layer_dense(units = 256, activation = \"relu\") %>%\n", - " layer_dense(units = 10, activation = \"softmax\")\n", - "summary(my_model)\n", - "# 割愛(Pythonの結果を参照)\n", - "\n", - "my_model %>% compile(loss = \"sparse_categorical_crossentropy\",\n", - " optimizer = \"rmsprop\",\n", - " metrics = c(\"accuracy\"))\n", - "\n", - "my_cb <- callback_early_stopping(patience = 5,\n", - " restore_best_weights = TRUE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history <- my_model %>%\n", - " fit(x = x_train,\n", - " y = y_train,\n", - " validation_split = 0.2,\n", - " batch_size = 128,\n", - " epochs = 20,\n", - " callbacks = list(my_cb),\n", - " verbose = 0)\n", - "\n", - "plot(my_history)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_model %>% predict(x_test)\n", - "y_ <- apply(tmp, 1, which.max) - 1\n", - "table(y_, y_test)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#> y_test\n", - "#> y_ 0 1 2 3 4 5 6 7 8 9\n", - "#> 0 962 0 8 2 0 6 11 0 8 11\n", - "#> 1 0 1110 1 0 3 1 3 8 2 4\n", - "#> 2 0 5 959 13 4 4 2 16 6 1\n", - "#> 3 1 1 22 958 1 27 0 7 33 13\n", - "#> 4 2 0 6 1 905 8 6 6 3 14\n", - "#> 5 5 2 0 12 1 809 9 1 15 4\n", - "#> 6 6 3 8 0 8 11 922 0 5 1\n", - "#> 7 1 1 7 7 1 2 0 963 4 8\n", - "#> 8 2 13 19 13 4 16 5 0 890 5\n", - "#> 9 1 0 2 4 55 8 0 27 8 948" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mean(y_ == y_test)\n", - "#> [1] 0.9426000" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>%\n", - " evaluate(x = x_test, y = y_test)\n", - "#> loss accuracy\n", - "#> 0.2071411 0.9426000" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.3.3 畳み込みニューラルネットワーク(CNN)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train2d <- x_train %>% array_reshape(c(-1, 28, 28, 1))\n", - "x_test2d <- x_test %>% array_reshape(c(-1, 28, 28, 1))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.1 単純なCNN" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- keras_model_sequential() %>%\n", - " layer_conv_2d(filters = 32, kernel_size = 3, # 畳み込み層\n", - " activation = \"relu\",\n", - " input_shape = c(28, 28, 1)) %>%\n", - " layer_max_pooling_2d(pool_size = 2) %>% # プーリング層\n", - " layer_flatten() %>%\n", - " layer_dense(units = 128, activation = \"relu\") %>%\n", - " layer_dense(units = 10, activation = \"softmax\")\n", - "\n", - "summary(my_model)\n", - "# 割愛(Python の結果を参照)\n", - "\n", - "my_model %>% compile(loss = \"sparse_categorical_crossentropy\",\n", - " optimizer = \"rmsprop\",\n", - " metrics = c(\"accuracy\"))\n", - "\n", - "my_cb <- callback_early_stopping(patience = 5,\n", - " restore_best_weights = TRUE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history <- my_model %>%\n", - " fit(x = x_train2d,\n", - " y = y_train,\n", - " validation_split = 0.2,\n", - " batch_size = 128,\n", - " epochs = 20,\n", - " callbacks = list(my_cb),\n", - " verbose = 0)\n", - "\n", - "plot(my_history)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>%\n", - " evaluate(x = x_test2d, y = y_test)\n", - "#> loss accuracy\n", - "#> 0.1392894 0.9607000" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.2 LeNet" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- keras_model_sequential() %>%\n", - " layer_conv_2d(filters = 20, kernel_size = 5, activation = \"relu\",\n", - " input_shape = c(28, 28, 1)) %>%\n", - " layer_max_pooling_2d(pool_size = 2, strides = 2) %>%\n", - " layer_conv_2d(filters = 50, kernel_size = 5, activation = \"relu\") %>%\n", - " layer_max_pooling_2d(pool_size = 2, strides = 2) %>%\n", - " layer_dropout(rate = 0.25) %>%\n", - " layer_flatten() %>%\n", - " layer_dense(units = 500, activation = \"relu\") %>%\n", - " layer_dropout(rate = 0.5) %>%\n", - " layer_dense(units = 10, activation = \"softmax\")\n", - "\n", - "my_model %>% compile(\n", - " loss = \"sparse_categorical_crossentropy\",\n", - " optimizer = \"rmsprop\",\n", - " metrics = c(\"accuracy\"))\n", - "\n", - "my_cb <- callback_early_stopping(patience = 5,\n", - " restore_best_weights = TRUE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history <- my_model %>%\n", - " fit(x = x_train2d,\n", - " y = y_train,\n", - " validation_split = 0.2,\n", - " batch_size = 128,\n", - " epochs = 20,\n", - " callbacks = list(my_cb),\n", - " verbose = 0)\n", - "\n", - "plot(my_history)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>%\n", - " evaluate(x = x_test2d, y = y_test)\n", - "#> loss accuracy\n", - "#> 0.07309694 0.98060000" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.3 補足:LeNetが自信満々で間違う例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_prob <- my_model %>% predict(x_test2d) # カテゴリに属する確率\n", - "\n", - "my_result <- data.frame(\n", - " y_prob = apply(y_prob, 1, max), # 確率の最大値\n", - " y_ = apply(y_prob, 1, which.max) - 1, # 予測カテゴリ\n", - " y = y_test, # 正解\n", - " id = seq_len(length(y_test))) %>% # 番号\n", - " filter(y_ != y) %>% # 予測がはずれたものを残す\n", - " arrange(desc(y_prob)) # 確率の大きい順に並び替える" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_result)\n", - "#> y_prob y_ y id\n", - "#> 1 0.9998116 9 4 2131\n", - "#> 2 0.9988768 6 5 9730\n", - "#> 3 0.9986107 3 5 2598\n", - "#> 4 0.9971705 3 5 2036\n", - "#> 5 0.9888211 1 6 2655\n", - "#> 6 0.9857675 0 6 2119" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_result[1:5, ]$id\n", - "my_labels <- sprintf(\"%s (%s)\",\n", - " my_result[1:5, ]$y, tmp)\n", - "my_fig <- expand.grid(\n", - " label = my_labels,\n", - " y = 28:1,\n", - " x = 1:28)\n", - "my_fig$z <- as.vector(\n", - " x_test[tmp, , ])\n", - "\n", - "my_fig %>% ggplot(\n", - " aes(x = x, y = y, fill = z)) +\n", - " geom_raster() +\n", - " coord_fixed() +\n", - " theme_void() +\n", - " theme(legend.position = \"none\") +\n", - " facet_grid(. ~ label)" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch11/11.04.ipynb b/code/R-notebook/ch11/11.04.ipynb deleted file mode 100644 index 6550609..0000000 --- a/code/R-notebook/ch11/11.04.ipynb +++ /dev/null @@ -1,197 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.4 AutoML\n", - "\n", - "### 11.4.1 H2Oの起動と停止" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(h2o)\n", - "library(keras)\n", - "library(tidyverse)\n", - "\n", - "h2o.init()\n", - "h2o.no_progress()\n", - "# h2o.shutdown(prompt = FALSE) # 停止" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.2 H2Oのデータフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)\n", - "my_frame <- as.h2o(my_data) # 通常のデータフレームをH2OFrameに変換する.\n", - "# あるいは\n", - "my_frame <- h2o.importFile(my_url, header = TRUE) # データを読み込む." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_frame\n", - "#> LPRICE2 WRAIN DEGREES HRAIN ...\n", - "#> 1 -0.99868 600 17.1167 160 ...\n", - "#> 2 -0.45440 690 16.7333 80 ...\n", - "#> 3 -0.80796 502 17.1500 130 ...\n", - "#> 4 -1.50926 420 16.1333 110 ...\n", - "#> 5 -1.71655 582 16.4167 187 ...\n", - "#> 6 -0.41800 485 17.4833 187 ...\n", - "#>\n", - "#> [27 rows x 5 columns]\n", - "\n", - "# 通常のデータフレームに戻す.\n", - "my_frame %>% as.data.frame %>% head\n", - "# 結果は割愛(見た目は同じ)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.3 AutoMLによる回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- h2o.automl(\n", - " y = \"LPRICE2\",\n", - " training_frame = my_frame,\n", - " max_runtime_secs = 60)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "min(my_model@leaderboard$rmse)\n", - "#> [1] 0.2922861" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_model %>%\n", - " predict(my_frame) %>%\n", - " as.data.frame\n", - "y_ <- tmp$predict\n", - "y <- my_data$LPRICE2\n", - "\n", - "plot(y, y_)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.4 AutoMLによる分類" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist())\n", - "my_index <- sample(1:60000, 6000)\n", - "x_train <- x_train[my_index, , ]\n", - "y_train <- y_train[my_index]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- x_train %>%\n", - " array_reshape(c(-1, 28 * 28)) %>%\n", - " as.data.frame\n", - "tmp$y <- as.factor(y_train)\n", - "my_train <- as.h2o(tmp)\n", - "\n", - "tmp <- x_test %>%\n", - " array_reshape(c(-1, 28 * 28)) %>%\n", - " as.data.frame\n", - "my_test <- as.h2o(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- h2o.automl(\n", - " y = \"y\",\n", - " training_frame = my_train,\n", - " max_runtime_secs = 120)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "min(my_model@leaderboard$\n", - " mean_per_class_error)\n", - "#> [1] 0.0806190885648608" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_model %>%\n", - " predict(my_test) %>% as.data.frame\n", - "y_ <- tmp$predict\n", - "\n", - "mean(y_ == y_test)\n", - "#> [1] 0.9306" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch11/11.ipynb b/code/R-notebook/ch11/11.ipynb deleted file mode 100644 index 6c3c920..0000000 --- a/code/R-notebook/ch11/11.ipynb +++ /dev/null @@ -1,877 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 11\n", - "\n", - "## 11.1 Kerasによる回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(keras)\n", - "library(tidyverse)\n", - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "tmp <- read_csv(my_url)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data <- tmp[sample(nrow(tmp)), ]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X <- my_data %>%\n", - " select(-LPRICE2) %>% scale\n", - "y <- my_data$LPRICE2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "curve(activation_relu(x), -3, 3)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- keras_model_sequential() %>%\n", - " layer_dense(units = 3, activation = \"relu\", input_shape = c(4)) %>%\n", - " layer_dense(units = 1)\n", - "\n", - "summary(my_model) # ネットワークの概要\n", - "# 割愛(Pythonの結果を参照)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>% compile(\n", - " loss = \"mse\",\n", - " optimizer = \"rmsprop\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_cb <- callback_early_stopping(\n", - " patience = 20,\n", - " restore_best_weights = TRUE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history <- my_model %>% fit(\n", - " x = X,\n", - " y = y,\n", - " validation_split = 0.25,\n", - " batch_size = 10,\n", - " epochs = 500,\n", - " callbacks = list(my_cb),\n", - " verbose = 0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plot(my_history)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history\n", - "#> Final epoch (plot to see history):\n", - "#> loss: 0.06124\n", - "#> val_loss: 0.1132" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ <- my_model %>% predict(X)\n", - "mean((y_ - y)^2)**0.5\n", - "#> [1] 0.2724372" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.2 Kerasによる分類" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(keras)\n", - "library(tidyverse)\n", - "my_data <- iris[sample(nrow(iris)), ]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X <- my_data %>%\n", - " select(-Species) %>% scale\n", - "y <- as.integer(my_data$Species) - 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- keras_model_sequential() %>%\n", - " layer_dense(units = 3, activation = \"relu\", input_shape = c(4)) %>%\n", - " layer_dense(units = 3, activation = \"softmax\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>% compile(loss = \"sparse_categorical_crossentropy\",\n", - " optimizer = \"rmsprop\",\n", - " metrics = c(\"accuracy\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_cb <- callback_early_stopping(\n", - " patience = 20,\n", - " restore_best_weights = TRUE)\n", - "\n", - "my_history <- my_model %>%\n", - " fit(x = X,\n", - " y = y,\n", - " validation_split = 0.25,\n", - " batch_size = 10,\n", - " epochs = 500,\n", - " callbacks = list(my_cb),\n", - " verbose = 0)\n", - "\n", - "plot(my_history)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history\n", - "#> Final epoch (plot to see history):\n", - "#> loss: 0.06206\n", - "#> accuracy: 0.9732\n", - "#> val_loss: 0.1269\n", - "#> val_accuracy: 0.9211" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_model %>% predict(X)\n", - "y_ <- apply(tmp, 1, which.max) - 1\n", - "mean(y_ == y)\n", - "#> [1] 0.9666667" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.2.1 交差エントロピー" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "-mean(log(c(0.8, 0.7, 0.3, 0.8)))\n", - "#> 0.5017337\n", - "\n", - "-mean(log(c(0.7, 0.6, 0.2, 0.7)))\n", - "#> 0.7084034" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y <- c(2, 1, 0, 1)\n", - "y_1 <- list(c(0.1, 0.1, 0.8),\n", - " c(0.1, 0.7, 0.2),\n", - " c(0.3, 0.4, 0.3),\n", - " c(0.1, 0.8, 0.1))\n", - "y_2 <- list(c(0.1, 0.2, 0.7),\n", - " c(0.2, 0.6, 0.2),\n", - " c(0.2, 0.5, 0.3),\n", - " c(0.2, 0.7, 0.1))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c(mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_1))),\n", - " mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_2))))\n", - "#> [1] 0.5017337 0.7084033" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.3 MNIST:手書き数字の分類\n", - "\n", - "### 11.3.1 データの形式" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(keras)\n", - "library(tidyverse)\n", - "keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist())" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "dim(x_train)\n", - "#> [1] 60000 28 28" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train[5, , ]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plot(as.raster(x = x_train[5, , ],\n", - " max = max(x_train)))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(y_train)\n", - "#> [1] 5 0 4 1 9 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c(min(x_train), max(x_train))\n", - "#> [1] 0 255" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train <- x_train / 255\n", - "x_test <- x_test / 255" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_index <- sample(1:60000, 6000)\n", - "x_train <- x_train[my_index, , ]\n", - "y_train <- y_train[my_index]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.3.2 多層パーセプトロン" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- keras_model_sequential() %>%\n", - " layer_flatten(input_shape = c(28, 28)) %>%\n", - " layer_dense(units = 256, activation = \"relu\") %>%\n", - " layer_dense(units = 10, activation = \"softmax\")\n", - "summary(my_model)\n", - "# 割愛(Pythonの結果を参照)\n", - "\n", - "my_model %>% compile(loss = \"sparse_categorical_crossentropy\",\n", - " optimizer = \"rmsprop\",\n", - " metrics = c(\"accuracy\"))\n", - "\n", - "my_cb <- callback_early_stopping(patience = 5,\n", - " restore_best_weights = TRUE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history <- my_model %>%\n", - " fit(x = x_train,\n", - " y = y_train,\n", - " validation_split = 0.2,\n", - " batch_size = 128,\n", - " epochs = 20,\n", - " callbacks = list(my_cb),\n", - " verbose = 0)\n", - "\n", - "plot(my_history)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_model %>% predict(x_test)\n", - "y_ <- apply(tmp, 1, which.max) - 1\n", - "table(y_, y_test)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#> y_test\n", - "#> y_ 0 1 2 3 4 5 6 7 8 9\n", - "#> 0 962 0 8 2 0 6 11 0 8 11\n", - "#> 1 0 1110 1 0 3 1 3 8 2 4\n", - "#> 2 0 5 959 13 4 4 2 16 6 1\n", - "#> 3 1 1 22 958 1 27 0 7 33 13\n", - "#> 4 2 0 6 1 905 8 6 6 3 14\n", - "#> 5 5 2 0 12 1 809 9 1 15 4\n", - "#> 6 6 3 8 0 8 11 922 0 5 1\n", - "#> 7 1 1 7 7 1 2 0 963 4 8\n", - "#> 8 2 13 19 13 4 16 5 0 890 5\n", - "#> 9 1 0 2 4 55 8 0 27 8 948" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mean(y_ == y_test)\n", - "#> [1] 0.9426000" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>%\n", - " evaluate(x = x_test, y = y_test)\n", - "#> loss accuracy\n", - "#> 0.2071411 0.9426000" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.3.3 畳み込みニューラルネットワーク(CNN)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_train2d <- x_train %>% array_reshape(c(-1, 28, 28, 1))\n", - "x_test2d <- x_test %>% array_reshape(c(-1, 28, 28, 1))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.1 単純なCNN" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- keras_model_sequential() %>%\n", - " layer_conv_2d(filters = 32, kernel_size = 3, # 畳み込み層\n", - " activation = \"relu\",\n", - " input_shape = c(28, 28, 1)) %>%\n", - " layer_max_pooling_2d(pool_size = 2) %>% # プーリング層\n", - " layer_flatten() %>%\n", - " layer_dense(units = 128, activation = \"relu\") %>%\n", - " layer_dense(units = 10, activation = \"softmax\")\n", - "\n", - "summary(my_model)\n", - "# 割愛(Python の結果を参照)\n", - "\n", - "my_model %>% compile(loss = \"sparse_categorical_crossentropy\",\n", - " optimizer = \"rmsprop\",\n", - " metrics = c(\"accuracy\"))\n", - "\n", - "my_cb <- callback_early_stopping(patience = 5,\n", - " restore_best_weights = TRUE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history <- my_model %>%\n", - " fit(x = x_train2d,\n", - " y = y_train,\n", - " validation_split = 0.2,\n", - " batch_size = 128,\n", - " epochs = 20,\n", - " callbacks = list(my_cb),\n", - " verbose = 0)\n", - "\n", - "plot(my_history)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>%\n", - " evaluate(x = x_test2d, y = y_test)\n", - "#> loss accuracy\n", - "#> 0.1392894 0.9607000" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.2 LeNet" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- keras_model_sequential() %>%\n", - " layer_conv_2d(filters = 20, kernel_size = 5, activation = \"relu\",\n", - " input_shape = c(28, 28, 1)) %>%\n", - " layer_max_pooling_2d(pool_size = 2, strides = 2) %>%\n", - " layer_conv_2d(filters = 50, kernel_size = 5, activation = \"relu\") %>%\n", - " layer_max_pooling_2d(pool_size = 2, strides = 2) %>%\n", - " layer_dropout(rate = 0.25) %>%\n", - " layer_flatten() %>%\n", - " layer_dense(units = 500, activation = \"relu\") %>%\n", - " layer_dropout(rate = 0.5) %>%\n", - " layer_dense(units = 10, activation = \"softmax\")\n", - "\n", - "my_model %>% compile(\n", - " loss = \"sparse_categorical_crossentropy\",\n", - " optimizer = \"rmsprop\",\n", - " metrics = c(\"accuracy\"))\n", - "\n", - "my_cb <- callback_early_stopping(patience = 5,\n", - " restore_best_weights = TRUE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_history <- my_model %>%\n", - " fit(x = x_train2d,\n", - " y = y_train,\n", - " validation_split = 0.2,\n", - " batch_size = 128,\n", - " epochs = 20,\n", - " callbacks = list(my_cb),\n", - " verbose = 0)\n", - "\n", - "plot(my_history)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model %>%\n", - " evaluate(x = x_test2d, y = y_test)\n", - "#> loss accuracy\n", - "#> 0.07309694 0.98060000" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 11.3.3.3 補足:LeNetが自信満々で間違う例" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_prob <- my_model %>% predict(x_test2d) # カテゴリに属する確率\n", - "\n", - "my_result <- data.frame(\n", - " y_prob = apply(y_prob, 1, max), # 確率の最大値\n", - " y_ = apply(y_prob, 1, which.max) - 1, # 予測カテゴリ\n", - " y = y_test, # 正解\n", - " id = seq_len(length(y_test))) %>% # 番号\n", - " filter(y_ != y) %>% # 予測がはずれたものを残す\n", - " arrange(desc(y_prob)) # 確率の大きい順に並び替える" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "head(my_result)\n", - "#> y_prob y_ y id\n", - "#> 1 0.9998116 9 4 2131\n", - "#> 2 0.9988768 6 5 9730\n", - "#> 3 0.9986107 3 5 2598\n", - "#> 4 0.9971705 3 5 2036\n", - "#> 5 0.9888211 1 6 2655\n", - "#> 6 0.9857675 0 6 2119" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_result[1:5, ]$id\n", - "my_labels <- sprintf(\"%s (%s)\",\n", - " my_result[1:5, ]$y, tmp)\n", - "my_fig <- expand.grid(\n", - " label = my_labels,\n", - " y = 28:1,\n", - " x = 1:28)\n", - "my_fig$z <- as.vector(\n", - " x_test[tmp, , ])\n", - "\n", - "my_fig %>% ggplot(\n", - " aes(x = x, y = y, fill = z)) +\n", - " geom_raster() +\n", - " coord_fixed() +\n", - " theme_void() +\n", - " theme(legend.position = \"none\") +\n", - " facet_grid(. ~ label)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 11.4 AutoML\n", - "\n", - "### 11.4.1 H2Oの起動と停止" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(h2o)\n", - "library(keras)\n", - "library(tidyverse)\n", - "\n", - "h2o.init()\n", - "h2o.no_progress()\n", - "# h2o.shutdown(prompt = FALSE) # 停止" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.2 H2Oのデータフレーム" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", - " \"/fromzero/master/data/wine.csv\")\n", - "my_data <- read_csv(my_url)\n", - "my_frame <- as.h2o(my_data) # 通常のデータフレームをH2OFrameに変換する.\n", - "# あるいは\n", - "my_frame <- h2o.importFile(my_url, header = TRUE) # データを読み込む." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_frame\n", - "#> LPRICE2 WRAIN DEGREES HRAIN ...\n", - "#> 1 -0.99868 600 17.1167 160 ...\n", - "#> 2 -0.45440 690 16.7333 80 ...\n", - "#> 3 -0.80796 502 17.1500 130 ...\n", - "#> 4 -1.50926 420 16.1333 110 ...\n", - "#> 5 -1.71655 582 16.4167 187 ...\n", - "#> 6 -0.41800 485 17.4833 187 ...\n", - "#>\n", - "#> [27 rows x 5 columns]\n", - "\n", - "# 通常のデータフレームに戻す.\n", - "my_frame %>% as.data.frame %>% head\n", - "# 結果は割愛(見た目は同じ)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.3 AutoMLによる回帰" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- h2o.automl(\n", - " y = \"LPRICE2\",\n", - " training_frame = my_frame,\n", - " max_runtime_secs = 60)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "min(my_model@leaderboard$rmse)\n", - "#> [1] 0.2922861" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_model %>%\n", - " predict(my_frame) %>%\n", - " as.data.frame\n", - "y_ <- tmp$predict\n", - "y <- my_data$LPRICE2\n", - "\n", - "plot(y, y_)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 11.4.4 AutoMLによる分類" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist())\n", - "my_index <- sample(1:60000, 6000)\n", - "x_train <- x_train[my_index, , ]\n", - "y_train <- y_train[my_index]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- x_train %>%\n", - " array_reshape(c(-1, 28 * 28)) %>%\n", - " as.data.frame\n", - "tmp$y <- as.factor(y_train)\n", - "my_train <- as.h2o(tmp)\n", - "\n", - "tmp <- x_test %>%\n", - " array_reshape(c(-1, 28 * 28)) %>%\n", - " as.data.frame\n", - "my_test <- as.h2o(tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_model <- h2o.automl(\n", - " y = \"y\",\n", - " training_frame = my_train,\n", - " max_runtime_secs = 120)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "min(my_model@leaderboard$\n", - " mean_per_class_error)\n", - "#> [1] 0.0806190885648608" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_model %>%\n", - " predict(my_test) %>% as.data.frame\n", - "y_ <- tmp$predict\n", - "\n", - "mean(y_ == y_test)\n", - "#> [1] 0.9306" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch12/12-colab.ipynb b/code/R-notebook/ch12/12-colab.ipynb deleted file mode 100644 index 69cb893..0000000 --- a/code/R-notebook/ch12/12-colab.ipynb +++ /dev/null @@ -1,339 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 12" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Google Colaboratoryの環境設定\n", - "system(\"apt-get install -y libcurl4-openssl-dev libv8-dev r-cran-rcppeigen\")\n", - "options(Ncpus = 2)\n", - "install.packages(c(\"caret\", \"fable\", \"feasts\", \"prophet\", \"tsibble\", \"urca\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 12.1 日時と日時の列\n", - "\n", - "### 12.1.1 日時" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "as.POSIXct(\"2021-01-01\")\n", - "#> [1] \"2021-01-01 JST\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.1.2 等間隔の日時" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tsibble)\n", - "\n", - "seq(from = 2021, to = 2023, by = 1)\n", - "#> [1] 2021 2022 2023\n", - "\n", - "seq(from = yearmonth(\"202101\"), to = yearmonth(\"202103\"), by = 2)\n", - "#> \n", - "#> [1] \"2021 1\" \"2021 3\"\n", - "\n", - "seq(from = as.POSIXct(\"2021-01-01\"), to = as.POSIXct(\"2021-01-03\"), by = \"1 day\")\n", - "#> [1] \"2021-01-01 JST\" \"2021-01-02 JST\" \"2021-01-03 JST\"\n", - "\n", - "seq(from = as.POSIXct(\"2021-01-01 00:00:00\"),\n", - " to = as.POSIXct(\"2021-01-01 03:00:00\"), by = \"2 hour\")\n", - "#> [1] \"2021-01-01 00:00:00 JST\" \"2021-01-01 02:00:00 JST\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 12.2 時系列データの予測\n", - "\n", - "### 12.2.1 データの準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data <- as.vector(AirPassengers)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n <- length(my_data) # データ数(144)\n", - "k <- 108 # 訓練データ数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "library(tsibble)\n", - "\n", - "my_ds <- seq(\n", - " from = yearmonth(\"1949/01\"),\n", - " to = yearmonth(\"1960/12\"),\n", - " by = 1)\n", - "my_label <- rep(\n", - " c(\"train\", \"test\"),\n", - " c(k, n - k))\n", - "my_df <- tsibble(\n", - " ds = my_ds,\n", - " x = 0:(n - 1),\n", - " y = my_data,\n", - " label = my_label,\n", - " index = ds) # 日時の列の指定\n", - "\n", - "head(my_df)\n", - "#> # A tsibble: 6 x 4 [1M]\n", - "#> ds x y label\n", - "#> \n", - "#> 1 1949 1 0 112 train\n", - "#> 2 1949 2 1 118 train\n", - "#> 3 1949 3 2 132 train\n", - "#> 4 1949 4 3 129 train\n", - "#> 5 1949 5 4 121 train\n", - "#> 6 1949 6 5 135 train" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_train <- my_df[ 1:k , ]\n", - "my_test <- my_df[-(1:k), ]\n", - "y <- my_test$y" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_plot <- my_df %>%\n", - " ggplot(aes(x = ds,\n", - " y = y,\n", - " color = label)) +\n", - " geom_line()\n", - "my_plot" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.2 線形回帰分析による時系列予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "my_lm_model <- train(form = y ~ x, data = my_train, method = \"lm\")\n", - "y_ <- my_lm_model %>% predict(my_test)\n", - "caret::RMSE(y, y_) # RMSE(テスト)\n", - "#> [1] 70.63707" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ <- my_lm_model %>% predict(my_df)\n", - "tmp <- my_df %>%\n", - " mutate(y = y_, label = \"model\")\n", - "my_plot + geom_line(data = tmp)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.3 SARIMAによる時系列予測\n", - "\n", - "#### 12.2.3.1 モデルの構築" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(fable)\n", - "my_arima_model <- my_train %>% model(ARIMA(y))\n", - "my_arima_model\n", - "#> # A mable: 1 x 1\n", - "#> `ARIMA(y)`\n", - "#> \n", - "#> 1 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 12.2.3.2 予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_arima_model %>% forecast(h = \"3 years\")\n", - "head(tmp)\n", - "#> # A fable: 6 x 4 [1M]\n", - "#> # Key: .model [1]\n", - "#> .model ds y .mean\n", - "#> \n", - "#> 1 ARIMA(y) 1958 1 N(346, 94) 346.\n", - "#> 2 ARIMA(y) 1958 2 N(332, 148) 332.\n", - "#> 3 ARIMA(y) 1958 3 N(387, 210) 387.\n", - "#> 4 ARIMA(y) 1958 4 N(379, 271) 379.\n", - "#> 5 ARIMA(y) 1958 5 N(386, 332) 386.\n", - "#> 6 ARIMA(y) 1958 6 N(453, 393) 453." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ <- tmp$.mean\n", - "caret::RMSE(y_, y)\n", - "#> [1] 22.13223" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 予測結果のみでよい場合\n", - "#tmp %>% autoplot\n", - "\n", - "tmp %>% autoplot +\n", - " geom_line(data = my_df,\n", - " aes(x = ds,\n", - " y = y,\n", - " color = label))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.4 Prophetによる時系列予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(prophet)\n", - "my_prophet_model <- my_train %>%\n", - " prophet(seasonality.mode = \"multiplicative\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_prophet_model %>% predict(my_test)\n", - "head(tmp[, c(\"ds\", \"yhat\", \"yhat_lower\", \"yhat_upper\")])\n", - "#> # A tibble: 6 x 4\n", - "#> ds yhat yhat_lower yhat_upper\n", - "#> \n", - "#> 1 1958-01-01 00:00:00 359. 350. 368.\n", - "#> 2 1958-02-01 00:00:00 350. 342. 360.\n", - "#> 3 1958-03-01 00:00:00 407. 398. 416.\n", - "#> 4 1958-04-01 00:00:00 398. 389. 407.\n", - "#> 5 1958-05-01 00:00:00 402. 393. 411.\n", - "#> 6 1958-06-01 00:00:00 459. 450. 469." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ <- tmp$yhat\n", - "caret::RMSE(y_, y)\n", - "#> [1] 33.68719" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# my_prophet_model %>% plot(tmp) # 予測結果のみでよい場合\n", - "\n", - "my_prophet_model %>% plot(tmp) +\n", - " geom_line(data = my_train, aes(x = as.POSIXct(ds))) +\n", - " geom_line(data = my_test, aes(x = as.POSIXct(ds)), color = \"red\")" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch12/12.01.ipynb b/code/R-notebook/ch12/12.01.ipynb deleted file mode 100644 index 499ddca..0000000 --- a/code/R-notebook/ch12/12.01.ipynb +++ /dev/null @@ -1,61 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 12.1 日時と日時の列\n", - "\n", - "### 12.1.1 日時" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "as.POSIXct(\"2021-01-01\")\n", - "#> [1] \"2021-01-01 JST\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.1.2 等間隔の日時" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tsibble)\n", - "\n", - "seq(from = 2021, to = 2023, by = 1)\n", - "#> [1] 2021 2022 2023\n", - "\n", - "seq(from = yearmonth(\"202101\"), to = yearmonth(\"202103\"), by = 2)\n", - "#> \n", - "#> [1] \"2021 1\" \"2021 3\"\n", - "\n", - "seq(from = as.POSIXct(\"2021-01-01\"), to = as.POSIXct(\"2021-01-03\"), by = \"1 day\")\n", - "#> [1] \"2021-01-01 JST\" \"2021-01-02 JST\" \"2021-01-03 JST\"\n", - "\n", - "seq(from = as.POSIXct(\"2021-01-01 00:00:00\"),\n", - " to = as.POSIXct(\"2021-01-01 03:00:00\"), by = \"2 hour\")\n", - "#> [1] \"2021-01-01 00:00:00 JST\" \"2021-01-01 02:00:00 JST\"" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch12/12.02.ipynb b/code/R-notebook/ch12/12.02.ipynb deleted file mode 100644 index f9db4ea..0000000 --- a/code/R-notebook/ch12/12.02.ipynb +++ /dev/null @@ -1,271 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 12.2 時系列データの予測\n", - "\n", - "### 12.2.1 データの準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data <- as.vector(AirPassengers)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n <- length(my_data) # データ数(144)\n", - "k <- 108 # 訓練データ数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "library(tsibble)\n", - "\n", - "my_ds <- seq(\n", - " from = yearmonth(\"1949/01\"),\n", - " to = yearmonth(\"1960/12\"),\n", - " by = 1)\n", - "my_label <- rep(\n", - " c(\"train\", \"test\"),\n", - " c(k, n - k))\n", - "my_df <- tsibble(\n", - " ds = my_ds,\n", - " x = 0:(n - 1),\n", - " y = my_data,\n", - " label = my_label,\n", - " index = ds) # 日時の列の指定\n", - "\n", - "head(my_df)\n", - "#> # A tsibble: 6 x 4 [1M]\n", - "#> ds x y label\n", - "#> \n", - "#> 1 1949 1 0 112 train\n", - "#> 2 1949 2 1 118 train\n", - "#> 3 1949 3 2 132 train\n", - "#> 4 1949 4 3 129 train\n", - "#> 5 1949 5 4 121 train\n", - "#> 6 1949 6 5 135 train" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_train <- my_df[ 1:k , ]\n", - "my_test <- my_df[-(1:k), ]\n", - "y <- my_test$y" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_plot <- my_df %>%\n", - " ggplot(aes(x = ds,\n", - " y = y,\n", - " color = label)) +\n", - " geom_line()\n", - "my_plot" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.2 線形回帰分析による時系列予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "my_lm_model <- train(form = y ~ x, data = my_train, method = \"lm\")\n", - "y_ <- my_lm_model %>% predict(my_test)\n", - "caret::RMSE(y, y_) # RMSE(テスト)\n", - "#> [1] 70.63707" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ <- my_lm_model %>% predict(my_df)\n", - "tmp <- my_df %>%\n", - " mutate(y = y_, label = \"model\")\n", - "my_plot + geom_line(data = tmp)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.3 SARIMAによる時系列予測\n", - "\n", - "#### 12.2.3.1 モデルの構築" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(fable)\n", - "my_arima_model <- my_train %>% model(ARIMA(y))\n", - "my_arima_model\n", - "#> # A mable: 1 x 1\n", - "#> `ARIMA(y)`\n", - "#> \n", - "#> 1 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 12.2.3.2 予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_arima_model %>% forecast(h = \"3 years\")\n", - "head(tmp)\n", - "#> # A fable: 6 x 4 [1M]\n", - "#> # Key: .model [1]\n", - "#> .model ds y .mean\n", - "#> \n", - "#> 1 ARIMA(y) 1958 1 N(346, 94) 346.\n", - "#> 2 ARIMA(y) 1958 2 N(332, 148) 332.\n", - "#> 3 ARIMA(y) 1958 3 N(387, 210) 387.\n", - "#> 4 ARIMA(y) 1958 4 N(379, 271) 379.\n", - "#> 5 ARIMA(y) 1958 5 N(386, 332) 386.\n", - "#> 6 ARIMA(y) 1958 6 N(453, 393) 453." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ <- tmp$.mean\n", - "caret::RMSE(y_, y)\n", - "#> [1] 22.13223" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 予測結果のみでよい場合\n", - "#tmp %>% autoplot\n", - "\n", - "tmp %>% autoplot +\n", - " geom_line(data = my_df,\n", - " aes(x = ds,\n", - " y = y,\n", - " color = label))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.4 Prophetによる時系列予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(prophet)\n", - "my_prophet_model <- my_train %>%\n", - " prophet(seasonality.mode = \"multiplicative\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_prophet_model %>% predict(my_test)\n", - "head(tmp[, c(\"ds\", \"yhat\", \"yhat_lower\", \"yhat_upper\")])\n", - "#> # A tibble: 6 x 4\n", - "#> ds yhat yhat_lower yhat_upper\n", - "#> \n", - "#> 1 1958-01-01 00:00:00 359. 350. 368.\n", - "#> 2 1958-02-01 00:00:00 350. 342. 360.\n", - "#> 3 1958-03-01 00:00:00 407. 398. 416.\n", - "#> 4 1958-04-01 00:00:00 398. 389. 407.\n", - "#> 5 1958-05-01 00:00:00 402. 393. 411.\n", - "#> 6 1958-06-01 00:00:00 459. 450. 469." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ <- tmp$yhat\n", - "caret::RMSE(y_, y)\n", - "#> [1] 33.68719" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# my_prophet_model %>% plot(tmp) # 予測結果のみでよい場合\n", - "\n", - "my_prophet_model %>% plot(tmp) +\n", - " geom_line(data = my_train, aes(x = as.POSIXct(ds))) +\n", - " geom_line(data = my_test, aes(x = as.POSIXct(ds)), color = \"red\")" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch12/12.ipynb b/code/R-notebook/ch12/12.ipynb deleted file mode 100644 index 6663b8c..0000000 --- a/code/R-notebook/ch12/12.ipynb +++ /dev/null @@ -1,322 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 12\n", - "\n", - "## 12.1 日時と日時の列\n", - "\n", - "### 12.1.1 日時" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "as.POSIXct(\"2021-01-01\")\n", - "#> [1] \"2021-01-01 JST\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.1.2 等間隔の日時" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tsibble)\n", - "\n", - "seq(from = 2021, to = 2023, by = 1)\n", - "#> [1] 2021 2022 2023\n", - "\n", - "seq(from = yearmonth(\"202101\"), to = yearmonth(\"202103\"), by = 2)\n", - "#> \n", - "#> [1] \"2021 1\" \"2021 3\"\n", - "\n", - "seq(from = as.POSIXct(\"2021-01-01\"), to = as.POSIXct(\"2021-01-03\"), by = \"1 day\")\n", - "#> [1] \"2021-01-01 JST\" \"2021-01-02 JST\" \"2021-01-03 JST\"\n", - "\n", - "seq(from = as.POSIXct(\"2021-01-01 00:00:00\"),\n", - " to = as.POSIXct(\"2021-01-01 03:00:00\"), by = \"2 hour\")\n", - "#> [1] \"2021-01-01 00:00:00 JST\" \"2021-01-01 02:00:00 JST\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 12.2 時系列データの予測\n", - "\n", - "### 12.2.1 データの準備" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_data <- as.vector(AirPassengers)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n <- length(my_data) # データ数(144)\n", - "k <- 108 # 訓練データ数" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "library(tsibble)\n", - "\n", - "my_ds <- seq(\n", - " from = yearmonth(\"1949/01\"),\n", - " to = yearmonth(\"1960/12\"),\n", - " by = 1)\n", - "my_label <- rep(\n", - " c(\"train\", \"test\"),\n", - " c(k, n - k))\n", - "my_df <- tsibble(\n", - " ds = my_ds,\n", - " x = 0:(n - 1),\n", - " y = my_data,\n", - " label = my_label,\n", - " index = ds) # 日時の列の指定\n", - "\n", - "head(my_df)\n", - "#> # A tsibble: 6 x 4 [1M]\n", - "#> ds x y label\n", - "#> \n", - "#> 1 1949 1 0 112 train\n", - "#> 2 1949 2 1 118 train\n", - "#> 3 1949 3 2 132 train\n", - "#> 4 1949 4 3 129 train\n", - "#> 5 1949 5 4 121 train\n", - "#> 6 1949 6 5 135 train" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_train <- my_df[ 1:k , ]\n", - "my_test <- my_df[-(1:k), ]\n", - "y <- my_test$y" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_plot <- my_df %>%\n", - " ggplot(aes(x = ds,\n", - " y = y,\n", - " color = label)) +\n", - " geom_line()\n", - "my_plot" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.2 線形回帰分析による時系列予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(caret)\n", - "my_lm_model <- train(form = y ~ x, data = my_train, method = \"lm\")\n", - "y_ <- my_lm_model %>% predict(my_test)\n", - "caret::RMSE(y, y_) # RMSE(テスト)\n", - "#> [1] 70.63707" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ <- my_lm_model %>% predict(my_df)\n", - "tmp <- my_df %>%\n", - " mutate(y = y_, label = \"model\")\n", - "my_plot + geom_line(data = tmp)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.3 SARIMAによる時系列予測\n", - "\n", - "#### 12.2.3.1 モデルの構築" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(fable)\n", - "my_arima_model <- my_train %>% model(ARIMA(y))\n", - "my_arima_model\n", - "#> # A mable: 1 x 1\n", - "#> `ARIMA(y)`\n", - "#> \n", - "#> 1 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 12.2.3.2 予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_arima_model %>% forecast(h = \"3 years\")\n", - "head(tmp)\n", - "#> # A fable: 6 x 4 [1M]\n", - "#> # Key: .model [1]\n", - "#> .model ds y .mean\n", - "#> \n", - "#> 1 ARIMA(y) 1958 1 N(346, 94) 346.\n", - "#> 2 ARIMA(y) 1958 2 N(332, 148) 332.\n", - "#> 3 ARIMA(y) 1958 3 N(387, 210) 387.\n", - "#> 4 ARIMA(y) 1958 4 N(379, 271) 379.\n", - "#> 5 ARIMA(y) 1958 5 N(386, 332) 386.\n", - "#> 6 ARIMA(y) 1958 6 N(453, 393) 453." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ <- tmp$.mean\n", - "caret::RMSE(y_, y)\n", - "#> [1] 22.13223" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 予測結果のみでよい場合\n", - "#tmp %>% autoplot\n", - "\n", - "tmp %>% autoplot +\n", - " geom_line(data = my_df,\n", - " aes(x = ds,\n", - " y = y,\n", - " color = label))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 12.2.4 Prophetによる時系列予測" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(prophet)\n", - "my_prophet_model <- my_train %>%\n", - " prophet(seasonality.mode = \"multiplicative\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tmp <- my_prophet_model %>% predict(my_test)\n", - "head(tmp[, c(\"ds\", \"yhat\", \"yhat_lower\", \"yhat_upper\")])\n", - "#> # A tibble: 6 x 4\n", - "#> ds yhat yhat_lower yhat_upper\n", - "#> \n", - "#> 1 1958-01-01 00:00:00 359. 350. 368.\n", - "#> 2 1958-02-01 00:00:00 350. 342. 360.\n", - "#> 3 1958-03-01 00:00:00 407. 398. 416.\n", - "#> 4 1958-04-01 00:00:00 398. 389. 407.\n", - "#> 5 1958-05-01 00:00:00 402. 393. 411.\n", - "#> 6 1958-06-01 00:00:00 459. 450. 469." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y_ <- tmp$yhat\n", - "caret::RMSE(y_, y)\n", - "#> [1] 33.68719" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# my_prophet_model %>% plot(tmp) # 予測結果のみでよい場合\n", - "\n", - "my_prophet_model %>% plot(tmp) +\n", - " geom_line(data = my_train, aes(x = as.POSIXct(ds))) +\n", - " geom_line(data = my_test, aes(x = as.POSIXct(ds)), color = \"red\")" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch13/13-colab.ipynb b/code/R-notebook/ch13/13-colab.ipynb deleted file mode 100644 index e848959..0000000 --- a/code/R-notebook/ch13/13-colab.ipynb +++ /dev/null @@ -1,380 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 13" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Google Colaboratoryの環境設定\n", - "options(Ncpus = 2)\n", - "install.packages(c(\"factoextra\", \"gplots\", \"igraph\"))\n", - "devtools::install_github(\"vqv/ggbiplot\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 13.1 主成分分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_data <- data.frame(\n", - " language = c( 0, 20, 20, 25, 22, 17),\n", - " english = c( 0, 20, 40, 20, 24, 18),\n", - " math = c(100, 20, 5, 30, 17, 25),\n", - " science = c( 0, 20, 5, 25, 16, 23),\n", - " society = c( 0, 20, 30, 0, 21, 17),\n", - " row.names = c(\"A\", \"B\", \"C\", \"D\", \"E\", \"F\"))\n", - "my_result <- my_data %>% prcomp # 主成分分析の実行" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result$x # 主成分スコア\n", - "#> PC1 PC2 ...\n", - "#> A -74.907282 -7.010808 ...\n", - "#> B 13.818842 2.753459 ...\n", - "#> C 33.714034 -18.417290 ...\n", - "#> D 1.730630 17.876372 ...\n", - "#> E 17.837474 -1.064998 ...\n", - "#> F 7.806303 5.863266 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result %>% ggbiplot::ggbiplot(\n", - " labels = row.names(my_data),\n", - " scale = 0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result$rotation %>% t\n", - "#> language english math science society\n", - "#> PC1 0.2074983 0.3043604 -0.887261240 0.1301984 0.2452041\n", - "#> PC2 0.2794627 -0.3250521 -0.097642669 0.7026667 -0.5594347\n", - "#> PC3 -0.3061175 -0.6157986 -0.056345381 0.3384462 0.6398152\n", - "#> PC4 0.7649426 -0.4716969 -0.007654992 -0.4180454 0.1324548\n", - "#> PC5 0.4472136 0.4472136 0.447213595 0.4472136 0.4472136" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "summary(my_result)\n", - "#> Importance of components:\n", - "#> PC1 PC2 PC3 PC4 PC5\n", - "#> Standard deviation 38.2644 12.25566 5.58845 1.52970 1.232e-15\n", - "#> Proportion of Variance 0.8885 0.09115 0.01895 0.00142 0.000e+00\n", - "#> Cumulative Proportion 0.8885 0.97963 0.99858 1.00000 1.000e+00" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.1.1 標準化+主成分分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result <- prcomp(\n", - " x = my_data,\n", - " scale = TRUE) # 標準化\n", - "# あるいは\n", - "my_result <- prcomp(\n", - " x = scale(my_data)) # 標準化データ\n", - "\n", - "my_result$x # 主成分スコア\n", - "#> PC1 PC2 ...\n", - "#> A -3.6737215 -0.5688501 ...\n", - "#> B 0.6528793 0.2469258 ...\n", - "#> C 1.5682936 -1.7425981 ...\n", - "#> D 0.2505043 1.6400394 ...\n", - "#> E 0.8861864 -0.1104931 ...\n", - "#> F 0.3158579 0.5349762 ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.1.2 補足:行列計算による再現" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Z <- my_data %>% scale(scale = FALSE) %>% as.matrix # 標準化しない場合\n", - "#Z <- my_data %>% scale(scale = TRUE) %>% as.matrix # 標準化する場合\n", - "\n", - "n <- nrow(my_data)\n", - "S <- var(Z) # 分散共分散行列\n", - "#S <- t(Z) %*% Z / (n - 1) # (同じ結果)\n", - "tmp <- eigen(S) # 固有値と固有ベクトル\n", - "Z %*% tmp$vectors # 主成分スコア(結果は割愛)\n", - "cumsum(tmp$values) / sum(tmp$values) # 累積寄与率\n", - "#> [1] 0.8884833 0.9796285 0.9985801 1.0000000 1.0000000" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "udv <- svd(Z) # 特異値分解\n", - "U <- udv$u\n", - "d <- udv$d\n", - "V <- udv$v\n", - "W <- diag(d)\n", - "\n", - "c(all.equal(Z, U %*% W %*% t(V), check.attributes = FALSE), # 確認1\n", - " all.equal(t(U) %*% U, diag(dim(U)[2])), # 確認2\n", - " all.equal(t(V) %*% V, diag(dim(V)[2]))) # 確認3\n", - "#> [1] TRUE TRUE TRUE\n", - "\n", - "U %*% W # 主成分スコア(結果は割愛)\n", - "\n", - "e <- d^2 / (n - 1) # 分散共分散行列の固有値\n", - "cumsum(e) / sum(e) # 累積寄与率\n", - "#> [1] 0.8884833 0.9796285 0.9985801 1.0000000 1.0000000" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 13.2 クラスタ分析\n", - "\n", - "### 13.2.1 階層的クラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_data <- data.frame(\n", - " x = c( 0, -16, 10, 10),\n", - " y = c( 0, 0, 10, -15),\n", - " row.names = c(\"A\", \"B\", \"C\", \"D\"))\n", - "\n", - "my_result <- my_data %>%\n", - " dist(\"euclidian\") %>% # distだけでも可\n", - " hclust(\"complete\") # hclustだけでも可" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result %>% factoextra::fviz_dend(\n", - " k = 3, # クラスタ数\n", - " rect = TRUE, rect_fill = TRUE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result %>% factoextra::fviz_dend(\n", - " k = 3,\n", - " rect = TRUE, rect_fill = TRUE,\n", - " type = \"phylogenic\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result %>% cutree(3)\n", - "#> A B C D\n", - "#> 1 2 1 3" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.2 階層的クラスタ分析とヒートマップ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_data <- data.frame(\n", - " language = c( 0, 20, 20, 25, 22, 17),\n", - " english = c( 0, 20, 40, 20, 24, 18),\n", - " math = c(100, 20, 5, 30, 17, 25),\n", - " science = c( 0, 20, 5, 25, 16, 23),\n", - " society = c( 0, 20, 30, 0, 21, 17),\n", - " row.names = c(\"A\", \"B\", \"C\", \"D\", \"E\", \"F\"))\n", - "\n", - "try( # RMarkdownで発生するエラーを回避する.\n", - " my_data %>% scale %>% # 列ごとの標準化\n", - " gplots::heatmap.2(cexRow = 1, cexCol = 1), # ラベルのサイズを指定して描画する.\n", - " silent = TRUE)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.3 非階層的クラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_data <- data.frame(\n", - " x = c( 0, -16, 10, 10),\n", - " y = c( 0, 0, 10, -15),\n", - " row.names = c(\"A\", \"B\", \"C\", \"D\"))\n", - "\n", - "my_result <- my_data %>% kmeans(3)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result$cluster\n", - "#> A B C D\n", - "#> 2 3 2 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.4 クラスタ数の決定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "library(factoextra)\n", - "\n", - "my_data <- iris[, -5]\n", - "\n", - "f <- 2:5 %>% map(function(k) {\n", - " my_data %>% kmeans(k) %>%\n", - " fviz_cluster(data = my_data, geom = \"point\") +\n", - " ggtitle(sprintf(\"k = %s\", k))\n", - "})\n", - "gridExtra::grid.arrange(f[[1]], f[[2]], f[[3]], f[[4]], ncol = 2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fviz_nbclust(my_data, kmeans, method = \"wss\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.5 主成分分析とクラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "my_data <- iris[, -5] %>% scale\n", - "\n", - "my_result <- prcomp(my_data)$x %>% as.data.frame # 主成分分析\n", - "\n", - "# 非階層的クラスタ分析の場合\n", - "my_result$cluster <- (my_data %>% scale %>% kmeans(3))$cluster %>% as.factor\n", - "\n", - "# 階層的クラスタ分析の場合\n", - "#my_result$cluster <- my_data %>% dist %>% hclust %>% cutree(3) %>% as.factor\n", - "\n", - "my_result %>%\n", - " ggplot(aes(x = PC1, y = PC2, color = cluster)) + # 色でクラスタを表現する.\n", - " geom_point(shape = iris$Species) + # 形で品種を表現する.\n", - " theme(legend.position = \"none\")" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch13/13.01.ipynb b/code/R-notebook/ch13/13.01.ipynb deleted file mode 100644 index 5ed6b1c..0000000 --- a/code/R-notebook/ch13/13.01.ipynb +++ /dev/null @@ -1,172 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 13.1 主成分分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_data <- data.frame(\n", - " language = c( 0, 20, 20, 25, 22, 17),\n", - " english = c( 0, 20, 40, 20, 24, 18),\n", - " math = c(100, 20, 5, 30, 17, 25),\n", - " science = c( 0, 20, 5, 25, 16, 23),\n", - " society = c( 0, 20, 30, 0, 21, 17),\n", - " row.names = c(\"A\", \"B\", \"C\", \"D\", \"E\", \"F\"))\n", - "my_result <- my_data %>% prcomp # 主成分分析の実行" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result$x # 主成分スコア\n", - "#> PC1 PC2 ...\n", - "#> A -74.907282 -7.010808 ...\n", - "#> B 13.818842 2.753459 ...\n", - "#> C 33.714034 -18.417290 ...\n", - "#> D 1.730630 17.876372 ...\n", - "#> E 17.837474 -1.064998 ...\n", - "#> F 7.806303 5.863266 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result %>% ggbiplot::ggbiplot(\n", - " labels = row.names(my_data),\n", - " scale = 0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result$rotation %>% t\n", - "#> language english math science society\n", - "#> PC1 0.2074983 0.3043604 -0.887261240 0.1301984 0.2452041\n", - "#> PC2 0.2794627 -0.3250521 -0.097642669 0.7026667 -0.5594347\n", - "#> PC3 -0.3061175 -0.6157986 -0.056345381 0.3384462 0.6398152\n", - "#> PC4 0.7649426 -0.4716969 -0.007654992 -0.4180454 0.1324548\n", - "#> PC5 0.4472136 0.4472136 0.447213595 0.4472136 0.4472136" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "summary(my_result)\n", - "#> Importance of components:\n", - "#> PC1 PC2 PC3 PC4 PC5\n", - "#> Standard deviation 38.2644 12.25566 5.58845 1.52970 1.232e-15\n", - "#> Proportion of Variance 0.8885 0.09115 0.01895 0.00142 0.000e+00\n", - "#> Cumulative Proportion 0.8885 0.97963 0.99858 1.00000 1.000e+00" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.1.1 標準化+主成分分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result <- prcomp(\n", - " x = my_data,\n", - " scale = TRUE) # 標準化\n", - "# あるいは\n", - "my_result <- prcomp(\n", - " x = scale(my_data)) # 標準化データ\n", - "\n", - "my_result$x # 主成分スコア\n", - "#> PC1 PC2 ...\n", - "#> A -3.6737215 -0.5688501 ...\n", - "#> B 0.6528793 0.2469258 ...\n", - "#> C 1.5682936 -1.7425981 ...\n", - "#> D 0.2505043 1.6400394 ...\n", - "#> E 0.8861864 -0.1104931 ...\n", - "#> F 0.3158579 0.5349762 ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.1.2 補足:行列計算による再現" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Z <- my_data %>% scale(scale = FALSE) %>% as.matrix # 標準化しない場合\n", - "#Z <- my_data %>% scale(scale = TRUE) %>% as.matrix # 標準化する場合\n", - "\n", - "n <- nrow(my_data)\n", - "S <- var(Z) # 分散共分散行列\n", - "#S <- t(Z) %*% Z / (n - 1) # (同じ結果)\n", - "tmp <- eigen(S) # 固有値と固有ベクトル\n", - "Z %*% tmp$vectors # 主成分スコア(結果は割愛)\n", - "cumsum(tmp$values) / sum(tmp$values) # 累積寄与率\n", - "#> [1] 0.8884833 0.9796285 0.9985801 1.0000000 1.0000000" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "udv <- svd(Z) # 特異値分解\n", - "U <- udv$u\n", - "d <- udv$d\n", - "V <- udv$v\n", - "W <- diag(d)\n", - "\n", - "c(all.equal(Z, U %*% W %*% t(V), check.attributes = FALSE), # 確認1\n", - " all.equal(t(U) %*% U, diag(dim(U)[2])), # 確認2\n", - " all.equal(t(V) %*% V, diag(dim(V)[2]))) # 確認3\n", - "#> [1] TRUE TRUE TRUE\n", - "\n", - "U %*% W # 主成分スコア(結果は割愛)\n", - "\n", - "e <- d^2 / (n - 1) # 分散共分散行列の固有値\n", - "cumsum(e) / sum(e) # 累積寄与率\n", - "#> [1] 0.8884833 0.9796285 0.9985801 1.0000000 1.0000000" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch13/13.02.ipynb b/code/R-notebook/ch13/13.02.ipynb deleted file mode 100644 index c7f632c..0000000 --- a/code/R-notebook/ch13/13.02.ipynb +++ /dev/null @@ -1,201 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 13.2 クラスタ分析\n", - "\n", - "### 13.2.1 階層的クラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_data <- data.frame(\n", - " x = c( 0, -16, 10, 10),\n", - " y = c( 0, 0, 10, -15),\n", - " row.names = c(\"A\", \"B\", \"C\", \"D\"))\n", - "\n", - "my_result <- my_data %>%\n", - " dist(\"euclidian\") %>% # distだけでも可\n", - " hclust(\"complete\") # hclustだけでも可" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result %>% factoextra::fviz_dend(\n", - " k = 3, # クラスタ数\n", - " rect = TRUE, rect_fill = TRUE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result %>% factoextra::fviz_dend(\n", - " k = 3,\n", - " rect = TRUE, rect_fill = TRUE,\n", - " type = \"phylogenic\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result %>% cutree(3)\n", - "#> A B C D\n", - "#> 1 2 1 3" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.2 階層的クラスタ分析とヒートマップ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_data <- data.frame(\n", - " language = c( 0, 20, 20, 25, 22, 17),\n", - " english = c( 0, 20, 40, 20, 24, 18),\n", - " math = c(100, 20, 5, 30, 17, 25),\n", - " science = c( 0, 20, 5, 25, 16, 23),\n", - " society = c( 0, 20, 30, 0, 21, 17),\n", - " row.names = c(\"A\", \"B\", \"C\", \"D\", \"E\", \"F\"))\n", - "\n", - "try( # RMarkdownで発生するエラーを回避する.\n", - " my_data %>% scale %>% # 列ごとの標準化\n", - " gplots::heatmap.2(cexRow = 1, cexCol = 1), # ラベルのサイズを指定して描画する.\n", - " silent = TRUE)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.3 非階層的クラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_data <- data.frame(\n", - " x = c( 0, -16, 10, 10),\n", - " y = c( 0, 0, 10, -15),\n", - " row.names = c(\"A\", \"B\", \"C\", \"D\"))\n", - "\n", - "my_result <- my_data %>% kmeans(3)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result$cluster\n", - "#> A B C D\n", - "#> 2 3 2 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.4 クラスタ数の決定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "library(factoextra)\n", - "\n", - "my_data <- iris[, -5]\n", - "\n", - "f <- 2:5 %>% map(function(k) {\n", - " my_data %>% kmeans(k) %>%\n", - " fviz_cluster(data = my_data, geom = \"point\") +\n", - " ggtitle(sprintf(\"k = %s\", k))\n", - "})\n", - "gridExtra::grid.arrange(f[[1]], f[[2]], f[[3]], f[[4]], ncol = 2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fviz_nbclust(my_data, kmeans, method = \"wss\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.5 主成分分析とクラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "my_data <- iris[, -5] %>% scale\n", - "\n", - "my_result <- prcomp(my_data)$x %>% as.data.frame # 主成分分析\n", - "\n", - "# 非階層的クラスタ分析の場合\n", - "my_result$cluster <- (my_data %>% scale %>% kmeans(3))$cluster %>% as.factor\n", - "\n", - "# 階層的クラスタ分析の場合\n", - "#my_result$cluster <- my_data %>% dist %>% hclust %>% cutree(3) %>% as.factor\n", - "\n", - "my_result %>%\n", - " ggplot(aes(x = PC1, y = PC2, color = cluster)) + # 色でクラスタを表現する.\n", - " geom_point(shape = iris$Species) + # 形で品種を表現する.\n", - " theme(legend.position = \"none\")" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/ch13/13.ipynb b/code/R-notebook/ch13/13.ipynb deleted file mode 100644 index 95ef0c7..0000000 --- a/code/R-notebook/ch13/13.ipynb +++ /dev/null @@ -1,363 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 13\n", - "\n", - "## 13.1 主成分分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_data <- data.frame(\n", - " language = c( 0, 20, 20, 25, 22, 17),\n", - " english = c( 0, 20, 40, 20, 24, 18),\n", - " math = c(100, 20, 5, 30, 17, 25),\n", - " science = c( 0, 20, 5, 25, 16, 23),\n", - " society = c( 0, 20, 30, 0, 21, 17),\n", - " row.names = c(\"A\", \"B\", \"C\", \"D\", \"E\", \"F\"))\n", - "my_result <- my_data %>% prcomp # 主成分分析の実行" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result$x # 主成分スコア\n", - "#> PC1 PC2 ...\n", - "#> A -74.907282 -7.010808 ...\n", - "#> B 13.818842 2.753459 ...\n", - "#> C 33.714034 -18.417290 ...\n", - "#> D 1.730630 17.876372 ...\n", - "#> E 17.837474 -1.064998 ...\n", - "#> F 7.806303 5.863266 ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result %>% ggbiplot::ggbiplot(\n", - " labels = row.names(my_data),\n", - " scale = 0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result$rotation %>% t\n", - "#> language english math science society\n", - "#> PC1 0.2074983 0.3043604 -0.887261240 0.1301984 0.2452041\n", - "#> PC2 0.2794627 -0.3250521 -0.097642669 0.7026667 -0.5594347\n", - "#> PC3 -0.3061175 -0.6157986 -0.056345381 0.3384462 0.6398152\n", - "#> PC4 0.7649426 -0.4716969 -0.007654992 -0.4180454 0.1324548\n", - "#> PC5 0.4472136 0.4472136 0.447213595 0.4472136 0.4472136" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "summary(my_result)\n", - "#> Importance of components:\n", - "#> PC1 PC2 PC3 PC4 PC5\n", - "#> Standard deviation 38.2644 12.25566 5.58845 1.52970 1.232e-15\n", - "#> Proportion of Variance 0.8885 0.09115 0.01895 0.00142 0.000e+00\n", - "#> Cumulative Proportion 0.8885 0.97963 0.99858 1.00000 1.000e+00" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.1.1 標準化+主成分分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result <- prcomp(\n", - " x = my_data,\n", - " scale = TRUE) # 標準化\n", - "# あるいは\n", - "my_result <- prcomp(\n", - " x = scale(my_data)) # 標準化データ\n", - "\n", - "my_result$x # 主成分スコア\n", - "#> PC1 PC2 ...\n", - "#> A -3.6737215 -0.5688501 ...\n", - "#> B 0.6528793 0.2469258 ...\n", - "#> C 1.5682936 -1.7425981 ...\n", - "#> D 0.2505043 1.6400394 ...\n", - "#> E 0.8861864 -0.1104931 ...\n", - "#> F 0.3158579 0.5349762 ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.1.2 補足:行列計算による再現" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Z <- my_data %>% scale(scale = FALSE) %>% as.matrix # 標準化しない場合\n", - "#Z <- my_data %>% scale(scale = TRUE) %>% as.matrix # 標準化する場合\n", - "\n", - "n <- nrow(my_data)\n", - "S <- var(Z) # 分散共分散行列\n", - "#S <- t(Z) %*% Z / (n - 1) # (同じ結果)\n", - "tmp <- eigen(S) # 固有値と固有ベクトル\n", - "Z %*% tmp$vectors # 主成分スコア(結果は割愛)\n", - "cumsum(tmp$values) / sum(tmp$values) # 累積寄与率\n", - "#> [1] 0.8884833 0.9796285 0.9985801 1.0000000 1.0000000" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "udv <- svd(Z) # 特異値分解\n", - "U <- udv$u\n", - "d <- udv$d\n", - "V <- udv$v\n", - "W <- diag(d)\n", - "\n", - "c(all.equal(Z, U %*% W %*% t(V), check.attributes = FALSE), # 確認1\n", - " all.equal(t(U) %*% U, diag(dim(U)[2])), # 確認2\n", - " all.equal(t(V) %*% V, diag(dim(V)[2]))) # 確認3\n", - "#> [1] TRUE TRUE TRUE\n", - "\n", - "U %*% W # 主成分スコア(結果は割愛)\n", - "\n", - "e <- d^2 / (n - 1) # 分散共分散行列の固有値\n", - "cumsum(e) / sum(e) # 累積寄与率\n", - "#> [1] 0.8884833 0.9796285 0.9985801 1.0000000 1.0000000" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 13.2 クラスタ分析\n", - "\n", - "### 13.2.1 階層的クラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_data <- data.frame(\n", - " x = c( 0, -16, 10, 10),\n", - " y = c( 0, 0, 10, -15),\n", - " row.names = c(\"A\", \"B\", \"C\", \"D\"))\n", - "\n", - "my_result <- my_data %>%\n", - " dist(\"euclidian\") %>% # distだけでも可\n", - " hclust(\"complete\") # hclustだけでも可" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result %>% factoextra::fviz_dend(\n", - " k = 3, # クラスタ数\n", - " rect = TRUE, rect_fill = TRUE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result %>% factoextra::fviz_dend(\n", - " k = 3,\n", - " rect = TRUE, rect_fill = TRUE,\n", - " type = \"phylogenic\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result %>% cutree(3)\n", - "#> A B C D\n", - "#> 1 2 1 3" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.2 階層的クラスタ分析とヒートマップ" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_data <- data.frame(\n", - " language = c( 0, 20, 20, 25, 22, 17),\n", - " english = c( 0, 20, 40, 20, 24, 18),\n", - " math = c(100, 20, 5, 30, 17, 25),\n", - " science = c( 0, 20, 5, 25, 16, 23),\n", - " society = c( 0, 20, 30, 0, 21, 17),\n", - " row.names = c(\"A\", \"B\", \"C\", \"D\", \"E\", \"F\"))\n", - "\n", - "try( # RMarkdownで発生するエラーを回避する.\n", - " my_data %>% scale %>% # 列ごとの標準化\n", - " gplots::heatmap.2(cexRow = 1, cexCol = 1), # ラベルのサイズを指定して描画する.\n", - " silent = TRUE)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.3 非階層的クラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "\n", - "my_data <- data.frame(\n", - " x = c( 0, -16, 10, 10),\n", - " y = c( 0, 0, 10, -15),\n", - " row.names = c(\"A\", \"B\", \"C\", \"D\"))\n", - "\n", - "my_result <- my_data %>% kmeans(3)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "my_result$cluster\n", - "#> A B C D\n", - "#> 2 3 2 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.4 クラスタ数の決定" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "library(factoextra)\n", - "\n", - "my_data <- iris[, -5]\n", - "\n", - "f <- 2:5 %>% map(function(k) {\n", - " my_data %>% kmeans(k) %>%\n", - " fviz_cluster(data = my_data, geom = \"point\") +\n", - " ggtitle(sprintf(\"k = %s\", k))\n", - "})\n", - "gridExtra::grid.arrange(f[[1]], f[[2]], f[[3]], f[[4]], ncol = 2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fviz_nbclust(my_data, kmeans, method = \"wss\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 13.2.5 主成分分析とクラスタ分析" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "library(tidyverse)\n", - "my_data <- iris[, -5] %>% scale\n", - "\n", - "my_result <- prcomp(my_data)$x %>% as.data.frame # 主成分分析\n", - "\n", - "# 非階層的クラスタ分析の場合\n", - "my_result$cluster <- (my_data %>% scale %>% kmeans(3))$cluster %>% as.factor\n", - "\n", - "# 階層的クラスタ分析の場合\n", - "#my_result$cluster <- my_data %>% dist %>% hclust %>% cutree(3) %>% as.factor\n", - "\n", - "my_result %>%\n", - " ggplot(aes(x = PC1, y = PC2, color = cluster)) + # 色でクラスタを表現する.\n", - " geom_point(shape = iris$Species) + # 形で品種を表現する.\n", - " theme(legend.position = \"none\")" - ] - } - ], - "nbformat": 4, - "nbformat_minor": 5, - "metadata": { - "kernelspec": { - "name": "ir", - "display_name": "R" - } - } -} diff --git a/code/R-notebook/r-03.ipynb b/code/R-notebook/r-03.ipynb new file mode 100644 index 0000000..b70855d --- /dev/null +++ b/code/R-notebook/r-03.ipynb @@ -0,0 +1,1434 @@ +{ + "cells": [ + { + "id": "427b8a53", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Google Colaboratory\u306e\u74b0\u5883\u8a2d\u5b9a\n", + "if (file.exists(\"/content\")) {\n", + " options(Ncpus = parallel::detectCores())\n", + " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"furrr\", \"keras\", \"proxy\")\n", + " install.packages(setdiff(packages_to_install, installed_packages))\n", + " install.packages(c(\"ggplot2\"))\n", + "}" + ], + "id": "386318dc-1a4c-4b0a-b66a-6f4d6fbe1f8a" + }, + { + "id": "c88b62b3", + "cell_type": "markdown", + "source": "## 3.1 \u5165\u9580", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "0x10" + ], + "id": "5b4c6e13-6329-404f-80d4-100ec21982fc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "1.23e5" + ], + "id": "c0fdac11-e68b-4048-b064-33b286cb9a4e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "2 * 3" + ], + "id": "7b187fb5-90b7-40e9-bf74-b55017b8244d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "10 / 3" + ], + "id": "d9fa8244-1e4f-4b67-aa7a-5eec327c1cd0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "10 %/% 3 # \u5546\n", + "\n", + "10 %% 3 # \u4f59\u308a" + ], + "id": "f0b33468-c31c-45f7-937d-bf56a404842d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- 2\n", + "y <- 3\n", + "x * y\n", + "\n", + "keras::`%<-%`(c(x, y), c(20, 30)) # \u307e\u3068\u3081\u3066\u540d\u4ed8\u3051\n", + "x * y" + ], + "id": "f8d6b631-f205-479b-b0ea-9f0751ea938a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- 1 + 1\n", + "# \u3053\u306e\u6bb5\u968e\u3067\u306f\u7d50\u679c\u306f\u8868\u793a\u3055\u308c\u306a\u3044\n", + "\n", + "x # \u5909\u6570\u540d\u3092\u8a55\u4fa1\u3059\u308b\uff0e" + ], + "id": "ec7806b8-b300-4312-920b-05591a58353e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_s <- \"abcde\"" + ], + "id": "4a24c434-6d8a-4076-9da5-32e3b897577d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "nchar(my_s)" + ], + "id": "c2b3b526-dc84-40f8-956f-5a4d9ae57b9a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)\n", + "str_c(\"This is \", \"a\", \" pen.\")" + ], + "id": "5fa5882c-e442-4545-b837-2bd649e6b477" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "substr(x = my_s, start = 2, stop = 4)" + ], + "id": "be8e332f-78a4-4019-9dd6-ae4cbea3afcd" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp <- \"%s is %s.\"\n", + "sprintf(tmp, \"This\", \"a pen\")" + ], + "id": "2b67d0ae-cf87-4cdd-81c4-539285d871fd" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "1 <= 2\n", + "\n", + "1 < 0" + ], + "id": "492a05b4-5222-45d5-8b50-b052ec15c9df" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "0.1 + 0.1 + 0.1 == 0.3\n", + "\n", + "all.equal(0.1 + 0.1 + 0.1, 0.3)" + ], + "id": "78311e05-dba9-4fb2-8ba4-6426a57b72fa" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "TRUE & FALSE # \u8ad6\u7406\u7a4d\uff08\u304b\u3064\uff09\n", + "\n", + "TRUE | FALSE # \u8ad6\u7406\u548c\uff08\u307e\u305f\u306f\uff09\n", + "\n", + "!TRUE # \u5426\u5b9a\uff08\u3067\u306a\u3044\uff09" + ], + "id": "a10d2189-9b68-4be8-804d-9a68bab05c18" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ifelse(3 < 5, 0, 10)" + ], + "id": "4797676c-62fe-41aa-9bb3-43b522c46f2f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "getwd()" + ], + "id": "d64191d2-a26d-4bf1-80fe-22c27a8f3370" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "setwd(\"..\")\n", + "getwd()" + ], + "id": "1ae31151-ba6e-4e36-af7b-5f82a7e6d936" + }, + { + "id": "68df6f43", + "cell_type": "markdown", + "source": "## 3.2 \u95a2\u6570", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sqrt(4)" + ], + "id": "00a5f384-0a87-4995-96bf-977ef8f2ff0c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "log(100, 10)" + ], + "id": "471bb672-6ce9-4c62-a378-6f5ba8d67049" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "log(100) # \u81ea\u7136\u5bfe\u6570\n", + "# \u3042\u308b\u3044\u306f\n", + "log(100, exp(1)) # \u7701\u7565\u3057\u306a\u3044\u5834\u5408\n" + ], + "id": "402e63fa-f43e-4889-b826-a5f93902be75" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "log10(100) # \u5e38\u7528\u5bfe\u6570\n", + "\n", + "log2(1024) # \u5e95\u304c2\u306e\u5bfe\u6570" + ], + "id": "5782db57-04ac-4ec9-a11f-8def90a69bb0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)\n", + "4 %>% sqrt" + ], + "id": "7093d76b-22ed-47d2-aef9-9cb284e2c7dc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "exp(log(5)) # \u901a\u5e38\u306e\u66f8\u304d\u65b9\n", + "# \u3042\u308b\u3044\u306f\n", + "5 %>% log %>% exp # \u30d1\u30a4\u30d7\u3092\u4f7f\u3046\u66f8\u304d\u65b9\n" + ], + "id": "0cfa763a-08b0-41a3-84f6-46a6739d4bf3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "f <- function(a, b) {\n", + " a - b\n", + "}" + ], + "id": "f677367b-6089-4bc9-9d6f-ed71134a6576" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "f(3, 5)" + ], + "id": "299ca25d-7945-4032-a62e-ada573761a00" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "f <- function(a, b = 5) {\n", + " a - b\n", + "}\n", + "\n", + "f(3) # f(3, 5)\u3068\u540c\u3058\u3053\u3068" + ], + "id": "31312988-ab61-4894-a328-d40076311563" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "(function(a, b) { a - b })(3, 5)" + ], + "id": "fe323a0c-25f7-4579-904b-e2823bbf4ba3" + }, + { + "id": "19e533c4", + "cell_type": "markdown", + "source": "## 3.3 \u30b3\u30ec\u30af\u30b7\u30e7\u30f3", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- c(\"foo\", \"bar\", \"baz\")" + ], + "id": "2fc62d44-a8a6-4d0f-9ec4-2341a3e7c411" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "length(x)" + ], + "id": "6dc8de13-ca24-4dca-bfe5-808ec3e3e269" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x[2]" + ], + "id": "1faad347-0e23-4cf3-9809-5a27ca2ec25e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x[2] <- \"BAR\"\n", + "x # \u7d50\u679c\u306e\u78ba\u8a8d\n", + "\n", + "x[2] <- \"bar\" # \u5143\u306b\u623b\u3059\uff0e" + ], + "id": "03496f3f-4a6a-407b-9be5-2cf143af099c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x[-2]" + ], + "id": "f70553a8-3e57-4855-a38f-12fd12e33c67" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c(x, \"qux\")" + ], + "id": "c265c22d-0a73-4971-9e7b-6d53e92a49d5" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- c(x, \"qux\")\n", + "x # \u7d50\u679c\u306e\u78ba\u8a8d" + ], + "id": "e5dbc1ab-d0fc-4849-bb6f-d424c5521a51" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "1:5" + ], + "id": "4887a6ca-4696-4dca-8658-172ac1227238" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "seq(from = 0, to = 10, by = 2)" + ], + "id": "145c3b53-bb6e-4369-aaaa-6f334ab9f981" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "seq(from = 0, to = 1, by = 0.5)" + ], + "id": "b702629c-3f1f-4eb8-84dc-7160ba73a133" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "seq(from = 0, to = 100, length.out = 5)" + ], + "id": "516a4c4d-1ace-4ae0-9433-cbe5da90d17d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rep(x = 10, times = 5)" + ], + "id": "bc582b53-5253-4fe1-a162-2e0df26e5b08" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp <- c(\"\u30b0\u30fc\", \"\u30d1\u30fc\", \"\u30b0\u30fc\", \"\u30d1\u30fc\")\n", + "x <- factor(tmp, levels = c(\"\u30b0\u30fc\", \"\u30c1\u30e7\u30ad\", \"\u30d1\u30fc\"))\n", + "x" + ], + "id": "5101cca0-83b2-4b9d-9140-8bda872242b8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- c(2, 3, 5, 7)\n", + "\n", + "x + 10 # \u52a0\u7b97\n", + "\n", + "x * 10 # \u4e57\u7b97" + ], + "id": "1d2c9946-ca36-486c-9eab-79cb5b1a671d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- c(2, 3)\n", + "sin(x)" + ], + "id": "c43fbeb7-888a-49a9-b330-a06b66486894" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- c(2, 3, 5, 7)\n", + "y <- c(1, 10, 100, 1000)\n", + "x + y\n", + "\n", + "x * y" + ], + "id": "ed135a52-4732-4097-b5d1-35c0cdaec394" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sum(x * y)" + ], + "id": "9e39cf36-b2ef-4211-92ba-ac77aa53aecb" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- c(TRUE, FALSE)\n", + "y <- c(TRUE, TRUE)\n", + "x & y" + ], + "id": "e0845380-021b-48ab-9659-38d0c6d56f01" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "u <- c(1, 2, 3)\n", + "v <- c(1, 2, 3)\n", + "w <- c(1, 2, 4)\n", + "\n", + "identical(u, v) # \u5168\u4f53\u306e\u6bd4\u8f03\n", + "\n", + "identical(u, w) # \u5168\u4f53\u306e\u6bd4\u8f03\n", + "\n", + "u == v # \u8981\u7d20\u3054\u3068\u306e\u6bd4\u8f03\n", + "\n", + "u == w # \u8981\u7d20\u3054\u3068\u306e\u6bd4\u8f03" + ], + "id": "cb6274cb-1882-4ca3-9c07-ce8c09108d58" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sum(u == w) # \u540c\u3058\u8981\u7d20\u306e\u6570\n", + "\n", + "mean(u == w) # \u540c\u3058\u8981\u7d20\u306e\u5272\u5408" + ], + "id": "7c06656b-fbb6-464d-8e99-17a1dcb831a7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- list(1, \"two\")" + ], + "id": "e7b27702-78a7-472d-bb9e-31c689913f28" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x[[2]]" + ], + "id": "27dfc78d-15f2-4553-aeb8-0a68091ab7d2" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- list(\"apple\" = \"\u308a\u3093\u3054\",\n", + " \"orange\" = \"\u307f\u304b\u3093\")" + ], + "id": "2e474ba9-517d-412a-aa6a-8f891ce678d3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x[[\"grape\"]] <- \"\u3076\u3069\u3046\"" + ], + "id": "8fba8686-cf88-48bb-8885-e833b10521b3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x$apple\n", + "# \u3042\u308b\u3044\u306f\n", + "x$\"apple\"\n", + "# \u3042\u308b\u3044\u306f\n", + "x[[\"apple\"]]\n", + "# \u3042\u308b\u3044\u306f\n", + "tmp <- \"apple\"\n", + "x[[tmp]]\n" + ], + "id": "d7a289ad-febd-4be2-b31e-cd3e35604d4d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- c(\"foo\", \"bar\", \"baz\")\n", + "y <- x\n", + "y[2] <- \"BAR\" # y\u3092\u66f4\u65b0\u3059\u308b\uff0e\n", + "y\n", + "\n", + "x # x\u306f\u5909\u308f\u3089\u306a\u3044\uff0e" + ], + "id": "f22e618c-3647-49f0-ba13-e6c8e5f50dc7" + }, + { + "id": "62c6a06a", + "cell_type": "markdown", + "source": "## 3.4 \u30c7\u30fc\u30bf\u30d5\u30ec\u30fc\u30e0", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)" + ], + "id": "3e10c5e9-7d47-4407-ac55-f5c8b5179cdc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df <- data.frame(\n", + " name = c(\"A\", \"B\", \"C\", \"D\"),\n", + " english = c( 60, 90, 70, 90),\n", + " math = c( 70, 80, 90, 100),\n", + " gender = c(\"f\", \"m\", \"m\", \"f\"))" + ], + "id": "5fe688bf-9dcd-4bbd-8fbb-0903fe554880" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df <- tribble(\n", + " ~name, ~english, ~math, ~gender,\n", + " \"A\", 60, 70, \"f\",\n", + " \"B\", 90, 80, \"m\",\n", + " \"C\", 70, 90, \"m\",\n", + " \"D\", 90, 100, \"f\")" + ], + "id": "384e74a6-0188-4300-ae5e-5bfdf718dc6b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "head(my_df)\n", + "# \u7d50\u679c\u306f\u5272\u611b" + ], + "id": "46936770-f953-447e-9d5d-9f68b5068264" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dim(my_df) # \u884c\u6570\u3068\u5217\u6570\n", + "\n", + "nrow(my_df) # \u884c\u6570\n", + "\n", + "ncol(my_df) # \u5217\u6570" + ], + "id": "0c62b652-7291-456f-839a-cbbfce7d17fc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2 <- expand.grid(\n", + " X = c(1, 2, 3),\n", + " Y = c(10, 100))\n", + "my_df2" + ], + "id": "102a4ee4-e480-462b-9b71-c0f88744da5f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "colnames(my_df2)" + ], + "id": "30465b06-386b-412e-96be-b48580ac169d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "colnames(my_df2) <- c(\"P\", \"Q\")\n", + "my_df2\n", + "# \u4ee5\u4e0b\u7701\u7565" + ], + "id": "48fd1de1-b9bf-4103-966e-6109142cadc2" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "row.names(my_df)" + ], + "id": "a578d78a-cd46-4aab-937c-1578cb8ce1bc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "row.names(my_df2) <-\n", + " c(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\")\n", + "my_df2\n", + "# \u4ee5\u4e0b\u7701\u7565" + ], + "id": "ee6161b3-9508-4660-92ac-ce5479016245" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df3 <- data.frame(\n", + " english = c( 60, 90, 70, 90),\n", + " math = c( 70, 80, 90, 100),\n", + " gender = c(\"f\", \"m\", \"m\", \"f\"),\n", + " row.names = c(\"A\", \"B\", \"C\", \"D\"))\n", + "my_df3" + ], + "id": "3cf40717-490d-47d7-b1d5-516a9a5a23e0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp <- data.frame(\n", + " name = \"E\",\n", + " english = 80,\n", + " math = 80,\n", + " gender = \"m\")\n", + "my_df2 <- rbind(my_df, tmp)" + ], + "id": "20ac584c-df91-45de-b84c-04d6a2102b5e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2 <- my_df %>%\n", + " mutate(id = c(1, 2, 3, 4))" + ], + "id": "2349c2ed-33d3-42e6-ad75-bb054e1212ab" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df3 <- my_df # \u30b3\u30d4\u30fc\n", + "my_df3[\"id\"] <- c(1, 2, 3, 4) # \u66f4\u65b0\n", + "my_df3 # \u7d50\u679c\u306e\u78ba\u8a8d\uff08\u5272\u611b\uff09" + ], + "id": "05346bd0-fd21-483e-b3eb-f53c405304bb" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df[1, 2]" + ], + "id": "6751160d-a746-4c51-bbb3-70727b664f65" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- my_df[, 2]\n", + "# \u3042\u308b\u3044\u306f\n", + "x <- my_df$english\n", + "# \u3042\u308b\u3044\u306f\n", + "x <- my_df$\"english\"\n", + "# \u3042\u308b\u3044\u306f\n", + "x <- my_df[[\"english\"]]\n", + "# \u3042\u308b\u3044\u306f\n", + "tmp <- \"english\"\n", + "x <- my_df[[tmp]]\n", + "\n", + "x # \u7d50\u679c\u306e\u78ba\u8a8d\uff08\u5272\u611b\uff09" + ], + "id": "e91b0826-9975-44f7-8660-0acabeefa1d9" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- my_df %>% select(name, math)" + ], + "id": "56dbf20e-d1ea-4c3a-88a1-093130f47f37" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- my_df[, c(1, 3)]" + ], + "id": "12d57272-b6c8-492b-a7d1-bf3f3b8bc770" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- my_df %>%\n", + " select(-c(english, gender))\n", + "# \u3042\u308b\u3044\u306f\n", + "x <- my_df[, -c(2, 4)]" + ], + "id": "081a8fa4-620c-403a-9e98-9912826bb624" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- my_df[c(1, 3), ]" + ], + "id": "f5031551-443c-4653-aec4-1f00edc3d9ab" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- my_df[-c(2, 4), ]" + ], + "id": "9096618a-aad3-496e-86b9-0613fa1a9a04" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- my_df[my_df$gender == \"m\", ]\n", + "# \u3042\u308b\u3044\u306f\n", + "x <- my_df %>% filter(gender == \"m\")" + ], + "id": "946b518d-f480-456e-b186-c56af3d6eedc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- my_df[my_df$english > 80 & my_df$gender == \"m\", ]\n", + "# \u3042\u308b\u3044\u306f\n", + "x <- my_df %>% filter(english > 80 & gender == \"m\")" + ], + "id": "1d1a951e-7911-4e7c-ab6d-3d569348c8e0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- my_df[my_df$english == max(my_df$english), ]\n", + "# \u3042\u308b\u3044\u306f\n", + "x <- my_df %>% filter(english == max(my_df$english))" + ], + "id": "2a4982a8-a9ea-4cf9-a603-e09aed97587d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2 <- my_df # \u30b3\u30d4\u30fc\n", + "my_df2[my_df$gender == \"m\", ]$gender <- \"M\"" + ], + "id": "4941b5ef-8b33-4919-98d4-4d57fc3d2c91" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2" + ], + "id": "78a69be3-ccfa-4ca1-ba1c-ed12aeee6782" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- my_df %>% arrange(english)" + ], + "id": "7428b185-ad76-45f2-8a21-26de1b473817" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- my_df %>% arrange(-english)" + ], + "id": "6c9c746a-7606-45e2-8465-0f7019ce50bd" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- c(2, 3, 5, 7, 11, 13, 17, 19, 23,\n", + " 29, 31, 37)\n", + "A <- matrix(\n", + " data = x, # 1\u6b21\u5143\u30c7\u30fc\u30bf\n", + " nrow = 3, # \u884c\u6570\n", + " byrow = TRUE) # \u884c\u3054\u3068\u306e\u751f\u6210\n", + "A" + ], + "id": "18554cee-bffe-413e-a03a-6e23d0cac17d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "A <- my_df[, c(2, 3)] %>% as.matrix\n", + "A" + ], + "id": "18373be3-6eae-47e8-ae09-0ae7391c807e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "as.data.frame(A)" + ], + "id": "d216c433-31a7-40cd-9f52-643462aeb5cb" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "t(A)" + ], + "id": "6a42aa49-3d84-4203-adb4-a821d87512a1" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "t(A) %*% A" + ], + "id": "b1f44ba2-9379-4491-99c1-f2775654b9f3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_wider <- data.frame(\n", + " day = c(25, 26, 27),\n", + " min = c(20, 21, 15),\n", + " max = c(24, 27, 21))" + ], + "id": "0e9d93db-3d9b-4b81-9b4c-1fee29b52ad4" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_longer <- my_wider %>%\n", + " pivot_longer(-day)\n", + "my_longer" + ], + "id": "6a0fccd2-2ff1-4335-9f47-7bbdcd246675" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_longer %>% pivot_wider()" + ], + "id": "3791aeea-74aa-48d5-a105-9906c2ba51b9" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_longer %>%\n", + " ggplot(aes(x = day, y = value,\n", + " color = name)) +\n", + " geom_point() +\n", + " geom_line() +\n", + " ylab(\"temperature\") + # y\u8ef8\u30e9\u30d9\u30eb\n", + " scale_x_continuous(\n", + " breaks = my_longer$day) # x\u8ef8\u76ee\u76db\u308a" + ], + "id": "a3aa19ae-917a-4871-ad01-a286f0342671" + }, + { + "id": "037d1620", + "cell_type": "markdown", + "source": "## 3.5 1\u6b21\u5143\u30c7\u30fc\u30bf\u306e\uff08\u975e\uff09\u985e\u4f3c\u5ea6", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "A <- c(3, 4, 5)\n", + "B <- c(3, 4, 29)\n", + "C <- c(9, -18, 8)\n", + "AB <- B - A\n", + "AC <- C - A\n", + "\n", + "sum(AB^2)^0.5\n", + "\n", + "sum(AC^2)^0.5" + ], + "id": "dc48b736-4c35-4511-9ebc-8409db2624a2" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sum(abs(AB))\n", + "\n", + "sum(abs(AC))" + ], + "id": "b0e22e97-65cd-42bb-9850-7b95e69d15f4" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sum(A * B) /\n", + " sum(A * A)^0.5 / sum(B * B)^0.5\n", + "\n", + "sum(A * C) /\n", + " sum(A * A)^0.5 / sum(C * C)^0.5" + ], + "id": "3750cad3-944d-47cb-be9d-70c355446734" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cor(A, B)\n", + "\n", + "cor(A, C)" + ], + "id": "41dfda02-af5a-470e-8077-1068108571b4" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)\n", + "\n", + "\n", + "\n", + "my_df <- data.frame(\n", + " x = c(3, 3, 9),\n", + " y = c(4, 4, -18),\n", + " z = c(5, 29, 8),\n", + " row.names = c(\"A\", \"B\", \"C\"))\n", + "\n", + "# \u30e6\u30fc\u30af\u30ea\u30c3\u30c9\u8ddd\u96e2\n", + "my_df %>% proxy::dist(\"Euclidean\")\n", + "\n", + "\n", + "# \u30de\u30f3\u30cf\u30c3\u30bf\u30f3\u8ddd\u96e2\n", + "my_df %>% proxy::dist(\"Manhattan\")\n", + "\n", + "\n", + "# \u30b3\u30b5\u30a4\u30f3\u985e\u4f3c\u5ea6\n", + "my_df %>% proxy::simil(\"cosine\")\n", + "\n", + "\n", + "# \u76f8\u95a2\u4fc2\u6570\n", + "my_df %>% proxy::simil(\"correlation\")" + ], + "id": "2176e3cf-1751-4bd1-abf4-3335eebbeb77" + }, + { + "id": "a4fd2b18", + "cell_type": "markdown", + "source": "## 3.6 R\u306e\u30d1\u30c3\u30b1\u30fc\u30b8\uff0cPython\u306e\u30e2\u30b8\u30e5\u30fc\u30eb", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)" + ], + "id": "bb8dc8b6-04a2-4426-8582-12df99a04604" + }, + { + "id": "694ee7ed", + "cell_type": "markdown", + "source": "## 3.7 \u53cd\u5fa9\u51e6\u7406", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)" + ], + "id": "80075ce6-afe5-4e75-9c40-3802ebd03ce0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "f1 <- function(x) {\n", + " tmp <- runif(x)\n", + " mean(tmp)\n", + "}\n", + "\n", + "f1(10) # \u52d5\u4f5c\u78ba\u8a8d" + ], + "id": "2765e2be-960b-4ad9-b092-f9f0a8029741" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "replicate(n = 3, expr = f1(10))" + ], + "id": "593f8447-1fba-4c52-8d65-8625d2504d38" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rep(x = f1(10), times = 3)" + ], + "id": "b86885a7-5a46-4180-8846-f41d794eca6d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "v <- c(5, 10, 100)\n", + "v %>% map_dbl(f1)" + ], + "id": "8a03dfd2-9bca-4d5a-b570-f44f37d59c66" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rep(x = 10, times = 3) %>% map_dbl(f1)\n", + "# \u7d50\u679c\u306f\u5272\u611b" + ], + "id": "99c22e7f-d0dc-4813-9fee-7b1ce15f2c8b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "f2 <- function(n) {\n", + " tmp <- runif(n)\n", + " list(x = n,\n", + " p = mean(tmp),\n", + " q = sd(tmp))\n", + "}\n", + "\n", + "f2(10) # \u52d5\u4f5c\u78ba\u8a8d" + ], + "id": "e28113b9-737b-457e-8fdf-2da38c34d12b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "v <- c(5, 10, 100)\n", + "v %>% map_dfr(f2)" + ], + "id": "fe5c2a94-0f2f-4fb7-8aa6-f24e08a73e53" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "f3 <- function(x, y) {\n", + " tmp <- runif(x, min = 1,\n", + " max = y + 1) %>%\n", + " as.integer\n", + " list(x = x,\n", + " y = y,\n", + " p = mean(tmp),\n", + " q = sd(tmp))\n", + "}\n", + "\n", + "f3(x = 10, y = 6) # \u52d5\u4f5c\u78ba\u8a8d" + ], + "id": "b4d8d5c5-b8b8-44c8-a98f-1b83156fcb75" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df <- data.frame(\n", + " x = c(5, 10, 100, 5, 10, 100),\n", + " y = c(6, 6, 6, 12, 12, 12))\n", + "\n", + "my_df %>% pmap_dfr(f3)" + ], + "id": "9f29ff4d-00af-4f11-bd24-ff894586a586" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(furrr)\n", + "plan(multisession) # \u6e96\u5099\n", + "\n", + "v <- c(5, 10, 100)\n", + "v %>% future_map_dbl(f1, .options =\n", + " furrr_options(seed = TRUE))\n", + "# \u7d50\u679c\u306f\u5272\u611b" + ], + "id": "a955b3e7-e570-4e9b-98ef-66bfebf4e404" + }, + { + "id": "268a1e01", + "cell_type": "markdown", + "source": "## 3.8 \u305d\u306e\u4ed6", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- 123\n", + "typeof(x)" + ], + "id": "88b936c9-1f20-49d6-b8f2-6c9cd860b4c7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "?log\n", + "# \u3042\u308b\u3044\u306f\n", + "help(log)" + ], + "id": "db8dac41-2f70-4cd7-ab4c-da6d56a6118d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "v <- c(1, NA, 3)\n", + "v" + ], + "id": "7777030f-0c33-41d9-89d1-7ac5f6691412" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "is.na(v[2])\n", + "\n", + "v[2] == NA # \u8aa4\u308a" + ], + "id": "a67616b5-86cb-4dce-a23b-5fd5ee782591" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "ir", + "display_name": "R" + } + } +} \ No newline at end of file diff --git a/code/R-notebook/r-04.ipynb b/code/R-notebook/r-04.ipynb new file mode 100644 index 0000000..2e37ba7 --- /dev/null +++ b/code/R-notebook/r-04.ipynb @@ -0,0 +1,878 @@ +{ + "cells": [ + { + "id": "d9ae0e80", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Google Colaboratory\u306e\u74b0\u5883\u8a2d\u5b9a\n", + "if (file.exists(\"/content\")) {\n", + " options(Ncpus = parallel::detectCores())\n", + " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"exactci\", \"ggmosaic\", \"pastecs\", \"psych\", \"vcd\")\n", + " install.packages(setdiff(packages_to_install, installed_packages))\n", + "}" + ], + "id": "4ede4e87-2b73-4e28-8a05-787e002fdef6" + }, + { + "id": "8fd64160", + "cell_type": "markdown", + "source": "## 4.1 \u8a18\u8ff0\u7d71\u8a08", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- c(165, 170, 175, 180, 185)\n", + "mean(x) # \u5e73\u5747" + ], + "id": "0ec724c9-b391-4536-b4bd-8c6b8b08ce29" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "n <- length(x) # \u30b5\u30f3\u30d7\u30eb\u30b5\u30a4\u30ba\n", + "sum(x) / n" + ], + "id": "74033f13-8aba-4cc5-8ed3-5a1ff8aba08d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y <- c(173, 174, 175, 176, 177)\n", + "mean(y)" + ], + "id": "088e2be3-59ef-4711-9edb-56eef7c9c20f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "var(x) # x\u306e\u5206\u6563\n", + "\n", + "var(y) # y\u306e\u5206\u6563" + ], + "id": "f7e420b9-1405-4835-8fbc-31efbc1fcd93" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sum((x - mean(x))^2) / (n - 1)" + ], + "id": "292265a7-c61a-49fd-a77f-e42b65005f07" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sd(x) # x\u306e\u6a19\u6e96\u504f\u5dee\n", + "\n", + "sd(y) # y\u306e\u6a19\u6e96\u504f\u5dee" + ], + "id": "ec48ed6d-d5b0-42d7-bf88-53e5f2ba6388" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "var(x)**0.5 # x\u306e\u6a19\u6e96\u504f\u5dee" + ], + "id": "6f0042c8-01c2-4e3a-a09f-c14a5d7a9831" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "psych::describe(x)\n", + "\n", + "# \u3042\u308b\u3044\u306f\n", + "\n", + "pastecs::stat.desc(x)" + ], + "id": "6d0e4e18-7e48-4782-a5c8-8ec078aa455d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "quantile(x)" + ], + "id": "6eac383d-bb67-415b-ac71-d97a2036b1fe" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- c(165, 170, 175, 180, 185)\n", + "\n", + "var(x) # \u4e0d\u504f\u5206\u6563\n", + "\n", + "mean((x - mean(x))^2) # \u6a19\u672c\u5206\u6563\n", + "# \u3042\u308b\u3044\u306f\n", + "n <- length(x)\n", + "var(x) * (n - 1) / n # \u6a19\u672c\u5206\u6563" + ], + "id": "da351ea6-9b3b-44ac-aa9e-53d89eb473cc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sd(x) # \u221a\u4e0d\u504f\u5206\u6563\n", + "\n", + "mean((x - mean(x))^2)^0.5 # \u221a\u6a19\u672c\u5206\u6563\n", + "# \u3042\u308b\u3044\u306f\n", + "sd(x) * sqrt((n - 1) / n) # \u221a\u6a19\u672c\u5206\u6563" + ], + "id": "2d7bfaca-2874-4de5-bb9a-257422228c17" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sd(x) / length(x)**0.5" + ], + "id": "0c649464-5d13-43e8-b486-803f9e279075" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)\n", + "\n", + "my_df <- data.frame(\n", + " name = c(\"A\", \"B\", \"C\", \"D\"),\n", + " english = c( 60, 90, 70, 90),\n", + " math = c( 70, 80, 90, 100),\n", + " gender = c(\"f\", \"m\", \"m\", \"f\"))" + ], + "id": "500c4ca7-00af-4904-947f-4702b8d0b069" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "var(my_df$english)" + ], + "id": "25040386-ad11-4df3-b272-dde3606efedc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# \u7d50\u679c\u306f\u30d9\u30af\u30bf\n", + "my_df[, c(2, 3)] %>% sapply(var)\n", + "\n", + "# \u7d50\u679c\u306f\u30ea\u30b9\u30c8\n", + "my_df[, c(2, 3)] %>% lapply(var)\n", + "\n", + "# \u7d50\u679c\u306f\u30c7\u30fc\u30bf\u30d5\u30ec\u30fc\u30e0\n", + "my_df[, c(2, 3)] %>% # 2, 3\u5217\u76ee\n", + " summarize(across( # \u306e\n", + " everything(), # \u5168\u3066\u306e\n", + " var)) # \u4e0d\u504f\u5206\u6563\n", + "# \u3042\u308b\u3044\u306f\n", + "my_df %>% # \u30c7\u30fc\u30bf\u30d5\u30ec\u30fc\u30e0\n", + " summarize(across( # \u306e\n", + " where(is.numeric), # \u6570\u5024\u306e\u5217\u306e\n", + " var)) # \u4e0d\u504f\u5206\u6563\n", + "# \u3042\u308b\u3044\u306f\n", + "my_df %>% # \u30c7\u30fc\u30bf\u30d5\u30ec\u30fc\u30e0\n", + " summarize(across( # \u306e\n", + " where(is.numeric), # \u6570\u5024\u306e\u5217\u306e\n", + " function(x) { var(x) })) # \u4e0d\u504f\u5206\u6563\n" + ], + "id": "14ce9ae1-c7e3-4bfc-9c41-8a453837c195" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "psych::describe(my_df)\n", + "\n", + "# \u3042\u308b\u3044\u306f\n", + "\n", + "pastecs::stat.desc(my_df)\n", + "# \u4ee5\u4e0b\u7701\u7565" + ], + "id": "6ce720c0-ac90-442c-8d10-644eb8582822" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "table(my_df$gender)\n" + ], + "id": "3648a011-3fd1-4d72-b109-b03263207a60" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2 <- data.frame(\n", + " gender = my_df$gender,\n", + " excel = my_df$math >= 80)\n", + "table(my_df2)\n" + ], + "id": "d6d5ef29-e3be-488d-9591-c68649188c95" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df %>% group_by(gender) %>%\n", + " summarize(across(\n", + " where(is.numeric), mean),\n", + " .groups = \"drop\") # \u30b0\u30eb\u30fc\u30d7\u5316\u89e3\u9664\n" + ], + "id": "3ea6c820-8e05-45ea-af9c-554424a79b9b" + }, + { + "id": "7d85ef9f", + "cell_type": "markdown", + "source": "## 4.2 \u30c7\u30fc\u30bf\u306e\u53ef\u8996\u5316", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "head(iris)" + ], + "id": "9b748598-9ea9-4a61-9a71-6397bd327988" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "hist(iris$Sepal.Length)" + ], + "id": "303a40c6-cac8-4bec-ba6c-a8d77cbd4aad" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- c(10, 20, 30)\n", + "hist(x, breaks = 2) # \u968e\u7d1a\u6570\u306f2" + ], + "id": "12f68e13-9dd9-48c8-b355-de6decc3c53d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- iris$Sepal.Length\n", + "tmp <- seq(min(x), max(x),\n", + " length.out = 10)\n", + "hist(x, breaks = tmp, right = FALSE)" + ], + "id": "90610aa1-5ad5-4423-9a73-6fc5ccf32f26" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plot(iris$Sepal.Length,\n", + " iris$Sepal.Width)" + ], + "id": "f5edf6b7-e6b7-4a95-8bc2-23ee85597696" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "boxplot(iris[, -5])" + ], + "id": "ec601d41-c642-41e6-8985-de78cbef77bc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)\n", + "my_df <- psych::describe(iris[, -5])\n", + "my_df %>% select(mean, sd, se)" + ], + "id": "8bc3c6a1-c9a0-480d-aeee-dd38821aab0e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp <- rownames(my_df)\n", + "my_df %>% ggplot(aes(x = factor(tmp, levels = tmp), y = mean)) +\n", + " geom_col() +\n", + " geom_errorbar(aes(ymin = mean - se, ymax = mean + se)) +\n", + " xlab(NULL)" + ], + "id": "3e3f2cc8-740d-4764-9eb2-067f863a9e33" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_group <- iris %>% group_by(Species) # \u54c1\u7a2e\u3054\u3068\u306b\uff0c\n", + "\n", + "my_df <- my_group %>% # \u5404\u5909\u6570\u306e\uff0c\u5e73\u5747\u3068\n", + " summarize(across(everything(), mean)) %>%\n", + " pivot_longer(-Species)\n", + "\n", + "tmp <- my_group %>% # \u6a19\u6e96\u8aa4\u5dee\u3092\u6c42\u3081\u308b\uff0e\n", + " summarize(across(everything(), ~ sd(.) / length(.)**0.5)) %>%\n", + " pivot_longer(-Species)\n", + "\n", + "my_df$se <- tmp$value\n", + "head(my_df)" + ], + "id": "e0b4ddd5-1e34-410a-b116-98eaf56dac22" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df %>%\n", + " ggplot(aes(x = Species, y = value, fill = name)) +\n", + " geom_col(position = \"dodge\") +\n", + " geom_errorbar(aes(ymin = value - se, ymax = value + se), position = \"dodge\")" + ], + "id": "61248896-261d-4c2e-9530-acd980d7abbe" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# \u5404\u5909\u6570\u306e\u5e73\u5747\n", + "iris %>% pivot_longer(-Species) %>%\n", + " ggplot(aes(x = name, y = value)) +\n", + " geom_bar(stat = \"summary\", fun = mean) +\n", + " stat_summary(geom = \"errorbar\", fun.data = mean_se) +\n", + " xlab(NULL)\n", + "\n", + "# \u5404\u5909\u6570\u306e\u5e73\u5747\uff08\u54c1\u7a2e\u3054\u3068\uff09\n", + "iris %>% pivot_longer(-Species) %>%\n", + " ggplot(aes(x = Species, y = value, fill = name)) +\n", + " geom_bar(stat = \"summary\", fun = mean, position = \"dodge\") +\n", + " stat_summary(geom = \"errorbar\", fun.data = mean_se, position = \"dodge\")" + ], + "id": "4bc2b38a-e784-465e-ba3e-d7b8f855f556" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df <- data.frame(\n", + " Species = iris$Species,\n", + " w_Sepal = iris$Sepal.Width > 3)\n", + "table(my_df) # \u5206\u5272\u8868\n", + "\n", + "mosaicplot(\n", + " formula = ~ Species + w_Sepal,\n", + " data = my_df)" + ], + "id": "c038396a-3606-40cf-a574-0ea1eaf5d203" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(vcd)\n", + "vcd::mosaic(formula = ~w_Sepal + Species, data = my_df,\n", + " labeling = labeling_values)" + ], + "id": "034441b9-8e24-42f6-a884-ffb8f4a0486e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "curve(x^3 - x, -2, 2)" + ], + "id": "23e4d0bb-b011-43f2-ba3f-d52efe8ff20f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- iris$Sepal.Length\n", + "tmp <- seq(min(x), max(x),\n", + " length.out = 10)\n", + "iris %>%\n", + " ggplot(aes(x = Sepal.Length)) +\n", + " geom_histogram(breaks = tmp,\n", + " closed = \"left\")" + ], + "id": "abd2b667-13fa-455c-b476-80683dc54ae2" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "iris %>%\n", + " ggplot(aes(x = Sepal.Length,\n", + " y = Sepal.Width)) +\n", + " geom_point()" + ], + "id": "18073cf2-e7e9-4bce-b4ee-56a35e3c3681" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "iris %>%\n", + " pivot_longer(-Species) %>%\n", + " ggplot(aes(\n", + " x = factor(name,\n", + " levels = names(iris)),\n", + " y = value)) +\n", + " geom_boxplot() +\n", + " xlab(NULL)" + ], + "id": "a25c3127-7ec2-46a3-8257-82db43a1a9bd" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(ggmosaic)\n", + "my_df <- data.frame(\n", + " Species = iris$Species,\n", + " w_Sepal = iris$Sepal.Width > 3)\n", + "my_df %>%\n", + " ggplot() +\n", + " geom_mosaic(\n", + " aes(x = product(w_Sepal, Species)))" + ], + "id": "4db99dbb-217a-464c-95f4-0fb746877fde" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "f <- function(x) { x^3 - x }\n", + "data.frame(x = c(-2, 2)) %>%\n", + " ggplot(aes(x = x)) +\n", + " stat_function(fun = f)" + ], + "id": "ab2bdfe6-ad01-4565-805d-7aba21866a28" + }, + { + "id": "53b3bf53", + "cell_type": "markdown", + "source": "## 4.3 \u4e71\u6570", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- sample(x = 1:6, # \u7bc4\u56f2\n", + " size = 10000, # \u4e71\u6570\u306e\u6570\n", + " replace = TRUE) # \u91cd\u8907\u3042\u308a\n", + "hist(x, breaks = 0:6) # \u30d2\u30b9\u30c8\u30b0\u30e9\u30e0" + ], + "id": "8ec8d8dd-45aa-4906-be9b-241dac935286" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- runif(min = 0, # \u6700\u5c0f\n", + " max = 1, # \u6700\u5927\n", + " n = 1000) # \u4e71\u6570\u306e\u6570\n", + "hist(x)" + ], + "id": "1896e61c-0255-4f1d-8b3c-61e31af22d11" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x <- as.integer( # \u6574\u6570\u306b\u5909\u63db\n", + " runif(min = 1, # \u6700\u5c0f\n", + " max = 7, # \u6700\u5927 + 1\n", + " n = 1000)) # \u4e71\u6570\u306e\u6570\n", + "hist(x, breaks = 0:6) # \u7d50\u679c\u306f\u5272\u611b" + ], + "id": "6b907ea1-7edd-43f3-a2b4-23b2887e79ae" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "n <- 100\n", + "p <- 0.5\n", + "r <- 10000\n", + "x <- rbinom(size = n, # \u8a66\u884c\u56de\u6570\n", + " prob = p, # \u78ba\u7387\n", + " n = r) # \u4e71\u6570\u306e\u6570\n", + "hist(x, breaks = max(x) - min(x))" + ], + "id": "1a981fd1-6605-4561-949f-9ac55dd531f9" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "r <- 10000\n", + "x <- rnorm(mean = 50, # \u5e73\u5747\n", + " sd = 5, # \u6a19\u6e96\u504f\u5dee\n", + " n = r) # \u4e71\u6570\u306e\u6570\n", + "hist(x, breaks = 40)" + ], + "id": "681090c9-fc60-40b7-be59-44ebf547ae52" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)\n", + "\n", + "f <- function(k) {\n", + " n <- 10000\n", + " tmp <- replicate(n = n, expr = g(rnorm(n = k, sd = 3)))\n", + " list(k = k,\n", + " mean = mean(tmp), # \u5e73\u5747\n", + " se = sd(tmp) / sqrt(n)) # \u6a19\u6e96\u8aa4\u5dee\n", + "}" + ], + "id": "568347fb-190d-472f-ab84-f8f9defb8ec7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "g <- var\n", + "c(10, 20, 30) %>% map_dfr(f)" + ], + "id": "53d6cb95-4f59-437a-978e-91fec3a30d30" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "g <- sd\n", + "c(5, 10, 15, 20) %>% map_dfr(f)" + ], + "id": "74e0611e-508e-4532-a6b0-42b7398f3f1a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "g <- function(x) {\n", + " n <- length(x)\n", + " sd(x) *\n", + " sqrt((n - 1) / 2) *\n", + " gamma((n - 1) / 2) /\n", + " gamma(n / 2)\n", + "}\n", + "c(10, 20, 30) %>% map_dfr(f)" + ], + "id": "ba68bded-a37d-426c-b3c5-d83b3ac411d7" + }, + { + "id": "40813453", + "cell_type": "markdown", + "source": "## 4.4 \u7d71\u8a08\u7684\u63a8\u6e2c", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(exactci)\n", + "library(tidyverse)\n", + "\n", + "a <- 0.05 # \u6709\u610f\u6c34\u6e96\n", + "binom.exact(x = 2, # \u5f53\u305f\u3063\u305f\u56de\u6570\n", + " n = 15, # \u304f\u3058\u3092\u5f15\u3044\u305f\u56de\u6570\n", + " p = 4 / 10, # \u5f53\u305f\u308b\u78ba\u7387\uff08\u4eee\u8aac\uff09\n", + " plot = TRUE, # p\u5024\u306e\u63cf\u753b\uff08\u7d50\u679c\u306f\u6b21\u9805\u306b\u63b2\u8f09\uff09\n", + " conf.level = 1 - a, # \u4fe1\u983c\u4fc2\u6570\uff08\u30c7\u30d5\u30a9\u30eb\u30c8\uff09\n", + " tsmethod = \"minlike\", # p\u5024\u306e\u5b9a\u7fa9\n", + " alternative = \"two.sided\") # \u4e21\u5074\u691c\u5b9a\uff08\u30c7\u30d5\u30a9\u30eb\u30c8\uff09\n", + " # \u5de6\u7247\u5074\u691c\u5b9a\u306a\u3089'less'\n", + " # \u53f3\u7247\u5074\u691c\u5b9a\u306a\u3089'greater'\n" + ], + "id": "b4805e83-abe1-4578-8726-712e4350d4da" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "t <- 4 / 10 # \u5f53\u305f\u308b\u78ba\u7387\n", + "n <- 15 # \u304f\u3058\u3092\u5f15\u3044\u305f\u56de\u6570\n", + "x <- 0:n # \u5f53\u305f\u3063\u305f\u56de\u6570\n", + "my_pr <- dbinom(x, n, t) # x\u56de\u5f53\u305f\u308b\u78ba\u7387\n", + "my_pr2 <- dbinom(2, n, t) # 2\u56de\u5f53\u305f\u308b\u78ba\u7387\n", + "\n", + "my_data <- data.frame(x = x,\n", + " probability = my_pr,\n", + " color = my_pr <= my_pr2) # \u5f53\u305f\u308b\u78ba\u7387\u304c\uff0c2\u56de\u5f53\u305f\u308b\u78ba\u7387\u4ee5\u4e0b\n", + "\n", + "my_data %>% ggplot(aes(x = x, y = probability, color = color)) +\n", + " geom_point(size = 3) +\n", + " geom_linerange(aes(ymin = 0, ymax = probability), ) + # \u5782\u76f4\u7dda\n", + " geom_hline(yintercept = my_pr2) + # \u6c34\u5e73\u7dda\n", + " theme(legend.position = \"none\") # \u51e1\u4f8b\u3092\u8868\u793a\u3057\u306a\u3044\uff0e" + ], + "id": "6cd423dd-9186-4557-a613-baf750bed67c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# \u524d\u9805\u306e\u7d50\u679c\uff08\u518d\u63b2\uff09" + ], + "id": "ae8a3627-07e0-44c5-9aee-12f84ae0f7b8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# \u524d\u9805\u5192\u982d\u306e\u30b3\u30fc\u30c9" + ], + "id": "e358f142-d21d-4264-9bb0-eeceaf975ccd" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "X <- c(32.1, 26.2, 27.5, 31.8, 32.1, 31.2, 30.1, 32.4, 32.3, 29.9,\n", + " 29.6, 26.6, 31.2, 30.9, 29.3)\n", + "Y <- c(35.4, 34.6, 31.1, 32.4, 33.3, 34.7, 35.3, 34.3, 32.1, 28.3,\n", + " 33.3, 30.5, 32.6, 33.3, 32.2)\n", + "\n", + "t.test(x = X, y = Y,\n", + " conf.level = 0.95, # \u4fe1\u983c\u4fc2\u6570\uff08\u30c7\u30d5\u30a9\u30eb\u30c8\uff09\n", + " paired = TRUE, # \u5bfe\u6a19\u672c\u3067\u3042\u308b\uff0e\n", + " alternative = \"two.sided\") # \u4e21\u5074\u691c\u5b9a\uff08\u30c7\u30d5\u30a9\u30eb\u30c8\uff09\n", + " # \u5de6\u7247\u5074\u691c\u5b9a\u306a\u3089'less'\n", + " # \u53f3\u7247\u5074\u691c\u5b9a\u306a\u3089'greater'\n" + ], + "id": "00e239c7-5043-435a-9434-ad8c3f87bd41" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "t.test(x = X, y = Y,\n", + " paired = FALSE, # \u5bfe\u6a19\u672c\u3067\u306f\u306a\u3044\uff08\u30c7\u30d5\u30a9\u30eb\u30c8\uff09\uff0e\n", + " var.equal = TRUE, # \u7b49\u5206\u6563\u3092\u4eee\u5b9a\u3059\u308b\uff0e\u4eee\u5b9a\u3057\u306a\u3044\u306a\u3089FALSE\uff08\u30c7\u30d5\u30a9\u30eb\u30c8\uff09\uff0e\n", + " alternative = \"two.sided\",\n", + " conf.level = 0.95)\n" + ], + "id": "6257f789-5e84-4e61-9ab8-02fc0bcd7586" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", + " \"/fromzero/master/data/smoker.csv\")\n", + "my_data <- read_csv(my_url)" + ], + "id": "c728218c-66b7-439e-bd10-daf45d1463f3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "head(my_data)" + ], + "id": "0aa8154a-8424-4604-ae96-6b58e76e6a06" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_table <- table(my_data)\n", + "my_table" + ], + "id": "ae9d7d55-910a-4a6a-b768-6186344f192c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "chisq.test(my_table, correct = FALSE)\n" + ], + "id": "7b939389-fa5a-4f4a-a30a-1ae56d7c6320" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "X <- rep(0:1, c(13, 2)) # \u624b\u98061\n", + "X\n", + "\n", + "tmp <- sample(X, size = length(X), replace = TRUE) # \u624b\u98062\n", + "tmp\n", + "\n", + "sum(tmp) # \u624b\u98063\n", + "\n", + "n <- 10^5\n", + "result <- replicate(n, sum(sample(X, size = length(X), replace = TRUE))) # \u624b\u98064" + ], + "id": "07f2f432-81f6-403c-9d8b-532b6fd4a8c6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "hist(x = result, breaks = 0:15,\n", + " right = FALSE)" + ], + "id": "bbd99c33-56df-44b1-86a8-f32b780f3b8f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "quantile(result, c(0.025, 0.975))" + ], + "id": "01402460-bb97-45a4-adcf-fae234bb9974" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "ir", + "display_name": "R" + } + } +} \ No newline at end of file diff --git a/code/R-notebook/r-05.ipynb b/code/R-notebook/r-05.ipynb new file mode 100644 index 0000000..f324a89 --- /dev/null +++ b/code/R-notebook/r-05.ipynb @@ -0,0 +1,366 @@ +{ + "cells": [ + { + "id": "31d06f8e", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Google Colaboratory\u306e\u74b0\u5883\u8a2d\u5b9a\n", + "if (file.exists(\"/content\")) {\n", + " options(Ncpus = parallel::detectCores())\n", + " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"caret\")\n", + " install.packages(setdiff(packages_to_install, installed_packages))\n", + "}" + ], + "id": "c48e0b71-1b4e-4087-8cf1-b22fccb33212" + }, + { + "id": "7184d23b", + "cell_type": "markdown", + "source": "## 5.1 \u30c7\u30fc\u30bf\u306e\u8aad\u307f\u8fbc\u307f", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)\n", + "system(str_c(\"wget https://raw.githubusercontent.com/taroyabuki\",\n", + " \"/fromzero/master/data/exam.csv\"))" + ], + "id": "525d0c9b-e0b2-45c1-af92-7eac47b9cd44" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df <- read_csv(\"exam.csv\")\n", + "# \u3042\u308b\u3044\u306f\n", + "my_df <- read.csv(\"exam.csv\",\n", + " stringsAsFactors = FALSE)\n", + "\n", + "my_df" + ], + "id": "2f8a4853-78aa-495a-9ed1-34911e5dcab3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", + " \"/fromzero/master/data/exam.csv\")\n", + "my_df <- read_csv(my_url)\n", + "# \u3042\u308b\u3044\u306f\n", + "my_df <- read.csv(my_url, stringsAsFactors = FALSE)" + ], + "id": "20eca9cd-ee4d-4e86-b58b-4e003efe5934" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2 <- read.csv(\n", + " file = \"exam.csv\",\n", + " stringsAsFactors = FALSE,\n", + " row.names = 1)\n", + "my_df2" + ], + "id": "8ef97f65-762d-4c53-83dd-0aa330835553" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df %>% write_csv(\"exam2.csv\")\n", + "# \u3042\u308b\u3044\u306f\n", + "my_df %>% write.csv(\n", + " file = \"exam2.csv\",\n", + " row.names = FALSE)" + ], + "id": "3842cb8b-af46-4166-a5b6-2fde4d3e964c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2 %>% write.csv(\"exam3.csv\")" + ], + "id": "f189b55d-1b00-4ec3-9892-bb0e209cd239" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df <- read_csv(file = \"exam.csv\",\n", + " locale = locale(encoding = \"UTF-8\"))\n", + "# \u3042\u308b\u3044\u306f\n", + "my_df <- read.csv(file = \"exam.csv\",\n", + " stringsAsFactors = FALSE,\n", + " fileEncoding = \"UTF-8\")" + ], + "id": "7460d645-4278-40d5-bf95-c1cdeb71a10f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df %>% write_csv(\"exam2.csv\")\n", + "# \u3042\u308b\u3044\u306f\n", + "my_df %>% write.csv(file = \"exam2.csv\", row.names = FALSE,\n", + " fileEncoding = \"UTF-8\")" + ], + "id": "18849e35-32f8-438e-b6e7-e781e716ce17" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_url <- \"https://taroyabuki.github.io/fromzero/exam.html\"\n", + "my_tables <- xml2::read_html(my_url) %>% rvest::html_table()" + ], + "id": "cc537325-68e4-4064-995e-13f8143d22a9" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_tables" + ], + "id": "1d86d62c-e31f-428d-a77c-4f3832f820d6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp <- my_tables[[1]]\n", + "tmp" + ], + "id": "4da57aa6-5186-41fa-8446-d697dbf3e3d0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# 1\u884c\u76ee\u306e\u30c7\u30fc\u30bf\u3092\u4f7f\u3063\u3066\u5217\u306e\u540d\u524d\u3092\u4ed8\u3051\u76f4\u3059\uff0e\n", + "colnames(tmp) <- tmp[1, ]\n", + "\n", + "# 1\u884c\u76ee\u30681\u5217\u76ee\u3092\u524a\u9664\u3059\u308b\uff0e\n", + "my_data <- tmp[-1, -1]\n", + "my_data" + ], + "id": "cd9c475b-c01d-4c98-8516-ca03ccfee6aa" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(jsonlite)\n", + "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", + " \"/fromzero/master/data/exam.json\")\n", + "my_data <- fromJSON(my_url)\n", + "#my_data <- fromJSON(\"exam.json\") # \uff08\u30d5\u30a1\u30a4\u30eb\u3092\u4f7f\u3046\u5834\u5408\uff09\n", + "my_data" + ], + "id": "81afd975-d123-4855-9333-ded0cb9625f7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(xml2)\n", + "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", + " \"/fromzero/master/data/exam.xml\")\n", + "my_xml <- read_xml(my_url) # XML\u30c7\u30fc\u30bf\u306e\u8aad\u307f\u8fbc\u307f\n", + "#my_xml <- read_xml(\"exam.xml\") # \uff08\u30d5\u30a1\u30a4\u30eb\u3092\u4f7f\u3046\u5834\u5408\uff09\n", + "xml_ns(my_xml) # \u540d\u524d\u7a7a\u9593\u306e\u78ba\u8a8d\uff08d1\uff09" + ], + "id": "fe546b26-f21e-4f03-80c7-8751e577dbb9" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_records <- xml_find_all(my_xml, \".//d1:record\")" + ], + "id": "75481c20-aa1b-4b1b-8141-75ff8f35a87a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "f <- function(record) {\n", + " tmp <- xml_attrs(record) # \u5c5e\u6027\u3092\u5168\u3066\u53d6\u308a\u51fa\u3057\uff0c\n", + " xml_children(record) %>% walk(function(e) {\n", + " tmp[xml_name(e)] <<- xml_text(e) # \u5b50\u8981\u7d20\u306e\u540d\u524d\u3068\u5185\u5bb9\u3092\u8ffd\u52a0\u3059\u308b\uff0e\n", + " })\n", + " tmp\n", + "}" + ], + "id": "cb57db3a-6b30-492b-aa70-857ebefb0430" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data <- my_records %>% map_dfr(f)\n", + "my_data$english <- as.numeric(my_data$english)\n", + "my_data$math <- as.numeric(my_data$math)\n", + "my_data" + ], + "id": "135bd1e0-4ff3-48b5-b69a-013bfe993883" + }, + { + "id": "7543154e", + "cell_type": "markdown", + "source": "## 5.2 \u30c7\u30fc\u30bf\u306e\u5909\u63db", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x1 <- c(1, 2, 3)\n", + "\n", + "z1 <- scale(x1)\n", + "# \u3042\u308b\u3044\u306f\n", + "z1 <- (x1 - mean(x1)) / sd(x1)\n", + "\n", + "z1" + ], + "id": "ef19c55f-67d8-4a35-8703-c45cb097dd11" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c(mean(z1), sd(z1))" + ], + "id": "1667bb1b-e924-4b92-a23d-af27e7e95978" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "z1 * sd(x1) + mean(x1)" + ], + "id": "6a004ca1-36bc-4cec-b2ec-12420de1fee3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x2 <- c(1, 3, 5)\n", + "z2 <- (x2 - mean(x1)) / sd(x1)\n", + "c(mean(z2), sd(z2))" + ], + "id": "250e7554-b5b6-41de-a5c2-472dcd43f71c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "\n", + "my_df <- data.frame(\n", + " id = c(1, 2, 3),\n", + " class = as.factor(\n", + " c(\"A\", \"B\", \"C\")))\n", + "\n", + "my_enc <- my_df %>%\n", + " dummyVars(formula = ~ .)\n", + "\n", + "my_enc %>% predict(my_df)" + ], + "id": "52302e1e-232a-40de-8ae9-fd8a1e4ad23b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_df2 <- data.frame(\n", + " id = c( 4 , 5 , 6 ),\n", + " class = c(\"B\", \"C\", \"B\"))\n", + "my_enc %>% predict(my_df2)" + ], + "id": "3f88cfab-47fe-44c9-b3d5-57e08535ef4d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_enc <- my_df %>%\n", + " dummyVars(formula = ~ .,\n", + " fullRank = TRUE)\n", + "my_enc %>% predict(my_df)\n", + "\n", + "my_enc %>% predict(my_df2)" + ], + "id": "1078cc35-b89f-4b9b-86c4-a3094c5c8f08" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "ir", + "display_name": "R" + } + } +} \ No newline at end of file diff --git a/code/R-notebook/r-06.ipynb b/code/R-notebook/r-06.ipynb new file mode 100644 index 0000000..ee34825 --- /dev/null +++ b/code/R-notebook/r-06.ipynb @@ -0,0 +1,47 @@ +{ + "cells": [ + { + "id": "5eb07532", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)\n\n\n", + "metadata": {} + }, + { + "id": "a3517c09", + "cell_type": "markdown", + "source": "## 6.1 \u6a5f\u68b0\u5b66\u7fd2\u306e\u76ee\u7684\uff08\u672c\u66f8\u306e\u5834\u5408\uff09\n\n\n", + "metadata": {} + }, + { + "id": "16fbf223", + "cell_type": "markdown", + "source": "## 6.2 \u6a5f\u68b0\u5b66\u7fd2\u306e\u305f\u3081\u306e\u30c7\u30fc\u30bf", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "iris\n", + "# \u4ee5\u4e0b\u7701\u7565" + ], + "id": "683e5483-df87-48d1-b8c1-9448e95e8afd" + }, + { + "id": "a2d2d145", + "cell_type": "markdown", + "source": "## 6.3 \u6a5f\u68b0\u5b66\u7fd2\u306e\u305f\u3081\u306e\u624b\u6cd5", + "metadata": {} + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "ir", + "display_name": "R" + } + } +} \ No newline at end of file diff --git a/code/R-notebook/r-07.ipynb b/code/R-notebook/r-07.ipynb new file mode 100644 index 0000000..78f30c3 --- /dev/null +++ b/code/R-notebook/r-07.ipynb @@ -0,0 +1,767 @@ +{ + "cells": [ + { + "id": "19ed5e50", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Google Colaboratory\u306e\u74b0\u5883\u8a2d\u5b9a\n", + "if (file.exists(\"/content\")) {\n", + " options(Ncpus = parallel::detectCores())\n", + " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"caret\", \"doParallel\", \"pastecs\")\n", + " install.packages(setdiff(packages_to_install, installed_packages))\n", + "}" + ], + "id": "6daafecb-ac54-42a0-be61-81882b0ba9d8" + }, + { + "id": "780b3547", + "cell_type": "markdown", + "source": "## 7.1 \u81ea\u52d5\u8eca\u306e\u505c\u6b62\u8ddd\u96e2\n\n\n", + "metadata": {} + }, + { + "id": "4c4b8d6c", + "cell_type": "markdown", + "source": "## 7.2 \u30c7\u30fc\u30bf\u306e\u78ba\u8a8d", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_data <- cars" + ], + "id": "d453a0dd-e469-46e1-ba0a-bd422ce68f19" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dim(my_data)" + ], + "id": "46ebb0d1-5bbc-4b36-8738-82e5c463afa2" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "head(my_data)" + ], + "id": "5f7a50f1-5024-4e34-a3b1-c9704ced9286" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "options(digits = 3)\n", + "pastecs::stat.desc(my_data)" + ], + "id": "c55c95b3-2ffa-40dc-9412-21bfec553bdc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data %>%\n", + " ggplot(aes(x = speed, y = dist)) +\n", + " geom_point()" + ], + "id": "6047b855-2d0e-41b0-a48a-8f575d8ddca1" + }, + { + "id": "66cdf411", + "cell_type": "markdown", + "source": "## 7.3 \u56de\u5e30\u5206\u6790", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)\n", + "\n", + "my_data <- cars\n", + "tmp <- data.frame(speed = 21.5, dist = 67)\n", + "my_data %>% ggplot(aes(x = speed, y = dist)) +\n", + " coord_cartesian(xlim = c(4, 25), ylim = c(0, 120)) +\n", + " geom_point() +\n", + " stat_smooth(formula = y ~ x, method = \"lm\") +\n", + " geom_pointrange(data = tmp, aes(ymin = -9, ymax = dist), linetype = \"dotted\") +\n", + " geom_pointrange(data = tmp, aes(xmin = 0, xmax = speed), linetype = \"dotted\")" + ], + "id": "c5cb02d3-12ee-4c9d-8df8-e878e0f4cdf0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_data <- cars" + ], + "id": "1e0db31c-d365-4521-8e78-6a19f0d1604d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- train(form = dist ~ speed, # \u30e2\u30c7\u30eb\u5f0f\uff08\u51fa\u529b\u5909\u6570\u3068\u5165\u529b\u5909\u6570\u306e\u95a2\u4fc2\uff09\n", + " data = my_data, # \u30c7\u30fc\u30bf\n", + " method = \"lm\") # \u624b\u6cd5" + ], + "id": "f1ccdfe8-770c-4a3f-a469-af590b057640" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "coef(my_model$finalModel)" + ], + "id": "e0ce6294-4385-4bdf-93cc-ad1485087adf" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp <- data.frame(speed = 21.5)\n", + "my_model %>% predict(tmp)" + ], + "id": "3dba6c39-fb4f-4c80-956f-42921c566b4c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "f <- function(x) { my_model %>% predict(data.frame(speed = x)) }" + ], + "id": "6a265022-83ec-462c-b6b2-50317bdb92fb" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data %>%\n", + " ggplot(aes(x = speed, y = dist,\n", + " color = \"data\")) +\n", + " geom_point() +\n", + " stat_function(\n", + " fun = f,\n", + " mapping = aes(color = \"model\"))" + ], + "id": "bc2fe818-0897-485b-a97b-08472fb23c8a" + }, + { + "id": "45ee793e", + "cell_type": "markdown", + "source": "## 7.4 \u5f53\u3066\u306f\u307e\u308a\u306e\u826f\u3055\u306e\u6307\u6a19", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_data <- cars\n", + "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\")\n", + "\n", + "y <- my_data$dist\n", + "y_ <- my_model %>% predict(my_data)\n", + "my_data$y_ <- y_" + ], + "id": "830ce8dd-40a3-4ec6-b79b-872f7a18d613" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data$residual <- y - y_\n", + "head(my_data)" + ], + "id": "b7fe4a81-4d2c-4382-912a-3ab4ab00fae5" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data %>%\n", + " ggplot(aes(x = speed, y = dist)) +\n", + " geom_point() +\n", + " geom_line(aes(x = speed, y = y_)) +\n", + " geom_linerange(mapping = aes(ymin = y_, ymax = dist), linetype = \"dotted\")" + ], + "id": "a77bf9b6-91ae-4d79-bf0c-781893923ffd" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "RMSE(y_, y)\n", + "# \u3042\u308b\u3044\u306f\n", + "mean((my_data$residual^2))**0.5\n" + ], + "id": "c6717b43-aac8-4391-af33-190217a33c2e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "R2(pred = y_, obs = y,\n", + " form = \"traditional\")" + ], + "id": "f315c857-bbb3-42ff-b554-580c578bab42" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "R2(pred = y_, obs = y,\n", + " form = \"corr\")\n", + "# \u3042\u308b\u3044\u306f\n", + "summary(my_model$finalModel)$r.squared" + ], + "id": "797a84a4-feb0-4e79-bf8a-883eb6caca6c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_test <- my_data[1:3, ]\n", + "y <- my_test$dist\n", + "y_ <- my_model %>% predict(my_test)\n", + "\n", + "R2(pred = y_, obs = y,\n", + " form = \"traditional\")\n", + "\n", + "R2(pred = y_, obs = y,\n", + " form = \"corr\")" + ], + "id": "9678df90-2690-4224-876e-62818c323814" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_data <- cars\n", + "my_idx <- c(2, 11, 27, 34, 39, 44)\n", + "my_sample <- my_data[my_idx, ]" + ], + "id": "549314c3-686a-4284-a840-04e9b64090df" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "options(warn = -1) # \u3053\u308c\u4ee5\u964d\uff0c\u8b66\u544a\u3092\u8868\u793a\u3057\u306a\u3044\uff0e\n", + "my_model <- train(form = dist ~ poly(speed, degree = 5, raw = TRUE),\n", + " data = my_sample,\n", + " method = \"lm\")\n", + "options(warn = 0) # \u3053\u308c\u4ee5\u964d\uff0c\u8b66\u544a\u3092\u8868\u793a\u3059\u308b\uff0e\n", + "\n", + "y <- my_sample$dist\n", + "y_ <- my_model %>% predict(my_sample)" + ], + "id": "96b57d18-9996-4ad8-bcaf-b901594b4b73" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "RMSE(y_, y)\n", + "\n", + "R2(pred = y_, obs = y,\n", + " form = \"traditional\")\n", + "\n", + "R2(pred = y_, obs = y,\n", + " form = \"corr\")" + ], + "id": "53b473f7-e007-4f0b-be25-c419db1f4e5c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "f <- function(x) { my_model %>% predict(data.frame(speed = x)) }\n", + "\n", + "my_data %>%\n", + " ggplot(aes(x = speed, y = dist, color = \"data\")) +\n", + " geom_point() +\n", + " geom_point(data = my_sample, mapping = aes(color = \"sample\")) +\n", + " stat_function(fun = f, mapping = aes(color = \"model\")) +\n", + " coord_cartesian(ylim = c(0, 120))" + ], + "id": "186cff45-0238-4b25-a155-6a975a563bcf" + }, + { + "id": "568b7388", + "cell_type": "markdown", + "source": "## 7.5 K\u6700\u8fd1\u508d\u6cd5", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# \u6e96\u5099\n", + "library(caret)\n", + "library(tidyverse)\n", + "my_data <- cars\n", + "\n", + "# \u8a13\u7df4\n", + "my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\")\n", + "\n", + "# \u53ef\u8996\u5316\u306e\u6e96\u5099\n", + "f <- function(x) { my_model %>% predict(data.frame(speed = x))}" + ], + "id": "4176be75-8cb6-4be5-ab6d-bef67f1f2510" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data %>%\n", + " ggplot(aes(x = speed,\n", + " y = dist,\n", + " color = \"data\")) +\n", + " geom_point() +\n", + " stat_function(\n", + " fun = f,\n", + " mapping = aes(color = \"model\"))" + ], + "id": "d9145b91-f4da-4577-9922-61c03cd5c9a1" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y <- my_data$dist\n", + "y_ <- my_model %>% predict(my_data)\n", + "\n", + "RMSE(y_, y)\n", + "\n", + "R2(pred = y_, obs = y,\n", + " form = \"traditional\")\n", + "\n", + "R2(pred = y_, obs = y,\n", + " form = \"corr\")" + ], + "id": "a1327ab7-ead1-41b6-a623-78521914be98" + }, + { + "id": "d4ff26ec", + "cell_type": "markdown", + "source": "## 7.6 \u691c\u8a3c", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_data <- cars\n", + "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\")\n", + "\n", + "my_model$results" + ], + "id": "517bb317-448d-48dd-9ff4-a9841b61c7a8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\",\n", + " trControl = trainControl(method = \"cv\", number = 5))\n", + "my_model$results" + ], + "id": "a902e863-49ad-44c6-9601-554ec1724155" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\",\n", + " trControl = trainControl(method = \"LOOCV\"))\n", + "my_model$results" + ], + "id": "48809d34-d02b-46d7-8602-71ab2498f0e8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(doParallel)\n", + "cl <- makeCluster(detectCores())\n", + "registerDoParallel(cl)" + ], + "id": "0b84c7e6-3fc7-4d83-9669-765c3bb3ba8a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_data <- cars\n", + "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\")\n", + "y <- my_data$dist\n", + "y_ <- my_model %>% predict(my_data)" + ], + "id": "e603dcaf-7b16-4ef8-8200-c2409b905b5d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# RMSE\uff08\u8a13\u7df4\uff09\n", + "RMSE(y_, y)\n", + "\n", + "# \u6c7a\u5b9a\u4fc2\u65701\uff08\u8a13\u7df4\uff09\n", + "R2(pred = y_, obs = y,\n", + " form = \"traditional\")\n", + "\n", + "# \u6c7a\u5b9a\u4fc2\u65706\uff08\u8a13\u7df4\uff09\n", + "R2(pred = y_, obs = y,\n", + " form = \"corr\")" + ], + "id": "c8ef2318-a46e-4bfb-9b9a-0197996b6bc6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "postResample(pred = y_, obs = y)" + ], + "id": "e44e6b14-93db-40c5-bf99-dd3600755e79" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\")\n", + "my_model$results\n", + "# \u5de6\u304b\u3089\uff0cRMSE\uff08\u691c\u8a3c\uff09\uff0c\u6c7a\u5b9a\u4fc2\u65706\uff08\u691c\u8a3c\uff09\uff0cMAE\uff08\u691c\u8a3c\uff09" + ], + "id": "c66d6533-343e-4ddc-a9f4-56c88e2c7754" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- train(form = dist ~ speed, data = my_data, method = \"lm\",\n", + " trControl = trainControl(method = \"LOOCV\"))\n", + "\n", + "# \u65b9\u6cd51\n", + "my_model$results\n", + "\n", + "# \u65b9\u6cd52\n", + "y <- my_model$pred$obs\n", + "y_ <- my_model$pred$pred\n", + "mean((y - y_)^2)**0.5" + ], + "id": "1292c887-a94a-44ab-a709-54cfb9b15d36" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mean(((y - y_)^2)**0.5)" + ], + "id": "37e09191-41f5-4787-83cd-3b4dbb661668" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_data <- cars\n", + "\n", + "my_lm_model <- train(form = dist ~ speed, data = my_data, method = \"lm\",\n", + " trControl = trainControl(method = \"LOOCV\"))\n", + "\n", + "my_knn_model <- train(form = dist ~ speed, data = my_data, method = \"knn\",\n", + " tuneGrid = data.frame(k = 5),\n", + " trControl = trainControl(method = \"LOOCV\"))" + ], + "id": "196b236e-b799-4ef9-b2b9-e708655329c7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_lm_model$results$RMSE\n", + "\n", + "my_knn_model$results$RMSE" + ], + "id": "812ebaa4-2695-4e50-a103-660e7047df95" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y <- my_data$dist\n", + "y_lm <- my_lm_model$pred$pred\n", + "y_knn <- my_knn_model$pred$pred\n", + "\n", + "my_df <- data.frame(\n", + " lm = (y - y_lm)^2,\n", + " knn = (y - y_knn)^2)\n", + "\n", + "head(my_df)" + ], + "id": "5ebc2d8d-3766-4b13-b88a-51d9c69a1899" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "boxplot(my_df, ylab = \"r^2\")" + ], + "id": "fdc6b337-fa88-4cf0-9b11-2c4569cf9b28" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "t.test(x = my_df$lm, y = my_df$knn,\n", + " conf.level = 0.95,\n", + " paired = TRUE,\n", + " alternative = \"two.sided\")\n" + ], + "id": "05f20f2e-1ba3-4ea6-9881-0ebd5fafce9a" + }, + { + "id": "bc753f89", + "cell_type": "markdown", + "source": "## 7.7 \u30d1\u30e9\u30e1\u30fc\u30bf\u30c1\u30e5\u30fc\u30cb\u30f3\u30b0", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_data <- cars\n", + "my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\")\n", + "my_model$results" + ], + "id": "c2846d5b-cbb2-40cc-bb93-a6a8efcaaefc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_params <- expand.grid(k = 1:15)\n", + "\n", + "my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\",\n", + " tuneGrid = my_params,\n", + " trControl = trainControl(method = \"LOOCV\"))" + ], + "id": "7e82ab9c-aa8e-4473-b9b1-8a3a87b1008a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "head(my_model$results)" + ], + "id": "59ed6d4c-c1bd-427c-ac4f-7af548088fe3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ggplot(my_model)" + ], + "id": "c25a6645-a886-478b-8c8d-31aeb16b829a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model$bestTune" + ], + "id": "8d95e669-74a2-4f7b-81ea-8941c2424dcd" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model$results %>%\n", + " filter(RMSE == min(RMSE))" + ], + "id": "2e37a40f-33f3-47bc-8ed3-3dc7a3124322" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y <- my_data$dist\n", + "y_ <- my_model %>% predict(my_data)\n", + "RMSE(y_, y)" + ], + "id": "b4741a59-ffad-458d-9100-c6adbe7efa41" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_data <- cars\n", + "\n", + "my_loocv <- function(k) {\n", + " my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\",\n", + " tuneGrid = data.frame(k = k),\n", + " trControl = trainControl(method = \"LOOCV\"))\n", + " y <- my_data$dist\n", + " y_ <- my_model %>% predict(my_data)\n", + " list(k = k,\n", + " training = RMSE(y_, y), # RMSE\uff08\u8a13\u7df4\uff09\n", + " validation = my_model$results$RMSE) # RMSE\uff08\u691c\u8a3c\uff09\n", + "}\n", + "\n", + "my_results <- 1:15 %>% map_dfr(my_loocv)" + ], + "id": "f1b2ee5b-1fe8-46c6-88fe-da72b4d4b20e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_results %>%\n", + " pivot_longer(-k) %>%\n", + " ggplot(aes(x = k, y = value,\n", + " color = name)) +\n", + " geom_line() + geom_point() +\n", + " xlab(\"#Neighbors\") + ylab(\"RMSE\") +\n", + " theme(legend.position = c(1, 0),\n", + " legend.justification = c(1, 0))" + ], + "id": "05342e21-c307-42dc-8a97-b526a7b57885" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "ir", + "display_name": "R" + } + } +} \ No newline at end of file diff --git a/code/R-notebook/r-08.ipynb b/code/R-notebook/r-08.ipynb new file mode 100644 index 0000000..bb20758 --- /dev/null +++ b/code/R-notebook/r-08.ipynb @@ -0,0 +1,553 @@ +{ + "cells": [ + { + "id": "b935dfa6", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Google Colaboratory\u306e\u74b0\u5883\u8a2d\u5b9a\n", + "if (file.exists(\"/content\")) {\n", + " options(Ncpus = parallel::detectCores())\n", + " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"caret\", \"ggfortify\", \"glmnetUtils\", \"leaps\", \"neuralnet\", \"psych\")\n", + " install.packages(setdiff(packages_to_install, installed_packages))\n", + "}" + ], + "id": "561b0a92-635a-4d98-aa64-9ccbc23fe94d" + }, + { + "id": "8770556c", + "cell_type": "markdown", + "source": "## 8.1 \u30d6\u30c9\u30a6\u306e\u751f\u80b2\u6761\u4ef6\u3068\u30ef\u30a4\u30f3\u306e\u4fa1\u683c", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)\n", + "my_url <- \"http://www.liquidasset.com/winedata.html\"\n", + "tmp <- read.table(file = my_url, # \u8aad\u307f\u8fbc\u3080\u5bfe\u8c61\n", + " header = TRUE, # 1\u884c\u76ee\u306f\u5909\u6570\u540d\n", + " na.string = \".\", # \u6b20\u640d\u5024\u3092\u8868\u3059\u6587\u5b57\u5217\n", + " skip = 62, # \u8aad\u307f\u98db\u3070\u3059\u884c\u6570\n", + " nrows = 38) # \u8aad\u307f\u8fbc\u3080\u884c\u6570\n", + "psych::describe(tmp)" + ], + "id": "55c3083e-3cfb-4e66-8dc2-a8d569ef98d6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data <- na.omit(tmp[, -c(1, 2)])\n", + "head(my_data)" + ], + "id": "35026df5-c628-4114-ac65-da801385baa4" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dim(my_data)" + ], + "id": "477907f0-6b70-4980-ad13-1defba9ba745" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data %>% write_csv(\"wine.csv\")" + ], + "id": "7f82ae72-7a4e-4ccf-8b58-4ca258f434ef" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#my_data <- read_csv(\"wine.csv\") # \u4f5c\u3063\u305f\u30d5\u30a1\u30a4\u30eb\u3092\u4f7f\u3046\u5834\u5408\n", + "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", + " \"/fromzero/master/data/wine.csv\")\n", + "my_data <- read_csv(my_url)" + ], + "id": "70353560-5931-41ff-94e4-cb6e1bcefa77" + }, + { + "id": "d940d42f", + "cell_type": "markdown", + "source": "## 8.2 \u91cd\u56de\u5e30\u5206\u6790", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", + " \"/fromzero/master/data/wine.csv\")\n", + "my_data <- read_csv(my_url)\n", + "\n", + "my_model <- train(form = LPRICE2 ~ WRAIN + DEGREES + HRAIN + TIME_SV,\n", + " data = my_data,\n", + " method = \"lm\",\n", + " trControl = trainControl(method = \"LOOCV\"))" + ], + "id": "799912e1-ecf9-4773-97da-7da53ca9d630" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "coef(my_model$finalModel) %>%\n", + " as.data.frame" + ], + "id": "05bf82c3-8d3f-4b79-84be-24684077ace1" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_test <- data.frame(\n", + " WRAIN = 500, DEGREES = 17,\n", + " HRAIN = 120, TIME_SV = 2)\n", + "my_model %>% predict(my_test)" + ], + "id": "90e98899-6800-4a99-92f2-03b8121db34f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y <- my_data$LPRICE2\n", + "y_ <- my_model %>% predict(my_data)\n", + "\n", + "RMSE(y_, y)\n", + "\n", + "R2(pred = y_, obs = y,\n", + " form = \"traditional\")\n", + "\n", + "R2(pred = y_, obs = y,\n", + " form = \"corr\")" + ], + "id": "8e3f7f78-7718-490d-a9d4-9f2c9463b180" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model$results" + ], + "id": "c7b05f73-1d83-4eeb-9e1e-c7d4ae024f66" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "M <- my_data[, -1] %>%\n", + " mutate(b0 = 1) %>% as.matrix\n", + "b <- MASS::ginv(M) %*% y\n", + "matrix(b,\n", + " dimnames = list(colnames(M)))" + ], + "id": "adfa0dff-19b0-4a1c-8c9d-7cb059f1405d" + }, + { + "id": "78ac68f3", + "cell_type": "markdown", + "source": "## 8.3 \u6a19\u6e96\u5316", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", + " \"/fromzero/master/data/wine.csv\")\n", + "my_data <- read_csv(my_url)\n", + "\n", + "my_data %>%\n", + " mutate_if(is.numeric, scale) %>% # \u6570\u5024\u306e\u5217\u306e\u6a19\u6e96\u5316\n", + " pivot_longer(-LPRICE2) %>%\n", + " ggplot(aes(x = name, y = value)) +\n", + " geom_boxplot() +\n", + " stat_summary(fun = mean, geom = \"point\", size = 3) +\n", + " xlab(NULL)" + ], + "id": "03bab3f4-9a9b-4294-9e8a-643f2edbe5b0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- train(\n", + " form = LPRICE2 ~ .,\n", + " data = my_data,\n", + " method = \"lm\",\n", + " preProcess = c(\"center\", \"scale\"))" + ], + "id": "74498f8a-c95e-43ee-a066-e11fae805a5c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "coef(my_model$finalModel) %>%\n", + " as.data.frame" + ], + "id": "b9eb19c2-70b9-455c-a139-999d45ab0c91" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_test <- data.frame(\n", + " WRAIN = 500, DEGREES = 17,\n", + " HRAIN = 120, TIME_SV = 2)\n", + "my_model %>% predict(my_test)" + ], + "id": "cadc1650-3741-4bb2-badb-67ad3d205572" + }, + { + "id": "030e6748", + "cell_type": "markdown", + "source": "## 8.4 \u5165\u529b\u5909\u6570\u306e\u6570\u3068\u30e2\u30c7\u30eb\u306e\u826f\u3055", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", + " \"/fromzero/master/data/wine.csv\")\n", + "my_data <- read_csv(my_url)\n", + "\n", + "n <- nrow(my_data)\n", + "my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2,\n", + " v2 = 0:(n - 1) %% 3)\n", + "head(my_data2)" + ], + "id": "38a3dc5b-df56-45f2-95c6-e5f5646ef001" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model2 <- train(form = LPRICE2 ~ ., data = my_data2, method = \"lm\",\n", + " trControl = trainControl(method = \"LOOCV\"))\n", + "y <- my_data2$LPRICE2\n", + "y_ <- my_model2 %>% predict(my_data2)\n", + "\n", + "RMSE(y_, y)\n", + "\n", + "my_model2$results$RMSE" + ], + "id": "d6f68c87-3afa-46fb-9c24-a08d4d2b93b5" + }, + { + "id": "277542b8", + "cell_type": "markdown", + "source": "## 8.5 \u5909\u6570\u9078\u629e", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", + " \"/fromzero/master/data/wine.csv\")\n", + "my_data <- read_csv(my_url)\n", + "n <- nrow(my_data)\n", + "my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2,\n", + " v2 = 0:(n - 1) %% 3)" + ], + "id": "22fc4bbc-5fe0-46aa-9aba-8f677963f3e1" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- train(form = LPRICE2 ~ .,\n", + " data = my_data2,\n", + " method = \"leapForward\", # \u5909\u6570\u5897\u52a0\u6cd5\n", + " trControl = trainControl(method = \"LOOCV\"),\n", + " tuneGrid = data.frame(nvmax = 1:6)) # \u9078\u629e\u3059\u308b\u5909\u6570\u306e\u4e0a\u9650\n", + "summary(my_model$finalModel)$outmat" + ], + "id": "6647adf2-39f0-412f-b2a0-72f2afbca8f7" + }, + { + "id": "fe89e198", + "cell_type": "markdown", + "source": "## 8.6 \u88dc\u8db3\uff1a\u6b63\u5247\u5316", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", + " \"/fromzero/master/data/wine.csv\")\n", + "my_data <- read_csv(my_url)" + ], + "id": "906c3c5a-555c-42d6-b9a4-2ca72e230222" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "A <- 2\n", + "B <- 0.1\n", + "\n", + "my_model <- train(\n", + " form = LPRICE2 ~ .,\n", + " data = my_data,\n", + " method = \"glmnet\",\n", + " standardize = TRUE,\n", + " tuneGrid = data.frame(\n", + " lambda = A,\n", + " alpha = B))" + ], + "id": "b7e5512c-b148-4556-98a3-82677d1746ce" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "coef(my_model$finalModel, A)" + ], + "id": "8445b2de-2215-439a-9f8a-4909f263ea57" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_test <- data.frame(\n", + " WRAIN = 500, DEGREES = 17,\n", + " HRAIN = 120, TIME_SV = 2)\n", + "my_model %>% predict(my_test)" + ], + "id": "eb8cbdcd-4845-4e20-ad26-27383db365ae" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(ggfortify)\n", + "library(glmnetUtils)\n", + "\n", + "my_data2 <- my_data %>% scale %>%\n", + " as.data.frame\n", + "\n", + "B <- 0.1\n", + "\n", + "glmnet(\n", + " form = LPRICE2 ~ .,\n", + " data = my_data2,\n", + " alpha = B) %>%\n", + " autoplot(xvar = \"lambda\") +\n", + " xlab(\"log A ( = log lambda)\") +\n", + " theme(legend.position = c(0.15, 0.25))" + ], + "id": "a324ef4f-191c-4c94-a5e5-aa0615ea7844" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "As <- seq(0, 0.1, length.out = 21)\n", + "Bs <- seq(0, 0.1, length.out = 6)\n", + "\n", + "my_model <- train(\n", + " form = LPRICE2 ~ ., data = my_data, method = \"glmnet\", standardize = TRUE,\n", + " trControl = trainControl(method = \"LOOCV\"),\n", + " tuneGrid = expand.grid(lambda = As, alpha = Bs))\n", + "\n", + "my_model$bestTune" + ], + "id": "85b7806e-2f39-4ea9-b07e-29f8a13f90f0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp <- \"B ( = alpha)\"\n", + "ggplot(my_model) +\n", + " theme(legend.position = c(0, 1), legend.justification = c(0, 1)) +\n", + " xlab(\"A ( = lambda)\") +\n", + " guides(shape = guide_legend(tmp), color = guide_legend(tmp))" + ], + "id": "0021348b-dfad-47d6-8102-604cabca4321" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model$results %>%\n", + " filter(RMSE == min(RMSE))" + ], + "id": "0d8c0655-cf26-4c1f-8b9f-0eeb889fd22f" + }, + { + "id": "1686468d", + "cell_type": "markdown", + "source": "## 8.7 \u30cb\u30e5\u30fc\u30e9\u30eb\u30cd\u30c3\u30c8\u30ef\u30fc\u30af", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "curve(1 / (1 + exp(-x)), -6, 6)" + ], + "id": "fd59339a-0fbb-4def-8875-fca78f9e1f8f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", + " \"/fromzero/master/data/wine.csv\")\n", + "my_data <- read_csv(my_url)" + ], + "id": "c9bcf872-0ae9-415a-8126-d71d4fe9c70f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- train(form = LPRICE2 ~ .,\n", + " data = my_data,\n", + " method = \"neuralnet\", # \u30cb\u30e5\u30fc\u30e9\u30eb\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\n", + " preProcess = c(\"center\", \"scale\"), # \u6a19\u6e96\u5316\n", + " trControl = trainControl(method = \"LOOCV\"))\n", + "plot(my_model$finalModel) # \u8a13\u7df4\u6e08\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u63cf\u753b" + ], + "id": "4c38242b-c8ca-496e-b3a0-9864561b418f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model$results" + ], + "id": "7e98889a-00d7-49f2-b99b-528c8cd07620" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- train(\n", + " form = LPRICE2 ~ .,\n", + " data = my_data,\n", + " method = \"neuralnet\",\n", + " preProcess = c(\"center\", \"scale\"),\n", + " trControl = trainControl(method = \"LOOCV\"),\n", + " tuneGrid = expand.grid(layer1 = 1:5,\n", + " layer2 = 0:2,\n", + " layer3 = 0))" + ], + "id": "2d3df4be-4a25-40f6-bd75-ff7610f3aa52" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model$results %>%\n", + " filter(RMSE == min(RMSE))" + ], + "id": "e66b3050-6314-4c81-8686-404dca249cbe" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "ir", + "display_name": "R" + } + } +} \ No newline at end of file diff --git a/code/R-notebook/r-09.ipynb b/code/R-notebook/r-09.ipynb new file mode 100644 index 0000000..d45e8e2 --- /dev/null +++ b/code/R-notebook/r-09.ipynb @@ -0,0 +1,395 @@ +{ + "cells": [ + { + "id": "f257bbbc", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Google Colaboratory\u306e\u74b0\u5883\u8a2d\u5b9a\n", + "if (file.exists(\"/content\")) {\n", + " options(Ncpus = parallel::detectCores())\n", + " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"caret\", \"furrr\", \"psych\", \"randomForest\", \"rpart.plot\", \"xgboost\")\n", + " install.packages(setdiff(packages_to_install, installed_packages))\n", + "}" + ], + "id": "672bb9c7-3b61-4fa8-a883-444d08f90ecd" + }, + { + "id": "e87dcb1e", + "cell_type": "markdown", + "source": "## 9.1 \u30a2\u30e4\u30e1\u306e\u30c7\u30fc\u30bf", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data <- iris\n", + "head(my_data)" + ], + "id": "91b68597-5d35-4caa-94fd-1b09bad2b8ef" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "psych::describe(my_data)" + ], + "id": "3041f6c7-9c72-411e-b57d-2184aa3af83c" + }, + { + "id": "4f62dd19", + "cell_type": "markdown", + "source": "## 9.2 \u6728\u306b\u3088\u308b\u5206\u985e", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_data <- iris\n", + "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart\")" + ], + "id": "56181aa2-1329-47bc-befc-243257a4db9c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rpart.plot::rpart.plot(my_model$finalModel, extra = 1)" + ], + "id": "f1cbea99-98e9-42af-b27a-411a3018a592" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_test <- tribble(\n", + "~Sepal.Length, ~Sepal.Width, ~Petal.Length, ~Petal.Width,\n", + " 5.0, 3.5, 1.5, 0.5,\n", + " 6.5, 3.0, 5.0, 2.0)\n", + "\n", + "my_model %>% predict(my_test)" + ], + "id": "41d30e52-8ca2-4fee-a041-4e365e21f8df" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model %>% predict(my_test,\n", + " type = \"prob\")" + ], + "id": "de364d4b-cd99-435a-a61a-fd3d64d84dbe" + }, + { + "id": "2574f70a", + "cell_type": "markdown", + "source": "## 9.3 \u6b63\u89e3\u7387", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_data <- iris\n", + "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\")\n", + "\n", + "y <- my_data$Species\n", + "y_ <- my_model %>% predict(my_data)\n", + "confusionMatrix(data = y_, reference = y)\n", + "# \u4ee5\u4e0b\u306f\u5272\u611b" + ], + "id": "f4368a81-f7ac-4c36-a801-c899ec9c6bca" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y <- my_data$Species\n", + "y_ <- my_model %>% predict(my_data)\n", + "mean(y_ == y)" + ], + "id": "975099dd-2b4a-4235-9f77-ec7164134942" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\",\n", + " trControl = trainControl(method = \"LOOCV\"))\n", + "my_model$results" + ], + "id": "cba9ee7d-a38a-4d81-ac03-62a5630f4280" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\",\n", + " tuneGrid = data.frame(maxdepth = 1:10),\n", + " trControl = trainControl(method = \"LOOCV\"))\n", + "my_model$results %>% filter(Accuracy == max(Accuracy))" + ], + "id": "1fec4b3d-4cdd-4d8d-9118-450dfb9a984b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# \u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u4e0e\u3048\u308b\u3068\u6b63\u89e3\u7387\uff08LOOCV\uff09\u3092\u8fd4\u3059\u95a2\u6570\n", + "my_loocv <- function(maxdepth, minbucket, minsplit) {\n", + " my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\",\n", + " trControl = trainControl(method = \"LOOCV\"),\n", + " tuneGrid = data.frame(maxdepth = maxdepth),\n", + " control = rpart::rpart.control(cp = 0.01,\n", + " minbucket = minbucket,\n", + " minsplit = minsplit))\n", + " list(maxdepth = maxdepth,\n", + " minbucket = minbucket,\n", + " minsplit = minsplit,\n", + " Accuracy = my_model$results$Accuracy)\n", + "}" + ], + "id": "2e1b0e96-dd4e-4869-a171-3843c3ebe6dc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_params <- expand.grid(\n", + " maxdepth = 2:5,\n", + " minbucket = 1:7,\n", + " minsplit = c(2, 20))\n", + "\n", + "library(furrr)\n", + "plan(multisession) # \u4e26\u5217\u51e6\u7406\u306e\u6e96\u5099\n", + "my_results <- my_params %>% future_pmap_dfr(my_loocv, # \u5b9f\u884c\n", + " .options = furrr_options(seed = TRUE))\n", + "\n", + "my_results %>% filter(Accuracy == max(Accuracy)) # \u6b63\u89e3\u7387\uff08\u691c\u8a3c\uff09\u306e\u6700\u5927\u5024" + ], + "id": "3804f0f4-5889-4977-a8cc-4f5a6dacb072" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart2\",\n", + " trControl = trainControl(method = \"none\"),\n", + " tuneGrid = data.frame(maxdepth = 3),\n", + " control = rpart::rpart.control(cp = 0.01,\n", + " minbucket = 5,\n", + " minsplit = 2))" + ], + "id": "c6cb1831-f3bb-4cc1-a4cf-9757a756d441" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rpart.plot::rpart.plot(\n", + " my_model$finalModel, extra = 1)" + ], + "id": "7f38c193-4e94-4642-8eef-4ee4c54edc0a" + }, + { + "id": "c0584e59", + "cell_type": "markdown", + "source": "## 9.4 \u8907\u6570\u306e\u6728\u3092\u4f7f\u3046\u65b9\u6cd5", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_data <- iris\n", + "\n", + "my_model <- train(form = Species ~ ., data = my_data, method = \"rf\",\n", + " tuneGrid = data.frame(mtry = 2:4), # \u7701\u7565\u53ef\n", + " trControl = trainControl(method = \"LOOCV\"))\n", + "my_model$results" + ], + "id": "f031d0bf-bb36-4916-842a-dbead571de98" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- train(\n", + " form = Species ~ ., data = my_data, method = \"xgbTree\",\n", + " tuneGrid = expand.grid(\n", + " nrounds = c(50, 100, 150),\n", + " max_depth = c(1, 2, 3),\n", + " eta = c(0.3, 0.4),\n", + " gamma = 0,\n", + " colsample_bytree = c(0.6, 0.8),\n", + " min_child_weight = 1,\n", + " subsample = c(0.5, 0.75, 1)),\n", + " trControl = trainControl(method = \"cv\", number = 5)) # 5\u5206\u5272\u4ea4\u5dee\u691c\u8a3c\n", + "my_model$results %>% filter(Accuracy == max(Accuracy)) %>% head(5) %>% t" + ], + "id": "d47da34c-9086-4216-977e-43df6ae435db" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- train(form = Species ~ ., data = my_data, method = \"rf\")\n", + "ggplot(varImp(my_model))" + ], + "id": "adb7d33c-3320-4c89-b663-460628a3aaca" + }, + { + "id": "9c146239", + "cell_type": "markdown", + "source": "## 9.5 \u6b20\u640d\u306e\u3042\u308b\u30c7\u30fc\u30bf\u3067\u306e\u5b66\u7fd2", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_data <- iris\n", + "\n", + "n <- nrow(my_data)\n", + "my_data$Petal.Length[0:(n - 1) %% 10 == 0] <- NA\n", + "my_data$Petal.Width[ 0:(n - 1) %% 10 == 1] <- NA\n", + "\n", + "psych::describe(my_data) # n\u306e\u5024\u304c135\u306e\u5909\u6570\u306b\uff0c150 - 135 = 15\u500b\u306e\u6b20\u640d\u304c\u3042\u308b\uff0e" + ], + "id": "c0e67edb-2aa0-43cb-9939-3c7ea477104c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- train(\n", + " form = Species ~ ., data = my_data, method = \"rpart2\",\n", + " na.action = na.pass, # \u6b20\u640d\u304c\u3042\u3063\u3066\u3082\u5b66\u7fd2\u3092\u6b62\u3081\u306a\u3044\uff0e\n", + " preProcess = \"medianImpute\", # \u6b20\u640d\u3092\u4e2d\u592e\u5024\u3067\u57cb\u3081\u308b\uff0e\n", + " trControl = trainControl(method = \"LOOCV\"),\n", + " tuneGrid = data.frame(maxdepth = 20), # \u6728\u306e\u9ad8\u3055\u306e\u4e0a\u9650\n", + " control = rpart::rpart.control(minsplit = 2, # \u5206\u5c90\u306e\u6761\u4ef6\n", + " minbucket = 1)) # \u7d42\u7aef\u30ce\u30fc\u30c9\u306e\u6761\u4ef6\n", + "max(my_model$results$Accuracy)" + ], + "id": "376865a4-d248-4b07-8b10-e1114e92061a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- train(form = Species ~ ., data = my_data, method = \"xgbTree\",\n", + " na.action = na.pass,\n", + " trControl = trainControl(method = \"cv\", number = 5))\n", + "max(my_model$results$Accuracy)" + ], + "id": "0c70a1dc-06f2-4c19-9fa1-79bca1945fde" + }, + { + "id": "0335b5a5", + "cell_type": "markdown", + "source": "## 9.6 \u4ed6\u306e\u5206\u985e\u624b\u6cd5", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_data <- iris\n", + "\n", + "my_model <- train(form = Species ~ ., data = my_data, method = \"knn\",\n", + " trControl = trainControl(method = \"LOOCV\"))\n", + "my_model$results %>% filter(Accuracy == max(Accuracy))" + ], + "id": "b1c532ce-597e-44bb-bc8e-857cb2db3b3c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(tidyverse)\n", + "my_data <- iris\n", + "\n", + "my_model <- train(form = Species ~ ., data = my_data, method = \"nnet\",\n", + " preProcess = c(\"center\", \"scale\"), # \u6a19\u6e96\u5316\n", + " trControl = trainControl(method = \"LOOCV\"),\n", + " trace = FALSE) # \u9014\u4e2d\u7d4c\u904e\u3092\u8868\u793a\u3057\u306a\u3044\n", + "my_model$results %>% filter(Accuracy == max(Accuracy))" + ], + "id": "bac8c29f-336b-4e63-bfb7-940b08ca52d6" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "ir", + "display_name": "R" + } + } +} \ No newline at end of file diff --git a/code/R-notebook/r-10.ipynb b/code/R-notebook/r-10.ipynb new file mode 100644 index 0000000..3a9438b --- /dev/null +++ b/code/R-notebook/r-10.ipynb @@ -0,0 +1,356 @@ +{ + "cells": [ + { + "id": "a7542dc4", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Google Colaboratory\u306e\u74b0\u5883\u8a2d\u5b9a\n", + "if (file.exists(\"/content\")) {\n", + " options(Ncpus = parallel::detectCores())\n", + " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"caret\", \"PRROC\", \"rpart.plot\")\n", + " install.packages(setdiff(packages_to_install, installed_packages))\n", + "}" + ], + "id": "4b6f1427-afa1-425d-a87d-4d12f5ef26a5" + }, + { + "id": "0a20667b", + "cell_type": "markdown", + "source": "## 10.1 2\u5024\u5206\u985e\u306e\u6027\u80fd\u6307\u6a19", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1)\n", + "y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5)" + ], + "id": "5d4b8906-9503-48da-9c74-22a597cd36b6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_ <- ifelse(0.5 <= y_score, 1, 0)\n", + "y_" + ], + "id": "7fe94f71-3ca1-4a8f-a4bb-dda7a9729942" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "confusionMatrix(data = as.factor(y_), # \u4e88\u6e2c\n", + " reference = as.factor(y), # \u6b63\u89e3\n", + " positive = \"1\", # \u300c1\u300d\u3092\u967d\u6027\u3068\u3059\u308b\uff0e\n", + " mode = \"everything\") # \u5168\u3066\u306e\u6307\u6a19\u3092\u6c42\u3081\u308b\uff0e" + ], + "id": "666b3422-7d1f-4034-8f35-17ec1741410e" + }, + { + "id": "48bd90c1", + "cell_type": "markdown", + "source": "## 10.2 \u30c8\u30ec\u30fc\u30c9\u30aa\u30d5", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(PRROC)\n", + "library(tidyverse)\n", + "\n", + "y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1)\n", + "y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5)\n", + "y_ <- ifelse(0.5 <= y_score, 1, 0)\n", + "\n", + "c(sum((y == 0) & (y_ == 1)) / sum(y == 0), # FPR\n", + " sum((y == 1) & (y_ == 1)) / sum(y == 1)) # TPR" + ], + "id": "6a8913af-73ea-4460-ba51-f50f4d5f6a4e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_roc <- roc.curve(scores.class0 = y_score[y == 1], # \u7b54\u3048\u304c1\u306e\u3082\u306e\u306e\u30b9\u30b3\u30a2\n", + " scores.class1 = y_score[y == 0], # \u7b54\u3048\u304c0\u306e\u3082\u306e\u306e\u30b9\u30b3\u30a2\n", + " curve = TRUE)\n", + "my_roc %>% plot(xlab = \"False Positive Rate\",\n", + " ylab = \"True Positive Rate\",\n", + " legend = FALSE)" + ], + "id": "f74d9790-9685-4693-a9d2-00a9d9051890" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_roc$auc" + ], + "id": "917add77-e039-496b-a428-b6e6acc1c8d1" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c(sum((y == 1) & (y_ == 1)) / sum(y == 1), # Recall == TPR\n", + " sum((y == 1) & (y_ == 1)) / sum(y_ == 1)) # Precision" + ], + "id": "96e071a2-bbe7-4c2d-871f-a1ed46b6e455" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_pr <- pr.curve(scores.class0 = y_score[y == 1],\n", + " scores.class1 = y_score[y == 0],\n", + " curve = TRUE)\n", + "my_pr %>% plot(xlab = \"Recall\",\n", + " ylab = \"Precision\",\n", + " legend = FALSE)" + ], + "id": "7dc1e8ae-303e-4303-96c2-b878aaaf182d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_pr$auc.integral" + ], + "id": "21d7225b-40b7-461a-9889-f779cf0e2882" + }, + { + "id": "5aa66aea", + "cell_type": "markdown", + "source": "## 10.3 \u30bf\u30a4\u30bf\u30cb\u30c3\u30af", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(PRROC)\n", + "library(tidyverse)\n", + "\n", + "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", + " \"/fromzero/master/data/titanic.csv\")\n", + "my_data <- read_csv(my_url)" + ], + "id": "7de0dc87-3ea4-42ef-b80e-70e8b2c21c31" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "head(my_data)" + ], + "id": "6fc5827d-5bd6-4004-ab45-d89b9792db58" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- train(form = Survived ~ ., data = my_data, method = \"rpart2\",\n", + " tuneGrid = data.frame(maxdepth = 2),\n", + " trControl = trainControl(method = \"LOOCV\"))" + ], + "id": "b056ad8e-7114-4c52-a84d-8dfb77ea0730" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rpart.plot::rpart.plot(my_model$finalModel, extra = 1)" + ], + "id": "bbbcab7d-0464-43d4-aa2d-6ef9bdca2bc8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model$results" + ], + "id": "30dd0757-5593-4669-ba77-aa72f953954f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y <- my_data$Survived\n", + "tmp <- my_model %>% predict(newdata = my_data, type = \"prob\")\n", + "y_score <- tmp$Yes\n", + "\n", + "my_roc <- roc.curve(scores.class0 = y_score[y == \"Yes\"],\n", + " scores.class1 = y_score[y == \"No\"],\n", + " curve = TRUE)\n", + "my_roc$auc\n", + "\n", + "my_roc %>% plot(xlab = \"False Positive Rate\",\n", + " ylab = \"True Positive Rate\",\n", + " legend = FALSE)" + ], + "id": "bb3059ad-8898-4af8-8a6e-2817ecfaa35b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "X <- my_data %>% select(Class) # \u8cea\u7684\u5165\u529b\u5909\u6570\n", + "y <- my_data$Survived # \u51fa\u529b\u5909\u6570\n", + "\n", + "options(warn = -1) # \u3053\u308c\u4ee5\u964d\uff0c\u8b66\u544a\u3092\u8868\u793a\u3057\u306a\u3044\uff0e\n", + "my_model1 <- train(x = X, y = y, method = \"rpart2\",\n", + " tuneGrid = data.frame(maxdepth = 2),\n", + " trControl = trainControl(method = \"LOOCV\"))\n", + "options(warn = 0) # \u3053\u308c\u4ee5\u964d\uff0c\u8b66\u544a\u3092\u8868\u793a\u3059\u308b\uff0e\n", + "\n", + "rpart.plot::rpart.plot(my_model1$finalModel, extra = 1)\n", + "my_model1$results" + ], + "id": "f8d30f5f-7b58-4ffa-ab23-35f38e83f496" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_enc <- my_data %>% dummyVars(formula = Survived ~ Class)\n", + "my_data2 <- my_enc %>%\n", + " predict(my_data) %>%\n", + " as.data.frame %>%\n", + " mutate(Survived = my_data$Survived)\n", + "\n", + "my_model2 <- train(form = Survived ~ ., data = my_data2, method = \"rpart2\",\n", + " tuneGrid = data.frame(maxdepth = 2),\n", + " trControl = trainControl(method = \"LOOCV\"))\n", + "rpart.plot::rpart.plot(my_model2$finalModel, extra = 1)\n", + "my_model2$results" + ], + "id": "4cc01c0d-c97c-4a10-87a4-33c87699f8e0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model3 <- train(form = Survived ~ Class, data = my_data, method = \"rpart2\",\n", + " tuneGrid = data.frame(maxdepth = 2),\n", + " trControl = trainControl(method = \"LOOCV\"))\n", + "rpart.plot::rpart.plot(my_model3$finalModel, extra = 1)\n", + "my_model3$results" + ], + "id": "358258cd-03c1-4ada-b993-9c05056fd3bd" + }, + { + "id": "1a880c82", + "cell_type": "markdown", + "source": "## 10.4 \u30ed\u30b8\u30b9\u30c6\u30a3\u30c3\u30af\u56de\u5e30", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "curve(1 / (1 + exp(-x)), -6, 6)" + ], + "id": "abacb546-4130-4264-a4cb-b80d206d53c5" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "library(PRROC)\n", + "library(tidyverse)\n", + "\n", + "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", + " \"/fromzero/master/data/titanic.csv\")\n", + "my_data <- read_csv(my_url)\n", + "\n", + "my_model <- train(form = Survived ~ ., data = my_data, method = \"glm\",\n", + " trControl = trainControl(method = \"LOOCV\"))" + ], + "id": "bf3b1d96-a0de-4a2c-a291-74d1214b7511" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "coef(my_model$finalModel) %>%\n", + " as.data.frame" + ], + "id": "e5092df9-371a-4820-9dfe-24561032ba68" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model$results" + ], + "id": "2607436f-b0a5-44d5-b4d2-29b09bf100e1" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "ir", + "display_name": "R" + } + } +} \ No newline at end of file diff --git a/code/R-notebook/r-11.ipynb b/code/R-notebook/r-11.ipynb new file mode 100644 index 0000000..adf2583 --- /dev/null +++ b/code/R-notebook/r-11.ipynb @@ -0,0 +1,827 @@ +{ + "cells": [ + { + "id": "5baa17a5", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Google Colaboratory\u306e\u74b0\u5883\u8a2d\u5b9a\n", + "if (file.exists(\"/content\")) {\n", + " options(Ncpus = parallel::detectCores())\n", + " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"h2o\", \"keras\")\n", + " install.packages(setdiff(packages_to_install, installed_packages))\n", + "}" + ], + "id": "da219d14-1c8e-4f4c-b0d8-0eafc0779fef" + }, + { + "id": "8da96981", + "cell_type": "markdown", + "source": "## 11.1 Keras\u306b\u3088\u308b\u56de\u5e30", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(keras)\n", + "library(tidyverse)\n", + "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", + " \"/fromzero/master/data/wine.csv\")\n", + "tmp <- read_csv(my_url)" + ], + "id": "d3a07388-a282-4c57-906b-b47b10f2a002" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data <- tmp[sample(nrow(tmp)), ]" + ], + "id": "2af767ad-fd90-40e1-9621-d62a347aba27" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "X <- my_data %>%\n", + " select(-LPRICE2) %>% scale\n", + "y <- my_data$LPRICE2" + ], + "id": "8b11871d-95cc-461d-9c12-4ebbbc0b07c8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "curve(activation_relu(x), -3, 3)" + ], + "id": "fbd6637f-0adc-4fdb-83af-d2198bf8bd8d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- keras_model_sequential() %>%\n", + " layer_dense(units = 3, activation = \"relu\", input_shape = c(4)) %>%\n", + " layer_dense(units = 1)\n", + "\n", + "summary(my_model) # \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u6982\u8981\n", + "# \u5272\u611b\uff08Python\u306e\u7d50\u679c\u3092\u53c2\u7167\uff09" + ], + "id": "7619ff4c-93cb-45ea-8627-4cf0321dd946" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model %>% compile(\n", + " loss = \"mse\",\n", + " optimizer = \"rmsprop\")" + ], + "id": "c1d9ccdf-e633-4dc2-8d89-7a242f32080d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_cb <- callback_early_stopping(\n", + " patience = 20,\n", + " restore_best_weights = TRUE)" + ], + "id": "f11d43d3-900d-40cd-9b69-321740d0b447" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_history <- my_model %>% fit(\n", + " x = X,\n", + " y = y,\n", + " validation_split = 0.25,\n", + " batch_size = 10,\n", + " epochs = 500,\n", + " callbacks = list(my_cb),\n", + " verbose = 0)" + ], + "id": "bf3919c3-9b64-4f60-9183-c2d648e94b74" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plot(my_history)" + ], + "id": "d18e8ffa-f973-40d0-89e7-582a20020a4d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_history" + ], + "id": "8290c4a9-62a2-4871-a559-b7079d8680c7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_ <- my_model %>% predict(X)\n", + "mean((y_ - y)^2)**0.5" + ], + "id": "cb8fb5b6-854a-4b4e-895f-2c52371b9657" + }, + { + "id": "8ffec1e8", + "cell_type": "markdown", + "source": "## 11.2 Keras\u306b\u3088\u308b\u5206\u985e", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(keras)\n", + "library(tidyverse)\n", + "my_data <- iris[sample(nrow(iris)), ]" + ], + "id": "30d0a550-120b-4360-9ccf-087605593cc3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "X <- my_data %>%\n", + " select(-Species) %>% scale\n", + "y <- as.integer(my_data$Species) - 1" + ], + "id": "ab7b55a6-4e69-4418-868f-6cca75f7ac81" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- keras_model_sequential() %>%\n", + " layer_dense(units = 3, activation = \"relu\", input_shape = c(4)) %>%\n", + " layer_dense(units = 3, activation = \"softmax\")" + ], + "id": "ab2d2e04-c0b7-4948-bf58-eaa77e601fa3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model %>% compile(loss = \"sparse_categorical_crossentropy\",\n", + " optimizer = \"rmsprop\",\n", + " metrics = c(\"accuracy\"))" + ], + "id": "c91aa7ec-f9d3-4731-be72-7e02ada8958a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_cb <- callback_early_stopping(\n", + " patience = 20,\n", + " restore_best_weights = TRUE)\n", + "\n", + "my_history <- my_model %>%\n", + " fit(x = X,\n", + " y = y,\n", + " validation_split = 0.25,\n", + " batch_size = 10,\n", + " epochs = 500,\n", + " callbacks = list(my_cb),\n", + " verbose = 0)\n", + "\n", + "plot(my_history)" + ], + "id": "155c6607-99e4-4916-8768-50285f52f5e7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_history" + ], + "id": "fcbd40ad-258e-4c95-a39a-b51c0b40bcdf" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp <- my_model %>% predict(X)\n", + "y_ <- apply(tmp, 1, which.max) - 1\n", + "mean(y_ == y)" + ], + "id": "1f3b920c-e580-465e-bc31-d6c71d7107d9" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "-mean(log(c(0.8, 0.7, 0.3, 0.8)))\n", + "\n", + "-mean(log(c(0.7, 0.6, 0.2, 0.7)))" + ], + "id": "0caf0701-e80b-4f72-b2a1-6a08d1dfae1b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y <- c(2, 1, 0, 1)\n", + "y_1 <- list(c(0.1, 0.1, 0.8),\n", + " c(0.1, 0.7, 0.2),\n", + " c(0.3, 0.4, 0.3),\n", + " c(0.1, 0.8, 0.1))\n", + "y_2 <- list(c(0.1, 0.2, 0.7),\n", + " c(0.2, 0.6, 0.2),\n", + " c(0.2, 0.5, 0.3),\n", + " c(0.2, 0.7, 0.1))" + ], + "id": "c9718504-52df-4006-b659-753740c858c6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c(mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_1))),\n", + " mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_2))))" + ], + "id": "2e50554a-9f64-4238-ab77-836da71f8558" + }, + { + "id": "18df10b6", + "cell_type": "markdown", + "source": "## 11.3 MNIST\uff1a\u624b\u66f8\u304d\u6570\u5b57\u306e\u5206\u985e", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(keras)\n", + "library(tidyverse)\n", + "keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist())" + ], + "id": "bb7d5c4e-3572-417f-8a44-b0c3b0b95a35" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dim(x_train)" + ], + "id": "311d99fc-fd32-43f8-9dbd-5629979655fa" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x_train[5, , ]" + ], + "id": "ab4e89e6-f69a-4645-9178-66c9d98e99b4" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plot(as.raster(x = x_train[5, , ],\n", + " max = max(x_train)))" + ], + "id": "a1f96f76-1101-4e0f-917c-d775245e44b4" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "head(y_train)" + ], + "id": "1faa2393-22cf-423f-8bce-96603db47b6c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c(min(x_train), max(x_train))" + ], + "id": "0bcde022-8a63-43e8-ab95-c25f845585be" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x_train <- x_train / 255\n", + "x_test <- x_test / 255" + ], + "id": "1094cf72-9dcc-49d8-8f4a-6e64d2589866" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_index <- sample(1:60000, 6000)\n", + "x_train <- x_train[my_index, , ]\n", + "y_train <- y_train[my_index]" + ], + "id": "67a07357-e145-4829-851f-98624341d987" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- keras_model_sequential() %>%\n", + " layer_flatten(input_shape = c(28, 28)) %>%\n", + " layer_dense(units = 256, activation = \"relu\") %>%\n", + " layer_dense(units = 10, activation = \"softmax\")\n", + "summary(my_model)\n", + "# \u5272\u611b\uff08Python\u306e\u7d50\u679c\u3092\u53c2\u7167\uff09\n", + "\n", + "my_model %>% compile(loss = \"sparse_categorical_crossentropy\",\n", + " optimizer = \"rmsprop\",\n", + " metrics = c(\"accuracy\"))\n", + "\n", + "my_cb <- callback_early_stopping(patience = 5,\n", + " restore_best_weights = TRUE)" + ], + "id": "24446c06-27c8-4d6c-9430-e5f3e3a53932" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_history <- my_model %>%\n", + " fit(x = x_train,\n", + " y = y_train,\n", + " validation_split = 0.2,\n", + " batch_size = 128,\n", + " epochs = 20,\n", + " callbacks = list(my_cb),\n", + " verbose = 0)\n", + "\n", + "plot(my_history)" + ], + "id": "1d8765ec-8988-472a-9796-a539b9c77899" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp <- my_model %>% predict(x_test)\n", + "y_ <- apply(tmp, 1, which.max) - 1\n", + "table(y_, y_test)" + ], + "id": "02828376-db58-4b96-89e6-ae8d30a77fc2" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [], + "id": "23b5a62b-83af-4096-999c-fadee5ef90cc" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mean(y_ == y_test)" + ], + "id": "39c5053c-2937-4212-b4ab-c3b96076bc80" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model %>%\n", + " evaluate(x = x_test, y = y_test)" + ], + "id": "2d96966e-200e-43cc-90ab-764c81a27ef2" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x_train2d <- x_train %>% array_reshape(c(-1, 28, 28, 1))\n", + "x_test2d <- x_test %>% array_reshape(c(-1, 28, 28, 1))" + ], + "id": "b8284d3d-e73a-4781-ace3-f46dbc587e3c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- keras_model_sequential() %>%\n", + " layer_conv_2d(filters = 32, kernel_size = 3, # \u7573\u307f\u8fbc\u307f\u5c64\n", + " activation = \"relu\",\n", + " input_shape = c(28, 28, 1)) %>%\n", + " layer_max_pooling_2d(pool_size = 2) %>% # \u30d7\u30fc\u30ea\u30f3\u30b0\u5c64\n", + " layer_flatten() %>%\n", + " layer_dense(units = 128, activation = \"relu\") %>%\n", + " layer_dense(units = 10, activation = \"softmax\")\n", + "\n", + "summary(my_model)\n", + "# \u5272\u611b\uff08Python \u306e\u7d50\u679c\u3092\u53c2\u7167\uff09\n", + "\n", + "my_model %>% compile(loss = \"sparse_categorical_crossentropy\",\n", + " optimizer = \"rmsprop\",\n", + " metrics = c(\"accuracy\"))\n", + "\n", + "my_cb <- callback_early_stopping(patience = 5,\n", + " restore_best_weights = TRUE)" + ], + "id": "e44598a9-a7d7-49f5-af9c-c6eabaf042fb" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_history <- my_model %>%\n", + " fit(x = x_train2d,\n", + " y = y_train,\n", + " validation_split = 0.2,\n", + " batch_size = 128,\n", + " epochs = 20,\n", + " callbacks = list(my_cb),\n", + " verbose = 0)\n", + "\n", + "plot(my_history)" + ], + "id": "dd640e4b-ac3f-40f3-8a2e-e507aca2f4cb" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model %>%\n", + " evaluate(x = x_test2d, y = y_test)" + ], + "id": "a427c67b-7df0-4da0-ac68-f67a2721b4d7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- keras_model_sequential() %>%\n", + " layer_conv_2d(filters = 20, kernel_size = 5, activation = \"relu\",\n", + " input_shape = c(28, 28, 1)) %>%\n", + " layer_max_pooling_2d(pool_size = 2, strides = 2) %>%\n", + " layer_conv_2d(filters = 50, kernel_size = 5, activation = \"relu\") %>%\n", + " layer_max_pooling_2d(pool_size = 2, strides = 2) %>%\n", + " layer_dropout(rate = 0.25) %>%\n", + " layer_flatten() %>%\n", + " layer_dense(units = 500, activation = \"relu\") %>%\n", + " layer_dropout(rate = 0.5) %>%\n", + " layer_dense(units = 10, activation = \"softmax\")\n", + "\n", + "my_model %>% compile(\n", + " loss = \"sparse_categorical_crossentropy\",\n", + " optimizer = \"rmsprop\",\n", + " metrics = c(\"accuracy\"))\n", + "\n", + "my_cb <- callback_early_stopping(patience = 5,\n", + " restore_best_weights = TRUE)" + ], + "id": "582ae7c3-94ed-468b-a987-d0e7f53a9e99" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_history <- my_model %>%\n", + " fit(x = x_train2d,\n", + " y = y_train,\n", + " validation_split = 0.2,\n", + " batch_size = 128,\n", + " epochs = 20,\n", + " callbacks = list(my_cb),\n", + " verbose = 0)\n", + "\n", + "plot(my_history)" + ], + "id": "7cc2ec11-6bba-4173-a5fd-30fb418c58ae" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model %>%\n", + " evaluate(x = x_test2d, y = y_test)" + ], + "id": "b1de224f-fac0-4609-a619-16b33687fc62" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_prob <- my_model %>% predict(x_test2d) # \u30ab\u30c6\u30b4\u30ea\u306b\u5c5e\u3059\u308b\u78ba\u7387\n", + "\n", + "my_result <- data.frame(\n", + " y_prob = apply(y_prob, 1, max), # \u78ba\u7387\u306e\u6700\u5927\u5024\n", + " y_ = apply(y_prob, 1, which.max) - 1, # \u4e88\u6e2c\u30ab\u30c6\u30b4\u30ea\n", + " y = y_test, # \u6b63\u89e3\n", + " id = seq_len(length(y_test))) %>% # \u756a\u53f7\n", + " filter(y_ != y) %>% # \u4e88\u6e2c\u304c\u306f\u305a\u308c\u305f\u3082\u306e\u3092\u6b8b\u3059\n", + " arrange(desc(y_prob)) # \u78ba\u7387\u306e\u5927\u304d\u3044\u9806\u306b\u4e26\u3073\u66ff\u3048\u308b" + ], + "id": "b11ef795-e857-4526-b57f-64e306cb1785" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "head(my_result)" + ], + "id": "4e4f6996-2e8f-4202-b753-4507bd09349a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp <- my_result[1:5, ]$id\n", + "my_labels <- sprintf(\"%s (%s)\",\n", + " my_result[1:5, ]$y, tmp)\n", + "my_fig <- expand.grid(\n", + " label = my_labels,\n", + " y = 28:1,\n", + " x = 1:28)\n", + "my_fig$z <- as.vector(\n", + " x_test[tmp, , ])\n", + "\n", + "my_fig %>% ggplot(\n", + " aes(x = x, y = y, fill = z)) +\n", + " geom_raster() +\n", + " coord_fixed() +\n", + " theme_void() +\n", + " theme(legend.position = \"none\") +\n", + " facet_grid(. ~ label)" + ], + "id": "386e1e97-556c-493a-b5c3-f70ee58326ba" + }, + { + "id": "408d59f5", + "cell_type": "markdown", + "source": "## 11.4 AutoML", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(h2o)\n", + "library(keras)\n", + "library(tidyverse)\n", + "\n", + "h2o.init()\n", + "h2o.no_progress()\n", + "# h2o.shutdown(prompt = FALSE) # \u505c\u6b62" + ], + "id": "c1e1dd2d-684c-4e86-abbb-a31c07784300" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_url <- str_c(\"https://raw.githubusercontent.com/taroyabuki\",\n", + " \"/fromzero/master/data/wine.csv\")\n", + "my_data <- read_csv(my_url)\n", + "my_frame <- as.h2o(my_data) # \u901a\u5e38\u306e\u30c7\u30fc\u30bf\u30d5\u30ec\u30fc\u30e0\u3092H2OFrame\u306b\u5909\u63db\u3059\u308b\uff0e\n", + "# \u3042\u308b\u3044\u306f\n", + "my_frame <- h2o.importFile(my_url, header = TRUE) # \u30c7\u30fc\u30bf\u3092\u8aad\u307f\u8fbc\u3080\uff0e" + ], + "id": "ecd111da-127b-4c8d-9e90-f9c091468867" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_frame\n", + "\n", + "# \u901a\u5e38\u306e\u30c7\u30fc\u30bf\u30d5\u30ec\u30fc\u30e0\u306b\u623b\u3059\uff0e\n", + "my_frame %>% as.data.frame %>% head\n", + "# \u7d50\u679c\u306f\u5272\u611b\uff08\u898b\u305f\u76ee\u306f\u540c\u3058\uff09" + ], + "id": "8db594c5-5aa1-4196-b763-fd628f1f61ba" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- h2o.automl(\n", + " y = \"LPRICE2\",\n", + " training_frame = my_frame,\n", + " max_runtime_secs = 60)" + ], + "id": "2255d94c-9ae3-48b3-9757-2a1c00493ef6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "min(my_model@leaderboard$rmse)" + ], + "id": "1fc1163e-77c2-4ae1-8f28-7da9ded46f62" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp <- my_model %>%\n", + " predict(my_frame) %>%\n", + " as.data.frame\n", + "y_ <- tmp$predict\n", + "y <- my_data$LPRICE2\n", + "\n", + "plot(y, y_)" + ], + "id": "19a260f7-87ea-4580-99a9-99f5af227a4b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist())\n", + "my_index <- sample(1:60000, 6000)\n", + "x_train <- x_train[my_index, , ]\n", + "y_train <- y_train[my_index]" + ], + "id": "e935eec8-efc9-4fee-9098-b67cb7e25bd6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp <- x_train %>%\n", + " array_reshape(c(-1, 28 * 28)) %>%\n", + " as.data.frame\n", + "tmp$y <- as.factor(y_train)\n", + "my_train <- as.h2o(tmp)\n", + "\n", + "tmp <- x_test %>%\n", + " array_reshape(c(-1, 28 * 28)) %>%\n", + " as.data.frame\n", + "my_test <- as.h2o(tmp)" + ], + "id": "575412c1-d66d-4dde-9ebf-3db515b34e1f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_model <- h2o.automl(\n", + " y = \"y\",\n", + " training_frame = my_train,\n", + " max_runtime_secs = 120)" + ], + "id": "28218f9b-6cf3-488d-9632-c31bda062ac0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "min(my_model@leaderboard$\n", + " mean_per_class_error)" + ], + "id": "8899da7a-c62d-467c-bd33-824838539c60" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp <- my_model %>%\n", + " predict(my_test) %>% as.data.frame\n", + "y_ <- tmp$predict\n", + "\n", + "mean(y_ == y_test)" + ], + "id": "34b0c5c1-da33-4355-b0d9-332a3a82f009" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "ir", + "display_name": "R" + } + } +} \ No newline at end of file diff --git a/code/R-notebook/r-12.ipynb b/code/R-notebook/r-12.ipynb new file mode 100644 index 0000000..ba45ab7 --- /dev/null +++ b/code/R-notebook/r-12.ipynb @@ -0,0 +1,276 @@ +{ + "cells": [ + { + "id": "51cb784e", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Google Colaboratory\u306e\u74b0\u5883\u8a2d\u5b9a\n", + "if (file.exists(\"/content\")) {\n", + " options(Ncpus = parallel::detectCores())\n", + " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"caret\", \"fable\", \"feasts\", \"prophet\", \"tsibble\", \"urca\")\n", + " install.packages(setdiff(packages_to_install, installed_packages))\n", + " install.packages(c(\"ggplot2\"))\n", + "}" + ], + "id": "eddf6905-02a7-4b1e-a5d7-d7ec120c142f" + }, + { + "id": "59c86d0c", + "cell_type": "markdown", + "source": "## 12.1 \u65e5\u6642\u3068\u65e5\u6642\u306e\u5217", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "as.POSIXct(\"2021-01-01\")" + ], + "id": "5ec4aa7d-7722-4429-bb21-c4caed4fe57f" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tsibble)\n", + "\n", + "seq(from = 2021, to = 2023, by = 1)\n", + "\n", + "seq(from = yearmonth(\"202101\"), to = yearmonth(\"202103\"), by = 2)\n", + "\n", + "seq(from = as.POSIXct(\"2021-01-01\"), to = as.POSIXct(\"2021-01-03\"), by = \"1 day\")\n", + "\n", + "seq(from = as.POSIXct(\"2021-01-01 00:00:00\"),\n", + " to = as.POSIXct(\"2021-01-01 03:00:00\"), by = \"2 hour\")" + ], + "id": "675b15bd-2033-4f3e-b2cf-0e560864db9f" + }, + { + "id": "b4c4b7ad", + "cell_type": "markdown", + "source": "## 12.2 \u6642\u7cfb\u5217\u30c7\u30fc\u30bf\u306e\u4e88\u6e2c", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_data <- as.vector(AirPassengers)" + ], + "id": "e36277e0-9ca4-4df2-8f3a-baf2e9e0e1a7" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "n <- length(my_data) # \u30c7\u30fc\u30bf\u6570\uff08144\uff09\n", + "k <- 108 # \u8a13\u7df4\u30c7\u30fc\u30bf\u6570" + ], + "id": "90063818-45b6-410f-9924-00f136d5420b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)\n", + "library(tsibble)\n", + "\n", + "my_ds <- seq(\n", + " from = yearmonth(\"1949/01\"),\n", + " to = yearmonth(\"1960/12\"),\n", + " by = 1)\n", + "my_label <- rep(\n", + " c(\"train\", \"test\"),\n", + " c(k, n - k))\n", + "my_df <- tsibble(\n", + " ds = my_ds,\n", + " x = 0:(n - 1),\n", + " y = my_data,\n", + " label = my_label,\n", + " index = ds) # \u65e5\u6642\u306e\u5217\u306e\u6307\u5b9a\n", + "\n", + "head(my_df)" + ], + "id": "99517db5-867e-41eb-9d79-66520a2a8b81" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_train <- my_df[ 1:k , ]\n", + "my_test <- my_df[-(1:k), ]\n", + "y <- my_test$y" + ], + "id": "2e58060f-b2ff-4192-a044-45593d987bb0" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_plot <- my_df %>%\n", + " ggplot(aes(x = ds,\n", + " y = y,\n", + " color = label)) +\n", + " geom_line()\n", + "my_plot" + ], + "id": "dc60b954-cfce-4b3f-906a-3044cadea3f2" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(caret)\n", + "my_lm_model <- train(form = y ~ x, data = my_train, method = \"lm\")\n", + "y_ <- my_lm_model %>% predict(my_test)\n", + "caret::RMSE(y, y_) # RMSE\uff08\u30c6\u30b9\u30c8\uff09" + ], + "id": "2c689f93-44d4-4195-944b-8caedf4884c3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_ <- my_lm_model %>% predict(my_df)\n", + "tmp <- my_df %>%\n", + " mutate(y = y_, label = \"model\")\n", + "my_plot + geom_line(data = tmp)" + ], + "id": "e1f33c13-600b-4275-b669-b458559edfe6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(fable)\n", + "my_arima_model <- my_train %>% model(ARIMA(y))\n", + "my_arima_model" + ], + "id": "0d04fc7b-3f79-43f1-bec7-68b4e4015b46" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp <- my_arima_model %>% forecast(h = \"3 years\")\n", + "head(tmp)" + ], + "id": "a873f192-d59b-456a-bc52-d19a87eeaa8d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_ <- tmp$.mean\n", + "caret::RMSE(y_, y)" + ], + "id": "10072df9-b095-4e9e-a36d-5ee742abbc12" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# \u4e88\u6e2c\u7d50\u679c\u306e\u307f\u3067\u3088\u3044\u5834\u5408\n", + "#tmp %>% autoplot\n", + "\n", + "tmp %>% autoplot +\n", + " geom_line(data = my_df,\n", + " aes(x = ds,\n", + " y = y,\n", + " color = label))" + ], + "id": "c516b971-7a33-47b9-a152-c3523600b20a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(prophet)\n", + "my_prophet_model <- my_train %>%\n", + " prophet(seasonality.mode = \"multiplicative\")" + ], + "id": "3dc92185-3c65-46af-8f3e-8968890820cf" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp <- my_prophet_model %>% predict(my_test)\n", + "head(tmp[, c(\"ds\", \"yhat\", \"yhat_lower\", \"yhat_upper\")])" + ], + "id": "c46d2cc3-e12a-4bab-8c1d-8506bcce626e" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "y_ <- tmp$yhat\n", + "caret::RMSE(y_, y)" + ], + "id": "c9e7c2c1-316e-4707-b527-d4fa996cacd3" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# my_prophet_model %>% plot(tmp) # \u4e88\u6e2c\u7d50\u679c\u306e\u307f\u3067\u3088\u3044\u5834\u5408\n", + "\n", + "my_prophet_model %>% plot(tmp) +\n", + " geom_line(data = my_train, aes(x = as.POSIXct(ds))) +\n", + " geom_line(data = my_test, aes(x = as.POSIXct(ds)), color = \"red\")" + ], + "id": "d203162b-363b-45b4-8349-24f0df4a8ef0" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "ir", + "display_name": "R" + } + } +} \ No newline at end of file diff --git a/code/R-notebook/r-13.ipynb b/code/R-notebook/r-13.ipynb new file mode 100644 index 0000000..276e9b4 --- /dev/null +++ b/code/R-notebook/r-13.ipynb @@ -0,0 +1,323 @@ +{ + "cells": [ + { + "id": "9489e381", + "cell_type": "markdown", + "source": "[\u8fbb\u771f\u543e\u30fb\u77e2\u5439\u592a\u6717\u300e\u30bc\u30ed\u304b\u3089\u306f\u3058\u3081\u308b\u30c7\u30fc\u30bf\u30b5\u30a4\u30a8\u30f3\u30b9\u5165\u9580\u300f\uff08\u8b1b\u8ac7\u793e,\u00a02021\uff09](https://github.com/taroyabuki/fromzero)", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Google Colaboratory\u306e\u74b0\u5883\u8a2d\u5b9a\n", + "if (file.exists(\"/content\")) {\n", + " options(Ncpus = parallel::detectCores())\n", + " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"factoextra\", \"ggbiplot\", \"igraph\")\n", + " install.packages(setdiff(packages_to_install, installed_packages))\n", + "}" + ], + "id": "65e4496c-ce1e-4af3-9e61-4e6832172178" + }, + { + "id": "6ce28508", + "cell_type": "markdown", + "source": "## 13.1 \u4e3b\u6210\u5206\u5206\u6790", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)\n", + "\n", + "my_data <- data.frame(\n", + " language = c( 0, 20, 20, 25, 22, 17),\n", + " english = c( 0, 20, 40, 20, 24, 18),\n", + " math = c(100, 20, 5, 30, 17, 25),\n", + " science = c( 0, 20, 5, 25, 16, 23),\n", + " society = c( 0, 20, 30, 0, 21, 17),\n", + " row.names = c(\"A\", \"B\", \"C\", \"D\", \"E\", \"F\"))\n", + "my_result <- my_data %>% prcomp # \u4e3b\u6210\u5206\u5206\u6790\u306e\u5b9f\u884c" + ], + "id": "f7addff0-82d8-405e-9d3c-c77e7511106d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_result$x # \u4e3b\u6210\u5206\u30b9\u30b3\u30a2" + ], + "id": "c94ef6c8-8254-43df-9604-53dd866af41b" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_result %>% ggbiplot::ggbiplot(\n", + " labels = row.names(my_data),\n", + " scale = 0)" + ], + "id": "ca328f8f-3a54-495e-bfc2-014ddd5ac988" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_result$rotation %>% t" + ], + "id": "43d6225f-d747-42aa-b18a-41e50050c6d6" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "summary(my_result)" + ], + "id": "196ab454-f3a6-4877-a66c-a74671a22c40" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_result <- prcomp(\n", + " x = my_data,\n", + " scale = TRUE) # \u6a19\u6e96\u5316\n", + "# \u3042\u308b\u3044\u306f\n", + "my_result <- prcomp(\n", + " x = scale(my_data)) # \u6a19\u6e96\u5316\u30c7\u30fc\u30bf\n", + "\n", + "my_result$x # \u4e3b\u6210\u5206\u30b9\u30b3\u30a2" + ], + "id": "97a8c7d3-cc4e-476d-b7ff-85cb61710757" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "Z <- my_data %>% scale(scale = FALSE) %>% as.matrix # \u6a19\u6e96\u5316\u3057\u306a\u3044\u5834\u5408\n", + "#Z <- my_data %>% scale(scale = TRUE) %>% as.matrix # \u6a19\u6e96\u5316\u3059\u308b\u5834\u5408\n", + "\n", + "n <- nrow(my_data)\n", + "S <- var(Z) # \u5206\u6563\u5171\u5206\u6563\u884c\u5217\n", + "#S <- t(Z) %*% Z / (n - 1) # \uff08\u540c\u3058\u7d50\u679c\uff09\n", + "tmp <- eigen(S) # \u56fa\u6709\u5024\u3068\u56fa\u6709\u30d9\u30af\u30c8\u30eb\n", + "Z %*% tmp$vectors # \u4e3b\u6210\u5206\u30b9\u30b3\u30a2\uff08\u7d50\u679c\u306f\u5272\u611b\uff09\n", + "cumsum(tmp$values) / sum(tmp$values) # \u7d2f\u7a4d\u5bc4\u4e0e\u7387" + ], + "id": "4dc0ab4a-1d9c-46c7-b516-1a51b990ae40" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "udv <- svd(Z) # \u7279\u7570\u5024\u5206\u89e3\n", + "U <- udv$u\n", + "d <- udv$d\n", + "V <- udv$v\n", + "W <- diag(d)\n", + "\n", + "c(all.equal(Z, U %*% W %*% t(V), check.attributes = FALSE), # \u78ba\u8a8d1\n", + " all.equal(t(U) %*% U, diag(dim(U)[2])), # \u78ba\u8a8d2\n", + " all.equal(t(V) %*% V, diag(dim(V)[2]))) # \u78ba\u8a8d3\n", + "\n", + "U %*% W # \u4e3b\u6210\u5206\u30b9\u30b3\u30a2\uff08\u7d50\u679c\u306f\u5272\u611b\uff09\n", + "\n", + "e <- d^2 / (n - 1) # \u5206\u6563\u5171\u5206\u6563\u884c\u5217\u306e\u56fa\u6709\u5024\n", + "cumsum(e) / sum(e) # \u7d2f\u7a4d\u5bc4\u4e0e\u7387" + ], + "id": "2973a72f-df12-4bce-ade3-b5830fe79acc" + }, + { + "id": "448d7fd4", + "cell_type": "markdown", + "source": "## 13.2 \u30af\u30e9\u30b9\u30bf\u5206\u6790", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)\n", + "\n", + "my_data <- data.frame(\n", + " x = c( 0, -16, 10, 10),\n", + " y = c( 0, 0, 10, -15),\n", + " row.names = c(\"A\", \"B\", \"C\", \"D\"))\n", + "\n", + "my_result <- my_data %>%\n", + " dist(\"euclidian\") %>% # dist\u3060\u3051\u3067\u3082\u53ef\n", + " hclust(\"complete\") # hclust\u3060\u3051\u3067\u3082\u53ef" + ], + "id": "3c5f1f80-5df7-4c12-ac69-11caae1890d8" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_result %>% factoextra::fviz_dend(\n", + " k = 3, # \u30af\u30e9\u30b9\u30bf\u6570\n", + " rect = TRUE, rect_fill = TRUE)" + ], + "id": "ded85d58-a9dd-47ee-8e96-5c0e5be58975" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_result %>% factoextra::fviz_dend(\n", + " k = 3,\n", + " rect = TRUE, rect_fill = TRUE,\n", + " type = \"phylogenic\")" + ], + "id": "91e8e646-23a0-426c-8065-9da32d26a4cf" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_result %>% cutree(3)" + ], + "id": "81aa312a-c8d8-407f-a140-754dc612c938" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)\n", + "\n", + "my_data <- data.frame(\n", + " language = c( 0, 20, 20, 25, 22, 17),\n", + " english = c( 0, 20, 40, 20, 24, 18),\n", + " math = c(100, 20, 5, 30, 17, 25),\n", + " science = c( 0, 20, 5, 25, 16, 23),\n", + " society = c( 0, 20, 30, 0, 21, 17),\n", + " row.names = c(\"A\", \"B\", \"C\", \"D\", \"E\", \"F\"))\n", + "\n", + "try( # RMarkdown\u3067\u767a\u751f\u3059\u308b\u30a8\u30e9\u30fc\u3092\u56de\u907f\u3059\u308b\uff0e\n", + " my_data %>% scale %>% # \u5217\u3054\u3068\u306e\u6a19\u6e96\u5316\n", + " gplots::heatmap.2(cexRow = 1, cexCol = 1), # \u30e9\u30d9\u30eb\u306e\u30b5\u30a4\u30ba\u3092\u6307\u5b9a\u3057\u3066\u63cf\u753b\u3059\u308b\uff0e\n", + " silent = TRUE)" + ], + "id": "bd195bdf-083a-4b3e-bee6-a365acf5d8fe" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)\n", + "\n", + "my_data <- data.frame(\n", + " x = c( 0, -16, 10, 10),\n", + " y = c( 0, 0, 10, -15),\n", + " row.names = c(\"A\", \"B\", \"C\", \"D\"))\n", + "\n", + "my_result <- my_data %>% kmeans(3)" + ], + "id": "c33d2025-f37c-4d71-8ae4-fa7058c2297d" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_result$cluster" + ], + "id": "4df04a35-942a-4ff7-92a0-e3f1c678125a" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)\n", + "library(factoextra)\n", + "\n", + "my_data <- iris[, -5]\n", + "\n", + "f <- 2:5 %>% map(function(k) {\n", + " my_data %>% kmeans(k) %>%\n", + " fviz_cluster(data = my_data, geom = \"point\") +\n", + " ggtitle(sprintf(\"k = %s\", k))\n", + "})\n", + "gridExtra::grid.arrange(f[[1]], f[[2]], f[[3]], f[[4]], ncol = 2)" + ], + "id": "f1bbad8f-594e-4b9b-90c6-4b76bee01fba" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fviz_nbclust(my_data, kmeans, method = \"wss\")" + ], + "id": "edfe198b-bf41-4c6a-8024-ba5d0d59c3ea" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "library(tidyverse)\n", + "my_data <- iris[, -5] %>% scale\n", + "\n", + "my_result <- prcomp(my_data)$x %>% as.data.frame # \u4e3b\u6210\u5206\u5206\u6790\n", + "\n", + "# \u975e\u968e\u5c64\u7684\u30af\u30e9\u30b9\u30bf\u5206\u6790\u306e\u5834\u5408\n", + "my_result$cluster <- (my_data %>% scale %>% kmeans(3))$cluster %>% as.factor\n", + "\n", + "# \u968e\u5c64\u7684\u30af\u30e9\u30b9\u30bf\u5206\u6790\u306e\u5834\u5408\n", + "#my_result$cluster <- my_data %>% dist %>% hclust %>% cutree(3) %>% as.factor\n", + "\n", + "my_result %>%\n", + " ggplot(aes(x = PC1, y = PC2, color = cluster)) + # \u8272\u3067\u30af\u30e9\u30b9\u30bf\u3092\u8868\u73fe\u3059\u308b\uff0e\n", + " geom_point(shape = iris$Species) + # \u5f62\u3067\u54c1\u7a2e\u3092\u8868\u73fe\u3059\u308b\uff0e\n", + " theme(legend.position = \"none\")" + ], + "id": "9002b283-f5ca-49a0-b5e3-00e069f7a25a" + } + ], + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "name": "ir", + "display_name": "R" + } + } +} \ No newline at end of file diff --git a/code/R/ch03/03.01.R b/code/R/ch03/03.01.R deleted file mode 100644 index 3fca5a5..0000000 --- a/code/R/ch03/03.01.R +++ /dev/null @@ -1,93 +0,0 @@ -## 3.1 入門 - -### 3.1.1 数値 - -0x10 -#> [1] 16 - -1.23e5 -#> [1] 123000 - -2 * 3 -#> [1] 6 - -10 / 3 -#> [1] 3.333333 - -10 %/% 3 # 商 -#> [1] 3 - -10 %% 3 # 余り -#> [1] 1 - -### 3.1.2 変数 - -x <- 2 -y <- 3 -x * y -#> [1] 6 - -keras::`%<-%`(c(x, y), c(20, 30)) # まとめて名付け -x * y -#> [1] 600 - -x <- 1 + 1 -# この段階では結果は表示されない - -x # 変数名を評価する. -#> [1] 2 - -### 3.1.3 文字列 - -my_s <- "abcde" - -nchar(my_s) -#> [1] 5 - -library(tidyverse) -str_c("This is ", "a", " pen.") -#> [1] "This is a pen." - -substr(x = my_s, start = 2, stop = 4) -#> [1] "bcd" - -tmp <- "%s is %s." -sprintf(tmp, "This", "a pen") -#> [1] "This is a pen." - -### 3.1.4 論理値 - -1 <= 2 -#> [1] TRUE - -1 < 0 -#> [1] FALSE - -0.1 + 0.1 + 0.1 == 0.3 -#> [1] FALSE - -all.equal(0.1 + 0.1 + 0.1, 0.3) -#> [1] TRUE - -TRUE & FALSE # 論理積(かつ) -#> [1] FALSE - -TRUE | FALSE # 論理和(または) -#> [1] TRUE - -!TRUE # 否定(でない) -#> [1] FALSE - -#### 3.1.4.1 条件演算子 - -ifelse(3 < 5, 0, 10) -#> 0 - -### 3.1.5 作業ディレクトリ - -getwd() -#> '/home/jovyan/work' - -setwd("..") -getwd() -#> '/home/jovyan' diff --git a/code/R/ch03/03.02.R b/code/R/ch03/03.02.R deleted file mode 100644 index df0dd81..0000000 --- a/code/R/ch03/03.02.R +++ /dev/null @@ -1,55 +0,0 @@ -## 3.2 関数 - -### 3.2.1 関数の利用 - -sqrt(4) -#> [1] 2 - -log(100, 10) -#> [1] 2 - -log(100) # 自然対数 -# あるいは -log(100, exp(1)) # 省略しない場合 - -#> [1] 4.60517 - -log10(100) # 常用対数 -#> [1] 2 - -log2(1024) # 底が2の対数 -#> [1] 10 - -#### 3.2.1.1 パイプ(Rのみ) - -library(tidyverse) -4 %>% sqrt - -exp(log(5)) # 通常の書き方 -# あるいは -5 %>% log %>% exp # パイプを使う書き方 - -#> 5 - -### 3.2.2 関数の定義 - -f <- function(a, b) { - a - b -} - -f(3, 5) -#> [1] -2 - -#### 3.2.2.1 デフォルト引数 - -f <- function(a, b = 5) { - a - b -} - -f(3) # f(3, 5)と同じこと -#> [1] -2 - -#### 3.2.2.2 無名関数 - -(function(a, b) { a - b })(3, 5) -#> [1] -2 diff --git a/code/R/ch03/03.03.R b/code/R/ch03/03.03.R deleted file mode 100644 index 8077125..0000000 --- a/code/R/ch03/03.03.R +++ /dev/null @@ -1,142 +0,0 @@ -## 3.3 コレクション - -### 3.3.1 1次元データ - -x <- c("foo", "bar", "baz") - -length(x) -#> [1] 3 - -x[2] -#> [1] "bar" - -x[2] <- "BAR" -x # 結果の確認 -#> [1] "foo" "BAR" "baz" - -x[2] <- "bar" # 元に戻す. - -x[-2] -#> [1] "foo" "baz" - -c(x, "qux") -#> [1] "foo" "bar" "baz" "qux" - -x <- c(x, "qux") -x # 結果の確認 -#> [1] "foo" "bar" "baz" "qux" - -#### 3.3.1.1 等間隔の数値からなる1次元データ - -1:5 -#> [1] 1 2 3 4 5 - -seq(from = 0, to = 10, by = 2) -#> [1] 0 2 4 6 8 10 - -seq(from = 0, to = 1, by = 0.5) -#> [1] 0.0 0.5 1.0 - -seq(from = 0, to = 100, length.out = 5) -#> [1] 0 25 50 75 100 - -rep(x = 10, times = 5) -#> [1] 10 10 10 10 10 - -#### 3.3.1.2 ファクタ(Rのみ) - -tmp <- c("グー", "パー", "グー", "パー") -x <- factor(tmp, levels = c("グー", "チョキ", "パー")) -x -#> [1] グー パー グー パー -#> Levels: グー チョキ パー - -### 3.3.2 数値計算やデータ解析用の1次元データ - -x <- c(2, 3, 5, 7) - -x + 10 # 加算 -#> [1] 12 13 15 17 - -x * 10 # 乗算 -#> [1] 20 30 50 70 - -x <- c(2, 3) -sin(x) -#> [1] 0.9092974 0.1411200 - -x <- c(2, 3, 5, 7) -y <- c(1, 10, 100, 1000) -x + y -#> [1] 3 13 105 1007 - -x * y -#> [1] 2 30 500 7000 - -sum(x * y) -#> [1] 7532 - -x <- c(TRUE, FALSE) -y <- c(TRUE, TRUE) -x & y -#> [1] TRUE FALSE - -#### 3.3.2.1 1次元データ同士の比較 - -u <- c(1, 2, 3) -v <- c(1, 2, 3) -w <- c(1, 2, 4) - -identical(u, v) # 全体の比較 -#> [1] TRUE - -identical(u, w) # 全体の比較 -#> [1] FALSE - -u == v # 要素ごとの比較 -#> [1] TRUE TRUE TRUE - -u == w # 要素ごとの比較 -#> [1] TRUE TRUE FALSE - -sum(u == w) # 同じ要素の数 -#> [1] 2 - -mean(u == w) # 同じ要素の割合 -#> [1] 0.6666667 - -### 3.3.3 複数種類のデータをひとまとめにする - -x <- list(1, "two") - -x[[2]] -#> [1] "two" - -### 3.3.4 文字列と値のペアのコレクション - -x <- list("apple" = "りんご", - "orange" = "みかん") - -x[["grape"]] <- "ぶどう" - -x$apple -# あるいは -x$"apple" -# あるいは -x[["apple"]] -# あるいは -tmp <- "apple" -x[[tmp]] - -#> [1] "りんご" - -### 3.3.5 補足:コピーと参照 - -x <- c("foo", "bar", "baz") -y <- x -y[2] <- "BAR" # yを更新する. -y -#> [1] "foo" "BAR" "baz" - -x # xは変わらない. -#> [1] "foo" "bar" "baz" diff --git a/code/R/ch03/03.04.R b/code/R/ch03/03.04.R deleted file mode 100644 index 09b7f99..0000000 --- a/code/R/ch03/03.04.R +++ /dev/null @@ -1,259 +0,0 @@ -## 3.4 データフレーム - -### 3.4.1 データフレームの作成 - -library(tidyverse) - -#### 3.4.1.1 データを列ごとに記述する方法 - -my_df <- data.frame( - name = c("A", "B", "C", "D"), - english = c( 60, 90, 70, 90), - math = c( 70, 80, 90, 100), - gender = c("f", "m", "m", "f")) - -#### 3.4.1.2 データを見た目のとおりに記述する方法 - -my_df <- tribble( - ~name, ~english, ~math, ~gender, - "A", 60, 70, "f", - "B", 90, 80, "m", - "C", 70, 90, "m", - "D", 90, 100, "f") - -head(my_df) -# 結果は割愛 - -#### 3.4.1.3 データフレームのサイズ - -dim(my_df) # 行数と列数 -#> [1] 4 4 - -nrow(my_df) # 行数 -#> [1] 4 - -ncol(my_df) # 列数 -#> [1] 4 - -#### 3.4.1.4 組合せ - -my_df2 <- expand.grid( - X = c(1, 2, 3), - Y = c(10, 100)) -my_df2 -#> X Y -#> 1 1 10 -#> 2 2 10 -#> 3 3 10 -#> 4 1 100 -#> 5 2 100 -#> 6 3 100 - -#### 3.4.1.5 列と行の名前 - -colnames(my_df2) -#> [1] "X" "Y" - -colnames(my_df2) <- c("P", "Q") -my_df2 -#> P Q -#> 1 1 10 -#> 2 2 10 -# 以下省略 - -row.names(my_df) -#> [1] "1" "2" "3" "4" - -row.names(my_df2) <- - c("a", "b", "c", "d", "e", "f") -my_df2 -#> P Q -#> a 1 10 -#> b 2 10 -#> c 3 10 -# 以下省略 - -my_df3 <- data.frame( - english = c( 60, 90, 70, 90), - math = c( 70, 80, 90, 100), - gender = c("f", "m", "m", "f"), - row.names = c("A", "B", "C", "D")) -my_df3 -#> english math gender -#> A 60 70 f -#> B 90 80 m -#> C 70 90 m -#> D 90 100 f - -### 3.4.2 データの追加 - -#### 3.4.2.1 行の追加(データフレームの結合) - -tmp <- data.frame( - name = "E", - english = 80, - math = 80, - gender = "m") -my_df2 <- rbind(my_df, tmp) - -#### 3.4.2.2 列の追加 - -my_df2 <- my_df %>% - mutate(id = c(1, 2, 3, 4)) - -my_df3 <- my_df # コピー -my_df3["id"] <- c(1, 2, 3, 4) # 更新 -my_df3 # 結果の確認(割愛) - -### 3.4.3 データの取り出し - -#### 3.4.3.1 観測値の取り出し - -my_df[1, 2] -#> [1] 60 - -#### 3.4.3.2 1列の取り出し(結果は1次元データ) - -x <- my_df[, 2] -# あるいは -x <- my_df$english -# あるいは -x <- my_df$"english" -# あるいは -x <- my_df[["english"]] -# あるいは -tmp <- "english" -x <- my_df[[tmp]] - -x # 結果の確認(割愛) - -#### 3.4.3.3 複数列の取り出し(結果はデータフレーム) - -x <- my_df %>% select(name, math) - -x <- my_df[, c(1, 3)] - -x <- my_df %>% - select(-c(english, gender)) -# あるいは -x <- my_df[, -c(2, 4)] - -#### 3.4.3.4 複数行の取り出し(結果はデータフレーム) - -x <- my_df[c(1, 3), ] - -x <- my_df[-c(2, 4), ] - -#### 3.4.3.5 検索 - -x <- my_df[my_df$gender == "m", ] -# あるいは -x <- my_df %>% filter(gender == "m") - -x <- my_df[my_df$english > 80 & my_df$gender == "m", ] -# あるいは -x <- my_df %>% filter(english > 80 & gender == "m") - -x <- my_df[my_df$english == max(my_df$english), ] -# あるいは -x <- my_df %>% filter(english == max(my_df$english)) - -my_df2 <- my_df # コピー -my_df2[my_df$gender == "m", ]$gender <- "M" - -my_df2 -#> name english math gender -#> 1 A 60 70 f -#> 2 B 90 80 M -#> 3 C 70 90 M -#> 4 D 90 100 f - -#### 3.4.3.6 並べ替え - -x <- my_df %>% arrange(english) - -x <- my_df %>% arrange(-english) - -### 3.4.4 補足:行列 - -#### 3.4.4.1 行列の生成 - -x <- c(2, 3, 5, 7, 11, 13, 17, 19, 23, - 29, 31, 37) -A <- matrix( - data = x, # 1次元データ - nrow = 3, # 行数 - byrow = TRUE) # 行ごとの生成 -A -#> [,1] [,2] [,3] [,4] -#> [1,] 2 3 5 7 -#> [2,] 11 13 17 19 -#> [3,] 23 29 31 37 - -#### 3.4.4.2 データフレームと行列 - -A <- my_df[, c(2, 3)] %>% as.matrix -A -#> english math -#> [1,] 60 70 -#> [2,] 90 80 -#> [3,] 70 90 -#> [4,] 90 100 - -as.data.frame(A) -#> english math -#> 1 60 70 -#> 2 90 80 -#> 3 70 90 -#> 4 90 100 - -#### 3.4.4.3 行列の変形 - -t(A) -#> [,1] [,2] [,3] [,4] -#> english 60 90 70 90 -#> math 70 80 90 100 - -#### 3.4.4.4 行列の積 - -t(A) %*% A -#> english math -#> english 24700 26700 -#> math 26700 29400 - -### 3.4.5 縦型と横型 - -my_wider <- data.frame( - day = c(25, 26, 27), - min = c(20, 21, 15), - max = c(24, 27, 21)) - -my_longer <- my_wider %>% - pivot_longer(-day) -my_longer -#> # A tibble: 6 x 3 -#> day name value -#> -#> 1 25 min 20 -#> 2 25 max 24 -#> 3 26 min 21 -#> 4 26 max 27 -#> 5 27 min 15 -#> 6 27 max 21 - -my_longer %>% pivot_wider() -#> # A tibble: 3 x 3 -#> day min max -#> -#> 1 25 20 24 -#> 2 26 21 27 -#> 3 27 15 21 - -my_longer %>% - ggplot(aes(x = day, y = value, - color = name)) + - geom_point() + - geom_line() + - ylab("temperature") + # y軸ラベル - scale_x_continuous( - breaks = my_longer$day) # x軸目盛り diff --git a/code/R/ch03/03.05.R b/code/R/ch03/03.05.R deleted file mode 100644 index 5f4f8dc..0000000 --- a/code/R/ch03/03.05.R +++ /dev/null @@ -1,80 +0,0 @@ -## 3.5 1次元データの(非)類似度 - -### 3.5.1 ユークリッド距離 - -A <- c(3, 4, 5) -B <- c(3, 4, 29) -C <- c(9, -18, 8) -AB <- B - A -AC <- C - A - -sum(AB^2)^0.5 -#> [1] 24 - -sum(AC^2)^0.5 -#> [1] 23 - -### 3.5.2 マンハッタン距離 - -sum(abs(AB)) -#> [1] 24 - -sum(abs(AC)) -#> [1] 31 - -### 3.5.3 コサイン類似度 - -sum(A * B) / - sum(A * A)^0.5 / sum(B * B)^0.5 -#> [1] 0.8169679 - -sum(A * C) / - sum(A * A)^0.5 / sum(C * C)^0.5 -#> [1] -0.03265116 - -### 3.5.4 相関係数 - -cor(A, B) -#> [1] 0.8824975 - -cor(A, C) -#> [1] -0.03266277 - -#### 3.5.4.1 データフレームを使う方法 - -library(tidyverse) - - - -my_df <- data.frame( - x = c(3, 3, 9), - y = c(4, 4, -18), - z = c(5, 29, 8), - row.names = c("A", "B", "C")) - -# ユークリッド距離 -my_df %>% proxy::dist("Euclidean") -#> A B -#> B 24 -#> C 23 31 - - -# マンハッタン距離 -my_df %>% proxy::dist("Manhattan") -#> A B -#> B 24 -#> C 31 49 - - -# コサイン類似度 -my_df %>% proxy::simil("cosine") -#> A B -#> B 0.81696786 -#> C -0.03265116 0.29342441 - - -# 相関係数 -my_df %>% proxy::simil("correlation") -#> A B -#> B 0.88249750 -#> C -0.03266277 0.44124132 diff --git a/code/R/ch03/03.06.R b/code/R/ch03/03.06.R deleted file mode 100644 index 761bb48..0000000 --- a/code/R/ch03/03.06.R +++ /dev/null @@ -1,7 +0,0 @@ -## 3.6 Rのパッケージ,Pythonのモジュール - -### 3.6.1 Rのパッケージ - -library(tidyverse) - -### 3.6.2 Pythonのモジュール diff --git a/code/R/ch03/03.07.R b/code/R/ch03/03.07.R deleted file mode 100644 index 585ca49..0000000 --- a/code/R/ch03/03.07.R +++ /dev/null @@ -1,104 +0,0 @@ -## 3.7 反復処理 - -library(tidyverse) - -### 3.7.1 指定した回数→1次元データ - -f1 <- function(x) { - tmp <- runif(x) - mean(tmp) -} - -f1(10) # 動作確認 -#> [1] 0.5776604 # 結果の例 - -replicate(n = 3, expr = f1(10)) -#> [1] 0.4672766 0.4712016 0.5579449 - -rep(x = f1(10), times = 3) -#> [1] 0.481329 0.481329 0.481329 - -### 3.7.2 1次元データ→1次元データ - -v <- c(5, 10, 100) -v %>% map_dbl(f1) -#> [1] 0.4857329 0.5322183 0.5084124 - -rep(x = 10, times = 3) %>% map_dbl(f1) -# 結果は割愛 - -### 3.7.3 1次元データ→データフレーム - -f2 <- function(n) { - tmp <- runif(n) - list(x = n, - p = mean(tmp), - q = sd(tmp)) -} - -f2(10) # 動作確認 -#> $x -#> [1] 10 -#> -#> $p -#> [1] 0.6840032 (平均の例) -#> -#> $q -#> [1] 0.3750788 (標準偏差の例) - -v <- c(5, 10, 100) -v %>% map_dfr(f2) -#> x p q -#> -#> 1 5 0.560 0.320 -#> 2 10 0.559 0.271 -#> 3 100 0.507 0.283 - -### 3.7.4 データフレーム→データフレーム - -f3 <- function(x, y) { - tmp <- runif(x, min = 1, - max = y + 1) %>% - as.integer - list(x = x, - y = y, - p = mean(tmp), - q = sd(tmp)) -} - -f3(x = 10, y = 6) # 動作確認 -#> $x -#> [1] 10 -#> -#> $y -#> [1] 6 -#> -#> $p -#> [1] 3.2 (平均の例) -#> -#> $q -#> [1] 1.316561 (標準偏差の例) - -my_df <- data.frame( - x = c(5, 10, 100, 5, 10, 100), - y = c(6, 6, 6, 12, 12, 12)) - -my_df %>% pmap_dfr(f3) -#> x y p q -#> -#> 1 5 6 3 1.41 -#> 2 10 6 3 1.49 -#> 3 100 6 3.57 1.78 -#> 4 5 12 7.6 5.22 -#> 5 10 12 5.7 3.77 -#> 6 100 12 6.36 3.59 - -### 3.7.5 補足:反復処理の並列化 - -library(furrr) -plan(multisession) # 準備 - -v <- c(5, 10, 100) -v %>% future_map_dbl(f1, .options = - furrr_options(seed = TRUE)) -# 結果は割愛 diff --git a/code/R/ch03/03.08.R b/code/R/ch03/03.08.R deleted file mode 100644 index c48f8e1..0000000 --- a/code/R/ch03/03.08.R +++ /dev/null @@ -1,25 +0,0 @@ -## 3.8 その他 - -### 3.8.1 よく遭遇するエラーとその対処方法 - -### 3.8.2 変数や関数についての調査 - -x <- 123 -typeof(x) -#> [1] "double" - -?log -# あるいは -help(log) - -### 3.8.3 RのNA,Pythonのnan - -v <- c(1, NA, 3) -v -#> [1] 1 NA 3 - -is.na(v[2]) -#> [1] TRUE - -v[2] == NA # 誤り -#> [1] NA diff --git a/code/R/ch03/03.R b/code/R/ch03/03.R deleted file mode 100644 index c53fb9d..0000000 --- a/code/R/ch03/03.R +++ /dev/null @@ -1,773 +0,0 @@ -## 3.1 入門 - -### 3.1.1 数値 - -0x10 -#> [1] 16 - -1.23e5 -#> [1] 123000 - -2 * 3 -#> [1] 6 - -10 / 3 -#> [1] 3.333333 - -10 %/% 3 # 商 -#> [1] 3 - -10 %% 3 # 余り -#> [1] 1 - -### 3.1.2 変数 - -x <- 2 -y <- 3 -x * y -#> [1] 6 - -keras::`%<-%`(c(x, y), c(20, 30)) # まとめて名付け -x * y -#> [1] 600 - -x <- 1 + 1 -# この段階では結果は表示されない - -x # 変数名を評価する. -#> [1] 2 - -### 3.1.3 文字列 - -my_s <- "abcde" - -nchar(my_s) -#> [1] 5 - -library(tidyverse) -str_c("This is ", "a", " pen.") -#> [1] "This is a pen." - -substr(x = my_s, start = 2, stop = 4) -#> [1] "bcd" - -tmp <- "%s is %s." -sprintf(tmp, "This", "a pen") -#> [1] "This is a pen." - -### 3.1.4 論理値 - -1 <= 2 -#> [1] TRUE - -1 < 0 -#> [1] FALSE - -0.1 + 0.1 + 0.1 == 0.3 -#> [1] FALSE - -all.equal(0.1 + 0.1 + 0.1, 0.3) -#> [1] TRUE - -TRUE & FALSE # 論理積(かつ) -#> [1] FALSE - -TRUE | FALSE # 論理和(または) -#> [1] TRUE - -!TRUE # 否定(でない) -#> [1] FALSE - -#### 3.1.4.1 条件演算子 - -ifelse(3 < 5, 0, 10) -#> 0 - -### 3.1.5 作業ディレクトリ - -getwd() -#> '/home/jovyan/work' - -setwd("..") -getwd() -#> '/home/jovyan' - -## 3.2 関数 - -### 3.2.1 関数の利用 - -sqrt(4) -#> [1] 2 - -log(100, 10) -#> [1] 2 - -log(100) # 自然対数 -# あるいは -log(100, exp(1)) # 省略しない場合 - -#> [1] 4.60517 - -log10(100) # 常用対数 -#> [1] 2 - -log2(1024) # 底が2の対数 -#> [1] 10 - -#### 3.2.1.1 パイプ(Rのみ) - -library(tidyverse) -4 %>% sqrt - -exp(log(5)) # 通常の書き方 -# あるいは -5 %>% log %>% exp # パイプを使う書き方 - -#> 5 - -### 3.2.2 関数の定義 - -f <- function(a, b) { - a - b -} - -f(3, 5) -#> [1] -2 - -#### 3.2.2.1 デフォルト引数 - -f <- function(a, b = 5) { - a - b -} - -f(3) # f(3, 5)と同じこと -#> [1] -2 - -#### 3.2.2.2 無名関数 - -(function(a, b) { a - b })(3, 5) -#> [1] -2 - -## 3.3 コレクション - -### 3.3.1 1次元データ - -x <- c("foo", "bar", "baz") - -length(x) -#> [1] 3 - -x[2] -#> [1] "bar" - -x[2] <- "BAR" -x # 結果の確認 -#> [1] "foo" "BAR" "baz" - -x[2] <- "bar" # 元に戻す. - -x[-2] -#> [1] "foo" "baz" - -c(x, "qux") -#> [1] "foo" "bar" "baz" "qux" - -x <- c(x, "qux") -x # 結果の確認 -#> [1] "foo" "bar" "baz" "qux" - -#### 3.3.1.1 等間隔の数値からなる1次元データ - -1:5 -#> [1] 1 2 3 4 5 - -seq(from = 0, to = 10, by = 2) -#> [1] 0 2 4 6 8 10 - -seq(from = 0, to = 1, by = 0.5) -#> [1] 0.0 0.5 1.0 - -seq(from = 0, to = 100, length.out = 5) -#> [1] 0 25 50 75 100 - -rep(x = 10, times = 5) -#> [1] 10 10 10 10 10 - -#### 3.3.1.2 ファクタ(Rのみ) - -tmp <- c("グー", "パー", "グー", "パー") -x <- factor(tmp, levels = c("グー", "チョキ", "パー")) -x -#> [1] グー パー グー パー -#> Levels: グー チョキ パー - -### 3.3.2 数値計算やデータ解析用の1次元データ - -x <- c(2, 3, 5, 7) - -x + 10 # 加算 -#> [1] 12 13 15 17 - -x * 10 # 乗算 -#> [1] 20 30 50 70 - -x <- c(2, 3) -sin(x) -#> [1] 0.9092974 0.1411200 - -x <- c(2, 3, 5, 7) -y <- c(1, 10, 100, 1000) -x + y -#> [1] 3 13 105 1007 - -x * y -#> [1] 2 30 500 7000 - -sum(x * y) -#> [1] 7532 - -x <- c(TRUE, FALSE) -y <- c(TRUE, TRUE) -x & y -#> [1] TRUE FALSE - -#### 3.3.2.1 1次元データ同士の比較 - -u <- c(1, 2, 3) -v <- c(1, 2, 3) -w <- c(1, 2, 4) - -identical(u, v) # 全体の比較 -#> [1] TRUE - -identical(u, w) # 全体の比較 -#> [1] FALSE - -u == v # 要素ごとの比較 -#> [1] TRUE TRUE TRUE - -u == w # 要素ごとの比較 -#> [1] TRUE TRUE FALSE - -sum(u == w) # 同じ要素の数 -#> [1] 2 - -mean(u == w) # 同じ要素の割合 -#> [1] 0.6666667 - -### 3.3.3 複数種類のデータをひとまとめにする - -x <- list(1, "two") - -x[[2]] -#> [1] "two" - -### 3.3.4 文字列と値のペアのコレクション - -x <- list("apple" = "りんご", - "orange" = "みかん") - -x[["grape"]] <- "ぶどう" - -x$apple -# あるいは -x$"apple" -# あるいは -x[["apple"]] -# あるいは -tmp <- "apple" -x[[tmp]] - -#> [1] "りんご" - -### 3.3.5 補足:コピーと参照 - -x <- c("foo", "bar", "baz") -y <- x -y[2] <- "BAR" # yを更新する. -y -#> [1] "foo" "BAR" "baz" - -x # xは変わらない. -#> [1] "foo" "bar" "baz" - -## 3.4 データフレーム - -### 3.4.1 データフレームの作成 - -library(tidyverse) - -#### 3.4.1.1 データを列ごとに記述する方法 - -my_df <- data.frame( - name = c("A", "B", "C", "D"), - english = c( 60, 90, 70, 90), - math = c( 70, 80, 90, 100), - gender = c("f", "m", "m", "f")) - -#### 3.4.1.2 データを見た目のとおりに記述する方法 - -my_df <- tribble( - ~name, ~english, ~math, ~gender, - "A", 60, 70, "f", - "B", 90, 80, "m", - "C", 70, 90, "m", - "D", 90, 100, "f") - -head(my_df) -# 結果は割愛 - -#### 3.4.1.3 データフレームのサイズ - -dim(my_df) # 行数と列数 -#> [1] 4 4 - -nrow(my_df) # 行数 -#> [1] 4 - -ncol(my_df) # 列数 -#> [1] 4 - -#### 3.4.1.4 組合せ - -my_df2 <- expand.grid( - X = c(1, 2, 3), - Y = c(10, 100)) -my_df2 -#> X Y -#> 1 1 10 -#> 2 2 10 -#> 3 3 10 -#> 4 1 100 -#> 5 2 100 -#> 6 3 100 - -#### 3.4.1.5 列と行の名前 - -colnames(my_df2) -#> [1] "X" "Y" - -colnames(my_df2) <- c("P", "Q") -my_df2 -#> P Q -#> 1 1 10 -#> 2 2 10 -# 以下省略 - -row.names(my_df) -#> [1] "1" "2" "3" "4" - -row.names(my_df2) <- - c("a", "b", "c", "d", "e", "f") -my_df2 -#> P Q -#> a 1 10 -#> b 2 10 -#> c 3 10 -# 以下省略 - -my_df3 <- data.frame( - english = c( 60, 90, 70, 90), - math = c( 70, 80, 90, 100), - gender = c("f", "m", "m", "f"), - row.names = c("A", "B", "C", "D")) -my_df3 -#> english math gender -#> A 60 70 f -#> B 90 80 m -#> C 70 90 m -#> D 90 100 f - -### 3.4.2 データの追加 - -#### 3.4.2.1 行の追加(データフレームの結合) - -tmp <- data.frame( - name = "E", - english = 80, - math = 80, - gender = "m") -my_df2 <- rbind(my_df, tmp) - -#### 3.4.2.2 列の追加 - -my_df2 <- my_df %>% - mutate(id = c(1, 2, 3, 4)) - -my_df3 <- my_df # コピー -my_df3["id"] <- c(1, 2, 3, 4) # 更新 -my_df3 # 結果の確認(割愛) - -### 3.4.3 データの取り出し - -#### 3.4.3.1 観測値の取り出し - -my_df[1, 2] -#> [1] 60 - -#### 3.4.3.2 1列の取り出し(結果は1次元データ) - -x <- my_df[, 2] -# あるいは -x <- my_df$english -# あるいは -x <- my_df$"english" -# あるいは -x <- my_df[["english"]] -# あるいは -tmp <- "english" -x <- my_df[[tmp]] - -x # 結果の確認(割愛) - -#### 3.4.3.3 複数列の取り出し(結果はデータフレーム) - -x <- my_df %>% select(name, math) - -x <- my_df[, c(1, 3)] - -x <- my_df %>% - select(-c(english, gender)) -# あるいは -x <- my_df[, -c(2, 4)] - -#### 3.4.3.4 複数行の取り出し(結果はデータフレーム) - -x <- my_df[c(1, 3), ] - -x <- my_df[-c(2, 4), ] - -#### 3.4.3.5 検索 - -x <- my_df[my_df$gender == "m", ] -# あるいは -x <- my_df %>% filter(gender == "m") - -x <- my_df[my_df$english > 80 & my_df$gender == "m", ] -# あるいは -x <- my_df %>% filter(english > 80 & gender == "m") - -x <- my_df[my_df$english == max(my_df$english), ] -# あるいは -x <- my_df %>% filter(english == max(my_df$english)) - -my_df2 <- my_df # コピー -my_df2[my_df$gender == "m", ]$gender <- "M" - -my_df2 -#> name english math gender -#> 1 A 60 70 f -#> 2 B 90 80 M -#> 3 C 70 90 M -#> 4 D 90 100 f - -#### 3.4.3.6 並べ替え - -x <- my_df %>% arrange(english) - -x <- my_df %>% arrange(-english) - -### 3.4.4 補足:行列 - -#### 3.4.4.1 行列の生成 - -x <- c(2, 3, 5, 7, 11, 13, 17, 19, 23, - 29, 31, 37) -A <- matrix( - data = x, # 1次元データ - nrow = 3, # 行数 - byrow = TRUE) # 行ごとの生成 -A -#> [,1] [,2] [,3] [,4] -#> [1,] 2 3 5 7 -#> [2,] 11 13 17 19 -#> [3,] 23 29 31 37 - -#### 3.4.4.2 データフレームと行列 - -A <- my_df[, c(2, 3)] %>% as.matrix -A -#> english math -#> [1,] 60 70 -#> [2,] 90 80 -#> [3,] 70 90 -#> [4,] 90 100 - -as.data.frame(A) -#> english math -#> 1 60 70 -#> 2 90 80 -#> 3 70 90 -#> 4 90 100 - -#### 3.4.4.3 行列の変形 - -t(A) -#> [,1] [,2] [,3] [,4] -#> english 60 90 70 90 -#> math 70 80 90 100 - -#### 3.4.4.4 行列の積 - -t(A) %*% A -#> english math -#> english 24700 26700 -#> math 26700 29400 - -### 3.4.5 縦型と横型 - -my_wider <- data.frame( - day = c(25, 26, 27), - min = c(20, 21, 15), - max = c(24, 27, 21)) - -my_longer <- my_wider %>% - pivot_longer(-day) -my_longer -#> # A tibble: 6 x 3 -#> day name value -#> -#> 1 25 min 20 -#> 2 25 max 24 -#> 3 26 min 21 -#> 4 26 max 27 -#> 5 27 min 15 -#> 6 27 max 21 - -my_longer %>% pivot_wider() -#> # A tibble: 3 x 3 -#> day min max -#> -#> 1 25 20 24 -#> 2 26 21 27 -#> 3 27 15 21 - -my_longer %>% - ggplot(aes(x = day, y = value, - color = name)) + - geom_point() + - geom_line() + - ylab("temperature") + # y軸ラベル - scale_x_continuous( - breaks = my_longer$day) # x軸目盛り - -## 3.5 1次元データの(非)類似度 - -### 3.5.1 ユークリッド距離 - -A <- c(3, 4, 5) -B <- c(3, 4, 29) -C <- c(9, -18, 8) -AB <- B - A -AC <- C - A - -sum(AB^2)^0.5 -#> [1] 24 - -sum(AC^2)^0.5 -#> [1] 23 - -### 3.5.2 マンハッタン距離 - -sum(abs(AB)) -#> [1] 24 - -sum(abs(AC)) -#> [1] 31 - -### 3.5.3 コサイン類似度 - -sum(A * B) / - sum(A * A)^0.5 / sum(B * B)^0.5 -#> [1] 0.8169679 - -sum(A * C) / - sum(A * A)^0.5 / sum(C * C)^0.5 -#> [1] -0.03265116 - -### 3.5.4 相関係数 - -cor(A, B) -#> [1] 0.8824975 - -cor(A, C) -#> [1] -0.03266277 - -#### 3.5.4.1 データフレームを使う方法 - -library(tidyverse) - - - -my_df <- data.frame( - x = c(3, 3, 9), - y = c(4, 4, -18), - z = c(5, 29, 8), - row.names = c("A", "B", "C")) - -# ユークリッド距離 -my_df %>% proxy::dist("Euclidean") -#> A B -#> B 24 -#> C 23 31 - - -# マンハッタン距離 -my_df %>% proxy::dist("Manhattan") -#> A B -#> B 24 -#> C 31 49 - - -# コサイン類似度 -my_df %>% proxy::simil("cosine") -#> A B -#> B 0.81696786 -#> C -0.03265116 0.29342441 - - -# 相関係数 -my_df %>% proxy::simil("correlation") -#> A B -#> B 0.88249750 -#> C -0.03266277 0.44124132 - -## 3.6 Rのパッケージ,Pythonのモジュール - -### 3.6.1 Rのパッケージ - -library(tidyverse) - -### 3.6.2 Pythonのモジュール - -## 3.7 反復処理 - -library(tidyverse) - -### 3.7.1 指定した回数→1次元データ - -f1 <- function(x) { - tmp <- runif(x) - mean(tmp) -} - -f1(10) # 動作確認 -#> [1] 0.5776604 # 結果の例 - -replicate(n = 3, expr = f1(10)) -#> [1] 0.4672766 0.4712016 0.5579449 - -rep(x = f1(10), times = 3) -#> [1] 0.481329 0.481329 0.481329 - -### 3.7.2 1次元データ→1次元データ - -v <- c(5, 10, 100) -v %>% map_dbl(f1) -#> [1] 0.4857329 0.5322183 0.5084124 - -rep(x = 10, times = 3) %>% map_dbl(f1) -# 結果は割愛 - -### 3.7.3 1次元データ→データフレーム - -f2 <- function(n) { - tmp <- runif(n) - list(x = n, - p = mean(tmp), - q = sd(tmp)) -} - -f2(10) # 動作確認 -#> $x -#> [1] 10 -#> -#> $p -#> [1] 0.6840032 (平均の例) -#> -#> $q -#> [1] 0.3750788 (標準偏差の例) - -v <- c(5, 10, 100) -v %>% map_dfr(f2) -#> x p q -#> -#> 1 5 0.560 0.320 -#> 2 10 0.559 0.271 -#> 3 100 0.507 0.283 - -### 3.7.4 データフレーム→データフレーム - -f3 <- function(x, y) { - tmp <- runif(x, min = 1, - max = y + 1) %>% - as.integer - list(x = x, - y = y, - p = mean(tmp), - q = sd(tmp)) -} - -f3(x = 10, y = 6) # 動作確認 -#> $x -#> [1] 10 -#> -#> $y -#> [1] 6 -#> -#> $p -#> [1] 3.2 (平均の例) -#> -#> $q -#> [1] 1.316561 (標準偏差の例) - -my_df <- data.frame( - x = c(5, 10, 100, 5, 10, 100), - y = c(6, 6, 6, 12, 12, 12)) - -my_df %>% pmap_dfr(f3) -#> x y p q -#> -#> 1 5 6 3 1.41 -#> 2 10 6 3 1.49 -#> 3 100 6 3.57 1.78 -#> 4 5 12 7.6 5.22 -#> 5 10 12 5.7 3.77 -#> 6 100 12 6.36 3.59 - -### 3.7.5 補足:反復処理の並列化 - -library(furrr) -plan(multisession) # 準備 - -v <- c(5, 10, 100) -v %>% future_map_dbl(f1, .options = - furrr_options(seed = TRUE)) -# 結果は割愛 - -## 3.8 その他 - -### 3.8.1 よく遭遇するエラーとその対処方法 - -### 3.8.2 変数や関数についての調査 - -x <- 123 -typeof(x) -#> [1] "double" - -?log -# あるいは -help(log) - -### 3.8.3 RのNA,Pythonのnan - -v <- c(1, NA, 3) -v -#> [1] 1 NA 3 - -is.na(v[2]) -#> [1] TRUE - -v[2] == NA # 誤り -#> [1] NA - diff --git a/code/R/ch04/04.01.R b/code/R/ch04/04.01.R deleted file mode 100644 index bcbbf88..0000000 --- a/code/R/ch04/04.01.R +++ /dev/null @@ -1,164 +0,0 @@ -## 4.1 記述統計 - -### 4.1.1 平均・分散・標準偏差 - -x <- c(165, 170, 175, 180, 185) -mean(x) # 平均 -#> [1] 175 - -n <- length(x) # サンプルサイズ -sum(x) / n -#> [1] 175 - -y <- c(173, 174, 175, 176, 177) -mean(y) -#> [1] 175 - -var(x) # xの分散 -#> [1] 62.5 - -var(y) # yの分散 -#> [1] 2.5 - -sum((x - mean(x))^2) / (n - 1) -#> [1] 62.5 - -sd(x) # xの標準偏差 -#> [1] 7.905694 - -sd(y) # yの標準偏差 -#> [1] 1.581139 - -var(x)**0.5 # xの標準偏差 -#> [1] 7.905694 - -psych::describe(x) -#> vars n mean sd ... -#> X1 1 5 175 7.91 ... - -# あるいは - -pastecs::stat.desc(x) -#> nbr.val ... std.dev ... -#> 5.0000000 ... 7.9056942 ... - -quantile(x) -#> 0% 25% 50% 75% 100% -#> 165 170 175 180 185 - -#### 4.1.1.1 不偏分散とその非負の平方根 - -x <- c(165, 170, 175, 180, 185) - -var(x) # 不偏分散 -#> [1] 62.5 - -mean((x - mean(x))^2) # 標本分散 -# あるいは -n <- length(x) -var(x) * (n - 1) / n # 標本分散 -#> [1] 50 - -sd(x) # √不偏分散 -#> [1] 7.905694 - -mean((x - mean(x))^2)^0.5 # √標本分散 -# あるいは -sd(x) * sqrt((n - 1) / n) # √標本分散 -#> [1] 7.071068 - -sd(x) / length(x)**0.5 -#> [1] 3.535534 - -### 4.1.2 データフレームの統計処理 - -library(tidyverse) - -my_df <- data.frame( - name = c("A", "B", "C", "D"), - english = c( 60, 90, 70, 90), - math = c( 70, 80, 90, 100), - gender = c("f", "m", "m", "f")) - -#### 4.1.2.1 列ごとの集計 - -var(my_df$english) -#> [1] 225 - -# 結果はベクタ -my_df[, c(2, 3)] %>% sapply(var) -#> english math -#> 225.0000 166.6667 - -# 結果はリスト -my_df[, c(2, 3)] %>% lapply(var) -#> $english -#> [1] 225 -#> -#> $math -#> [1] 166.6667 - -# 結果はデータフレーム -my_df[, c(2, 3)] %>% # 2, 3列目 - summarize(across( # の - everything(), # 全ての - var)) # 不偏分散 -# あるいは -my_df %>% # データフレーム - summarize(across( # の - where(is.numeric), # 数値の列の - var)) # 不偏分散 -# あるいは -my_df %>% # データフレーム - summarize(across( # の - where(is.numeric), # 数値の列の - function(x) { var(x) })) # 不偏分散 - -#> english math -#> 1 225 166.6667 - -psych::describe(my_df) -#> vars n mean sd ... -#> name* 1 4 2.5 1.29 ... -#> english 2 4 77.5 15.00 ... -#> math 3 4 85.0 12.91 ... -#> gender* 4 4 1.5 0.58 ... - -# あるいは - -pastecs::stat.desc(my_df) -#> name english ... -#> nbr.val NA 4.0000000 ... -#> nbr.null NA 0.0000000 ... -#> nbr.na NA 0.0000000 ... -#> min NA 60.0000000 ... -#> max NA 90.0000000 ... -# 以下省略 - -#### 4.1.2.2 分割表とグループごとの集計 - -table(my_df$gender) - -#> f m -#> 2 2 - -my_df2 <- data.frame( - gender = my_df$gender, - excel = my_df$math >= 80) -table(my_df2) - -#> excel -#> gender FALSE TRUE -#> f 1 1 -#> m 0 2 - -my_df %>% group_by(gender) %>% - summarize(across( - where(is.numeric), mean), - .groups = "drop") # グループ化解除 - -#> # A tibble: 2 x 3 -#> gender english math -#> -#> 1 f 75 85 -#> 2 m 80 85 diff --git a/code/R/ch04/04.02.R b/code/R/ch04/04.02.R deleted file mode 100644 index 103391f..0000000 --- a/code/R/ch04/04.02.R +++ /dev/null @@ -1,150 +0,0 @@ -## 4.2 データの可視化 - -head(iris) -#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species -#> 1 5.1 3.5 1.4 0.2 setosa -#> 2 4.9 3.0 1.4 0.2 setosa -#> 3 4.7 3.2 1.3 0.2 setosa -#> 4 4.6 3.1 1.5 0.2 setosa -#> 5 5.0 3.6 1.4 0.2 setosa -#> 6 5.4 3.9 1.7 0.4 setosa - -### 4.2.1 ヒストグラム - -hist(iris$Sepal.Length) - -x <- c(10, 20, 30) -hist(x, breaks = 2) # 階級数は2 - -x <- iris$Sepal.Length -tmp <- seq(min(x), max(x), - length.out = 10) -hist(x, breaks = tmp, right = FALSE) - -### 4.2.2 散布図 - -plot(iris$Sepal.Length, - iris$Sepal.Width) - -### 4.2.3 箱ひげ図 - -boxplot(iris[, -5]) - -### 4.2.4 棒グラフとエラーバー - -library(tidyverse) -my_df <- psych::describe(iris[, -5]) -my_df %>% select(mean, sd, se) -#> mean sd se -#> Sepal.Length 5.84 0.83 0.07 -#> Sepal.Width 3.06 0.44 0.04 -#> Petal.Length 3.76 1.77 0.14 -#> Petal.Width 1.20 0.76 0.06 - -tmp <- rownames(my_df) -my_df %>% ggplot(aes(x = factor(tmp, levels = tmp), y = mean)) + - geom_col() + - geom_errorbar(aes(ymin = mean - se, ymax = mean + se)) + - xlab(NULL) - -my_group <- iris %>% group_by(Species) # 品種ごとに, - -my_df <- my_group %>% # 各変数の,平均と - summarize(across(everything(), mean)) %>% - pivot_longer(-Species) - -tmp <- my_group %>% # 標準誤差を求める. - summarize(across(everything(), ~ sd(.) / length(.)**0.5)) %>% - pivot_longer(-Species) - -my_df$se <- tmp$value -head(my_df) -#> # A tibble: 6 x 4 -#> Species name value se -#> -#> 1 setosa Sepal.Length 5.01 0.0498 -#> 2 setosa Sepal.Width 3.43 0.0536 -#> 3 setosa Petal.Length 1.46 0.0246 -#> 4 setosa Petal.Width 0.246 0.0149 -#> 5 versicolor Sepal.Length 5.94 0.0730 -#> 6 versicolor Sepal.Width 2.77 0.0444 - -my_df %>% - ggplot(aes(x = Species, y = value, fill = name)) + - geom_col(position = "dodge") + - geom_errorbar(aes(ymin = value - se, ymax = value + se), position = "dodge") - -# 各変数の平均 -iris %>% pivot_longer(-Species) %>% - ggplot(aes(x = name, y = value)) + - geom_bar(stat = "summary", fun = mean) + - stat_summary(geom = "errorbar", fun.data = mean_se) + - xlab(NULL) - -# 各変数の平均(品種ごと) -iris %>% pivot_longer(-Species) %>% - ggplot(aes(x = Species, y = value, fill = name)) + - geom_bar(stat = "summary", fun = mean, position = "dodge") + - stat_summary(geom = "errorbar", fun.data = mean_se, position = "dodge") - -### 4.2.5 モザイクプロット - -my_df <- data.frame( - Species = iris$Species, - w_Sepal = iris$Sepal.Width > 3) -table(my_df) # 分割表 -#> w_Sepal -#> Species FALSE TRUE -#> setosa 8 42 -#> versicolor 42 8 -#> virginica 33 17 - -mosaicplot( - formula = ~ Species + w_Sepal, - data = my_df) - -library(vcd) -vcd::mosaic(formula = ~w_Sepal + Species, data = my_df, - labeling = labeling_values) - -### 4.2.6 関数のグラフ - -curve(x^3 - x, -2, 2) - -### 4.2.7 ggplot2 (R) - -x <- iris$Sepal.Length -tmp <- seq(min(x), max(x), - length.out = 10) -iris %>% - ggplot(aes(x = Sepal.Length)) + - geom_histogram(breaks = tmp, - closed = "left") - -iris %>% - ggplot(aes(x = Sepal.Length, - y = Sepal.Width)) + - geom_point() - -iris %>% - pivot_longer(-Species) %>% - ggplot(aes( - x = factor(name, - levels = names(iris)), - y = value)) + - geom_boxplot() + - xlab(NULL) - -library(ggmosaic) -my_df <- data.frame( - Species = iris$Species, - w_Sepal = iris$Sepal.Width > 3) -my_df %>% - ggplot() + - geom_mosaic( - aes(x = product(w_Sepal, Species))) - -f <- function(x) { x^3 - x } -data.frame(x = c(-2, 2)) %>% - ggplot(aes(x = x)) + - stat_function(fun = f) diff --git a/code/R/ch04/04.03.R b/code/R/ch04/04.03.R deleted file mode 100644 index f78231b..0000000 --- a/code/R/ch04/04.03.R +++ /dev/null @@ -1,84 +0,0 @@ -## 4.3 乱数 - -### 4.3.1 一様乱数(離散) - -x <- sample(x = 1:6, # 範囲 - size = 10000, # 乱数の数 - replace = TRUE) # 重複あり -hist(x, breaks = 0:6) # ヒストグラム - -### 4.3.2 一様乱数(連続) - -x <- runif(min = 0, # 最小 - max = 1, # 最大 - n = 1000) # 乱数の数 -hist(x) - -x <- as.integer( # 整数に変換 - runif(min = 1, # 最小 - max = 7, # 最大 + 1 - n = 1000)) # 乱数の数 -hist(x, breaks = 0:6) # 結果は割愛 - -### 4.3.3 二項乱数 - -n <- 100 -p <- 0.5 -r <- 10000 -x <- rbinom(size = n, # 試行回数 - prob = p, # 確率 - n = r) # 乱数の数 -hist(x, breaks = max(x) - min(x)) - -### 4.3.4 正規乱数 - -r <- 10000 -x <- rnorm(mean = 50, # 平均 - sd = 5, # 標準偏差 - n = r) # 乱数の数 -hist(x, breaks = 40) - -#### 4.3.4.1 補足:不偏性の具体例 - -library(tidyverse) - -f <- function(k) { - n <- 10000 - tmp <- replicate(n = n, expr = g(rnorm(n = k, sd = 3))) - list(k = k, - mean = mean(tmp), # 平均 - se = sd(tmp) / sqrt(n)) # 標準誤差 -} - -g <- var -c(10, 20, 30) %>% map_dfr(f) -#> # A tibble: 3 x 3 -#> k mean se -#> -#> 1 10 8.98 0.0427 -#> 2 20 8.97 0.0288 -#> 3 30 9.03 0.0233 - -g <- sd -c(5, 10, 15, 20) %>% map_dfr(f) -#> # A tibble: 3 x 3 -#> k mean se -#> -#> 1 10 2.92 0.00701 -#> 2 20 2.95 0.00481 -#> 3 30 2.97 0.00394 - -g <- function(x) { - n <- length(x) - sd(x) * - sqrt((n - 1) / 2) * - gamma((n - 1) / 2) / - gamma(n / 2) -} -c(10, 20, 30) %>% map_dfr(f) -#> # A tibble: 3 x 3 -#> k mean se -#> -#> 1 10 3.00 0.00717 -#> 2 20 2.99 0.00488 -#> 3 30 3.00 0.00396 diff --git a/code/R/ch04/04.04.R b/code/R/ch04/04.04.R deleted file mode 100644 index 1fbf3e2..0000000 --- a/code/R/ch04/04.04.R +++ /dev/null @@ -1,151 +0,0 @@ -## 4.4 統計的推測 - -### 4.4.1 検定 - -library(exactci) -library(tidyverse) - -a <- 0.05 # 有意水準 -binom.exact(x = 2, # 当たった回数 - n = 15, # くじを引いた回数 - p = 4 / 10, # 当たる確率(仮説) - plot = TRUE, # p値の描画(結果は次項に掲載) - conf.level = 1 - a, # 信頼係数(デフォルト) - tsmethod = "minlike", # p値の定義 - alternative = "two.sided") # 両側検定(デフォルト) - # 左片側検定なら'less' - # 右片側検定なら'greater' - -#> Exact two-sided binomial test (central method) -#> -#> data: 2 and 15 -#> number of successes = 2, number of trials = 15, -#> p-value = 0.03646 -#> alternative hypothesis: true probability of success is not equal to 0.4 -#> 95 percent confidence interval: -#> 0.0242 0.3967 -#> sample estimates: -#> probability of success -#> 0.1333333 - -#### 4.4.1.1 補足:p値とは何か - -t <- 4 / 10 # 当たる確率 -n <- 15 # くじを引いた回数 -x <- 0:n # 当たった回数 -my_pr <- dbinom(x, n, t) # x回当たる確率 -my_pr2 <- dbinom(2, n, t) # 2回当たる確率 - -my_data <- data.frame(x = x, - probability = my_pr, - color = my_pr <= my_pr2) # 当たる確率が,2回当たる確率以下 - -my_data %>% ggplot(aes(x = x, y = probability, color = color)) + - geom_point(size = 3) + - geom_linerange(aes(ymin = 0, ymax = probability), ) + # 垂直線 - geom_hline(yintercept = my_pr2) + # 水平線 - theme(legend.position = "none") # 凡例を表示しない. - -### 4.4.2 推定 - -# 前項の結果(再掲) -#> 95 percent confidence interval: -#> 0.0242 0.3967 - -# 前項冒頭のコード - -### 4.4.3 平均の差の検定と推定(t検定) - -X <- c(32.1, 26.2, 27.5, 31.8, 32.1, 31.2, 30.1, 32.4, 32.3, 29.9, - 29.6, 26.6, 31.2, 30.9, 29.3) -Y <- c(35.4, 34.6, 31.1, 32.4, 33.3, 34.7, 35.3, 34.3, 32.1, 28.3, - 33.3, 30.5, 32.6, 33.3, 32.2) - -t.test(x = X, y = Y, - conf.level = 0.95, # 信頼係数(デフォルト) - paired = TRUE, # 対標本である. - alternative = "two.sided") # 両側検定(デフォルト) - # 左片側検定なら'less' - # 右片側検定なら'greater' - -#> Paired t-test -#> -#> data: X and Y -#> t = -4.3694, df = 14, p-value = 0.0006416 -#> alternative hypothesis: true difference in means is not equal to 0 -#> 95 percent confidence interval: -#> -3.995525 -1.364475 -#> sample estimates: -#> mean of the differences -#> -2.68 - -t.test(x = X, y = Y, - paired = FALSE, # 対標本ではない(デフォルト). - var.equal = TRUE, # 等分散を仮定する.仮定しないならFALSE(デフォルト). - alternative = "two.sided", - conf.level = 0.95) - -#> Two Sample t-test -#> -#> data: X and Y -#> t = -3.6821, df = 28, p-value = 0.0009785 -#> alternative hypothesis: true difference in means is not equal to 0 -#> 95 percent confidence interval: -#> -4.170906 -1.189094 -#> sample estimates: -#> mean of x mean of y -#> 30.21333 32.89333 - -### 4.4.4 独立性の検定(カイ2乗検定) - -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/smoker.csv") -my_data <- read_csv(my_url) - -head(my_data) -#> alive smoker -#> 1 Yes No -#> 2 Yes No -#> 3 Yes No -#> 4 Yes No -#> 5 Yes No -#> 6 Yes No - -my_table <- table(my_data) -my_table -#> smoker -#> alive No Yes -#> No 117 54 -#> Yes 950 348 - -chisq.test(my_table, correct = FALSE) - -#> Pearson's Chi-squared test -#> -#> data: my_data -#> X-squared = 1.7285, df = 1, p-value = 0.1886 - -### 4.4.5 ブートストラップ - -#### 4.4.5.1 15回引いて2回当たったくじ - -X <- rep(0:1, c(13, 2)) # 手順1 -X -#> [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 - -tmp <- sample(X, size = length(X), replace = TRUE) # 手順2 -tmp -#> [1] 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 - -sum(tmp) # 手順3 -#> [1] 2 - -n <- 10^5 -result <- replicate(n, sum(sample(X, size = length(X), replace = TRUE))) # 手順4 - -hist(x = result, breaks = 0:15, - right = FALSE) - -quantile(result, c(0.025, 0.975)) -#> 2.5% 97.5% -#> 0 5 diff --git a/code/R/ch04/04.R b/code/R/ch04/04.R deleted file mode 100644 index c2a8686..0000000 --- a/code/R/ch04/04.R +++ /dev/null @@ -1,553 +0,0 @@ -## 4.1 記述統計 - -### 4.1.1 平均・分散・標準偏差 - -x <- c(165, 170, 175, 180, 185) -mean(x) # 平均 -#> [1] 175 - -n <- length(x) # サンプルサイズ -sum(x) / n -#> [1] 175 - -y <- c(173, 174, 175, 176, 177) -mean(y) -#> [1] 175 - -var(x) # xの分散 -#> [1] 62.5 - -var(y) # yの分散 -#> [1] 2.5 - -sum((x - mean(x))^2) / (n - 1) -#> [1] 62.5 - -sd(x) # xの標準偏差 -#> [1] 7.905694 - -sd(y) # yの標準偏差 -#> [1] 1.581139 - -var(x)**0.5 # xの標準偏差 -#> [1] 7.905694 - -psych::describe(x) -#> vars n mean sd ... -#> X1 1 5 175 7.91 ... - -# あるいは - -pastecs::stat.desc(x) -#> nbr.val ... std.dev ... -#> 5.0000000 ... 7.9056942 ... - -quantile(x) -#> 0% 25% 50% 75% 100% -#> 165 170 175 180 185 - -#### 4.1.1.1 不偏分散とその非負の平方根 - -x <- c(165, 170, 175, 180, 185) - -var(x) # 不偏分散 -#> [1] 62.5 - -mean((x - mean(x))^2) # 標本分散 -# あるいは -n <- length(x) -var(x) * (n - 1) / n # 標本分散 -#> [1] 50 - -sd(x) # √不偏分散 -#> [1] 7.905694 - -mean((x - mean(x))^2)^0.5 # √標本分散 -# あるいは -sd(x) * sqrt((n - 1) / n) # √標本分散 -#> [1] 7.071068 - -sd(x) / length(x)**0.5 -#> [1] 3.535534 - -### 4.1.2 データフレームの統計処理 - -library(tidyverse) - -my_df <- data.frame( - name = c("A", "B", "C", "D"), - english = c( 60, 90, 70, 90), - math = c( 70, 80, 90, 100), - gender = c("f", "m", "m", "f")) - -#### 4.1.2.1 列ごとの集計 - -var(my_df$english) -#> [1] 225 - -# 結果はベクタ -my_df[, c(2, 3)] %>% sapply(var) -#> english math -#> 225.0000 166.6667 - -# 結果はリスト -my_df[, c(2, 3)] %>% lapply(var) -#> $english -#> [1] 225 -#> -#> $math -#> [1] 166.6667 - -# 結果はデータフレーム -my_df[, c(2, 3)] %>% # 2, 3列目 - summarize(across( # の - everything(), # 全ての - var)) # 不偏分散 -# あるいは -my_df %>% # データフレーム - summarize(across( # の - where(is.numeric), # 数値の列の - var)) # 不偏分散 -# あるいは -my_df %>% # データフレーム - summarize(across( # の - where(is.numeric), # 数値の列の - function(x) { var(x) })) # 不偏分散 - -#> english math -#> 1 225 166.6667 - -psych::describe(my_df) -#> vars n mean sd ... -#> name* 1 4 2.5 1.29 ... -#> english 2 4 77.5 15.00 ... -#> math 3 4 85.0 12.91 ... -#> gender* 4 4 1.5 0.58 ... - -# あるいは - -pastecs::stat.desc(my_df) -#> name english ... -#> nbr.val NA 4.0000000 ... -#> nbr.null NA 0.0000000 ... -#> nbr.na NA 0.0000000 ... -#> min NA 60.0000000 ... -#> max NA 90.0000000 ... -# 以下省略 - -#### 4.1.2.2 分割表とグループごとの集計 - -table(my_df$gender) - -#> f m -#> 2 2 - -my_df2 <- data.frame( - gender = my_df$gender, - excel = my_df$math >= 80) -table(my_df2) - -#> excel -#> gender FALSE TRUE -#> f 1 1 -#> m 0 2 - -my_df %>% group_by(gender) %>% - summarize(across( - where(is.numeric), mean), - .groups = "drop") # グループ化解除 - -#> # A tibble: 2 x 3 -#> gender english math -#> -#> 1 f 75 85 -#> 2 m 80 85 - -## 4.2 データの可視化 - -head(iris) -#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species -#> 1 5.1 3.5 1.4 0.2 setosa -#> 2 4.9 3.0 1.4 0.2 setosa -#> 3 4.7 3.2 1.3 0.2 setosa -#> 4 4.6 3.1 1.5 0.2 setosa -#> 5 5.0 3.6 1.4 0.2 setosa -#> 6 5.4 3.9 1.7 0.4 setosa - -### 4.2.1 ヒストグラム - -hist(iris$Sepal.Length) - -x <- c(10, 20, 30) -hist(x, breaks = 2) # 階級数は2 - -x <- iris$Sepal.Length -tmp <- seq(min(x), max(x), - length.out = 10) -hist(x, breaks = tmp, right = FALSE) - -### 4.2.2 散布図 - -plot(iris$Sepal.Length, - iris$Sepal.Width) - -### 4.2.3 箱ひげ図 - -boxplot(iris[, -5]) - -### 4.2.4 棒グラフとエラーバー - -library(tidyverse) -my_df <- psych::describe(iris[, -5]) -my_df %>% select(mean, sd, se) -#> mean sd se -#> Sepal.Length 5.84 0.83 0.07 -#> Sepal.Width 3.06 0.44 0.04 -#> Petal.Length 3.76 1.77 0.14 -#> Petal.Width 1.20 0.76 0.06 - -tmp <- rownames(my_df) -my_df %>% ggplot(aes(x = factor(tmp, levels = tmp), y = mean)) + - geom_col() + - geom_errorbar(aes(ymin = mean - se, ymax = mean + se)) + - xlab(NULL) - -my_group <- iris %>% group_by(Species) # 品種ごとに, - -my_df <- my_group %>% # 各変数の,平均と - summarize(across(everything(), mean)) %>% - pivot_longer(-Species) - -tmp <- my_group %>% # 標準誤差を求める. - summarize(across(everything(), ~ sd(.) / length(.)**0.5)) %>% - pivot_longer(-Species) - -my_df$se <- tmp$value -head(my_df) -#> # A tibble: 6 x 4 -#> Species name value se -#> -#> 1 setosa Sepal.Length 5.01 0.0498 -#> 2 setosa Sepal.Width 3.43 0.0536 -#> 3 setosa Petal.Length 1.46 0.0246 -#> 4 setosa Petal.Width 0.246 0.0149 -#> 5 versicolor Sepal.Length 5.94 0.0730 -#> 6 versicolor Sepal.Width 2.77 0.0444 - -my_df %>% - ggplot(aes(x = Species, y = value, fill = name)) + - geom_col(position = "dodge") + - geom_errorbar(aes(ymin = value - se, ymax = value + se), position = "dodge") - -# 各変数の平均 -iris %>% pivot_longer(-Species) %>% - ggplot(aes(x = name, y = value)) + - geom_bar(stat = "summary", fun = mean) + - stat_summary(geom = "errorbar", fun.data = mean_se) + - xlab(NULL) - -# 各変数の平均(品種ごと) -iris %>% pivot_longer(-Species) %>% - ggplot(aes(x = Species, y = value, fill = name)) + - geom_bar(stat = "summary", fun = mean, position = "dodge") + - stat_summary(geom = "errorbar", fun.data = mean_se, position = "dodge") - -### 4.2.5 モザイクプロット - -my_df <- data.frame( - Species = iris$Species, - w_Sepal = iris$Sepal.Width > 3) -table(my_df) # 分割表 -#> w_Sepal -#> Species FALSE TRUE -#> setosa 8 42 -#> versicolor 42 8 -#> virginica 33 17 - -mosaicplot( - formula = ~ Species + w_Sepal, - data = my_df) - -library(vcd) -vcd::mosaic(formula = ~w_Sepal + Species, data = my_df, - labeling = labeling_values) - -### 4.2.6 関数のグラフ - -curve(x^3 - x, -2, 2) - -### 4.2.7 ggplot2 (R) - -x <- iris$Sepal.Length -tmp <- seq(min(x), max(x), - length.out = 10) -iris %>% - ggplot(aes(x = Sepal.Length)) + - geom_histogram(breaks = tmp, - closed = "left") - -iris %>% - ggplot(aes(x = Sepal.Length, - y = Sepal.Width)) + - geom_point() - -iris %>% - pivot_longer(-Species) %>% - ggplot(aes( - x = factor(name, - levels = names(iris)), - y = value)) + - geom_boxplot() + - xlab(NULL) - -library(ggmosaic) -my_df <- data.frame( - Species = iris$Species, - w_Sepal = iris$Sepal.Width > 3) -my_df %>% - ggplot() + - geom_mosaic( - aes(x = product(w_Sepal, Species))) - -f <- function(x) { x^3 - x } -data.frame(x = c(-2, 2)) %>% - ggplot(aes(x = x)) + - stat_function(fun = f) - -## 4.3 乱数 - -### 4.3.1 一様乱数(離散) - -x <- sample(x = 1:6, # 範囲 - size = 10000, # 乱数の数 - replace = TRUE) # 重複あり -hist(x, breaks = 0:6) # ヒストグラム - -### 4.3.2 一様乱数(連続) - -x <- runif(min = 0, # 最小 - max = 1, # 最大 - n = 1000) # 乱数の数 -hist(x) - -x <- as.integer( # 整数に変換 - runif(min = 1, # 最小 - max = 7, # 最大 + 1 - n = 1000)) # 乱数の数 -hist(x, breaks = 0:6) # 結果は割愛 - -### 4.3.3 二項乱数 - -n <- 100 -p <- 0.5 -r <- 10000 -x <- rbinom(size = n, # 試行回数 - prob = p, # 確率 - n = r) # 乱数の数 -hist(x, breaks = max(x) - min(x)) - -### 4.3.4 正規乱数 - -r <- 10000 -x <- rnorm(mean = 50, # 平均 - sd = 5, # 標準偏差 - n = r) # 乱数の数 -hist(x, breaks = 40) - -#### 4.3.4.1 補足:不偏性の具体例 - -library(tidyverse) - -f <- function(k) { - n <- 10000 - tmp <- replicate(n = n, expr = g(rnorm(n = k, sd = 3))) - list(k = k, - mean = mean(tmp), # 平均 - se = sd(tmp) / sqrt(n)) # 標準誤差 -} - -g <- var -c(10, 20, 30) %>% map_dfr(f) -#> # A tibble: 3 x 3 -#> k mean se -#> -#> 1 10 8.98 0.0427 -#> 2 20 8.97 0.0288 -#> 3 30 9.03 0.0233 - -g <- sd -c(5, 10, 15, 20) %>% map_dfr(f) -#> # A tibble: 3 x 3 -#> k mean se -#> -#> 1 10 2.92 0.00701 -#> 2 20 2.95 0.00481 -#> 3 30 2.97 0.00394 - -g <- function(x) { - n <- length(x) - sd(x) * - sqrt((n - 1) / 2) * - gamma((n - 1) / 2) / - gamma(n / 2) -} -c(10, 20, 30) %>% map_dfr(f) -#> # A tibble: 3 x 3 -#> k mean se -#> -#> 1 10 3.00 0.00717 -#> 2 20 2.99 0.00488 -#> 3 30 3.00 0.00396 - -## 4.4 統計的推測 - -### 4.4.1 検定 - -library(exactci) -library(tidyverse) - -a <- 0.05 # 有意水準 -binom.exact(x = 2, # 当たった回数 - n = 15, # くじを引いた回数 - p = 4 / 10, # 当たる確率(仮説) - plot = TRUE, # p値の描画(結果は次項に掲載) - conf.level = 1 - a, # 信頼係数(デフォルト) - tsmethod = "minlike", # p値の定義 - alternative = "two.sided") # 両側検定(デフォルト) - # 左片側検定なら'less' - # 右片側検定なら'greater' - -#> Exact two-sided binomial test (central method) -#> -#> data: 2 and 15 -#> number of successes = 2, number of trials = 15, -#> p-value = 0.03646 -#> alternative hypothesis: true probability of success is not equal to 0.4 -#> 95 percent confidence interval: -#> 0.0242 0.3967 -#> sample estimates: -#> probability of success -#> 0.1333333 - -#### 4.4.1.1 補足:p値とは何か - -t <- 4 / 10 # 当たる確率 -n <- 15 # くじを引いた回数 -x <- 0:n # 当たった回数 -my_pr <- dbinom(x, n, t) # x回当たる確率 -my_pr2 <- dbinom(2, n, t) # 2回当たる確率 - -my_data <- data.frame(x = x, - probability = my_pr, - color = my_pr <= my_pr2) # 当たる確率が,2回当たる確率以下 - -my_data %>% ggplot(aes(x = x, y = probability, color = color)) + - geom_point(size = 3) + - geom_linerange(aes(ymin = 0, ymax = probability), ) + # 垂直線 - geom_hline(yintercept = my_pr2) + # 水平線 - theme(legend.position = "none") # 凡例を表示しない. - -### 4.4.2 推定 - -# 前項の結果(再掲) -#> 95 percent confidence interval: -#> 0.0242 0.3967 - -# 前項冒頭のコード - -### 4.4.3 平均の差の検定と推定(t検定) - -X <- c(32.1, 26.2, 27.5, 31.8, 32.1, 31.2, 30.1, 32.4, 32.3, 29.9, - 29.6, 26.6, 31.2, 30.9, 29.3) -Y <- c(35.4, 34.6, 31.1, 32.4, 33.3, 34.7, 35.3, 34.3, 32.1, 28.3, - 33.3, 30.5, 32.6, 33.3, 32.2) - -t.test(x = X, y = Y, - conf.level = 0.95, # 信頼係数(デフォルト) - paired = TRUE, # 対標本である. - alternative = "two.sided") # 両側検定(デフォルト) - # 左片側検定なら'less' - # 右片側検定なら'greater' - -#> Paired t-test -#> -#> data: X and Y -#> t = -4.3694, df = 14, p-value = 0.0006416 -#> alternative hypothesis: true difference in means is not equal to 0 -#> 95 percent confidence interval: -#> -3.995525 -1.364475 -#> sample estimates: -#> mean of the differences -#> -2.68 - -t.test(x = X, y = Y, - paired = FALSE, # 対標本ではない(デフォルト). - var.equal = TRUE, # 等分散を仮定する.仮定しないならFALSE(デフォルト). - alternative = "two.sided", - conf.level = 0.95) - -#> Two Sample t-test -#> -#> data: X and Y -#> t = -3.6821, df = 28, p-value = 0.0009785 -#> alternative hypothesis: true difference in means is not equal to 0 -#> 95 percent confidence interval: -#> -4.170906 -1.189094 -#> sample estimates: -#> mean of x mean of y -#> 30.21333 32.89333 - -### 4.4.4 独立性の検定(カイ2乗検定) - -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/smoker.csv") -my_data <- read_csv(my_url) - -head(my_data) -#> alive smoker -#> 1 Yes No -#> 2 Yes No -#> 3 Yes No -#> 4 Yes No -#> 5 Yes No -#> 6 Yes No - -my_table <- table(my_data) -my_table -#> smoker -#> alive No Yes -#> No 117 54 -#> Yes 950 348 - -chisq.test(my_table, correct = FALSE) - -#> Pearson's Chi-squared test -#> -#> data: my_data -#> X-squared = 1.7285, df = 1, p-value = 0.1886 - -### 4.4.5 ブートストラップ - -#### 4.4.5.1 15回引いて2回当たったくじ - -X <- rep(0:1, c(13, 2)) # 手順1 -X -#> [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 - -tmp <- sample(X, size = length(X), replace = TRUE) # 手順2 -tmp -#> [1] 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 - -sum(tmp) # 手順3 -#> [1] 2 - -n <- 10^5 -result <- replicate(n, sum(sample(X, size = length(X), replace = TRUE))) # 手順4 - -hist(x = result, breaks = 0:15, - right = FALSE) - -quantile(result, c(0.025, 0.975)) -#> 2.5% 97.5% -#> 0 5 - diff --git a/code/R/ch05/05.01.R b/code/R/ch05/05.01.R deleted file mode 100644 index f74f689..0000000 --- a/code/R/ch05/05.01.R +++ /dev/null @@ -1,144 +0,0 @@ -## 5.1 データの読み込み - -### 5.1.1 CSV - -library(tidyverse) -system(str_c("wget https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/exam.csv")) - -#### 5.1.1.1 CSVの読み込み - -my_df <- read_csv("exam.csv") -# あるいは -my_df <- read.csv("exam.csv", - stringsAsFactors = FALSE) - -my_df -#> name english math gender -#> 1 A 60 70 f -#> 2 B 90 80 m -#> 3 C 70 90 m -#> 4 D 90 100 f - -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/exam.csv") -my_df <- read_csv(my_url) -# あるいは -my_df <- read.csv(my_url, stringsAsFactors = FALSE) - -my_df2 <- read.csv( - file = "exam.csv", - stringsAsFactors = FALSE, - row.names = 1) -my_df2 -#> english math gender -#> A 60 70 f -#> B 90 80 m -#> C 70 90 m -#> D 90 100 f - -#### 5.1.1.2 CSVファイルへの書き出し - -my_df %>% write_csv("exam2.csv") -# あるいは -my_df %>% write.csv( - file = "exam2.csv", - row.names = FALSE) - -my_df2 %>% write.csv("exam3.csv") - -### 5.1.2 文字コード - -my_df <- read_csv(file = "exam.csv", - locale = locale(encoding = "UTF-8")) -# あるいは -my_df <- read.csv(file = "exam.csv", - stringsAsFactors = FALSE, - fileEncoding = "UTF-8") - -my_df %>% write_csv("exam2.csv") -# あるいは -my_df %>% write.csv(file = "exam2.csv", row.names = FALSE, - fileEncoding = "UTF-8") - -### 5.1.3 ウェブ上の表 - -my_url <- "https://taroyabuki.github.io/fromzero/exam.html" -my_tables <- xml2::read_html(my_url) %>% rvest::html_table() - -my_tables -#> [[1]] -#> X1 X2 X3 X4 X5 -#> 1 NA name english math gender -#> 2 NA A 60 70 f -#> 3 NA B 90 80 m -#> 4 NA C 70 90 m -#> 5 NA D 90 100 f - -tmp <- my_tables[[1]] -tmp -#> X1 X2 X3 X4 X5 -#> 1 NA name english math gender -#> 2 NA A 60 70 f -#> 3 NA B 90 80 m -#> 4 NA C 70 90 m -#> 5 NA D 90 100 f - -# 1行目のデータを使って列の名前を付け直す. -colnames(tmp) <- tmp[1, ] - -# 1行目と1列目を削除する. -my_data <- tmp[-1, -1] -my_data -#> name english math gender -#> 2 A 60 70 f -#> 3 B 90 80 m -#> 4 C 70 90 m -#> 5 D 90 100 f - -### 5.1.4 JSONとXML - -#### 5.1.4.1 JSONデータの読み込み - -library(jsonlite) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/exam.json") -my_data <- fromJSON(my_url) -#my_data <- fromJSON("exam.json") # (ファイルを使う場合) -my_data -#> name english math gender -#> 1 A 60 70 f -#> 2 B 90 80 m -#> 3 C 70 90 m -#> 4 D 90 100 f - -#### 5.1.4.2 XMLデータの読み込み - -library(xml2) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/exam.xml") -my_xml <- read_xml(my_url) # XMLデータの読み込み -#my_xml <- read_xml("exam.xml") # (ファイルを使う場合) -xml_ns(my_xml) # 名前空間の確認(d1) -#> d1 <-> https://www.example.net/ns/1.0 - -my_records <- xml_find_all(my_xml, ".//d1:record") - -f <- function(record) { - tmp <- xml_attrs(record) # 属性を全て取り出し, - xml_children(record) %>% walk(function(e) { - tmp[xml_name(e)] <<- xml_text(e) # 子要素の名前と内容を追加する. - }) - tmp -} - -my_data <- my_records %>% map_dfr(f) -my_data$english <- as.numeric(my_data$english) -my_data$math <- as.numeric(my_data$math) -my_data -#> english math gender name -#> -#> 1 60 70 f A -#> 2 90 80 m B -#> 3 70 90 m C -#> 4 90 100 f D diff --git a/code/R/ch05/05.02.R b/code/R/ch05/05.02.R deleted file mode 100644 index c6fc390..0000000 --- a/code/R/ch05/05.02.R +++ /dev/null @@ -1,68 +0,0 @@ -## 5.2 データの変換 - -### 5.2.1 標準化 - -x1 <- c(1, 2, 3) - -z1 <- scale(x1) -# あるいは -z1 <- (x1 - mean(x1)) / sd(x1) - -z1 -#> [1] -1 0 1 - -c(mean(z1), sd(z1)) -#> [1] 0 1 - -z1 * sd(x1) + mean(x1) -#> [1] 1 2 3 - -x2 <- c(1, 3, 5) -z2 <- (x2 - mean(x1)) / sd(x1) -c(mean(z2), sd(z2)) -#> [1] 1 2 - -### 5.2.2 ワンホットエンコーディング - -library(caret) -library(tidyverse) - -my_df <- data.frame( - id = c(1, 2, 3), - class = as.factor( - c("A", "B", "C"))) - -my_enc <- my_df %>% - dummyVars(formula = ~ .) - -my_enc %>% predict(my_df) -#> id class.A class.B class.C -#> 1 1 1 0 0 -#> 2 2 0 1 0 -#> 3 3 0 0 1 - -my_df2 <- data.frame( - id = c( 4 , 5 , 6 ), - class = c("B", "C", "B")) -my_enc %>% predict(my_df2) -#> id class.A class.B class.C -#> 1 4 0 1 0 -#> 2 5 0 0 1 -#> 3 6 0 1 0 - -#### 5.2.2.1 補足:冗長性の排除 - -my_enc <- my_df %>% - dummyVars(formula = ~ ., - fullRank = TRUE) -my_enc %>% predict(my_df) -#> id class.B class.C -#> 1 1 0 0 -#> 2 2 1 0 -#> 3 3 0 1 - -my_enc %>% predict(my_df2) -#> id class.B class.C -#> 1 4 1 0 -#> 2 5 0 1 -#> 3 6 1 0 diff --git a/code/R/ch05/05.R b/code/R/ch05/05.R deleted file mode 100644 index 5dfd8d3..0000000 --- a/code/R/ch05/05.R +++ /dev/null @@ -1,214 +0,0 @@ -## 5.1 データの読み込み - -### 5.1.1 CSV - -library(tidyverse) -system(str_c("wget https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/exam.csv")) - -#### 5.1.1.1 CSVの読み込み - -my_df <- read_csv("exam.csv") -# あるいは -my_df <- read.csv("exam.csv", - stringsAsFactors = FALSE) - -my_df -#> name english math gender -#> 1 A 60 70 f -#> 2 B 90 80 m -#> 3 C 70 90 m -#> 4 D 90 100 f - -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/exam.csv") -my_df <- read_csv(my_url) -# あるいは -my_df <- read.csv(my_url, stringsAsFactors = FALSE) - -my_df2 <- read.csv( - file = "exam.csv", - stringsAsFactors = FALSE, - row.names = 1) -my_df2 -#> english math gender -#> A 60 70 f -#> B 90 80 m -#> C 70 90 m -#> D 90 100 f - -#### 5.1.1.2 CSVファイルへの書き出し - -my_df %>% write_csv("exam2.csv") -# あるいは -my_df %>% write.csv( - file = "exam2.csv", - row.names = FALSE) - -my_df2 %>% write.csv("exam3.csv") - -### 5.1.2 文字コード - -my_df <- read_csv(file = "exam.csv", - locale = locale(encoding = "UTF-8")) -# あるいは -my_df <- read.csv(file = "exam.csv", - stringsAsFactors = FALSE, - fileEncoding = "UTF-8") - -my_df %>% write_csv("exam2.csv") -# あるいは -my_df %>% write.csv(file = "exam2.csv", row.names = FALSE, - fileEncoding = "UTF-8") - -### 5.1.3 ウェブ上の表 - -my_url <- "https://taroyabuki.github.io/fromzero/exam.html" -my_tables <- xml2::read_html(my_url) %>% rvest::html_table() - -my_tables -#> [[1]] -#> X1 X2 X3 X4 X5 -#> 1 NA name english math gender -#> 2 NA A 60 70 f -#> 3 NA B 90 80 m -#> 4 NA C 70 90 m -#> 5 NA D 90 100 f - -tmp <- my_tables[[1]] -tmp -#> X1 X2 X3 X4 X5 -#> 1 NA name english math gender -#> 2 NA A 60 70 f -#> 3 NA B 90 80 m -#> 4 NA C 70 90 m -#> 5 NA D 90 100 f - -# 1行目のデータを使って列の名前を付け直す. -colnames(tmp) <- tmp[1, ] - -# 1行目と1列目を削除する. -my_data <- tmp[-1, -1] -my_data -#> name english math gender -#> 2 A 60 70 f -#> 3 B 90 80 m -#> 4 C 70 90 m -#> 5 D 90 100 f - -### 5.1.4 JSONとXML - -#### 5.1.4.1 JSONデータの読み込み - -library(jsonlite) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/exam.json") -my_data <- fromJSON(my_url) -#my_data <- fromJSON("exam.json") # (ファイルを使う場合) -my_data -#> name english math gender -#> 1 A 60 70 f -#> 2 B 90 80 m -#> 3 C 70 90 m -#> 4 D 90 100 f - -#### 5.1.4.2 XMLデータの読み込み - -library(xml2) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/exam.xml") -my_xml <- read_xml(my_url) # XMLデータの読み込み -#my_xml <- read_xml("exam.xml") # (ファイルを使う場合) -xml_ns(my_xml) # 名前空間の確認(d1) -#> d1 <-> https://www.example.net/ns/1.0 - -my_records <- xml_find_all(my_xml, ".//d1:record") - -f <- function(record) { - tmp <- xml_attrs(record) # 属性を全て取り出し, - xml_children(record) %>% walk(function(e) { - tmp[xml_name(e)] <<- xml_text(e) # 子要素の名前と内容を追加する. - }) - tmp -} - -my_data <- my_records %>% map_dfr(f) -my_data$english <- as.numeric(my_data$english) -my_data$math <- as.numeric(my_data$math) -my_data -#> english math gender name -#> -#> 1 60 70 f A -#> 2 90 80 m B -#> 3 70 90 m C -#> 4 90 100 f D - -## 5.2 データの変換 - -### 5.2.1 標準化 - -x1 <- c(1, 2, 3) - -z1 <- scale(x1) -# あるいは -z1 <- (x1 - mean(x1)) / sd(x1) - -z1 -#> [1] -1 0 1 - -c(mean(z1), sd(z1)) -#> [1] 0 1 - -z1 * sd(x1) + mean(x1) -#> [1] 1 2 3 - -x2 <- c(1, 3, 5) -z2 <- (x2 - mean(x1)) / sd(x1) -c(mean(z2), sd(z2)) -#> [1] 1 2 - -### 5.2.2 ワンホットエンコーディング - -library(caret) -library(tidyverse) - -my_df <- data.frame( - id = c(1, 2, 3), - class = as.factor( - c("A", "B", "C"))) - -my_enc <- my_df %>% - dummyVars(formula = ~ .) - -my_enc %>% predict(my_df) -#> id class.A class.B class.C -#> 1 1 1 0 0 -#> 2 2 0 1 0 -#> 3 3 0 0 1 - -my_df2 <- data.frame( - id = c( 4 , 5 , 6 ), - class = c("B", "C", "B")) -my_enc %>% predict(my_df2) -#> id class.A class.B class.C -#> 1 4 0 1 0 -#> 2 5 0 0 1 -#> 3 6 0 1 0 - -#### 5.2.2.1 補足:冗長性の排除 - -my_enc <- my_df %>% - dummyVars(formula = ~ ., - fullRank = TRUE) -my_enc %>% predict(my_df) -#> id class.B class.C -#> 1 1 0 0 -#> 2 2 1 0 -#> 3 3 0 1 - -my_enc %>% predict(my_df2) -#> id class.B class.C -#> 1 4 1 0 -#> 2 5 0 1 -#> 3 6 1 0 - diff --git a/code/R/ch06/06.01.R b/code/R/ch06/06.01.R deleted file mode 100644 index cd21786..0000000 --- a/code/R/ch06/06.01.R +++ /dev/null @@ -1 +0,0 @@ -## 6.1 機械学習の目的(本書の場合) diff --git a/code/R/ch06/06.02.R b/code/R/ch06/06.02.R deleted file mode 100644 index b748ee8..0000000 --- a/code/R/ch06/06.02.R +++ /dev/null @@ -1,20 +0,0 @@ -## 6.2 機械学習のためのデータ - -### 6.2.1 機械学習を学ぶのに使うデータセット - -#### 6.2.1.1 教師データあり - -#### 6.2.1.2 時系列データ(第\ref{時系列予測 - -#### 6.2.1.3 教師データなし(第\ref{教師なし学習 - -### 6.2.2 補足:アヤメのデータ - -#### 6.2.2.1 R - -iris -#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species -#> 1 5.1 3.5 1.4 0.2 setosa -# 以下省略 - -#### 6.2.2.2 Python diff --git a/code/R/ch06/06.03.R b/code/R/ch06/06.03.R deleted file mode 100644 index b322a14..0000000 --- a/code/R/ch06/06.03.R +++ /dev/null @@ -1,5 +0,0 @@ -## 6.3 機械学習のための手法 - -### 6.3.1 教師あり学習のためのフレームワーク - -### 6.3.2 本書で勧める手法とデータセットの組合せ diff --git a/code/R/ch06/06.R b/code/R/ch06/06.R deleted file mode 100644 index 6805954..0000000 --- a/code/R/ch06/06.R +++ /dev/null @@ -1,29 +0,0 @@ -## 6.1 機械学習の目的(本書の場合) - -## 6.2 機械学習のためのデータ - -### 6.2.1 機械学習を学ぶのに使うデータセット - -#### 6.2.1.1 教師データあり - -#### 6.2.1.2 時系列データ(第\ref{時系列予測 - -#### 6.2.1.3 教師データなし(第\ref{教師なし学習 - -### 6.2.2 補足:アヤメのデータ - -#### 6.2.2.1 R - -iris -#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species -#> 1 5.1 3.5 1.4 0.2 setosa -# 以下省略 - -#### 6.2.2.2 Python - -## 6.3 機械学習のための手法 - -### 6.3.1 教師あり学習のためのフレームワーク - -### 6.3.2 本書で勧める手法とデータセットの組合せ - diff --git a/code/R/ch07/07.01.R b/code/R/ch07/07.01.R deleted file mode 100644 index 615411e..0000000 --- a/code/R/ch07/07.01.R +++ /dev/null @@ -1 +0,0 @@ -## 7.1 自動車の停止距離 diff --git a/code/R/ch07/07.02.R b/code/R/ch07/07.02.R deleted file mode 100644 index bc5dbe4..0000000 --- a/code/R/ch07/07.02.R +++ /dev/null @@ -1,39 +0,0 @@ -## 7.2 データの確認 - -library(caret) -library(tidyverse) -my_data <- cars - -dim(my_data) -#> [1] 50 2 - -head(my_data) -#> speed dist -#> 1 4 2 -#> 2 4 10 -#> 3 7 4 -#> 4 7 22 -#> 5 8 16 -#> 6 9 10 - -options(digits = 3) -pastecs::stat.desc(my_data) -#> speed dist -#> nbr.val 50.000 50.00 -#> nbr.null 0.000 0.00 -#> nbr.na 0.000 0.00 -#> min 4.000 2.00 -#> max 25.000 120.00 -#> range 21.000 118.00 -#> sum 770.000 2149.00 -#> median 15.000 36.00 -#> mean 15.400 42.98 -#> SE.mean 0.748 3.64 -#> CI.mean.0.95 1.503 7.32 -#> var 27.959 664.06 -#> std.dev 5.288 25.77 -#> coef.var 0.343 0.60 - -my_data %>% - ggplot(aes(x = speed, y = dist)) + - geom_point() diff --git a/code/R/ch07/07.03.R b/code/R/ch07/07.03.R deleted file mode 100644 index 84993ce..0000000 --- a/code/R/ch07/07.03.R +++ /dev/null @@ -1,53 +0,0 @@ -## 7.3 回帰分析 - -### 7.3.1 回帰分析とは何か - -### 7.3.2 線形単回帰分析 - -library(tidyverse) - -my_data <- cars -tmp <- data.frame(speed = 21.5, dist = 67) -my_data %>% ggplot(aes(x = speed, y = dist)) + - coord_cartesian(xlim = c(4, 25), ylim = c(0, 120)) + - geom_point() + - stat_smooth(formula = y ~ x, method = "lm") + - geom_pointrange(data = tmp, aes(ymin = -9, ymax = dist), linetype = "dotted") + - geom_pointrange(data = tmp, aes(xmin = 0, xmax = speed), linetype = "dotted") - -### 7.3.3 回帰分析の実践 - -#### 7.3.3.1 データの用意 - -library(caret) -library(tidyverse) -my_data <- cars - -#### 7.3.3.2 訓練 - -my_model <- train(form = dist ~ speed, # モデル式(出力変数と入力変数の関係) - data = my_data, # データ - method = "lm") # 手法 - -coef(my_model$finalModel) -#> (Intercept) speed -#> -17.579095 3.932409 - -#### 7.3.3.3 予測 - -tmp <- data.frame(speed = 21.5) -my_model %>% predict(tmp) -#> 1 -#> 66.96769 - -#### 7.3.3.4 モデルの可視化 - -f <- function(x) { my_model %>% predict(data.frame(speed = x)) } - -my_data %>% - ggplot(aes(x = speed, y = dist, - color = "data")) + - geom_point() + - stat_function( - fun = f, - mapping = aes(color = "model")) diff --git a/code/R/ch07/07.04.R b/code/R/ch07/07.04.R deleted file mode 100644 index 26c9e0e..0000000 --- a/code/R/ch07/07.04.R +++ /dev/null @@ -1,95 +0,0 @@ -## 7.4 当てはまりの良さの指標 - -### 7.4.1 RMSE - -library(caret) -library(tidyverse) -my_data <- cars -my_model <- train(form = dist ~ speed, data = my_data, method = "lm") - -y <- my_data$dist -y_ <- my_model %>% predict(my_data) -my_data$y_ <- y_ - -my_data$residual <- y - y_ -head(my_data) -#> speed dist y_ residual -#> 1 4 2 -1.849460 3.849460 -#> 2 4 10 -1.849460 11.849460 -#> 3 7 4 9.947766 -5.947766 -#> 4 7 22 9.947766 12.052234 -#> 5 8 16 13.880175 2.119825 -#> 6 9 10 17.812584 -7.812584 - -my_data %>% - ggplot(aes(x = speed, y = dist)) + - geom_point() + - geom_line(aes(x = speed, y = y_)) + - geom_linerange(mapping = aes(ymin = y_, ymax = dist), linetype = "dotted") - -RMSE(y_, y) -# あるいは -mean((my_data$residual^2))**0.5 - -#> [1] 15.06886 - -### 7.4.2 決定係数 - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 0.6510794 - -R2(pred = y_, obs = y, - form = "corr") -# あるいは -summary(my_model$finalModel)$r.squared -#> [1] 0.6510794 - -my_test <- my_data[1:3, ] -y <- my_test$dist -y_ <- my_model %>% predict(my_test) - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] -4.498191 # 決定係数1 - -R2(pred = y_, obs = y, - form = "corr") -#> [1] 0.07692308 # 決定係数6 - -### 7.4.3 当てはまりの良さの指標の問題点 - -library(caret) -library(tidyverse) -my_data <- cars -my_idx <- c(2, 11, 27, 34, 39, 44) -my_sample <- my_data[my_idx, ] - -options(warn = -1) # これ以降,警告を表示しない. -my_model <- train(form = dist ~ poly(speed, degree = 5, raw = TRUE), - data = my_sample, - method = "lm") -options(warn = 0) # これ以降,警告を表示する. - -y <- my_sample$dist -y_ <- my_model %>% predict(my_sample) - -RMSE(y_, y) -#> [1] 1.042275e-10 # RMSE - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 1 # 決定係数1 - -R2(pred = y_, obs = y, - form = "corr") -#> [1] 1 # 決定係数6 - -f <- function(x) { my_model %>% predict(data.frame(speed = x)) } - -my_data %>% - ggplot(aes(x = speed, y = dist, color = "data")) + - geom_point() + - geom_point(data = my_sample, mapping = aes(color = "sample")) + - stat_function(fun = f, mapping = aes(color = "model")) + - coord_cartesian(ylim = c(0, 120)) diff --git a/code/R/ch07/07.05.R b/code/R/ch07/07.05.R deleted file mode 100644 index 7f335ff..0000000 --- a/code/R/ch07/07.05.R +++ /dev/null @@ -1,39 +0,0 @@ -## 7.5 K最近傍法 - -### 7.5.1 K最近傍法とは何か - -### 7.5.2 K最近傍法の実践 - -# 準備 -library(caret) -library(tidyverse) -my_data <- cars - -# 訓練 -my_model <- train(form = dist ~ speed, data = my_data, method = "knn") - -# 可視化の準備 -f <- function(x) { my_model %>% predict(data.frame(speed = x))} - -my_data %>% - ggplot(aes(x = speed, - y = dist, - color = "data")) + - geom_point() + - stat_function( - fun = f, - mapping = aes(color = "model")) - -y <- my_data$dist -y_ <- my_model %>% predict(my_data) - -RMSE(y_, y) -#> [1] 13.96845 # RMSE - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 0.7001789 # 決定係数1 - -R2(pred = y_, obs = y, - form = "corr") -#> [1] 0.7017314 # 決定係数6 diff --git a/code/R/ch07/07.06.R b/code/R/ch07/07.06.R deleted file mode 100644 index d2db637..0000000 --- a/code/R/ch07/07.06.R +++ /dev/null @@ -1,146 +0,0 @@ -## 7.6 検証 - -### 7.6.1 訓練データ・検証データ・テストデータ - -### 7.6.2 検証とは何か - -### 7.6.3 検証の実践 - -library(caret) -library(tidyverse) -my_data <- cars -my_model <- train(form = dist ~ speed, data = my_data, method = "lm") - -my_model$results -#> intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD -#> 1 TRUE 16.0206 0.6662176 12.14701 2.518604 0.09249158 1.920564 - -my_model <- train(form = dist ~ speed, data = my_data, method = "lm", - trControl = trainControl(method = "cv", number = 5)) -my_model$results -#> intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD -#> 1 TRUE 15.06708 0.6724501 12.12448 4.75811 0.1848932 3.052435 - -my_model <- train(form = dist ~ speed, data = my_data, method = "lm", - trControl = trainControl(method = "LOOCV")) -my_model$results -#> intercept RMSE Rsquared MAE -#> 1 TRUE 15.69731 0.6217139 12.05918 - -### 7.6.4 検証の並列化 - -library(doParallel) -cl <- makeCluster(detectCores()) -registerDoParallel(cl) - -### 7.6.5 指標のまとめ - -#### 7.6.5.1 準備 - -library(caret) -library(tidyverse) -my_data <- cars -my_model <- train(form = dist ~ speed, data = my_data, method = "lm") -y <- my_data$dist -y_ <- my_model %>% predict(my_data) - -#### 7.6.5.2 当てはまりの良さの指標 - -# RMSE(訓練) -RMSE(y_, y) -#> [1] 15.06886 - -# 決定係数1(訓練) -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 0.6510794 - -# 決定係数6(訓練) -R2(pred = y_, obs = y, - form = "corr") -#> [1] 0.6510794 - -postResample(pred = y_, obs = y) -#> RMSE Rsquared MAE -#> 15.0688560 0.6510794 11.5801191 - -#### 7.6.5.3 予測性能の指標(簡単に求められるもの) - -my_model <- train(form = dist ~ speed, data = my_data, method = "lm") -my_model$results -#> intercept RMSE Rsquared MAE ... -#> 1 TRUE 14.88504 0.6700353 11.59226 ... -# 左から,RMSE(検証),決定係数6(検証),MAE(検証) - -#### 7.6.5.4 予測性能の指標(RとPythonで同じ結果を得る) - -my_model <- train(form = dist ~ speed, data = my_data, method = "lm", - trControl = trainControl(method = "LOOCV")) - -# 方法1 -my_model$results -#> intercept RMSE Rsquared MAE -#> 1 TRUE 15.69731 0.6217139 12.05918 - -# 方法2 -y <- my_model$pred$obs -y_ <- my_model$pred$pred -mean((y - y_)^2)**0.5 -#> [1] 15.69731 - -mean(((y - y_)^2)**0.5) -#> [1] 12.05918 - -### 7.6.6 補足:検証による手法の比較 - -library(caret) -library(tidyverse) -my_data <- cars - -my_lm_model <- train(form = dist ~ speed, data = my_data, method = "lm", - trControl = trainControl(method = "LOOCV")) - -my_knn_model <- train(form = dist ~ speed, data = my_data, method = "knn", - tuneGrid = data.frame(k = 5), - trControl = trainControl(method = "LOOCV")) - -my_lm_model$results$RMSE -#> [1] 15.69731 # 線形回帰分析 - -my_knn_model$results$RMSE -#> [1] 15.79924 # K最近傍法 - -y <- my_data$dist -y_lm <- my_lm_model$pred$pred -y_knn <- my_knn_model$pred$pred - -my_df <- data.frame( - lm = (y - y_lm)^2, - knn = (y - y_knn)^2) - -head(my_df) -#> lm knn -#> 1 18.913720 108.1600 -#> 2 179.215044 0.6400 -#> 3 41.034336 175.5625 -#> 4 168.490212 49.0000 -#> 5 5.085308 9.0000 -#> 6 67.615888 112.8906 - -boxplot(my_df, ylab = "r^2") - -t.test(x = my_df$lm, y = my_df$knn, - conf.level = 0.95, - paired = TRUE, - alternative = "two.sided") - -#> Paired t-test -#> -#> data: my_df$lm and my_df$knn -#> t = -0.12838, df = 49, p-value = 0.8984 -#> alternative hypothesis: true difference in means is not equal to 0 -#> 95 percent confidence interval: -#> -53.46930 47.04792 -#> sample estimates: -#> mean of the differences -#> -3.210688 diff --git a/code/R/ch07/07.07.R b/code/R/ch07/07.07.R deleted file mode 100644 index 24a6f97..0000000 --- a/code/R/ch07/07.07.R +++ /dev/null @@ -1,70 +0,0 @@ -## 7.7 パラメータチューニング - -library(caret) -library(tidyverse) -my_data <- cars -my_model <- train(form = dist ~ speed, data = my_data, method = "knn") -my_model$results -#> k RMSE Rsquared MAE RMSESD RsquaredSD MAESD -#> 1 5 15.72114 0.6615765 12.54588 3.013243 0.11043907 2.372245 -#> 2 7 16.19047 0.6601173 12.68464 3.165330 0.09990158 2.329326 -#> 3 9 16.30276 0.6556700 12.84811 3.367423 0.09645747 2.471620 - -my_params <- expand.grid(k = 1:15) - -my_model <- train(form = dist ~ speed, data = my_data, method = "knn", - tuneGrid = my_params, - trControl = trainControl(method = "LOOCV")) - -head(my_model$results) -#> k RMSE Rsquared MAE -#> 1 1 17.22299 0.5777197 13.84900 -#> 2 2 16.81462 0.5936438 13.03469 -#> 3 3 16.32874 0.6218866 12.74524 -#> 4 4 15.98970 0.6086993 12.27888 -#> 5 5 15.79924 0.6169267 11.96067 -#> 6 6 15.98720 0.6079396 12.26667 - -ggplot(my_model) - -my_model$bestTune -#> k -#> 5 5 - -my_model$results %>% - filter(RMSE == min(RMSE)) -#> k RMSE Rsquared MAE -#> 1 5 15.79924 0.6169267 11.96067 - -y <- my_data$dist -y_ <- my_model %>% predict(my_data) -RMSE(y_, y) -#> [1] 13.96845 - -### 7.7.1 補足:ハイパーパラメータとRMSE(訓練) - -library(caret) -library(tidyverse) -my_data <- cars - -my_loocv <- function(k) { - my_model <- train(form = dist ~ speed, data = my_data, method = "knn", - tuneGrid = data.frame(k = k), - trControl = trainControl(method = "LOOCV")) - y <- my_data$dist - y_ <- my_model %>% predict(my_data) - list(k = k, - training = RMSE(y_, y), # RMSE(訓練) - validation = my_model$results$RMSE) # RMSE(検証) -} - -my_results <- 1:15 %>% map_dfr(my_loocv) - -my_results %>% - pivot_longer(-k) %>% - ggplot(aes(x = k, y = value, - color = name)) + - geom_line() + geom_point() + - xlab("#Neighbors") + ylab("RMSE") + - theme(legend.position = c(1, 0), - legend.justification = c(1, 0)) diff --git a/code/R/ch07/07.R b/code/R/ch07/07.R deleted file mode 100644 index 3a57075..0000000 --- a/code/R/ch07/07.R +++ /dev/null @@ -1,450 +0,0 @@ -## 7.1 自動車の停止距離 - -## 7.2 データの確認 - -library(caret) -library(tidyverse) -my_data <- cars - -dim(my_data) -#> [1] 50 2 - -head(my_data) -#> speed dist -#> 1 4 2 -#> 2 4 10 -#> 3 7 4 -#> 4 7 22 -#> 5 8 16 -#> 6 9 10 - -options(digits = 3) -pastecs::stat.desc(my_data) -#> speed dist -#> nbr.val 50.000 50.00 -#> nbr.null 0.000 0.00 -#> nbr.na 0.000 0.00 -#> min 4.000 2.00 -#> max 25.000 120.00 -#> range 21.000 118.00 -#> sum 770.000 2149.00 -#> median 15.000 36.00 -#> mean 15.400 42.98 -#> SE.mean 0.748 3.64 -#> CI.mean.0.95 1.503 7.32 -#> var 27.959 664.06 -#> std.dev 5.288 25.77 -#> coef.var 0.343 0.60 - -my_data %>% - ggplot(aes(x = speed, y = dist)) + - geom_point() - -## 7.3 回帰分析 - -### 7.3.1 回帰分析とは何か - -### 7.3.2 線形単回帰分析 - -library(tidyverse) - -my_data <- cars -tmp <- data.frame(speed = 21.5, dist = 67) -my_data %>% ggplot(aes(x = speed, y = dist)) + - coord_cartesian(xlim = c(4, 25), ylim = c(0, 120)) + - geom_point() + - stat_smooth(formula = y ~ x, method = "lm") + - geom_pointrange(data = tmp, aes(ymin = -9, ymax = dist), linetype = "dotted") + - geom_pointrange(data = tmp, aes(xmin = 0, xmax = speed), linetype = "dotted") - -### 7.3.3 回帰分析の実践 - -#### 7.3.3.1 データの用意 - -library(caret) -library(tidyverse) -my_data <- cars - -#### 7.3.3.2 訓練 - -my_model <- train(form = dist ~ speed, # モデル式(出力変数と入力変数の関係) - data = my_data, # データ - method = "lm") # 手法 - -coef(my_model$finalModel) -#> (Intercept) speed -#> -17.579095 3.932409 - -#### 7.3.3.3 予測 - -tmp <- data.frame(speed = 21.5) -my_model %>% predict(tmp) -#> 1 -#> 66.96769 - -#### 7.3.3.4 モデルの可視化 - -f <- function(x) { my_model %>% predict(data.frame(speed = x)) } - -my_data %>% - ggplot(aes(x = speed, y = dist, - color = "data")) + - geom_point() + - stat_function( - fun = f, - mapping = aes(color = "model")) - -## 7.4 当てはまりの良さの指標 - -### 7.4.1 RMSE - -library(caret) -library(tidyverse) -my_data <- cars -my_model <- train(form = dist ~ speed, data = my_data, method = "lm") - -y <- my_data$dist -y_ <- my_model %>% predict(my_data) -my_data$y_ <- y_ - -my_data$residual <- y - y_ -head(my_data) -#> speed dist y_ residual -#> 1 4 2 -1.849460 3.849460 -#> 2 4 10 -1.849460 11.849460 -#> 3 7 4 9.947766 -5.947766 -#> 4 7 22 9.947766 12.052234 -#> 5 8 16 13.880175 2.119825 -#> 6 9 10 17.812584 -7.812584 - -my_data %>% - ggplot(aes(x = speed, y = dist)) + - geom_point() + - geom_line(aes(x = speed, y = y_)) + - geom_linerange(mapping = aes(ymin = y_, ymax = dist), linetype = "dotted") - -RMSE(y_, y) -# あるいは -mean((my_data$residual^2))**0.5 - -#> [1] 15.06886 - -### 7.4.2 決定係数 - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 0.6510794 - -R2(pred = y_, obs = y, - form = "corr") -# あるいは -summary(my_model$finalModel)$r.squared -#> [1] 0.6510794 - -my_test <- my_data[1:3, ] -y <- my_test$dist -y_ <- my_model %>% predict(my_test) - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] -4.498191 # 決定係数1 - -R2(pred = y_, obs = y, - form = "corr") -#> [1] 0.07692308 # 決定係数6 - -### 7.4.3 当てはまりの良さの指標の問題点 - -library(caret) -library(tidyverse) -my_data <- cars -my_idx <- c(2, 11, 27, 34, 39, 44) -my_sample <- my_data[my_idx, ] - -options(warn = -1) # これ以降,警告を表示しない. -my_model <- train(form = dist ~ poly(speed, degree = 5, raw = TRUE), - data = my_sample, - method = "lm") -options(warn = 0) # これ以降,警告を表示する. - -y <- my_sample$dist -y_ <- my_model %>% predict(my_sample) - -RMSE(y_, y) -#> [1] 1.042275e-10 # RMSE - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 1 # 決定係数1 - -R2(pred = y_, obs = y, - form = "corr") -#> [1] 1 # 決定係数6 - -f <- function(x) { my_model %>% predict(data.frame(speed = x)) } - -my_data %>% - ggplot(aes(x = speed, y = dist, color = "data")) + - geom_point() + - geom_point(data = my_sample, mapping = aes(color = "sample")) + - stat_function(fun = f, mapping = aes(color = "model")) + - coord_cartesian(ylim = c(0, 120)) - -## 7.5 K最近傍法 - -### 7.5.1 K最近傍法とは何か - -### 7.5.2 K最近傍法の実践 - -# 準備 -library(caret) -library(tidyverse) -my_data <- cars - -# 訓練 -my_model <- train(form = dist ~ speed, data = my_data, method = "knn") - -# 可視化の準備 -f <- function(x) { my_model %>% predict(data.frame(speed = x))} - -my_data %>% - ggplot(aes(x = speed, - y = dist, - color = "data")) + - geom_point() + - stat_function( - fun = f, - mapping = aes(color = "model")) - -y <- my_data$dist -y_ <- my_model %>% predict(my_data) - -RMSE(y_, y) -#> [1] 13.96845 # RMSE - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 0.7001789 # 決定係数1 - -R2(pred = y_, obs = y, - form = "corr") -#> [1] 0.7017314 # 決定係数6 - -## 7.6 検証 - -### 7.6.1 訓練データ・検証データ・テストデータ - -### 7.6.2 検証とは何か - -### 7.6.3 検証の実践 - -library(caret) -library(tidyverse) -my_data <- cars -my_model <- train(form = dist ~ speed, data = my_data, method = "lm") - -my_model$results -#> intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD -#> 1 TRUE 16.0206 0.6662176 12.14701 2.518604 0.09249158 1.920564 - -my_model <- train(form = dist ~ speed, data = my_data, method = "lm", - trControl = trainControl(method = "cv", number = 5)) -my_model$results -#> intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD -#> 1 TRUE 15.06708 0.6724501 12.12448 4.75811 0.1848932 3.052435 - -my_model <- train(form = dist ~ speed, data = my_data, method = "lm", - trControl = trainControl(method = "LOOCV")) -my_model$results -#> intercept RMSE Rsquared MAE -#> 1 TRUE 15.69731 0.6217139 12.05918 - -### 7.6.4 検証の並列化 - -library(doParallel) -cl <- makeCluster(detectCores()) -registerDoParallel(cl) - -### 7.6.5 指標のまとめ - -#### 7.6.5.1 準備 - -library(caret) -library(tidyverse) -my_data <- cars -my_model <- train(form = dist ~ speed, data = my_data, method = "lm") -y <- my_data$dist -y_ <- my_model %>% predict(my_data) - -#### 7.6.5.2 当てはまりの良さの指標 - -# RMSE(訓練) -RMSE(y_, y) -#> [1] 15.06886 - -# 決定係数1(訓練) -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 0.6510794 - -# 決定係数6(訓練) -R2(pred = y_, obs = y, - form = "corr") -#> [1] 0.6510794 - -postResample(pred = y_, obs = y) -#> RMSE Rsquared MAE -#> 15.0688560 0.6510794 11.5801191 - -#### 7.6.5.3 予測性能の指標(簡単に求められるもの) - -my_model <- train(form = dist ~ speed, data = my_data, method = "lm") -my_model$results -#> intercept RMSE Rsquared MAE ... -#> 1 TRUE 14.88504 0.6700353 11.59226 ... -# 左から,RMSE(検証),決定係数6(検証),MAE(検証) - -#### 7.6.5.4 予測性能の指標(RとPythonで同じ結果を得る) - -my_model <- train(form = dist ~ speed, data = my_data, method = "lm", - trControl = trainControl(method = "LOOCV")) - -# 方法1 -my_model$results -#> intercept RMSE Rsquared MAE -#> 1 TRUE 15.69731 0.6217139 12.05918 - -# 方法2 -y <- my_model$pred$obs -y_ <- my_model$pred$pred -mean((y - y_)^2)**0.5 -#> [1] 15.69731 - -mean(((y - y_)^2)**0.5) -#> [1] 12.05918 - -### 7.6.6 補足:検証による手法の比較 - -library(caret) -library(tidyverse) -my_data <- cars - -my_lm_model <- train(form = dist ~ speed, data = my_data, method = "lm", - trControl = trainControl(method = "LOOCV")) - -my_knn_model <- train(form = dist ~ speed, data = my_data, method = "knn", - tuneGrid = data.frame(k = 5), - trControl = trainControl(method = "LOOCV")) - -my_lm_model$results$RMSE -#> [1] 15.69731 # 線形回帰分析 - -my_knn_model$results$RMSE -#> [1] 15.79924 # K最近傍法 - -y <- my_data$dist -y_lm <- my_lm_model$pred$pred -y_knn <- my_knn_model$pred$pred - -my_df <- data.frame( - lm = (y - y_lm)^2, - knn = (y - y_knn)^2) - -head(my_df) -#> lm knn -#> 1 18.913720 108.1600 -#> 2 179.215044 0.6400 -#> 3 41.034336 175.5625 -#> 4 168.490212 49.0000 -#> 5 5.085308 9.0000 -#> 6 67.615888 112.8906 - -boxplot(my_df, ylab = "r^2") - -t.test(x = my_df$lm, y = my_df$knn, - conf.level = 0.95, - paired = TRUE, - alternative = "two.sided") - -#> Paired t-test -#> -#> data: my_df$lm and my_df$knn -#> t = -0.12838, df = 49, p-value = 0.8984 -#> alternative hypothesis: true difference in means is not equal to 0 -#> 95 percent confidence interval: -#> -53.46930 47.04792 -#> sample estimates: -#> mean of the differences -#> -3.210688 - -## 7.7 パラメータチューニング - -library(caret) -library(tidyverse) -my_data <- cars -my_model <- train(form = dist ~ speed, data = my_data, method = "knn") -my_model$results -#> k RMSE Rsquared MAE RMSESD RsquaredSD MAESD -#> 1 5 15.72114 0.6615765 12.54588 3.013243 0.11043907 2.372245 -#> 2 7 16.19047 0.6601173 12.68464 3.165330 0.09990158 2.329326 -#> 3 9 16.30276 0.6556700 12.84811 3.367423 0.09645747 2.471620 - -my_params <- expand.grid(k = 1:15) - -my_model <- train(form = dist ~ speed, data = my_data, method = "knn", - tuneGrid = my_params, - trControl = trainControl(method = "LOOCV")) - -head(my_model$results) -#> k RMSE Rsquared MAE -#> 1 1 17.22299 0.5777197 13.84900 -#> 2 2 16.81462 0.5936438 13.03469 -#> 3 3 16.32874 0.6218866 12.74524 -#> 4 4 15.98970 0.6086993 12.27888 -#> 5 5 15.79924 0.6169267 11.96067 -#> 6 6 15.98720 0.6079396 12.26667 - -ggplot(my_model) - -my_model$bestTune -#> k -#> 5 5 - -my_model$results %>% - filter(RMSE == min(RMSE)) -#> k RMSE Rsquared MAE -#> 1 5 15.79924 0.6169267 11.96067 - -y <- my_data$dist -y_ <- my_model %>% predict(my_data) -RMSE(y_, y) -#> [1] 13.96845 - -### 7.7.1 補足:ハイパーパラメータとRMSE(訓練) - -library(caret) -library(tidyverse) -my_data <- cars - -my_loocv <- function(k) { - my_model <- train(form = dist ~ speed, data = my_data, method = "knn", - tuneGrid = data.frame(k = k), - trControl = trainControl(method = "LOOCV")) - y <- my_data$dist - y_ <- my_model %>% predict(my_data) - list(k = k, - training = RMSE(y_, y), # RMSE(訓練) - validation = my_model$results$RMSE) # RMSE(検証) -} - -my_results <- 1:15 %>% map_dfr(my_loocv) - -my_results %>% - pivot_longer(-k) %>% - ggplot(aes(x = k, y = value, - color = name)) + - geom_line() + geom_point() + - xlab("#Neighbors") + ylab("RMSE") + - theme(legend.position = c(1, 0), - legend.justification = c(1, 0)) - diff --git a/code/R/ch08/08.01.R b/code/R/ch08/08.01.R deleted file mode 100644 index dc65f38..0000000 --- a/code/R/ch08/08.01.R +++ /dev/null @@ -1,38 +0,0 @@ -## 8.1 ブドウの生育条件とワインの価格 - -library(tidyverse) -my_url <- "http://www.liquidasset.com/winedata.html" -tmp <- read.table(file = my_url, # 読み込む対象 - header = TRUE, # 1行目は変数名 - na.string = ".", # 欠損値を表す文字列 - skip = 62, # 読み飛ばす行数 - nrows = 38) # 読み込む行数 -psych::describe(tmp) -#> vars n mean sd median trimmed mad min max ... -#> OBS 1 38 19.50 11.11 19.50 19.50 14.08 1.00 38.00 ... -#> VINT 2 38 1970.50 11.11 1970.50 1970.50 14.08 1952.00 1989.00 ... -#> LPRICE2 3 27 -1.45 0.63 -1.51 -1.49 0.72 -2.29 0.00 ... -#> WRAIN 4 38 605.00 135.28 586.50 603.06 174.95 376.00 845.00 ... -#> DEGREES 5 37 16.52 0.66 16.53 16.55 0.67 14.98 17.65 ... -#> HRAIN 6 38 137.00 66.74 120.50 132.19 59.30 38.00 292.00 ... -#> TIME_SV 7 38 12.50 11.11 12.50 12.50 14.08 -6.00 31.00 ... - -my_data <- na.omit(tmp[, -c(1, 2)]) -head(my_data) -#> LPRICE2 WRAIN DEGREES ... -#> 1 -0.99868 600 17.1167 ... -#> 2 -0.45440 690 16.7333 ... -#> 4 -0.80796 502 17.1500 ... -#> 6 -1.50926 420 16.1333 ... -#> 7 -1.71655 582 16.4167 ... -#> 8 -0.41800 485 17.4833 ... - -dim(my_data) -#> [1] 27 5 - -my_data %>% write_csv("wine.csv") - -#my_data <- read_csv("wine.csv") # 作ったファイルを使う場合 -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) diff --git a/code/R/ch08/08.02.R b/code/R/ch08/08.02.R deleted file mode 100644 index a2df4fa..0000000 --- a/code/R/ch08/08.02.R +++ /dev/null @@ -1,60 +0,0 @@ -## 8.2 重回帰分析 - -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) - -my_model <- train(form = LPRICE2 ~ WRAIN + DEGREES + HRAIN + TIME_SV, - data = my_data, - method = "lm", - trControl = trainControl(method = "LOOCV")) - -coef(my_model$finalModel) %>% - as.data.frame -#> . -#> (Intercept) -12.145333577 -#> WRAIN 0.001166782 -#> DEGREES 0.616392441 -#> HRAIN -0.003860554 -#> TIME_SV 0.023847413 - -my_test <- data.frame( - WRAIN = 500, DEGREES = 17, - HRAIN = 120, TIME_SV = 2) -my_model %>% predict(my_test) -#> 1 -#> -1.498843 - -y <- my_data$LPRICE2 -y_ <- my_model %>% predict(my_data) - -RMSE(y_, y) -#> [1] 0.2586167 # RMSE(訓練) - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 0.8275278 # 決定係数1(訓練) - -R2(pred = y_, obs = y, - form = "corr") -#> [1] 0.8275278 # 決定係数6(訓練) - -my_model$results -#> intercept RMSE Rsquared MAE -#> 1 TRUE 0.3230043 0.7361273 0.2767282 - -### 8.2.1 補足:行列計算による再現 - -M <- my_data[, -1] %>% - mutate(b0 = 1) %>% as.matrix -b <- MASS::ginv(M) %*% y -matrix(b, - dimnames = list(colnames(M))) -#> [,1] -#> WRAIN 0.001166782 -#> DEGREES 0.616392441 -#> HRAIN -0.003860554 -#> TIME_SV 0.023847413 -#> b0 -12.145333577 diff --git a/code/R/ch08/08.03.R b/code/R/ch08/08.03.R deleted file mode 100644 index ace9d17..0000000 --- a/code/R/ch08/08.03.R +++ /dev/null @@ -1,37 +0,0 @@ -## 8.3 標準化 - -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) - -my_data %>% - mutate_if(is.numeric, scale) %>% # 数値の列の標準化 - pivot_longer(-LPRICE2) %>% - ggplot(aes(x = name, y = value)) + - geom_boxplot() + - stat_summary(fun = mean, geom = "point", size = 3) + - xlab(NULL) - -my_model <- train( - form = LPRICE2 ~ ., - data = my_data, - method = "lm", - preProcess = c("center", "scale")) - -coef(my_model$finalModel) %>% - as.data.frame -#> . -#> (Intercept) -1.4517652 -#> WRAIN 0.1505557 -#> DEGREES 0.4063194 -#> HRAIN -0.2820746 -#> TIME_SV 0.1966549 - -my_test <- data.frame( - WRAIN = 500, DEGREES = 17, - HRAIN = 120, TIME_SV = 2) -my_model %>% predict(my_test) -#> 1 -#> -1.498843 diff --git a/code/R/ch08/08.04.R b/code/R/ch08/08.04.R deleted file mode 100644 index 5d75bdc..0000000 --- a/code/R/ch08/08.04.R +++ /dev/null @@ -1,32 +0,0 @@ -## 8.4 入力変数の数とモデルの良さ - -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) - -n <- nrow(my_data) -my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2, - v2 = 0:(n - 1) %% 3) -head(my_data2) -#> # A tibble: 6 x 7 -#> LPRICE2 WRAIN DEGREES HRAIN TIME_SV v1 v2 -#> -#> 1 -0.999 600 17.1 160 31 0 0 -#> 2 -0.454 690 16.7 80 30 1 1 -#> 3 -0.808 502 17.2 130 28 0 2 -#> 4 -1.51 420 16.1 110 26 1 0 -#> 5 -1.72 582 16.4 187 25 0 1 -#> 6 -0.418 485 17.5 187 24 1 2 - -my_model2 <- train(form = LPRICE2 ~ ., data = my_data2, method = "lm", - trControl = trainControl(method = "LOOCV")) -y <- my_data2$LPRICE2 -y_ <- my_model2 %>% predict(my_data2) - -RMSE(y_, y) -#> [1] 0.256212 # RMSE(訓練) - -my_model2$results$RMSE -#> [1] 0.3569918 # RMSE(検証) diff --git a/code/R/ch08/08.05.R b/code/R/ch08/08.05.R deleted file mode 100644 index 1f087b3..0000000 --- a/code/R/ch08/08.05.R +++ /dev/null @@ -1,22 +0,0 @@ -## 8.5 変数選択 - -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) -n <- nrow(my_data) -my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2, - v2 = 0:(n - 1) %% 3) - -my_model <- train(form = LPRICE2 ~ ., - data = my_data2, - method = "leapForward", # 変数増加法 - trControl = trainControl(method = "LOOCV"), - tuneGrid = data.frame(nvmax = 1:6)) # 選択する変数の上限 -summary(my_model$finalModel)$outmat -#> WRAIN DEGREES HRAIN TIME_SV v1 v2 -#> 1 ( 1 ) " " "*" " " " " " " " " -#> 2 ( 1 ) " " "*" "*" " " " " " " -#> 3 ( 1 ) " " "*" "*" "*" " " " " -#> 4 ( 1 ) "*" "*" "*" "*" " " " " diff --git a/code/R/ch08/08.06.R b/code/R/ch08/08.06.R deleted file mode 100644 index 12d6de3..0000000 --- a/code/R/ch08/08.06.R +++ /dev/null @@ -1,80 +0,0 @@ -## 8.6 補足:正則化 - -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) - -### 8.6.1 正則化の実践 - -A <- 2 -B <- 0.1 - -my_model <- train( - form = LPRICE2 ~ ., - data = my_data, - method = "glmnet", - standardize = TRUE, - tuneGrid = data.frame( - lambda = A, - alpha = B)) - -coef(my_model$finalModel, A) -#> 1 -#> (Intercept) -2.8015519302 -#> WRAIN . -#> DEGREES 0.0832910512 -#> HRAIN -0.0004147386 -#> TIME_SV 0.0023104647 - -my_test <- data.frame( - WRAIN = 500, DEGREES = 17, - HRAIN = 120, TIME_SV = 2) -my_model %>% predict(my_test) -#> [1] -1.430752 - -### 8.6.2 ペナルティの強さと係数の関係 - -library(ggfortify) -library(glmnetUtils) - -my_data2 <- my_data %>% scale %>% - as.data.frame - -B <- 0.1 - -glmnet( - form = LPRICE2 ~ ., - data = my_data2, - alpha = B) %>% - autoplot(xvar = "lambda") + - xlab("log A ( = log lambda)") + - theme(legend.position = c(0.15, 0.25)) - -### 8.6.3 パラメータの決定 - -As <- seq(0, 0.1, length.out = 21) -Bs <- seq(0, 0.1, length.out = 6) - -my_model <- train( - form = LPRICE2 ~ ., data = my_data, method = "glmnet", standardize = TRUE, - trControl = trainControl(method = "LOOCV"), - tuneGrid = expand.grid(lambda = As, alpha = Bs)) - -my_model$bestTune -#> alpha lambda -#> 8 0 0.035 - -tmp <- "B ( = alpha)" -ggplot(my_model) + - theme(legend.position = c(0, 1), legend.justification = c(0, 1)) + - xlab("A ( = lambda)") + - guides(shape = guide_legend(tmp), color = guide_legend(tmp)) - -my_model$results %>% - filter(RMSE == min(RMSE)) -#> alpha lambda RMSE ... -#> 1 0 0.0595 0.3117092 ... - -### 8.6.4 補足:RとPythonで結果を同じにする方法 diff --git a/code/R/ch08/08.07.R b/code/R/ch08/08.07.R deleted file mode 100644 index 92add72..0000000 --- a/code/R/ch08/08.07.R +++ /dev/null @@ -1,43 +0,0 @@ -## 8.7 ニューラルネットワーク - -### 8.7.1 ニューラルネットワークとは何か - -curve(1 / (1 + exp(-x)), -6, 6) - -### 8.7.2 ニューラルネットワークの訓練 - -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) - -my_model <- train(form = LPRICE2 ~ ., - data = my_data, - method = "neuralnet", # ニューラルネットワーク - preProcess = c("center", "scale"), # 標準化 - trControl = trainControl(method = "LOOCV")) -plot(my_model$finalModel) # 訓練済ネットワークの描画 - -my_model$results -#> layer1 layer2 layer3 RMSE ... -#> 1 1 0 0 0.3504016 ... -#> 2 3 0 0 0.4380399 ... -#> 3 5 0 0 0.4325535 ... - -### 8.7.3 ニューラルネットワークのチューニング - -my_model <- train( - form = LPRICE2 ~ ., - data = my_data, - method = "neuralnet", - preProcess = c("center", "scale"), - trControl = trainControl(method = "LOOCV"), - tuneGrid = expand.grid(layer1 = 1:5, - layer2 = 0:2, - layer3 = 0)) - -my_model$results %>% - filter(RMSE == min(RMSE)) -#> layer1 layer2 layer3 RMSE ... -#> 1 2 0 0 0.3165704 ... diff --git a/code/R/ch08/08.R b/code/R/ch08/08.R deleted file mode 100644 index cc86c59..0000000 --- a/code/R/ch08/08.R +++ /dev/null @@ -1,319 +0,0 @@ -## 8.1 ブドウの生育条件とワインの価格 - -library(tidyverse) -my_url <- "http://www.liquidasset.com/winedata.html" -tmp <- read.table(file = my_url, # 読み込む対象 - header = TRUE, # 1行目は変数名 - na.string = ".", # 欠損値を表す文字列 - skip = 62, # 読み飛ばす行数 - nrows = 38) # 読み込む行数 -psych::describe(tmp) -#> vars n mean sd median trimmed mad min max ... -#> OBS 1 38 19.50 11.11 19.50 19.50 14.08 1.00 38.00 ... -#> VINT 2 38 1970.50 11.11 1970.50 1970.50 14.08 1952.00 1989.00 ... -#> LPRICE2 3 27 -1.45 0.63 -1.51 -1.49 0.72 -2.29 0.00 ... -#> WRAIN 4 38 605.00 135.28 586.50 603.06 174.95 376.00 845.00 ... -#> DEGREES 5 37 16.52 0.66 16.53 16.55 0.67 14.98 17.65 ... -#> HRAIN 6 38 137.00 66.74 120.50 132.19 59.30 38.00 292.00 ... -#> TIME_SV 7 38 12.50 11.11 12.50 12.50 14.08 -6.00 31.00 ... - -my_data <- na.omit(tmp[, -c(1, 2)]) -head(my_data) -#> LPRICE2 WRAIN DEGREES ... -#> 1 -0.99868 600 17.1167 ... -#> 2 -0.45440 690 16.7333 ... -#> 4 -0.80796 502 17.1500 ... -#> 6 -1.50926 420 16.1333 ... -#> 7 -1.71655 582 16.4167 ... -#> 8 -0.41800 485 17.4833 ... - -dim(my_data) -#> [1] 27 5 - -my_data %>% write_csv("wine.csv") - -#my_data <- read_csv("wine.csv") # 作ったファイルを使う場合 -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) - -## 8.2 重回帰分析 - -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) - -my_model <- train(form = LPRICE2 ~ WRAIN + DEGREES + HRAIN + TIME_SV, - data = my_data, - method = "lm", - trControl = trainControl(method = "LOOCV")) - -coef(my_model$finalModel) %>% - as.data.frame -#> . -#> (Intercept) -12.145333577 -#> WRAIN 0.001166782 -#> DEGREES 0.616392441 -#> HRAIN -0.003860554 -#> TIME_SV 0.023847413 - -my_test <- data.frame( - WRAIN = 500, DEGREES = 17, - HRAIN = 120, TIME_SV = 2) -my_model %>% predict(my_test) -#> 1 -#> -1.498843 - -y <- my_data$LPRICE2 -y_ <- my_model %>% predict(my_data) - -RMSE(y_, y) -#> [1] 0.2586167 # RMSE(訓練) - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 0.8275278 # 決定係数1(訓練) - -R2(pred = y_, obs = y, - form = "corr") -#> [1] 0.8275278 # 決定係数6(訓練) - -my_model$results -#> intercept RMSE Rsquared MAE -#> 1 TRUE 0.3230043 0.7361273 0.2767282 - -### 8.2.1 補足:行列計算による再現 - -M <- my_data[, -1] %>% - mutate(b0 = 1) %>% as.matrix -b <- MASS::ginv(M) %*% y -matrix(b, - dimnames = list(colnames(M))) -#> [,1] -#> WRAIN 0.001166782 -#> DEGREES 0.616392441 -#> HRAIN -0.003860554 -#> TIME_SV 0.023847413 -#> b0 -12.145333577 - -## 8.3 標準化 - -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) - -my_data %>% - mutate_if(is.numeric, scale) %>% # 数値の列の標準化 - pivot_longer(-LPRICE2) %>% - ggplot(aes(x = name, y = value)) + - geom_boxplot() + - stat_summary(fun = mean, geom = "point", size = 3) + - xlab(NULL) - -my_model <- train( - form = LPRICE2 ~ ., - data = my_data, - method = "lm", - preProcess = c("center", "scale")) - -coef(my_model$finalModel) %>% - as.data.frame -#> . -#> (Intercept) -1.4517652 -#> WRAIN 0.1505557 -#> DEGREES 0.4063194 -#> HRAIN -0.2820746 -#> TIME_SV 0.1966549 - -my_test <- data.frame( - WRAIN = 500, DEGREES = 17, - HRAIN = 120, TIME_SV = 2) -my_model %>% predict(my_test) -#> 1 -#> -1.498843 - -## 8.4 入力変数の数とモデルの良さ - -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) - -n <- nrow(my_data) -my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2, - v2 = 0:(n - 1) %% 3) -head(my_data2) -#> # A tibble: 6 x 7 -#> LPRICE2 WRAIN DEGREES HRAIN TIME_SV v1 v2 -#> -#> 1 -0.999 600 17.1 160 31 0 0 -#> 2 -0.454 690 16.7 80 30 1 1 -#> 3 -0.808 502 17.2 130 28 0 2 -#> 4 -1.51 420 16.1 110 26 1 0 -#> 5 -1.72 582 16.4 187 25 0 1 -#> 6 -0.418 485 17.5 187 24 1 2 - -my_model2 <- train(form = LPRICE2 ~ ., data = my_data2, method = "lm", - trControl = trainControl(method = "LOOCV")) -y <- my_data2$LPRICE2 -y_ <- my_model2 %>% predict(my_data2) - -RMSE(y_, y) -#> [1] 0.256212 # RMSE(訓練) - -my_model2$results$RMSE -#> [1] 0.3569918 # RMSE(検証) - -## 8.5 変数選択 - -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) -n <- nrow(my_data) -my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2, - v2 = 0:(n - 1) %% 3) - -my_model <- train(form = LPRICE2 ~ ., - data = my_data2, - method = "leapForward", # 変数増加法 - trControl = trainControl(method = "LOOCV"), - tuneGrid = data.frame(nvmax = 1:6)) # 選択する変数の上限 -summary(my_model$finalModel)$outmat -#> WRAIN DEGREES HRAIN TIME_SV v1 v2 -#> 1 ( 1 ) " " "*" " " " " " " " " -#> 2 ( 1 ) " " "*" "*" " " " " " " -#> 3 ( 1 ) " " "*" "*" "*" " " " " -#> 4 ( 1 ) "*" "*" "*" "*" " " " " - -## 8.6 補足:正則化 - -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) - -### 8.6.1 正則化の実践 - -A <- 2 -B <- 0.1 - -my_model <- train( - form = LPRICE2 ~ ., - data = my_data, - method = "glmnet", - standardize = TRUE, - tuneGrid = data.frame( - lambda = A, - alpha = B)) - -coef(my_model$finalModel, A) -#> 1 -#> (Intercept) -2.8015519302 -#> WRAIN . -#> DEGREES 0.0832910512 -#> HRAIN -0.0004147386 -#> TIME_SV 0.0023104647 - -my_test <- data.frame( - WRAIN = 500, DEGREES = 17, - HRAIN = 120, TIME_SV = 2) -my_model %>% predict(my_test) -#> [1] -1.430752 - -### 8.6.2 ペナルティの強さと係数の関係 - -library(ggfortify) -library(glmnetUtils) - -my_data2 <- my_data %>% scale %>% - as.data.frame - -B <- 0.1 - -glmnet( - form = LPRICE2 ~ ., - data = my_data2, - alpha = B) %>% - autoplot(xvar = "lambda") + - xlab("log A ( = log lambda)") + - theme(legend.position = c(0.15, 0.25)) - -### 8.6.3 パラメータの決定 - -As <- seq(0, 0.1, length.out = 21) -Bs <- seq(0, 0.1, length.out = 6) - -my_model <- train( - form = LPRICE2 ~ ., data = my_data, method = "glmnet", standardize = TRUE, - trControl = trainControl(method = "LOOCV"), - tuneGrid = expand.grid(lambda = As, alpha = Bs)) - -my_model$bestTune -#> alpha lambda -#> 8 0 0.035 - -tmp <- "B ( = alpha)" -ggplot(my_model) + - theme(legend.position = c(0, 1), legend.justification = c(0, 1)) + - xlab("A ( = lambda)") + - guides(shape = guide_legend(tmp), color = guide_legend(tmp)) - -my_model$results %>% - filter(RMSE == min(RMSE)) -#> alpha lambda RMSE ... -#> 1 0 0.0595 0.3117092 ... - -### 8.6.4 補足:RとPythonで結果を同じにする方法 - -## 8.7 ニューラルネットワーク - -### 8.7.1 ニューラルネットワークとは何か - -curve(1 / (1 + exp(-x)), -6, 6) - -### 8.7.2 ニューラルネットワークの訓練 - -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) - -my_model <- train(form = LPRICE2 ~ ., - data = my_data, - method = "neuralnet", # ニューラルネットワーク - preProcess = c("center", "scale"), # 標準化 - trControl = trainControl(method = "LOOCV")) -plot(my_model$finalModel) # 訓練済ネットワークの描画 - -my_model$results -#> layer1 layer2 layer3 RMSE ... -#> 1 1 0 0 0.3504016 ... -#> 2 3 0 0 0.4380399 ... -#> 3 5 0 0 0.4325535 ... - -### 8.7.3 ニューラルネットワークのチューニング - -my_model <- train( - form = LPRICE2 ~ ., - data = my_data, - method = "neuralnet", - preProcess = c("center", "scale"), - trControl = trainControl(method = "LOOCV"), - tuneGrid = expand.grid(layer1 = 1:5, - layer2 = 0:2, - layer3 = 0)) - -my_model$results %>% - filter(RMSE == min(RMSE)) -#> layer1 layer2 layer3 RMSE ... -#> 1 2 0 0 0.3165704 ... - diff --git a/code/R/ch09/09.01.R b/code/R/ch09/09.01.R deleted file mode 100644 index 4f4fa68..0000000 --- a/code/R/ch09/09.01.R +++ /dev/null @@ -1,19 +0,0 @@ -## 9.1 アヤメのデータ - -my_data <- iris -head(my_data) -#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species -#> 1 5.1 3.5 1.4 0.2 setosa -#> 2 4.9 3.0 1.4 0.2 setosa -#> 3 4.7 3.2 1.3 0.2 setosa -#> 4 4.6 3.1 1.5 0.2 setosa -#> 5 5.0 3.6 1.4 0.2 setosa -#> 6 5.4 3.9 1.7 0.4 setosa - -psych::describe(my_data) -#> vars n mean sd median trimmed mad min max range ... -#> Sepal.Length 1 150 5.84 0.83 5.80 5.81 1.04 4.3 7.9 3.6 ... -#> Sepal.Width 2 150 3.06 0.44 3.00 3.04 0.44 2.0 4.4 2.4 ... -#> Petal.Length 3 150 3.76 1.77 4.35 3.76 1.85 1.0 6.9 5.9 ... -#> Petal.Width 4 150 1.20 0.76 1.30 1.18 1.04 0.1 2.5 2.4 ... -#> Species* 5 150 2.00 0.82 2.00 2.00 1.48 1.0 3.0 2.0 ... diff --git a/code/R/ch09/09.02.R b/code/R/ch09/09.02.R deleted file mode 100644 index 36b2aa6..0000000 --- a/code/R/ch09/09.02.R +++ /dev/null @@ -1,25 +0,0 @@ -## 9.2 木による分類 - -### 9.2.1 分類木の作成と利用 - -library(caret) -library(tidyverse) -my_data <- iris -my_model <- train(form = Species ~ ., data = my_data, method = "rpart") - -rpart.plot::rpart.plot(my_model$finalModel, extra = 1) - -my_test <- tribble( -~Sepal.Length, ~Sepal.Width, ~Petal.Length, ~Petal.Width, - 5.0, 3.5, 1.5, 0.5, - 6.5, 3.0, 5.0, 2.0) - -my_model %>% predict(my_test) -#> [1] setosa virginica -#> Levels: setosa versicolor virginica - -my_model %>% predict(my_test, - type = "prob") -#> setosa versicolor virginica -#> 1 1 0.00000000 0.0000000 -#> 2 0 0.02173913 0.9782609 diff --git a/code/R/ch09/09.03.R b/code/R/ch09/09.03.R deleted file mode 100644 index a4da7f9..0000000 --- a/code/R/ch09/09.03.R +++ /dev/null @@ -1,91 +0,0 @@ -## 9.3 正解率 - -### 9.3.1 混同行列 - -library(caret) -library(tidyverse) -my_data <- iris -my_model <- train(form = Species ~ ., data = my_data, method = "rpart2") - -y <- my_data$Species -y_ <- my_model %>% predict(my_data) -confusionMatrix(data = y_, reference = y) -#> Confusion Matrix and Statistics -#> -#> Reference -#> Prediction setosa versicolor virginica -#> setosa 50 0 0 -#> versicolor 0 49 1 -#> virginica 0 5 45 -# 以下は割愛 - -### 9.3.2 正解率(訓練) - -y <- my_data$Species -y_ <- my_model %>% predict(my_data) -mean(y_ == y) -#> [1] 0.96 - -### 9.3.3 正解率(検証) - -my_model <- train(form = Species ~ ., data = my_data, method = "rpart2", - trControl = trainControl(method = "LOOCV")) -my_model$results -#> maxdepth Accuracy Kappa -#> 1 1 0.3333333 0.00 -#> 2 2 0.9533333 0.93 - -### 9.3.4 パラメータチューニング - -my_model <- train(form = Species ~ ., data = my_data, method = "rpart2", - tuneGrid = data.frame(maxdepth = 1:10), - trControl = trainControl(method = "LOOCV")) -my_model$results %>% filter(Accuracy == max(Accuracy)) -#> maxdepth Accuracy Kappa -#> 1 2 0.9533333 0.93 - -### 9.3.5 補足:木の複雑さの制限 - -# パラメータを与えると正解率(LOOCV)を返す関数 -my_loocv <- function(maxdepth, minbucket, minsplit) { - my_model <- train(form = Species ~ ., data = my_data, method = "rpart2", - trControl = trainControl(method = "LOOCV"), - tuneGrid = data.frame(maxdepth = maxdepth), - control = rpart::rpart.control(cp = 0.01, - minbucket = minbucket, - minsplit = minsplit)) - list(maxdepth = maxdepth, - minbucket = minbucket, - minsplit = minsplit, - Accuracy = my_model$results$Accuracy) -} - -my_params <- expand.grid( - maxdepth = 2:5, - minbucket = 1:7, - minsplit = c(2, 20)) - -library(furrr) -plan(multisession) # 並列処理の準備 -my_results <- my_params %>% future_pmap_dfr(my_loocv, # 実行 - .options = furrr_options(seed = TRUE)) - -my_results %>% filter(Accuracy == max(Accuracy)) # 正解率(検証)の最大値 -#> maxdepth minbucket minsplit Accuracy -#> -#> 1 3 5 2 0.973 -#> 2 4 5 2 0.973 -#> 3 5 5 2 0.973 -#> 4 3 5 20 0.973 -#> 5 4 5 20 0.973 -#> 6 5 5 20 0.973 - -my_model <- train(form = Species ~ ., data = my_data, method = "rpart2", - trControl = trainControl(method = "none"), - tuneGrid = data.frame(maxdepth = 3), - control = rpart::rpart.control(cp = 0.01, - minbucket = 5, - minsplit = 2)) - -rpart.plot::rpart.plot( - my_model$finalModel, extra = 1) diff --git a/code/R/ch09/09.04.R b/code/R/ch09/09.04.R deleted file mode 100644 index ff6d3a4..0000000 --- a/code/R/ch09/09.04.R +++ /dev/null @@ -1,48 +0,0 @@ -## 9.4 複数の木を使う方法 - -### 9.4.1 ランダムフォレスト - -library(caret) -library(tidyverse) -my_data <- iris - -my_model <- train(form = Species ~ ., data = my_data, method = "rf", - tuneGrid = data.frame(mtry = 2:4), # 省略可 - trControl = trainControl(method = "LOOCV")) -my_model$results -#> mtry Accuracy Kappa -#> 1 2 0.96 0.94 -#> 2 3 0.96 0.94 -#> 3 4 0.96 0.94 - -### 9.4.2 ブースティング - -my_model <- train( - form = Species ~ ., data = my_data, method = "xgbTree", - tuneGrid = expand.grid( - nrounds = c(50, 100, 150), - max_depth = c(1, 2, 3), - eta = c(0.3, 0.4), - gamma = 0, - colsample_bytree = c(0.6, 0.8), - min_child_weight = 1, - subsample = c(0.5, 0.75, 1)), - trControl = trainControl(method = "cv", number = 5)) # 5分割交差検証 -my_model$results %>% filter(Accuracy == max(Accuracy)) %>% head(5) %>% t -#> 1 2 3 4 5 -#> eta 0.30000000 0.30000000 0.30000000 0.40000000 0.30000000 -#> max_depth 1.00000000 1.00000000 1.00000000 1.00000000 3.00000000 -#> gamma 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 -#> colsample_bytree 0.60000000 0.60000000 0.80000000 0.60000000 0.80000000 -#> min_child_weight 1.00000000 1.00000000 1.00000000 1.00000000 1.00000000 -#> subsample 0.50000000 0.75000000 0.75000000 0.50000000 0.50000000 -#> nrounds 50.00000000 50.00000000 50.00000000 50.00000000 50.00000000 -#> Accuracy 0.96000000 0.96000000 0.96000000 0.96000000 0.96000000 -#> Kappa 0.94000000 0.94000000 0.94000000 0.94000000 0.94000000 -#> AccuracySD 0.02788867 0.02788867 0.02788867 0.01490712 0.01490712 -#> KappaSD 0.04183300 0.04183300 0.04183300 0.02236068 0.02236068 - -### 9.4.3 入力変数の重要度 - -my_model <- train(form = Species ~ ., data = my_data, method = "rf") -ggplot(varImp(my_model)) diff --git a/code/R/ch09/09.05.R b/code/R/ch09/09.05.R deleted file mode 100644 index b38121b..0000000 --- a/code/R/ch09/09.05.R +++ /dev/null @@ -1,40 +0,0 @@ -## 9.5 欠損のあるデータでの学習 - -### 9.5.1 欠損のあるデータの準備 - -library(caret) -library(tidyverse) -my_data <- iris - -n <- nrow(my_data) -my_data$Petal.Length[0:(n - 1) %% 10 == 0] <- NA -my_data$Petal.Width[ 0:(n - 1) %% 10 == 1] <- NA - -psych::describe(my_data) # nの値が135の変数に,150 - 135 = 15個の欠損がある. -#> vars n mean sd median trimmed mad min max range ... -#> Sepal.Length 1 150 5.84 0.83 5.8 5.81 1.04 4.3 7.9 3.6 ... -#> Sepal.Width 2 150 3.06 0.44 3.0 3.04 0.44 2.0 4.4 2.4 ... -#> Petal.Length 3 135 3.75 1.76 4.3 3.75 1.78 1.0 6.9 5.9 ... -#> Petal.Width 4 135 1.20 0.77 1.3 1.18 1.04 0.1 2.5 2.4 ... -#> Species* 5 150 2.00 0.82 2.0 2.00 1.48 1.0 3.0 2.0 ... - -### 9.5.2 方針1:欠損を埋めて学習する. - -my_model <- train( - form = Species ~ ., data = my_data, method = "rpart2", - na.action = na.pass, # 欠損があっても学習を止めない. - preProcess = "medianImpute", # 欠損を中央値で埋める. - trControl = trainControl(method = "LOOCV"), - tuneGrid = data.frame(maxdepth = 20), # 木の高さの上限 - control = rpart::rpart.control(minsplit = 2, # 分岐の条件 - minbucket = 1)) # 終端ノードの条件 -max(my_model$results$Accuracy) -#> [1] 0.9266667 - -### 9.5.3 方針2:欠損があっても使える手法で学習する. - -my_model <- train(form = Species ~ ., data = my_data, method = "xgbTree", - na.action = na.pass, - trControl = trainControl(method = "cv", number = 5)) -max(my_model$results$Accuracy) -#> [1] 0.966666666666667 diff --git a/code/R/ch09/09.06.R b/code/R/ch09/09.06.R deleted file mode 100644 index ef91047..0000000 --- a/code/R/ch09/09.06.R +++ /dev/null @@ -1,28 +0,0 @@ -## 9.6 他の分類手法 - -### 9.6.1 K最近傍法 - -library(caret) -library(tidyverse) -my_data <- iris - -my_model <- train(form = Species ~ ., data = my_data, method = "knn", - trControl = trainControl(method = "LOOCV")) -my_model$results %>% filter(Accuracy == max(Accuracy)) -#> k Accuracy Kappa -#> 1 9 0.9733333 0.96 - -### 9.6.2 ニューラルネットワーク - -library(caret) -library(tidyverse) -my_data <- iris - -my_model <- train(form = Species ~ ., data = my_data, method = "nnet", - preProcess = c("center", "scale"), # 標準化 - trControl = trainControl(method = "LOOCV"), - trace = FALSE) # 途中経過を表示しない -my_model$results %>% filter(Accuracy == max(Accuracy)) -#> size decay Accuracy Kappa -#> 1 3 0.1 0.9733333 0.96 -#> 2 5 0.1 0.9733333 0.96 diff --git a/code/R/ch09/09.R b/code/R/ch09/09.R deleted file mode 100644 index e061a87..0000000 --- a/code/R/ch09/09.R +++ /dev/null @@ -1,257 +0,0 @@ -## 9.1 アヤメのデータ - -my_data <- iris -head(my_data) -#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species -#> 1 5.1 3.5 1.4 0.2 setosa -#> 2 4.9 3.0 1.4 0.2 setosa -#> 3 4.7 3.2 1.3 0.2 setosa -#> 4 4.6 3.1 1.5 0.2 setosa -#> 5 5.0 3.6 1.4 0.2 setosa -#> 6 5.4 3.9 1.7 0.4 setosa - -psych::describe(my_data) -#> vars n mean sd median trimmed mad min max range ... -#> Sepal.Length 1 150 5.84 0.83 5.80 5.81 1.04 4.3 7.9 3.6 ... -#> Sepal.Width 2 150 3.06 0.44 3.00 3.04 0.44 2.0 4.4 2.4 ... -#> Petal.Length 3 150 3.76 1.77 4.35 3.76 1.85 1.0 6.9 5.9 ... -#> Petal.Width 4 150 1.20 0.76 1.30 1.18 1.04 0.1 2.5 2.4 ... -#> Species* 5 150 2.00 0.82 2.00 2.00 1.48 1.0 3.0 2.0 ... - -## 9.2 木による分類 - -### 9.2.1 分類木の作成と利用 - -library(caret) -library(tidyverse) -my_data <- iris -my_model <- train(form = Species ~ ., data = my_data, method = "rpart") - -rpart.plot::rpart.plot(my_model$finalModel, extra = 1) - -my_test <- tribble( -~Sepal.Length, ~Sepal.Width, ~Petal.Length, ~Petal.Width, - 5.0, 3.5, 1.5, 0.5, - 6.5, 3.0, 5.0, 2.0) - -my_model %>% predict(my_test) -#> [1] setosa virginica -#> Levels: setosa versicolor virginica - -my_model %>% predict(my_test, - type = "prob") -#> setosa versicolor virginica -#> 1 1 0.00000000 0.0000000 -#> 2 0 0.02173913 0.9782609 - -## 9.3 正解率 - -### 9.3.1 混同行列 - -library(caret) -library(tidyverse) -my_data <- iris -my_model <- train(form = Species ~ ., data = my_data, method = "rpart2") - -y <- my_data$Species -y_ <- my_model %>% predict(my_data) -confusionMatrix(data = y_, reference = y) -#> Confusion Matrix and Statistics -#> -#> Reference -#> Prediction setosa versicolor virginica -#> setosa 50 0 0 -#> versicolor 0 49 1 -#> virginica 0 5 45 -# 以下は割愛 - -### 9.3.2 正解率(訓練) - -y <- my_data$Species -y_ <- my_model %>% predict(my_data) -mean(y_ == y) -#> [1] 0.96 - -### 9.3.3 正解率(検証) - -my_model <- train(form = Species ~ ., data = my_data, method = "rpart2", - trControl = trainControl(method = "LOOCV")) -my_model$results -#> maxdepth Accuracy Kappa -#> 1 1 0.3333333 0.00 -#> 2 2 0.9533333 0.93 - -### 9.3.4 パラメータチューニング - -my_model <- train(form = Species ~ ., data = my_data, method = "rpart2", - tuneGrid = data.frame(maxdepth = 1:10), - trControl = trainControl(method = "LOOCV")) -my_model$results %>% filter(Accuracy == max(Accuracy)) -#> maxdepth Accuracy Kappa -#> 1 2 0.9533333 0.93 - -### 9.3.5 補足:木の複雑さの制限 - -# パラメータを与えると正解率(LOOCV)を返す関数 -my_loocv <- function(maxdepth, minbucket, minsplit) { - my_model <- train(form = Species ~ ., data = my_data, method = "rpart2", - trControl = trainControl(method = "LOOCV"), - tuneGrid = data.frame(maxdepth = maxdepth), - control = rpart::rpart.control(cp = 0.01, - minbucket = minbucket, - minsplit = minsplit)) - list(maxdepth = maxdepth, - minbucket = minbucket, - minsplit = minsplit, - Accuracy = my_model$results$Accuracy) -} - -my_params <- expand.grid( - maxdepth = 2:5, - minbucket = 1:7, - minsplit = c(2, 20)) - -library(furrr) -plan(multisession) # 並列処理の準備 -my_results <- my_params %>% future_pmap_dfr(my_loocv, # 実行 - .options = furrr_options(seed = TRUE)) - -my_results %>% filter(Accuracy == max(Accuracy)) # 正解率(検証)の最大値 -#> maxdepth minbucket minsplit Accuracy -#> -#> 1 3 5 2 0.973 -#> 2 4 5 2 0.973 -#> 3 5 5 2 0.973 -#> 4 3 5 20 0.973 -#> 5 4 5 20 0.973 -#> 6 5 5 20 0.973 - -my_model <- train(form = Species ~ ., data = my_data, method = "rpart2", - trControl = trainControl(method = "none"), - tuneGrid = data.frame(maxdepth = 3), - control = rpart::rpart.control(cp = 0.01, - minbucket = 5, - minsplit = 2)) - -rpart.plot::rpart.plot( - my_model$finalModel, extra = 1) - -## 9.4 複数の木を使う方法 - -### 9.4.1 ランダムフォレスト - -library(caret) -library(tidyverse) -my_data <- iris - -my_model <- train(form = Species ~ ., data = my_data, method = "rf", - tuneGrid = data.frame(mtry = 2:4), # 省略可 - trControl = trainControl(method = "LOOCV")) -my_model$results -#> mtry Accuracy Kappa -#> 1 2 0.96 0.94 -#> 2 3 0.96 0.94 -#> 3 4 0.96 0.94 - -### 9.4.2 ブースティング - -my_model <- train( - form = Species ~ ., data = my_data, method = "xgbTree", - tuneGrid = expand.grid( - nrounds = c(50, 100, 150), - max_depth = c(1, 2, 3), - eta = c(0.3, 0.4), - gamma = 0, - colsample_bytree = c(0.6, 0.8), - min_child_weight = 1, - subsample = c(0.5, 0.75, 1)), - trControl = trainControl(method = "cv", number = 5)) # 5分割交差検証 -my_model$results %>% filter(Accuracy == max(Accuracy)) %>% head(5) %>% t -#> 1 2 3 4 5 -#> eta 0.30000000 0.30000000 0.30000000 0.40000000 0.30000000 -#> max_depth 1.00000000 1.00000000 1.00000000 1.00000000 3.00000000 -#> gamma 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 -#> colsample_bytree 0.60000000 0.60000000 0.80000000 0.60000000 0.80000000 -#> min_child_weight 1.00000000 1.00000000 1.00000000 1.00000000 1.00000000 -#> subsample 0.50000000 0.75000000 0.75000000 0.50000000 0.50000000 -#> nrounds 50.00000000 50.00000000 50.00000000 50.00000000 50.00000000 -#> Accuracy 0.96000000 0.96000000 0.96000000 0.96000000 0.96000000 -#> Kappa 0.94000000 0.94000000 0.94000000 0.94000000 0.94000000 -#> AccuracySD 0.02788867 0.02788867 0.02788867 0.01490712 0.01490712 -#> KappaSD 0.04183300 0.04183300 0.04183300 0.02236068 0.02236068 - -### 9.4.3 入力変数の重要度 - -my_model <- train(form = Species ~ ., data = my_data, method = "rf") -ggplot(varImp(my_model)) - -## 9.5 欠損のあるデータでの学習 - -### 9.5.1 欠損のあるデータの準備 - -library(caret) -library(tidyverse) -my_data <- iris - -n <- nrow(my_data) -my_data$Petal.Length[0:(n - 1) %% 10 == 0] <- NA -my_data$Petal.Width[ 0:(n - 1) %% 10 == 1] <- NA - -psych::describe(my_data) # nの値が135の変数に,150 - 135 = 15個の欠損がある. -#> vars n mean sd median trimmed mad min max range ... -#> Sepal.Length 1 150 5.84 0.83 5.8 5.81 1.04 4.3 7.9 3.6 ... -#> Sepal.Width 2 150 3.06 0.44 3.0 3.04 0.44 2.0 4.4 2.4 ... -#> Petal.Length 3 135 3.75 1.76 4.3 3.75 1.78 1.0 6.9 5.9 ... -#> Petal.Width 4 135 1.20 0.77 1.3 1.18 1.04 0.1 2.5 2.4 ... -#> Species* 5 150 2.00 0.82 2.0 2.00 1.48 1.0 3.0 2.0 ... - -### 9.5.2 方針1:欠損を埋めて学習する. - -my_model <- train( - form = Species ~ ., data = my_data, method = "rpart2", - na.action = na.pass, # 欠損があっても学習を止めない. - preProcess = "medianImpute", # 欠損を中央値で埋める. - trControl = trainControl(method = "LOOCV"), - tuneGrid = data.frame(maxdepth = 20), # 木の高さの上限 - control = rpart::rpart.control(minsplit = 2, # 分岐の条件 - minbucket = 1)) # 終端ノードの条件 -max(my_model$results$Accuracy) -#> [1] 0.9266667 - -### 9.5.3 方針2:欠損があっても使える手法で学習する. - -my_model <- train(form = Species ~ ., data = my_data, method = "xgbTree", - na.action = na.pass, - trControl = trainControl(method = "cv", number = 5)) -max(my_model$results$Accuracy) -#> [1] 0.966666666666667 - -## 9.6 他の分類手法 - -### 9.6.1 K最近傍法 - -library(caret) -library(tidyverse) -my_data <- iris - -my_model <- train(form = Species ~ ., data = my_data, method = "knn", - trControl = trainControl(method = "LOOCV")) -my_model$results %>% filter(Accuracy == max(Accuracy)) -#> k Accuracy Kappa -#> 1 9 0.9733333 0.96 - -### 9.6.2 ニューラルネットワーク - -library(caret) -library(tidyverse) -my_data <- iris - -my_model <- train(form = Species ~ ., data = my_data, method = "nnet", - preProcess = c("center", "scale"), # 標準化 - trControl = trainControl(method = "LOOCV"), - trace = FALSE) # 途中経過を表示しない -my_model$results %>% filter(Accuracy == max(Accuracy)) -#> size decay Accuracy Kappa -#> 1 3 0.1 0.9733333 0.96 -#> 2 5 0.1 0.9733333 0.96 - diff --git a/code/R/ch10/10.01.R b/code/R/ch10/10.01.R deleted file mode 100644 index d44c09f..0000000 --- a/code/R/ch10/10.01.R +++ /dev/null @@ -1,45 +0,0 @@ -## 10.1 2値分類の性能指標 - -### 10.1.1 陽性と陰性 - -y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1) -y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5) - -y_ <- ifelse(0.5 <= y_score, 1, 0) -y_ -#> [1] 1 1 0 0 1 1 1 0 0 1 - -library(caret) -confusionMatrix(data = as.factor(y_), # 予測 - reference = as.factor(y), # 正解 - positive = "1", # 「1」を陽性とする. - mode = "everything") # 全ての指標を求める. -#> Confusion Matrix and Statistics -#> -#> Reference -#> Prediction 0 1 -#> 0 3 1 -#> 1 2 4 -#> -#> Accuracy : 0.7 -#> 95% CI : (0.3475, 0.9333) -#> No Information Rate : 0.5 -#> P-Value [Acc > NIR] : 0.1719 -#> -#> Kappa : 0.4 -#> -#> Mcnemar's Test P-Value : 1.0000 -#> -#> Sensitivity : 0.8000 -#> Specificity : 0.6000 -#> Pos Pred Value : 0.6667 -#> Neg Pred Value : 0.7500 -#> Precision : 0.6667 -#> Recall : 0.8000 -#> F1 : 0.7273 -#> Prevalence : 0.5000 -#> Detection Rate : 0.4000 -#> Detection Prevalence : 0.6000 -#> Balanced Accuracy : 0.7000 -#> -#> 'Positive' Class : 1 diff --git a/code/R/ch10/10.02.R b/code/R/ch10/10.02.R deleted file mode 100644 index e3b47f7..0000000 --- a/code/R/ch10/10.02.R +++ /dev/null @@ -1,40 +0,0 @@ -## 10.2 トレードオフ - -### 10.2.1 偽陽性率と真陽性率のトレードオフ(ROC曲線) - -library(PRROC) -library(tidyverse) - -y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1) -y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5) -y_ <- ifelse(0.5 <= y_score, 1, 0) - -c(sum((y == 0) & (y_ == 1)) / sum(y == 0), # FPR - sum((y == 1) & (y_ == 1)) / sum(y == 1)) # TPR -#> [1] 0.4 0.8 - -my_roc <- roc.curve(scores.class0 = y_score[y == 1], # 答えが1のもののスコア - scores.class1 = y_score[y == 0], # 答えが0のもののスコア - curve = TRUE) -my_roc %>% plot(xlab = "False Positive Rate", - ylab = "True Positive Rate", - legend = FALSE) - -my_roc$auc -#> [1] 0.8 - -### 10.2.2 再現率と精度のトレードオフ(PR曲線) - -c(sum((y == 1) & (y_ == 1)) / sum(y == 1), # Recall == TPR - sum((y == 1) & (y_ == 1)) / sum(y_ == 1)) # Precision -#> [1] 0.8000000 0.6666667 - -my_pr <- pr.curve(scores.class0 = y_score[y == 1], - scores.class1 = y_score[y == 0], - curve = TRUE) -my_pr %>% plot(xlab = "Recall", - ylab = "Precision", - legend = FALSE) - -my_pr$auc.integral -#> [1] 0.8469525 diff --git a/code/R/ch10/10.03.R b/code/R/ch10/10.03.R deleted file mode 100644 index 1e09b32..0000000 --- a/code/R/ch10/10.03.R +++ /dev/null @@ -1,90 +0,0 @@ -## 10.3 タイタニック - -library(caret) -library(PRROC) -library(tidyverse) - -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/titanic.csv") -my_data <- read_csv(my_url) - -head(my_data) -#> # A tibble: 6 x 4 -#> Class Sex Age Survived -#> -#> 1 1st Male Child Yes -#> 2 1st Male Child Yes -#> 3 1st Male Child Yes -#> 4 1st Male Child Yes -#> 5 1st Male Child Yes -#> 6 1st Male Adult No - -### 10.3.1 質的入力変数の扱い方 - -### 10.3.2 決定木の訓練 - -my_model <- train(form = Survived ~ ., data = my_data, method = "rpart2", - tuneGrid = data.frame(maxdepth = 2), - trControl = trainControl(method = "LOOCV")) - -### 10.3.3 決定木の描画 - -rpart.plot::rpart.plot(my_model$finalModel, extra = 1) - -### 10.3.4 決定木の評価 - -my_model$results -#> maxdepth Accuracy Kappa -#> 1 2 0.7832803 0.4096365 - -y <- my_data$Survived -tmp <- my_model %>% predict(newdata = my_data, type = "prob") -y_score <- tmp$Yes - -my_roc <- roc.curve(scores.class0 = y_score[y == "Yes"], - scores.class1 = y_score[y == "No"], - curve = TRUE) -my_roc$auc -#> [1] 0.7114887 - -my_roc %>% plot(xlab = "False Positive Rate", - ylab = "True Positive Rate", - legend = FALSE) - -### 10.3.5 補足:質的入力変数の扱い - -X <- my_data %>% select(Class) # 質的入力変数 -y <- my_data$Survived # 出力変数 - -options(warn = -1) # これ以降,警告を表示しない. -my_model1 <- train(x = X, y = y, method = "rpart2", - tuneGrid = data.frame(maxdepth = 2), - trControl = trainControl(method = "LOOCV")) -options(warn = 0) # これ以降,警告を表示する. - -rpart.plot::rpart.plot(my_model1$finalModel, extra = 1) -my_model1$results -#> maxdepth Accuracy Kappa -#> 1 2 0.7137665 0.2373133 - -my_enc <- my_data %>% dummyVars(formula = Survived ~ Class) -my_data2 <- my_enc %>% - predict(my_data) %>% - as.data.frame %>% - mutate(Survived = my_data$Survived) - -my_model2 <- train(form = Survived ~ ., data = my_data2, method = "rpart2", - tuneGrid = data.frame(maxdepth = 2), - trControl = trainControl(method = "LOOCV")) -rpart.plot::rpart.plot(my_model2$finalModel, extra = 1) -my_model2$results -#> maxdepth Accuracy Kappa -#> 1 2 0.7137665 0.2373133 - -my_model3 <- train(form = Survived ~ Class, data = my_data, method = "rpart2", - tuneGrid = data.frame(maxdepth = 2), - trControl = trainControl(method = "LOOCV")) -rpart.plot::rpart.plot(my_model3$finalModel, extra = 1) -my_model3$results -#> maxdepth Accuracy Kappa -#> 1 2 0.6915039 0.2674485 diff --git a/code/R/ch10/10.04.R b/code/R/ch10/10.04.R deleted file mode 100644 index fc87e09..0000000 --- a/code/R/ch10/10.04.R +++ /dev/null @@ -1,28 +0,0 @@ -## 10.4 ロジスティック回帰 - -curve(1 / (1 + exp(-x)), -6, 6) - -library(caret) -library(PRROC) -library(tidyverse) - -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/titanic.csv") -my_data <- read_csv(my_url) - -my_model <- train(form = Survived ~ ., data = my_data, method = "glm", - trControl = trainControl(method = "LOOCV")) - -coef(my_model$finalModel) %>% - as.data.frame -#> . -#> (Intercept) 2.0438374 -#> Class2nd -1.0180950 -#> Class3rd -1.7777622 -#> ClassCrew -0.8576762 -#> SexMale -2.4200603 -#> AgeChild 1.0615424 - -my_model$results -#> parameter Accuracy Kappa -#> 1 none 0.7782826 0.4448974 diff --git a/code/R/ch10/10.R b/code/R/ch10/10.R deleted file mode 100644 index 58e4920..0000000 --- a/code/R/ch10/10.R +++ /dev/null @@ -1,207 +0,0 @@ -## 10.1 2値分類の性能指標 - -### 10.1.1 陽性と陰性 - -y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1) -y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5) - -y_ <- ifelse(0.5 <= y_score, 1, 0) -y_ -#> [1] 1 1 0 0 1 1 1 0 0 1 - -library(caret) -confusionMatrix(data = as.factor(y_), # 予測 - reference = as.factor(y), # 正解 - positive = "1", # 「1」を陽性とする. - mode = "everything") # 全ての指標を求める. -#> Confusion Matrix and Statistics -#> -#> Reference -#> Prediction 0 1 -#> 0 3 1 -#> 1 2 4 -#> -#> Accuracy : 0.7 -#> 95% CI : (0.3475, 0.9333) -#> No Information Rate : 0.5 -#> P-Value [Acc > NIR] : 0.1719 -#> -#> Kappa : 0.4 -#> -#> Mcnemar's Test P-Value : 1.0000 -#> -#> Sensitivity : 0.8000 -#> Specificity : 0.6000 -#> Pos Pred Value : 0.6667 -#> Neg Pred Value : 0.7500 -#> Precision : 0.6667 -#> Recall : 0.8000 -#> F1 : 0.7273 -#> Prevalence : 0.5000 -#> Detection Rate : 0.4000 -#> Detection Prevalence : 0.6000 -#> Balanced Accuracy : 0.7000 -#> -#> 'Positive' Class : 1 - -## 10.2 トレードオフ - -### 10.2.1 偽陽性率と真陽性率のトレードオフ(ROC曲線) - -library(PRROC) -library(tidyverse) - -y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1) -y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5) -y_ <- ifelse(0.5 <= y_score, 1, 0) - -c(sum((y == 0) & (y_ == 1)) / sum(y == 0), # FPR - sum((y == 1) & (y_ == 1)) / sum(y == 1)) # TPR -#> [1] 0.4 0.8 - -my_roc <- roc.curve(scores.class0 = y_score[y == 1], # 答えが1のもののスコア - scores.class1 = y_score[y == 0], # 答えが0のもののスコア - curve = TRUE) -my_roc %>% plot(xlab = "False Positive Rate", - ylab = "True Positive Rate", - legend = FALSE) - -my_roc$auc -#> [1] 0.8 - -### 10.2.2 再現率と精度のトレードオフ(PR曲線) - -c(sum((y == 1) & (y_ == 1)) / sum(y == 1), # Recall == TPR - sum((y == 1) & (y_ == 1)) / sum(y_ == 1)) # Precision -#> [1] 0.8000000 0.6666667 - -my_pr <- pr.curve(scores.class0 = y_score[y == 1], - scores.class1 = y_score[y == 0], - curve = TRUE) -my_pr %>% plot(xlab = "Recall", - ylab = "Precision", - legend = FALSE) - -my_pr$auc.integral -#> [1] 0.8469525 - -## 10.3 タイタニック - -library(caret) -library(PRROC) -library(tidyverse) - -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/titanic.csv") -my_data <- read_csv(my_url) - -head(my_data) -#> # A tibble: 6 x 4 -#> Class Sex Age Survived -#> -#> 1 1st Male Child Yes -#> 2 1st Male Child Yes -#> 3 1st Male Child Yes -#> 4 1st Male Child Yes -#> 5 1st Male Child Yes -#> 6 1st Male Adult No - -### 10.3.1 質的入力変数の扱い方 - -### 10.3.2 決定木の訓練 - -my_model <- train(form = Survived ~ ., data = my_data, method = "rpart2", - tuneGrid = data.frame(maxdepth = 2), - trControl = trainControl(method = "LOOCV")) - -### 10.3.3 決定木の描画 - -rpart.plot::rpart.plot(my_model$finalModel, extra = 1) - -### 10.3.4 決定木の評価 - -my_model$results -#> maxdepth Accuracy Kappa -#> 1 2 0.7832803 0.4096365 - -y <- my_data$Survived -tmp <- my_model %>% predict(newdata = my_data, type = "prob") -y_score <- tmp$Yes - -my_roc <- roc.curve(scores.class0 = y_score[y == "Yes"], - scores.class1 = y_score[y == "No"], - curve = TRUE) -my_roc$auc -#> [1] 0.7114887 - -my_roc %>% plot(xlab = "False Positive Rate", - ylab = "True Positive Rate", - legend = FALSE) - -### 10.3.5 補足:質的入力変数の扱い - -X <- my_data %>% select(Class) # 質的入力変数 -y <- my_data$Survived # 出力変数 - -options(warn = -1) # これ以降,警告を表示しない. -my_model1 <- train(x = X, y = y, method = "rpart2", - tuneGrid = data.frame(maxdepth = 2), - trControl = trainControl(method = "LOOCV")) -options(warn = 0) # これ以降,警告を表示する. - -rpart.plot::rpart.plot(my_model1$finalModel, extra = 1) -my_model1$results -#> maxdepth Accuracy Kappa -#> 1 2 0.7137665 0.2373133 - -my_enc <- my_data %>% dummyVars(formula = Survived ~ Class) -my_data2 <- my_enc %>% - predict(my_data) %>% - as.data.frame %>% - mutate(Survived = my_data$Survived) - -my_model2 <- train(form = Survived ~ ., data = my_data2, method = "rpart2", - tuneGrid = data.frame(maxdepth = 2), - trControl = trainControl(method = "LOOCV")) -rpart.plot::rpart.plot(my_model2$finalModel, extra = 1) -my_model2$results -#> maxdepth Accuracy Kappa -#> 1 2 0.7137665 0.2373133 - -my_model3 <- train(form = Survived ~ Class, data = my_data, method = "rpart2", - tuneGrid = data.frame(maxdepth = 2), - trControl = trainControl(method = "LOOCV")) -rpart.plot::rpart.plot(my_model3$finalModel, extra = 1) -my_model3$results -#> maxdepth Accuracy Kappa -#> 1 2 0.6915039 0.2674485 - -## 10.4 ロジスティック回帰 - -curve(1 / (1 + exp(-x)), -6, 6) - -library(caret) -library(PRROC) -library(tidyverse) - -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/titanic.csv") -my_data <- read_csv(my_url) - -my_model <- train(form = Survived ~ ., data = my_data, method = "glm", - trControl = trainControl(method = "LOOCV")) - -coef(my_model$finalModel) %>% - as.data.frame -#> . -#> (Intercept) 2.0438374 -#> Class2nd -1.0180950 -#> Class3rd -1.7777622 -#> ClassCrew -0.8576762 -#> SexMale -2.4200603 -#> AgeChild 1.0615424 - -my_model$results -#> parameter Accuracy Kappa -#> 1 none 0.7782826 0.4448974 - diff --git a/code/R/ch11/11.01.R b/code/R/ch11/11.01.R deleted file mode 100644 index f7b0559..0000000 --- a/code/R/ch11/11.01.R +++ /dev/null @@ -1,50 +0,0 @@ -## 11.1 Kerasによる回帰 - -library(keras) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -tmp <- read_csv(my_url) - -my_data <- tmp[sample(nrow(tmp)), ] - -X <- my_data %>% - select(-LPRICE2) %>% scale -y <- my_data$LPRICE2 - -curve(activation_relu(x), -3, 3) - -my_model <- keras_model_sequential() %>% - layer_dense(units = 3, activation = "relu", input_shape = c(4)) %>% - layer_dense(units = 1) - -summary(my_model) # ネットワークの概要 -# 割愛(Pythonの結果を参照) - -my_model %>% compile( - loss = "mse", - optimizer = "rmsprop") - -my_cb <- callback_early_stopping( - patience = 20, - restore_best_weights = TRUE) - -my_history <- my_model %>% fit( - x = X, - y = y, - validation_split = 0.25, - batch_size = 10, - epochs = 500, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) - -my_history -#> Final epoch (plot to see history): -#> loss: 0.06124 -#> val_loss: 0.1132 - -y_ <- my_model %>% predict(X) -mean((y_ - y)^2)**0.5 -#> [1] 0.2724372 diff --git a/code/R/ch11/11.02.R b/code/R/ch11/11.02.R deleted file mode 100644 index fd64fe9..0000000 --- a/code/R/ch11/11.02.R +++ /dev/null @@ -1,66 +0,0 @@ -## 11.2 Kerasによる分類 - -library(keras) -library(tidyverse) -my_data <- iris[sample(nrow(iris)), ] - -X <- my_data %>% - select(-Species) %>% scale -y <- as.integer(my_data$Species) - 1 - -my_model <- keras_model_sequential() %>% - layer_dense(units = 3, activation = "relu", input_shape = c(4)) %>% - layer_dense(units = 3, activation = "softmax") - -my_model %>% compile(loss = "sparse_categorical_crossentropy", - optimizer = "rmsprop", - metrics = c("accuracy")) - -my_cb <- callback_early_stopping( - patience = 20, - restore_best_weights = TRUE) - -my_history <- my_model %>% - fit(x = X, - y = y, - validation_split = 0.25, - batch_size = 10, - epochs = 500, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) - -my_history -#> Final epoch (plot to see history): -#> loss: 0.06206 -#> accuracy: 0.9732 -#> val_loss: 0.1269 -#> val_accuracy: 0.9211 - -tmp <- my_model %>% predict(X) -y_ <- apply(tmp, 1, which.max) - 1 -mean(y_ == y) -#> [1] 0.9666667 - -### 11.2.1 交差エントロピー - --mean(log(c(0.8, 0.7, 0.3, 0.8))) -#> 0.5017337 - --mean(log(c(0.7, 0.6, 0.2, 0.7))) -#> 0.7084034 - -y <- c(2, 1, 0, 1) -y_1 <- list(c(0.1, 0.1, 0.8), - c(0.1, 0.7, 0.2), - c(0.3, 0.4, 0.3), - c(0.1, 0.8, 0.1)) -y_2 <- list(c(0.1, 0.2, 0.7), - c(0.2, 0.6, 0.2), - c(0.2, 0.5, 0.3), - c(0.2, 0.7, 0.1)) - -c(mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_1))), - mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_2)))) -#> [1] 0.5017337 0.7084033 diff --git a/code/R/ch11/11.03.R b/code/R/ch11/11.03.R deleted file mode 100644 index bdb280a..0000000 --- a/code/R/ch11/11.03.R +++ /dev/null @@ -1,199 +0,0 @@ -## 11.3 MNIST:手書き数字の分類 - -### 11.3.1 データの形式 - -library(keras) -library(tidyverse) -keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist()) - -dim(x_train) -#> [1] 60000 28 28 - -x_train[5, , ] - -plot(as.raster(x = x_train[5, , ], - max = max(x_train))) - -head(y_train) -#> [1] 5 0 4 1 9 2 - -c(min(x_train), max(x_train)) -#> [1] 0 255 - -x_train <- x_train / 255 -x_test <- x_test / 255 - -my_index <- sample(1:60000, 6000) -x_train <- x_train[my_index, , ] -y_train <- y_train[my_index] - -### 11.3.2 多層パーセプトロン - -my_model <- keras_model_sequential() %>% - layer_flatten(input_shape = c(28, 28)) %>% - layer_dense(units = 256, activation = "relu") %>% - layer_dense(units = 10, activation = "softmax") -summary(my_model) -# 割愛(Pythonの結果を参照) - -my_model %>% compile(loss = "sparse_categorical_crossentropy", - optimizer = "rmsprop", - metrics = c("accuracy")) - -my_cb <- callback_early_stopping(patience = 5, - restore_best_weights = TRUE) - -my_history <- my_model %>% - fit(x = x_train, - y = y_train, - validation_split = 0.2, - batch_size = 128, - epochs = 20, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) - -tmp <- my_model %>% predict(x_test) -y_ <- apply(tmp, 1, which.max) - 1 -table(y_, y_test) - -#> y_test -#> y_ 0 1 2 3 4 5 6 7 8 9 -#> 0 962 0 8 2 0 6 11 0 8 11 -#> 1 0 1110 1 0 3 1 3 8 2 4 -#> 2 0 5 959 13 4 4 2 16 6 1 -#> 3 1 1 22 958 1 27 0 7 33 13 -#> 4 2 0 6 1 905 8 6 6 3 14 -#> 5 5 2 0 12 1 809 9 1 15 4 -#> 6 6 3 8 0 8 11 922 0 5 1 -#> 7 1 1 7 7 1 2 0 963 4 8 -#> 8 2 13 19 13 4 16 5 0 890 5 -#> 9 1 0 2 4 55 8 0 27 8 948 - -mean(y_ == y_test) -#> [1] 0.9426000 - -my_model %>% - evaluate(x = x_test, y = y_test) -#> loss accuracy -#> 0.2071411 0.9426000 - -### 11.3.3 畳み込みニューラルネットワーク(CNN) - -x_train2d <- x_train %>% array_reshape(c(-1, 28, 28, 1)) -x_test2d <- x_test %>% array_reshape(c(-1, 28, 28, 1)) - -#### 11.3.3.1 単純なCNN - -my_model <- keras_model_sequential() %>% - layer_conv_2d(filters = 32, kernel_size = 3, # 畳み込み層 - activation = "relu", - input_shape = c(28, 28, 1)) %>% - layer_max_pooling_2d(pool_size = 2) %>% # プーリング層 - layer_flatten() %>% - layer_dense(units = 128, activation = "relu") %>% - layer_dense(units = 10, activation = "softmax") - -summary(my_model) -# 割愛(Python の結果を参照) - -my_model %>% compile(loss = "sparse_categorical_crossentropy", - optimizer = "rmsprop", - metrics = c("accuracy")) - -my_cb <- callback_early_stopping(patience = 5, - restore_best_weights = TRUE) - -my_history <- my_model %>% - fit(x = x_train2d, - y = y_train, - validation_split = 0.2, - batch_size = 128, - epochs = 20, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) - -my_model %>% - evaluate(x = x_test2d, y = y_test) -#> loss accuracy -#> 0.1392894 0.9607000 - -#### 11.3.3.2 LeNet - -my_model <- keras_model_sequential() %>% - layer_conv_2d(filters = 20, kernel_size = 5, activation = "relu", - input_shape = c(28, 28, 1)) %>% - layer_max_pooling_2d(pool_size = 2, strides = 2) %>% - layer_conv_2d(filters = 50, kernel_size = 5, activation = "relu") %>% - layer_max_pooling_2d(pool_size = 2, strides = 2) %>% - layer_dropout(rate = 0.25) %>% - layer_flatten() %>% - layer_dense(units = 500, activation = "relu") %>% - layer_dropout(rate = 0.5) %>% - layer_dense(units = 10, activation = "softmax") - -my_model %>% compile( - loss = "sparse_categorical_crossentropy", - optimizer = "rmsprop", - metrics = c("accuracy")) - -my_cb <- callback_early_stopping(patience = 5, - restore_best_weights = TRUE) - -my_history <- my_model %>% - fit(x = x_train2d, - y = y_train, - validation_split = 0.2, - batch_size = 128, - epochs = 20, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) - -my_model %>% - evaluate(x = x_test2d, y = y_test) -#> loss accuracy -#> 0.07309694 0.98060000 - -#### 11.3.3.3 補足:LeNetが自信満々で間違う例 - -y_prob <- my_model %>% predict(x_test2d) # カテゴリに属する確率 - -my_result <- data.frame( - y_prob = apply(y_prob, 1, max), # 確率の最大値 - y_ = apply(y_prob, 1, which.max) - 1, # 予測カテゴリ - y = y_test, # 正解 - id = seq_len(length(y_test))) %>% # 番号 - filter(y_ != y) %>% # 予測がはずれたものを残す - arrange(desc(y_prob)) # 確率の大きい順に並び替える - -head(my_result) -#> y_prob y_ y id -#> 1 0.9998116 9 4 2131 -#> 2 0.9988768 6 5 9730 -#> 3 0.9986107 3 5 2598 -#> 4 0.9971705 3 5 2036 -#> 5 0.9888211 1 6 2655 -#> 6 0.9857675 0 6 2119 - -tmp <- my_result[1:5, ]$id -my_labels <- sprintf("%s (%s)", - my_result[1:5, ]$y, tmp) -my_fig <- expand.grid( - label = my_labels, - y = 28:1, - x = 1:28) -my_fig$z <- as.vector( - x_test[tmp, , ]) - -my_fig %>% ggplot( - aes(x = x, y = y, fill = z)) + - geom_raster() + - coord_fixed() + - theme_void() + - theme(legend.position = "none") + - facet_grid(. ~ label) diff --git a/code/R/ch11/11.04.R b/code/R/ch11/11.04.R deleted file mode 100644 index 258eb92..0000000 --- a/code/R/ch11/11.04.R +++ /dev/null @@ -1,87 +0,0 @@ -## 11.4 AutoML - -### 11.4.1 H2Oの起動と停止 - -library(h2o) -library(keras) -library(tidyverse) - -h2o.init() -h2o.no_progress() -# h2o.shutdown(prompt = FALSE) # 停止 - -### 11.4.2 H2Oのデータフレーム - -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) -my_frame <- as.h2o(my_data) # 通常のデータフレームをH2OFrameに変換する. -# あるいは -my_frame <- h2o.importFile(my_url, header = TRUE) # データを読み込む. - -my_frame -#> LPRICE2 WRAIN DEGREES HRAIN ... -#> 1 -0.99868 600 17.1167 160 ... -#> 2 -0.45440 690 16.7333 80 ... -#> 3 -0.80796 502 17.1500 130 ... -#> 4 -1.50926 420 16.1333 110 ... -#> 5 -1.71655 582 16.4167 187 ... -#> 6 -0.41800 485 17.4833 187 ... -#> -#> [27 rows x 5 columns] - -# 通常のデータフレームに戻す. -my_frame %>% as.data.frame %>% head -# 結果は割愛(見た目は同じ) - -### 11.4.3 AutoMLによる回帰 - -my_model <- h2o.automl( - y = "LPRICE2", - training_frame = my_frame, - max_runtime_secs = 60) - -min(my_model@leaderboard$rmse) -#> [1] 0.2922861 - -tmp <- my_model %>% - predict(my_frame) %>% - as.data.frame -y_ <- tmp$predict -y <- my_data$LPRICE2 - -plot(y, y_) - -### 11.4.4 AutoMLによる分類 - -keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist()) -my_index <- sample(1:60000, 6000) -x_train <- x_train[my_index, , ] -y_train <- y_train[my_index] - -tmp <- x_train %>% - array_reshape(c(-1, 28 * 28)) %>% - as.data.frame -tmp$y <- as.factor(y_train) -my_train <- as.h2o(tmp) - -tmp <- x_test %>% - array_reshape(c(-1, 28 * 28)) %>% - as.data.frame -my_test <- as.h2o(tmp) - -my_model <- h2o.automl( - y = "y", - training_frame = my_train, - max_runtime_secs = 120) - -min(my_model@leaderboard$ - mean_per_class_error) -#> [1] 0.0806190885648608 - -tmp <- my_model %>% - predict(my_test) %>% as.data.frame -y_ <- tmp$predict - -mean(y_ == y_test) -#> [1] 0.9306 diff --git a/code/R/ch11/11.R b/code/R/ch11/11.R deleted file mode 100644 index 0046dd5..0000000 --- a/code/R/ch11/11.R +++ /dev/null @@ -1,406 +0,0 @@ -## 11.1 Kerasによる回帰 - -library(keras) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -tmp <- read_csv(my_url) - -my_data <- tmp[sample(nrow(tmp)), ] - -X <- my_data %>% - select(-LPRICE2) %>% scale -y <- my_data$LPRICE2 - -curve(activation_relu(x), -3, 3) - -my_model <- keras_model_sequential() %>% - layer_dense(units = 3, activation = "relu", input_shape = c(4)) %>% - layer_dense(units = 1) - -summary(my_model) # ネットワークの概要 -# 割愛(Pythonの結果を参照) - -my_model %>% compile( - loss = "mse", - optimizer = "rmsprop") - -my_cb <- callback_early_stopping( - patience = 20, - restore_best_weights = TRUE) - -my_history <- my_model %>% fit( - x = X, - y = y, - validation_split = 0.25, - batch_size = 10, - epochs = 500, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) - -my_history -#> Final epoch (plot to see history): -#> loss: 0.06124 -#> val_loss: 0.1132 - -y_ <- my_model %>% predict(X) -mean((y_ - y)^2)**0.5 -#> [1] 0.2724372 - -## 11.2 Kerasによる分類 - -library(keras) -library(tidyverse) -my_data <- iris[sample(nrow(iris)), ] - -X <- my_data %>% - select(-Species) %>% scale -y <- as.integer(my_data$Species) - 1 - -my_model <- keras_model_sequential() %>% - layer_dense(units = 3, activation = "relu", input_shape = c(4)) %>% - layer_dense(units = 3, activation = "softmax") - -my_model %>% compile(loss = "sparse_categorical_crossentropy", - optimizer = "rmsprop", - metrics = c("accuracy")) - -my_cb <- callback_early_stopping( - patience = 20, - restore_best_weights = TRUE) - -my_history <- my_model %>% - fit(x = X, - y = y, - validation_split = 0.25, - batch_size = 10, - epochs = 500, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) - -my_history -#> Final epoch (plot to see history): -#> loss: 0.06206 -#> accuracy: 0.9732 -#> val_loss: 0.1269 -#> val_accuracy: 0.9211 - -tmp <- my_model %>% predict(X) -y_ <- apply(tmp, 1, which.max) - 1 -mean(y_ == y) -#> [1] 0.9666667 - -### 11.2.1 交差エントロピー - --mean(log(c(0.8, 0.7, 0.3, 0.8))) -#> 0.5017337 - --mean(log(c(0.7, 0.6, 0.2, 0.7))) -#> 0.7084034 - -y <- c(2, 1, 0, 1) -y_1 <- list(c(0.1, 0.1, 0.8), - c(0.1, 0.7, 0.2), - c(0.3, 0.4, 0.3), - c(0.1, 0.8, 0.1)) -y_2 <- list(c(0.1, 0.2, 0.7), - c(0.2, 0.6, 0.2), - c(0.2, 0.5, 0.3), - c(0.2, 0.7, 0.1)) - -c(mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_1))), - mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_2)))) -#> [1] 0.5017337 0.7084033 - -## 11.3 MNIST:手書き数字の分類 - -### 11.3.1 データの形式 - -library(keras) -library(tidyverse) -keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist()) - -dim(x_train) -#> [1] 60000 28 28 - -x_train[5, , ] - -plot(as.raster(x = x_train[5, , ], - max = max(x_train))) - -head(y_train) -#> [1] 5 0 4 1 9 2 - -c(min(x_train), max(x_train)) -#> [1] 0 255 - -x_train <- x_train / 255 -x_test <- x_test / 255 - -my_index <- sample(1:60000, 6000) -x_train <- x_train[my_index, , ] -y_train <- y_train[my_index] - -### 11.3.2 多層パーセプトロン - -my_model <- keras_model_sequential() %>% - layer_flatten(input_shape = c(28, 28)) %>% - layer_dense(units = 256, activation = "relu") %>% - layer_dense(units = 10, activation = "softmax") -summary(my_model) -# 割愛(Pythonの結果を参照) - -my_model %>% compile(loss = "sparse_categorical_crossentropy", - optimizer = "rmsprop", - metrics = c("accuracy")) - -my_cb <- callback_early_stopping(patience = 5, - restore_best_weights = TRUE) - -my_history <- my_model %>% - fit(x = x_train, - y = y_train, - validation_split = 0.2, - batch_size = 128, - epochs = 20, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) - -tmp <- my_model %>% predict(x_test) -y_ <- apply(tmp, 1, which.max) - 1 -table(y_, y_test) - -#> y_test -#> y_ 0 1 2 3 4 5 6 7 8 9 -#> 0 962 0 8 2 0 6 11 0 8 11 -#> 1 0 1110 1 0 3 1 3 8 2 4 -#> 2 0 5 959 13 4 4 2 16 6 1 -#> 3 1 1 22 958 1 27 0 7 33 13 -#> 4 2 0 6 1 905 8 6 6 3 14 -#> 5 5 2 0 12 1 809 9 1 15 4 -#> 6 6 3 8 0 8 11 922 0 5 1 -#> 7 1 1 7 7 1 2 0 963 4 8 -#> 8 2 13 19 13 4 16 5 0 890 5 -#> 9 1 0 2 4 55 8 0 27 8 948 - -mean(y_ == y_test) -#> [1] 0.9426000 - -my_model %>% - evaluate(x = x_test, y = y_test) -#> loss accuracy -#> 0.2071411 0.9426000 - -### 11.3.3 畳み込みニューラルネットワーク(CNN) - -x_train2d <- x_train %>% array_reshape(c(-1, 28, 28, 1)) -x_test2d <- x_test %>% array_reshape(c(-1, 28, 28, 1)) - -#### 11.3.3.1 単純なCNN - -my_model <- keras_model_sequential() %>% - layer_conv_2d(filters = 32, kernel_size = 3, # 畳み込み層 - activation = "relu", - input_shape = c(28, 28, 1)) %>% - layer_max_pooling_2d(pool_size = 2) %>% # プーリング層 - layer_flatten() %>% - layer_dense(units = 128, activation = "relu") %>% - layer_dense(units = 10, activation = "softmax") - -summary(my_model) -# 割愛(Python の結果を参照) - -my_model %>% compile(loss = "sparse_categorical_crossentropy", - optimizer = "rmsprop", - metrics = c("accuracy")) - -my_cb <- callback_early_stopping(patience = 5, - restore_best_weights = TRUE) - -my_history <- my_model %>% - fit(x = x_train2d, - y = y_train, - validation_split = 0.2, - batch_size = 128, - epochs = 20, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) - -my_model %>% - evaluate(x = x_test2d, y = y_test) -#> loss accuracy -#> 0.1392894 0.9607000 - -#### 11.3.3.2 LeNet - -my_model <- keras_model_sequential() %>% - layer_conv_2d(filters = 20, kernel_size = 5, activation = "relu", - input_shape = c(28, 28, 1)) %>% - layer_max_pooling_2d(pool_size = 2, strides = 2) %>% - layer_conv_2d(filters = 50, kernel_size = 5, activation = "relu") %>% - layer_max_pooling_2d(pool_size = 2, strides = 2) %>% - layer_dropout(rate = 0.25) %>% - layer_flatten() %>% - layer_dense(units = 500, activation = "relu") %>% - layer_dropout(rate = 0.5) %>% - layer_dense(units = 10, activation = "softmax") - -my_model %>% compile( - loss = "sparse_categorical_crossentropy", - optimizer = "rmsprop", - metrics = c("accuracy")) - -my_cb <- callback_early_stopping(patience = 5, - restore_best_weights = TRUE) - -my_history <- my_model %>% - fit(x = x_train2d, - y = y_train, - validation_split = 0.2, - batch_size = 128, - epochs = 20, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) - -my_model %>% - evaluate(x = x_test2d, y = y_test) -#> loss accuracy -#> 0.07309694 0.98060000 - -#### 11.3.3.3 補足:LeNetが自信満々で間違う例 - -y_prob <- my_model %>% predict(x_test2d) # カテゴリに属する確率 - -my_result <- data.frame( - y_prob = apply(y_prob, 1, max), # 確率の最大値 - y_ = apply(y_prob, 1, which.max) - 1, # 予測カテゴリ - y = y_test, # 正解 - id = seq_len(length(y_test))) %>% # 番号 - filter(y_ != y) %>% # 予測がはずれたものを残す - arrange(desc(y_prob)) # 確率の大きい順に並び替える - -head(my_result) -#> y_prob y_ y id -#> 1 0.9998116 9 4 2131 -#> 2 0.9988768 6 5 9730 -#> 3 0.9986107 3 5 2598 -#> 4 0.9971705 3 5 2036 -#> 5 0.9888211 1 6 2655 -#> 6 0.9857675 0 6 2119 - -tmp <- my_result[1:5, ]$id -my_labels <- sprintf("%s (%s)", - my_result[1:5, ]$y, tmp) -my_fig <- expand.grid( - label = my_labels, - y = 28:1, - x = 1:28) -my_fig$z <- as.vector( - x_test[tmp, , ]) - -my_fig %>% ggplot( - aes(x = x, y = y, fill = z)) + - geom_raster() + - coord_fixed() + - theme_void() + - theme(legend.position = "none") + - facet_grid(. ~ label) - -## 11.4 AutoML - -### 11.4.1 H2Oの起動と停止 - -library(h2o) -library(keras) -library(tidyverse) - -h2o.init() -h2o.no_progress() -# h2o.shutdown(prompt = FALSE) # 停止 - -### 11.4.2 H2Oのデータフレーム - -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) -my_frame <- as.h2o(my_data) # 通常のデータフレームをH2OFrameに変換する. -# あるいは -my_frame <- h2o.importFile(my_url, header = TRUE) # データを読み込む. - -my_frame -#> LPRICE2 WRAIN DEGREES HRAIN ... -#> 1 -0.99868 600 17.1167 160 ... -#> 2 -0.45440 690 16.7333 80 ... -#> 3 -0.80796 502 17.1500 130 ... -#> 4 -1.50926 420 16.1333 110 ... -#> 5 -1.71655 582 16.4167 187 ... -#> 6 -0.41800 485 17.4833 187 ... -#> -#> [27 rows x 5 columns] - -# 通常のデータフレームに戻す. -my_frame %>% as.data.frame %>% head -# 結果は割愛(見た目は同じ) - -### 11.4.3 AutoMLによる回帰 - -my_model <- h2o.automl( - y = "LPRICE2", - training_frame = my_frame, - max_runtime_secs = 60) - -min(my_model@leaderboard$rmse) -#> [1] 0.2922861 - -tmp <- my_model %>% - predict(my_frame) %>% - as.data.frame -y_ <- tmp$predict -y <- my_data$LPRICE2 - -plot(y, y_) - -### 11.4.4 AutoMLによる分類 - -keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist()) -my_index <- sample(1:60000, 6000) -x_train <- x_train[my_index, , ] -y_train <- y_train[my_index] - -tmp <- x_train %>% - array_reshape(c(-1, 28 * 28)) %>% - as.data.frame -tmp$y <- as.factor(y_train) -my_train <- as.h2o(tmp) - -tmp <- x_test %>% - array_reshape(c(-1, 28 * 28)) %>% - as.data.frame -my_test <- as.h2o(tmp) - -my_model <- h2o.automl( - y = "y", - training_frame = my_train, - max_runtime_secs = 120) - -min(my_model@leaderboard$ - mean_per_class_error) -#> [1] 0.0806190885648608 - -tmp <- my_model %>% - predict(my_test) %>% as.data.frame -y_ <- tmp$predict - -mean(y_ == y_test) -#> [1] 0.9306 - diff --git a/code/R/ch12/12.01.R b/code/R/ch12/12.01.R deleted file mode 100644 index ec651db..0000000 --- a/code/R/ch12/12.01.R +++ /dev/null @@ -1,24 +0,0 @@ -## 12.1 日時と日時の列 - -### 12.1.1 日時 - -as.POSIXct("2021-01-01") -#> [1] "2021-01-01 JST" - -### 12.1.2 等間隔の日時 - -library(tsibble) - -seq(from = 2021, to = 2023, by = 1) -#> [1] 2021 2022 2023 - -seq(from = yearmonth("202101"), to = yearmonth("202103"), by = 2) -#> -#> [1] "2021 1" "2021 3" - -seq(from = as.POSIXct("2021-01-01"), to = as.POSIXct("2021-01-03"), by = "1 day") -#> [1] "2021-01-01 JST" "2021-01-02 JST" "2021-01-03 JST" - -seq(from = as.POSIXct("2021-01-01 00:00:00"), - to = as.POSIXct("2021-01-01 03:00:00"), by = "2 hour") -#> [1] "2021-01-01 00:00:00 JST" "2021-01-01 02:00:00 JST" diff --git a/code/R/ch12/12.02.R b/code/R/ch12/12.02.R deleted file mode 100644 index e87828f..0000000 --- a/code/R/ch12/12.02.R +++ /dev/null @@ -1,128 +0,0 @@ -## 12.2 時系列データの予測 - -### 12.2.1 データの準備 - -my_data <- as.vector(AirPassengers) - -n <- length(my_data) # データ数(144) -k <- 108 # 訓練データ数 - -library(tidyverse) -library(tsibble) - -my_ds <- seq( - from = yearmonth("1949/01"), - to = yearmonth("1960/12"), - by = 1) -my_label <- rep( - c("train", "test"), - c(k, n - k)) -my_df <- tsibble( - ds = my_ds, - x = 0:(n - 1), - y = my_data, - label = my_label, - index = ds) # 日時の列の指定 - -head(my_df) -#> # A tsibble: 6 x 4 [1M] -#> ds x y label -#> -#> 1 1949 1 0 112 train -#> 2 1949 2 1 118 train -#> 3 1949 3 2 132 train -#> 4 1949 4 3 129 train -#> 5 1949 5 4 121 train -#> 6 1949 6 5 135 train - -my_train <- my_df[ 1:k , ] -my_test <- my_df[-(1:k), ] -y <- my_test$y - -my_plot <- my_df %>% - ggplot(aes(x = ds, - y = y, - color = label)) + - geom_line() -my_plot - -### 12.2.2 線形回帰分析による時系列予測 - -library(caret) -my_lm_model <- train(form = y ~ x, data = my_train, method = "lm") -y_ <- my_lm_model %>% predict(my_test) -caret::RMSE(y, y_) # RMSE(テスト) -#> [1] 70.63707 - -y_ <- my_lm_model %>% predict(my_df) -tmp <- my_df %>% - mutate(y = y_, label = "model") -my_plot + geom_line(data = tmp) - -### 12.2.3 SARIMAによる時系列予測 - -#### 12.2.3.1 モデルの構築 - -library(fable) -my_arima_model <- my_train %>% model(ARIMA(y)) -my_arima_model -#> # A mable: 1 x 1 -#> `ARIMA(y)` -#> -#> 1 - -#### 12.2.3.2 予測 - -tmp <- my_arima_model %>% forecast(h = "3 years") -head(tmp) -#> # A fable: 6 x 4 [1M] -#> # Key: .model [1] -#> .model ds y .mean -#> -#> 1 ARIMA(y) 1958 1 N(346, 94) 346. -#> 2 ARIMA(y) 1958 2 N(332, 148) 332. -#> 3 ARIMA(y) 1958 3 N(387, 210) 387. -#> 4 ARIMA(y) 1958 4 N(379, 271) 379. -#> 5 ARIMA(y) 1958 5 N(386, 332) 386. -#> 6 ARIMA(y) 1958 6 N(453, 393) 453. - -y_ <- tmp$.mean -caret::RMSE(y_, y) -#> [1] 22.13223 - -# 予測結果のみでよい場合 -#tmp %>% autoplot - -tmp %>% autoplot + - geom_line(data = my_df, - aes(x = ds, - y = y, - color = label)) - -### 12.2.4 Prophetによる時系列予測 - -library(prophet) -my_prophet_model <- my_train %>% - prophet(seasonality.mode = "multiplicative") - -tmp <- my_prophet_model %>% predict(my_test) -head(tmp[, c("ds", "yhat", "yhat_lower", "yhat_upper")]) -#> # A tibble: 6 x 4 -#> ds yhat yhat_lower yhat_upper -#> -#> 1 1958-01-01 00:00:00 359. 350. 368. -#> 2 1958-02-01 00:00:00 350. 342. 360. -#> 3 1958-03-01 00:00:00 407. 398. 416. -#> 4 1958-04-01 00:00:00 398. 389. 407. -#> 5 1958-05-01 00:00:00 402. 393. 411. -#> 6 1958-06-01 00:00:00 459. 450. 469. - -y_ <- tmp$yhat -caret::RMSE(y_, y) -#> [1] 33.68719 - -# my_prophet_model %>% plot(tmp) # 予測結果のみでよい場合 - -my_prophet_model %>% plot(tmp) + - geom_line(data = my_train, aes(x = as.POSIXct(ds))) + - geom_line(data = my_test, aes(x = as.POSIXct(ds)), color = "red") diff --git a/code/R/ch12/12.R b/code/R/ch12/12.R deleted file mode 100644 index 6aaa3c1..0000000 --- a/code/R/ch12/12.R +++ /dev/null @@ -1,154 +0,0 @@ -## 12.1 日時と日時の列 - -### 12.1.1 日時 - -as.POSIXct("2021-01-01") -#> [1] "2021-01-01 JST" - -### 12.1.2 等間隔の日時 - -library(tsibble) - -seq(from = 2021, to = 2023, by = 1) -#> [1] 2021 2022 2023 - -seq(from = yearmonth("202101"), to = yearmonth("202103"), by = 2) -#> -#> [1] "2021 1" "2021 3" - -seq(from = as.POSIXct("2021-01-01"), to = as.POSIXct("2021-01-03"), by = "1 day") -#> [1] "2021-01-01 JST" "2021-01-02 JST" "2021-01-03 JST" - -seq(from = as.POSIXct("2021-01-01 00:00:00"), - to = as.POSIXct("2021-01-01 03:00:00"), by = "2 hour") -#> [1] "2021-01-01 00:00:00 JST" "2021-01-01 02:00:00 JST" - -## 12.2 時系列データの予測 - -### 12.2.1 データの準備 - -my_data <- as.vector(AirPassengers) - -n <- length(my_data) # データ数(144) -k <- 108 # 訓練データ数 - -library(tidyverse) -library(tsibble) - -my_ds <- seq( - from = yearmonth("1949/01"), - to = yearmonth("1960/12"), - by = 1) -my_label <- rep( - c("train", "test"), - c(k, n - k)) -my_df <- tsibble( - ds = my_ds, - x = 0:(n - 1), - y = my_data, - label = my_label, - index = ds) # 日時の列の指定 - -head(my_df) -#> # A tsibble: 6 x 4 [1M] -#> ds x y label -#> -#> 1 1949 1 0 112 train -#> 2 1949 2 1 118 train -#> 3 1949 3 2 132 train -#> 4 1949 4 3 129 train -#> 5 1949 5 4 121 train -#> 6 1949 6 5 135 train - -my_train <- my_df[ 1:k , ] -my_test <- my_df[-(1:k), ] -y <- my_test$y - -my_plot <- my_df %>% - ggplot(aes(x = ds, - y = y, - color = label)) + - geom_line() -my_plot - -### 12.2.2 線形回帰分析による時系列予測 - -library(caret) -my_lm_model <- train(form = y ~ x, data = my_train, method = "lm") -y_ <- my_lm_model %>% predict(my_test) -caret::RMSE(y, y_) # RMSE(テスト) -#> [1] 70.63707 - -y_ <- my_lm_model %>% predict(my_df) -tmp <- my_df %>% - mutate(y = y_, label = "model") -my_plot + geom_line(data = tmp) - -### 12.2.3 SARIMAによる時系列予測 - -#### 12.2.3.1 モデルの構築 - -library(fable) -my_arima_model <- my_train %>% model(ARIMA(y)) -my_arima_model -#> # A mable: 1 x 1 -#> `ARIMA(y)` -#> -#> 1 - -#### 12.2.3.2 予測 - -tmp <- my_arima_model %>% forecast(h = "3 years") -head(tmp) -#> # A fable: 6 x 4 [1M] -#> # Key: .model [1] -#> .model ds y .mean -#> -#> 1 ARIMA(y) 1958 1 N(346, 94) 346. -#> 2 ARIMA(y) 1958 2 N(332, 148) 332. -#> 3 ARIMA(y) 1958 3 N(387, 210) 387. -#> 4 ARIMA(y) 1958 4 N(379, 271) 379. -#> 5 ARIMA(y) 1958 5 N(386, 332) 386. -#> 6 ARIMA(y) 1958 6 N(453, 393) 453. - -y_ <- tmp$.mean -caret::RMSE(y_, y) -#> [1] 22.13223 - -# 予測結果のみでよい場合 -#tmp %>% autoplot - -tmp %>% autoplot + - geom_line(data = my_df, - aes(x = ds, - y = y, - color = label)) - -### 12.2.4 Prophetによる時系列予測 - -library(prophet) -my_prophet_model <- my_train %>% - prophet(seasonality.mode = "multiplicative") - -tmp <- my_prophet_model %>% predict(my_test) -head(tmp[, c("ds", "yhat", "yhat_lower", "yhat_upper")]) -#> # A tibble: 6 x 4 -#> ds yhat yhat_lower yhat_upper -#> -#> 1 1958-01-01 00:00:00 359. 350. 368. -#> 2 1958-02-01 00:00:00 350. 342. 360. -#> 3 1958-03-01 00:00:00 407. 398. 416. -#> 4 1958-04-01 00:00:00 398. 389. 407. -#> 5 1958-05-01 00:00:00 402. 393. 411. -#> 6 1958-06-01 00:00:00 459. 450. 469. - -y_ <- tmp$yhat -caret::RMSE(y_, y) -#> [1] 33.68719 - -# my_prophet_model %>% plot(tmp) # 予測結果のみでよい場合 - -my_prophet_model %>% plot(tmp) + - geom_line(data = my_train, aes(x = as.POSIXct(ds))) + - geom_line(data = my_test, aes(x = as.POSIXct(ds)), color = "red") - diff --git a/code/R/ch13/13.01.R b/code/R/ch13/13.01.R deleted file mode 100644 index 8a81eab..0000000 --- a/code/R/ch13/13.01.R +++ /dev/null @@ -1,88 +0,0 @@ -## 13.1 主成分分析 - -library(tidyverse) - -my_data <- data.frame( - language = c( 0, 20, 20, 25, 22, 17), - english = c( 0, 20, 40, 20, 24, 18), - math = c(100, 20, 5, 30, 17, 25), - science = c( 0, 20, 5, 25, 16, 23), - society = c( 0, 20, 30, 0, 21, 17), - row.names = c("A", "B", "C", "D", "E", "F")) -my_result <- my_data %>% prcomp # 主成分分析の実行 - -my_result$x # 主成分スコア -#> PC1 PC2 ... -#> A -74.907282 -7.010808 ... -#> B 13.818842 2.753459 ... -#> C 33.714034 -18.417290 ... -#> D 1.730630 17.876372 ... -#> E 17.837474 -1.064998 ... -#> F 7.806303 5.863266 ... - -my_result %>% ggbiplot::ggbiplot( - labels = row.names(my_data), - scale = 0) - -my_result$rotation %>% t -#> language english math science society -#> PC1 0.2074983 0.3043604 -0.887261240 0.1301984 0.2452041 -#> PC2 0.2794627 -0.3250521 -0.097642669 0.7026667 -0.5594347 -#> PC3 -0.3061175 -0.6157986 -0.056345381 0.3384462 0.6398152 -#> PC4 0.7649426 -0.4716969 -0.007654992 -0.4180454 0.1324548 -#> PC5 0.4472136 0.4472136 0.447213595 0.4472136 0.4472136 - -summary(my_result) -#> Importance of components: -#> PC1 PC2 PC3 PC4 PC5 -#> Standard deviation 38.2644 12.25566 5.58845 1.52970 1.232e-15 -#> Proportion of Variance 0.8885 0.09115 0.01895 0.00142 0.000e+00 -#> Cumulative Proportion 0.8885 0.97963 0.99858 1.00000 1.000e+00 - -### 13.1.1 標準化+主成分分析 - -my_result <- prcomp( - x = my_data, - scale = TRUE) # 標準化 -# あるいは -my_result <- prcomp( - x = scale(my_data)) # 標準化データ - -my_result$x # 主成分スコア -#> PC1 PC2 ... -#> A -3.6737215 -0.5688501 ... -#> B 0.6528793 0.2469258 ... -#> C 1.5682936 -1.7425981 ... -#> D 0.2505043 1.6400394 ... -#> E 0.8861864 -0.1104931 ... -#> F 0.3158579 0.5349762 ... - -### 13.1.2 補足:行列計算による再現 - -Z <- my_data %>% scale(scale = FALSE) %>% as.matrix # 標準化しない場合 -#Z <- my_data %>% scale(scale = TRUE) %>% as.matrix # 標準化する場合 - -n <- nrow(my_data) -S <- var(Z) # 分散共分散行列 -#S <- t(Z) %*% Z / (n - 1) # (同じ結果) -tmp <- eigen(S) # 固有値と固有ベクトル -Z %*% tmp$vectors # 主成分スコア(結果は割愛) -cumsum(tmp$values) / sum(tmp$values) # 累積寄与率 -#> [1] 0.8884833 0.9796285 0.9985801 1.0000000 1.0000000 - -udv <- svd(Z) # 特異値分解 -U <- udv$u -d <- udv$d -V <- udv$v -W <- diag(d) - -c(all.equal(Z, U %*% W %*% t(V), check.attributes = FALSE), # 確認1 - all.equal(t(U) %*% U, diag(dim(U)[2])), # 確認2 - all.equal(t(V) %*% V, diag(dim(V)[2]))) # 確認3 -#> [1] TRUE TRUE TRUE - -U %*% W # 主成分スコア(結果は割愛) - -e <- d^2 / (n - 1) # 分散共分散行列の固有値 -cumsum(e) / sum(e) # 累積寄与率 -#> [1] 0.8884833 0.9796285 0.9985801 1.0000000 1.0000000 diff --git a/code/R/ch13/13.02.R b/code/R/ch13/13.02.R deleted file mode 100644 index faa7db6..0000000 --- a/code/R/ch13/13.02.R +++ /dev/null @@ -1,93 +0,0 @@ -## 13.2 クラスタ分析 - -### 13.2.1 階層的クラスタ分析 - -library(tidyverse) - -my_data <- data.frame( - x = c( 0, -16, 10, 10), - y = c( 0, 0, 10, -15), - row.names = c("A", "B", "C", "D")) - -my_result <- my_data %>% - dist("euclidian") %>% # distだけでも可 - hclust("complete") # hclustだけでも可 - -my_result %>% factoextra::fviz_dend( - k = 3, # クラスタ数 - rect = TRUE, rect_fill = TRUE) - -my_result %>% factoextra::fviz_dend( - k = 3, - rect = TRUE, rect_fill = TRUE, - type = "phylogenic") - -my_result %>% cutree(3) -#> A B C D -#> 1 2 1 3 - -### 13.2.2 階層的クラスタ分析とヒートマップ - -library(tidyverse) - -my_data <- data.frame( - language = c( 0, 20, 20, 25, 22, 17), - english = c( 0, 20, 40, 20, 24, 18), - math = c(100, 20, 5, 30, 17, 25), - science = c( 0, 20, 5, 25, 16, 23), - society = c( 0, 20, 30, 0, 21, 17), - row.names = c("A", "B", "C", "D", "E", "F")) - -try( # RMarkdownで発生するエラーを回避する. - my_data %>% scale %>% # 列ごとの標準化 - gplots::heatmap.2(cexRow = 1, cexCol = 1), # ラベルのサイズを指定して描画する. - silent = TRUE) - -### 13.2.3 非階層的クラスタ分析 - -library(tidyverse) - -my_data <- data.frame( - x = c( 0, -16, 10, 10), - y = c( 0, 0, 10, -15), - row.names = c("A", "B", "C", "D")) - -my_result <- my_data %>% kmeans(3) - -my_result$cluster -#> A B C D -#> 2 3 2 1 - -### 13.2.4 クラスタ数の決定 - -library(tidyverse) -library(factoextra) - -my_data <- iris[, -5] - -f <- 2:5 %>% map(function(k) { - my_data %>% kmeans(k) %>% - fviz_cluster(data = my_data, geom = "point") + - ggtitle(sprintf("k = %s", k)) -}) -gridExtra::grid.arrange(f[[1]], f[[2]], f[[3]], f[[4]], ncol = 2) - -fviz_nbclust(my_data, kmeans, method = "wss") - -### 13.2.5 主成分分析とクラスタ分析 - -library(tidyverse) -my_data <- iris[, -5] %>% scale - -my_result <- prcomp(my_data)$x %>% as.data.frame # 主成分分析 - -# 非階層的クラスタ分析の場合 -my_result$cluster <- (my_data %>% scale %>% kmeans(3))$cluster %>% as.factor - -# 階層的クラスタ分析の場合 -#my_result$cluster <- my_data %>% dist %>% hclust %>% cutree(3) %>% as.factor - -my_result %>% - ggplot(aes(x = PC1, y = PC2, color = cluster)) + # 色でクラスタを表現する. - geom_point(shape = iris$Species) + # 形で品種を表現する. - theme(legend.position = "none") diff --git a/code/R/ch13/13.R b/code/R/ch13/13.R deleted file mode 100644 index 7ce205e..0000000 --- a/code/R/ch13/13.R +++ /dev/null @@ -1,183 +0,0 @@ -## 13.1 主成分分析 - -library(tidyverse) - -my_data <- data.frame( - language = c( 0, 20, 20, 25, 22, 17), - english = c( 0, 20, 40, 20, 24, 18), - math = c(100, 20, 5, 30, 17, 25), - science = c( 0, 20, 5, 25, 16, 23), - society = c( 0, 20, 30, 0, 21, 17), - row.names = c("A", "B", "C", "D", "E", "F")) -my_result <- my_data %>% prcomp # 主成分分析の実行 - -my_result$x # 主成分スコア -#> PC1 PC2 ... -#> A -74.907282 -7.010808 ... -#> B 13.818842 2.753459 ... -#> C 33.714034 -18.417290 ... -#> D 1.730630 17.876372 ... -#> E 17.837474 -1.064998 ... -#> F 7.806303 5.863266 ... - -my_result %>% ggbiplot::ggbiplot( - labels = row.names(my_data), - scale = 0) - -my_result$rotation %>% t -#> language english math science society -#> PC1 0.2074983 0.3043604 -0.887261240 0.1301984 0.2452041 -#> PC2 0.2794627 -0.3250521 -0.097642669 0.7026667 -0.5594347 -#> PC3 -0.3061175 -0.6157986 -0.056345381 0.3384462 0.6398152 -#> PC4 0.7649426 -0.4716969 -0.007654992 -0.4180454 0.1324548 -#> PC5 0.4472136 0.4472136 0.447213595 0.4472136 0.4472136 - -summary(my_result) -#> Importance of components: -#> PC1 PC2 PC3 PC4 PC5 -#> Standard deviation 38.2644 12.25566 5.58845 1.52970 1.232e-15 -#> Proportion of Variance 0.8885 0.09115 0.01895 0.00142 0.000e+00 -#> Cumulative Proportion 0.8885 0.97963 0.99858 1.00000 1.000e+00 - -### 13.1.1 標準化+主成分分析 - -my_result <- prcomp( - x = my_data, - scale = TRUE) # 標準化 -# あるいは -my_result <- prcomp( - x = scale(my_data)) # 標準化データ - -my_result$x # 主成分スコア -#> PC1 PC2 ... -#> A -3.6737215 -0.5688501 ... -#> B 0.6528793 0.2469258 ... -#> C 1.5682936 -1.7425981 ... -#> D 0.2505043 1.6400394 ... -#> E 0.8861864 -0.1104931 ... -#> F 0.3158579 0.5349762 ... - -### 13.1.2 補足:行列計算による再現 - -Z <- my_data %>% scale(scale = FALSE) %>% as.matrix # 標準化しない場合 -#Z <- my_data %>% scale(scale = TRUE) %>% as.matrix # 標準化する場合 - -n <- nrow(my_data) -S <- var(Z) # 分散共分散行列 -#S <- t(Z) %*% Z / (n - 1) # (同じ結果) -tmp <- eigen(S) # 固有値と固有ベクトル -Z %*% tmp$vectors # 主成分スコア(結果は割愛) -cumsum(tmp$values) / sum(tmp$values) # 累積寄与率 -#> [1] 0.8884833 0.9796285 0.9985801 1.0000000 1.0000000 - -udv <- svd(Z) # 特異値分解 -U <- udv$u -d <- udv$d -V <- udv$v -W <- diag(d) - -c(all.equal(Z, U %*% W %*% t(V), check.attributes = FALSE), # 確認1 - all.equal(t(U) %*% U, diag(dim(U)[2])), # 確認2 - all.equal(t(V) %*% V, diag(dim(V)[2]))) # 確認3 -#> [1] TRUE TRUE TRUE - -U %*% W # 主成分スコア(結果は割愛) - -e <- d^2 / (n - 1) # 分散共分散行列の固有値 -cumsum(e) / sum(e) # 累積寄与率 -#> [1] 0.8884833 0.9796285 0.9985801 1.0000000 1.0000000 - -## 13.2 クラスタ分析 - -### 13.2.1 階層的クラスタ分析 - -library(tidyverse) - -my_data <- data.frame( - x = c( 0, -16, 10, 10), - y = c( 0, 0, 10, -15), - row.names = c("A", "B", "C", "D")) - -my_result <- my_data %>% - dist("euclidian") %>% # distだけでも可 - hclust("complete") # hclustだけでも可 - -my_result %>% factoextra::fviz_dend( - k = 3, # クラスタ数 - rect = TRUE, rect_fill = TRUE) - -my_result %>% factoextra::fviz_dend( - k = 3, - rect = TRUE, rect_fill = TRUE, - type = "phylogenic") - -my_result %>% cutree(3) -#> A B C D -#> 1 2 1 3 - -### 13.2.2 階層的クラスタ分析とヒートマップ - -library(tidyverse) - -my_data <- data.frame( - language = c( 0, 20, 20, 25, 22, 17), - english = c( 0, 20, 40, 20, 24, 18), - math = c(100, 20, 5, 30, 17, 25), - science = c( 0, 20, 5, 25, 16, 23), - society = c( 0, 20, 30, 0, 21, 17), - row.names = c("A", "B", "C", "D", "E", "F")) - -try( # RMarkdownで発生するエラーを回避する. - my_data %>% scale %>% # 列ごとの標準化 - gplots::heatmap.2(cexRow = 1, cexCol = 1), # ラベルのサイズを指定して描画する. - silent = TRUE) - -### 13.2.3 非階層的クラスタ分析 - -library(tidyverse) - -my_data <- data.frame( - x = c( 0, -16, 10, 10), - y = c( 0, 0, 10, -15), - row.names = c("A", "B", "C", "D")) - -my_result <- my_data %>% kmeans(3) - -my_result$cluster -#> A B C D -#> 2 3 2 1 - -### 13.2.4 クラスタ数の決定 - -library(tidyverse) -library(factoextra) - -my_data <- iris[, -5] - -f <- 2:5 %>% map(function(k) { - my_data %>% kmeans(k) %>% - fviz_cluster(data = my_data, geom = "point") + - ggtitle(sprintf("k = %s", k)) -}) -gridExtra::grid.arrange(f[[1]], f[[2]], f[[3]], f[[4]], ncol = 2) - -fviz_nbclust(my_data, kmeans, method = "wss") - -### 13.2.5 主成分分析とクラスタ分析 - -library(tidyverse) -my_data <- iris[, -5] %>% scale - -my_result <- prcomp(my_data)$x %>% as.data.frame # 主成分分析 - -# 非階層的クラスタ分析の場合 -my_result$cluster <- (my_data %>% scale %>% kmeans(3))$cluster %>% as.factor - -# 階層的クラスタ分析の場合 -#my_result$cluster <- my_data %>% dist %>% hclust %>% cutree(3) %>% as.factor - -my_result %>% - ggplot(aes(x = PC1, y = PC2, color = cluster)) + # 色でクラスタを表現する. - geom_point(shape = iris$Species) + # 形で品種を表現する. - theme(legend.position = "none") - diff --git a/code/Rmd/ch03/03.01.Rmd b/code/Rmd/ch03/03.01.Rmd deleted file mode 100644 index 46c5a47..0000000 --- a/code/Rmd/ch03/03.01.Rmd +++ /dev/null @@ -1,130 +0,0 @@ -## 3.1 入門 - -### 3.1.1 数値 - -```{r} -0x10 -#> [1] 16 -``` - -```{r} -1.23e5 -#> [1] 123000 -``` - -```{r} -2 * 3 -#> [1] 6 -``` - -```{r} -10 / 3 -#> [1] 3.333333 -``` - -```{r} -10 %/% 3 # 商 -#> [1] 3 - -10 %% 3 # 余り -#> [1] 1 -``` - -### 3.1.2 変数 - -```{r} -x <- 2 -y <- 3 -x * y -#> [1] 6 - -keras::`%<-%`(c(x, y), c(20, 30)) # まとめて名付け -x * y -#> [1] 600 -``` - -```{r} -x <- 1 + 1 -# この段階では結果は表示されない - -x # 変数名を評価する. -#> [1] 2 -``` - -### 3.1.3 文字列 - -```{r} -my_s <- "abcde" -``` - -```{r} -nchar(my_s) -#> [1] 5 -``` - -```{r} -library(tidyverse) -str_c("This is ", "a", " pen.") -#> [1] "This is a pen." -``` - -```{r} -substr(x = my_s, start = 2, stop = 4) -#> [1] "bcd" -``` - -```{r} -tmp <- "%s is %s." -sprintf(tmp, "This", "a pen") -#> [1] "This is a pen." -``` - -### 3.1.4 論理値 - -```{r} -1 <= 2 -#> [1] TRUE - -1 < 0 -#> [1] FALSE -``` - -```{r} -0.1 + 0.1 + 0.1 == 0.3 -#> [1] FALSE - -all.equal(0.1 + 0.1 + 0.1, 0.3) -#> [1] TRUE -``` - -```{r} -TRUE & FALSE # 論理積(かつ) -#> [1] FALSE - -TRUE | FALSE # 論理和(または) -#> [1] TRUE - -!TRUE # 否定(でない) -#> [1] FALSE -``` - -#### 3.1.4.1 条件演算子 - -```{r} -ifelse(3 < 5, 0, 10) -#> 0 -``` - -### 3.1.5 作業ディレクトリ - -```{r} -getwd() -#> '/home/jovyan/work' -``` - -```{r} -setwd("..") -getwd() -#> '/home/jovyan' -``` - diff --git a/code/Rmd/ch03/03.02.Rmd b/code/Rmd/ch03/03.02.Rmd deleted file mode 100644 index 6803c9a..0000000 --- a/code/Rmd/ch03/03.02.Rmd +++ /dev/null @@ -1,76 +0,0 @@ -## 3.2 関数 - -### 3.2.1 関数の利用 - -```{r} -sqrt(4) -#> [1] 2 -``` - -```{r} -log(100, 10) -#> [1] 2 -``` - -```{r} -log(100) # 自然対数 -# あるいは -log(100, exp(1)) # 省略しない場合 - -#> [1] 4.60517 -``` - -```{r} -log10(100) # 常用対数 -#> [1] 2 - -log2(1024) # 底が2の対数 -#> [1] 10 -``` - -#### 3.2.1.1 パイプ(Rのみ) - -```{r} -library(tidyverse) -4 %>% sqrt -``` - -```{r} -exp(log(5)) # 通常の書き方 -# あるいは -5 %>% log %>% exp # パイプを使う書き方 - -#> 5 -``` - -### 3.2.2 関数の定義 - -```{r} -f <- function(a, b) { - a - b -} -``` - -```{r} -f(3, 5) -#> [1] -2 -``` - -#### 3.2.2.1 デフォルト引数 - -```{r} -f <- function(a, b = 5) { - a - b -} - -f(3) # f(3, 5)と同じこと -#> [1] -2 -``` - -#### 3.2.2.2 無名関数 - -```{r} -(function(a, b) { a - b })(3, 5) -#> [1] -2 -``` - diff --git a/code/Rmd/ch03/03.03.Rmd b/code/Rmd/ch03/03.03.Rmd deleted file mode 100644 index 9517fa1..0000000 --- a/code/Rmd/ch03/03.03.Rmd +++ /dev/null @@ -1,195 +0,0 @@ -## 3.3 コレクション - -### 3.3.1 1次元データ - -```{r} -x <- c("foo", "bar", "baz") -``` - -```{r} -length(x) -#> [1] 3 -``` - -```{r} -x[2] -#> [1] "bar" -``` - -```{r} -x[2] <- "BAR" -x # 結果の確認 -#> [1] "foo" "BAR" "baz" - -x[2] <- "bar" # 元に戻す. -``` - -```{r} -x[-2] -#> [1] "foo" "baz" -``` - -```{r} -c(x, "qux") -#> [1] "foo" "bar" "baz" "qux" -``` - -```{r} -x <- c(x, "qux") -x # 結果の確認 -#> [1] "foo" "bar" "baz" "qux" -``` - -#### 3.3.1.1 等間隔の数値からなる1次元データ - -```{r} -1:5 -#> [1] 1 2 3 4 5 -``` - -```{r} -seq(from = 0, to = 10, by = 2) -#> [1] 0 2 4 6 8 10 -``` - -```{r} -seq(from = 0, to = 1, by = 0.5) -#> [1] 0.0 0.5 1.0 -``` - -```{r} -seq(from = 0, to = 100, length.out = 5) -#> [1] 0 25 50 75 100 -``` - -```{r} -rep(x = 10, times = 5) -#> [1] 10 10 10 10 10 -``` - -#### 3.3.1.2 ファクタ(Rのみ) - -```{r} -tmp <- c("グー", "パー", "グー", "パー") -x <- factor(tmp, levels = c("グー", "チョキ", "パー")) -x -#> [1] グー パー グー パー -#> Levels: グー チョキ パー -``` - -### 3.3.2 数値計算やデータ解析用の1次元データ - -```{r} -x <- c(2, 3, 5, 7) - -x + 10 # 加算 -#> [1] 12 13 15 17 - -x * 10 # 乗算 -#> [1] 20 30 50 70 -``` - -```{r} -x <- c(2, 3) -sin(x) -#> [1] 0.9092974 0.1411200 -``` - -```{r} -x <- c(2, 3, 5, 7) -y <- c(1, 10, 100, 1000) -x + y -#> [1] 3 13 105 1007 - -x * y -#> [1] 2 30 500 7000 -``` - -```{r} -sum(x * y) -#> [1] 7532 -``` - -```{r} -x <- c(TRUE, FALSE) -y <- c(TRUE, TRUE) -x & y -#> [1] TRUE FALSE -``` - -#### 3.3.2.1 1次元データ同士の比較 - -```{r} -u <- c(1, 2, 3) -v <- c(1, 2, 3) -w <- c(1, 2, 4) - -identical(u, v) # 全体の比較 -#> [1] TRUE - -identical(u, w) # 全体の比較 -#> [1] FALSE - -u == v # 要素ごとの比較 -#> [1] TRUE TRUE TRUE - -u == w # 要素ごとの比較 -#> [1] TRUE TRUE FALSE -``` - -```{r} -sum(u == w) # 同じ要素の数 -#> [1] 2 - -mean(u == w) # 同じ要素の割合 -#> [1] 0.6666667 -``` - -### 3.3.3 複数種類のデータをひとまとめにする - -```{r} -x <- list(1, "two") -``` - -```{r} -x[[2]] -#> [1] "two" -``` - -### 3.3.4 文字列と値のペアのコレクション - -```{r} -x <- list("apple" = "りんご", - "orange" = "みかん") -``` - -```{r} -x[["grape"]] <- "ぶどう" -``` - -```{r} -x$apple -# あるいは -x$"apple" -# あるいは -x[["apple"]] -# あるいは -tmp <- "apple" -x[[tmp]] - -#> [1] "りんご" -``` - -### 3.3.5 補足:コピーと参照 - -```{r} -x <- c("foo", "bar", "baz") -y <- x -y[2] <- "BAR" # yを更新する. -y -#> [1] "foo" "BAR" "baz" - -x # xは変わらない. -#> [1] "foo" "bar" "baz" -``` - diff --git a/code/Rmd/ch03/03.04.Rmd b/code/Rmd/ch03/03.04.Rmd deleted file mode 100644 index 0c4f3f9..0000000 --- a/code/Rmd/ch03/03.04.Rmd +++ /dev/null @@ -1,334 +0,0 @@ -## 3.4 データフレーム - -### 3.4.1 データフレームの作成 - -```{r} -library(tidyverse) -``` - -#### 3.4.1.1 データを列ごとに記述する方法 - -```{r} -my_df <- data.frame( - name = c("A", "B", "C", "D"), - english = c( 60, 90, 70, 90), - math = c( 70, 80, 90, 100), - gender = c("f", "m", "m", "f")) -``` - -#### 3.4.1.2 データを見た目のとおりに記述する方法 - -```{r} -my_df <- tribble( - ~name, ~english, ~math, ~gender, - "A", 60, 70, "f", - "B", 90, 80, "m", - "C", 70, 90, "m", - "D", 90, 100, "f") -``` - -```{r} -head(my_df) -# 結果は割愛 -``` - -#### 3.4.1.3 データフレームのサイズ - -```{r} -dim(my_df) # 行数と列数 -#> [1] 4 4 - -nrow(my_df) # 行数 -#> [1] 4 - -ncol(my_df) # 列数 -#> [1] 4 -``` - -#### 3.4.1.4 組合せ - -```{r} -my_df2 <- expand.grid( - X = c(1, 2, 3), - Y = c(10, 100)) -my_df2 -#> X Y -#> 1 1 10 -#> 2 2 10 -#> 3 3 10 -#> 4 1 100 -#> 5 2 100 -#> 6 3 100 -``` - -#### 3.4.1.5 列と行の名前 - -```{r} -colnames(my_df2) -#> [1] "X" "Y" -``` - -```{r} -colnames(my_df2) <- c("P", "Q") -my_df2 -#> P Q -#> 1 1 10 -#> 2 2 10 -# 以下省略 -``` - -```{r} -row.names(my_df) -#> [1] "1" "2" "3" "4" -``` - -```{r} -row.names(my_df2) <- - c("a", "b", "c", "d", "e", "f") -my_df2 -#> P Q -#> a 1 10 -#> b 2 10 -#> c 3 10 -# 以下省略 -``` - -```{r} -my_df3 <- data.frame( - english = c( 60, 90, 70, 90), - math = c( 70, 80, 90, 100), - gender = c("f", "m", "m", "f"), - row.names = c("A", "B", "C", "D")) -my_df3 -#> english math gender -#> A 60 70 f -#> B 90 80 m -#> C 70 90 m -#> D 90 100 f -``` - -### 3.4.2 データの追加 - -#### 3.4.2.1 行の追加(データフレームの結合) - -```{r} -tmp <- data.frame( - name = "E", - english = 80, - math = 80, - gender = "m") -my_df2 <- rbind(my_df, tmp) -``` - -#### 3.4.2.2 列の追加 - -```{r} -my_df2 <- my_df %>% - mutate(id = c(1, 2, 3, 4)) -``` - -```{r} -my_df3 <- my_df # コピー -my_df3["id"] <- c(1, 2, 3, 4) # 更新 -my_df3 # 結果の確認(割愛) -``` - -### 3.4.3 データの取り出し - -#### 3.4.3.1 観測値の取り出し - -```{r} -my_df[1, 2] -#> [1] 60 -``` - -#### 3.4.3.2 1列の取り出し(結果は1次元データ) - -```{r} -x <- my_df[, 2] -# あるいは -x <- my_df$english -# あるいは -x <- my_df$"english" -# あるいは -x <- my_df[["english"]] -# あるいは -tmp <- "english" -x <- my_df[[tmp]] - -x # 結果の確認(割愛) -``` - -#### 3.4.3.3 複数列の取り出し(結果はデータフレーム) - -```{r} -x <- my_df %>% select(name, math) -``` - -```{r} -x <- my_df[, c(1, 3)] -``` - -```{r} -x <- my_df %>% - select(-c(english, gender)) -# あるいは -x <- my_df[, -c(2, 4)] -``` - -#### 3.4.3.4 複数行の取り出し(結果はデータフレーム) - -```{r} -x <- my_df[c(1, 3), ] -``` - -```{r} -x <- my_df[-c(2, 4), ] -``` - -#### 3.4.3.5 検索 - -```{r} -x <- my_df[my_df$gender == "m", ] -# あるいは -x <- my_df %>% filter(gender == "m") -``` - -```{r} -x <- my_df[my_df$english > 80 & my_df$gender == "m", ] -# あるいは -x <- my_df %>% filter(english > 80 & gender == "m") -``` - -```{r} -x <- my_df[my_df$english == max(my_df$english), ] -# あるいは -x <- my_df %>% filter(english == max(my_df$english)) -``` - -```{r} -my_df2 <- my_df # コピー -my_df2[my_df$gender == "m", ]$gender <- "M" -``` - -```{r} -my_df2 -#> name english math gender -#> 1 A 60 70 f -#> 2 B 90 80 M -#> 3 C 70 90 M -#> 4 D 90 100 f -``` - -#### 3.4.3.6 並べ替え - -```{r} -x <- my_df %>% arrange(english) -``` - -```{r} -x <- my_df %>% arrange(-english) -``` - -### 3.4.4 補足:行列 - -#### 3.4.4.1 行列の生成 - -```{r} -x <- c(2, 3, 5, 7, 11, 13, 17, 19, 23, - 29, 31, 37) -A <- matrix( - data = x, # 1次元データ - nrow = 3, # 行数 - byrow = TRUE) # 行ごとの生成 -A -#> [,1] [,2] [,3] [,4] -#> [1,] 2 3 5 7 -#> [2,] 11 13 17 19 -#> [3,] 23 29 31 37 -``` - -#### 3.4.4.2 データフレームと行列 - -```{r} -A <- my_df[, c(2, 3)] %>% as.matrix -A -#> english math -#> [1,] 60 70 -#> [2,] 90 80 -#> [3,] 70 90 -#> [4,] 90 100 -``` - -```{r} -as.data.frame(A) -#> english math -#> 1 60 70 -#> 2 90 80 -#> 3 70 90 -#> 4 90 100 -``` - -#### 3.4.4.3 行列の変形 - -```{r} -t(A) -#> [,1] [,2] [,3] [,4] -#> english 60 90 70 90 -#> math 70 80 90 100 -``` - -#### 3.4.4.4 行列の積 - -```{r} -t(A) %*% A -#> english math -#> english 24700 26700 -#> math 26700 29400 -``` - -### 3.4.5 縦型と横型 - -```{r} -my_wider <- data.frame( - day = c(25, 26, 27), - min = c(20, 21, 15), - max = c(24, 27, 21)) -``` - -```{r} -my_longer <- my_wider %>% - pivot_longer(-day) -my_longer -#> # A tibble: 6 x 3 -#> day name value -#> -#> 1 25 min 20 -#> 2 25 max 24 -#> 3 26 min 21 -#> 4 26 max 27 -#> 5 27 min 15 -#> 6 27 max 21 -``` - -```{r} -my_longer %>% pivot_wider() -#> # A tibble: 3 x 3 -#> day min max -#> -#> 1 25 20 24 -#> 2 26 21 27 -#> 3 27 15 21 -``` - -```{r} -my_longer %>% - ggplot(aes(x = day, y = value, - color = name)) + - geom_point() + - geom_line() + - ylab("temperature") + # y軸ラベル - scale_x_continuous( - breaks = my_longer$day) # x軸目盛り -``` - diff --git a/code/Rmd/ch03/03.05.Rmd b/code/Rmd/ch03/03.05.Rmd deleted file mode 100644 index 6b18395..0000000 --- a/code/Rmd/ch03/03.05.Rmd +++ /dev/null @@ -1,91 +0,0 @@ -## 3.5 1次元データの(非)類似度 - -### 3.5.1 ユークリッド距離 - -```{r} -A <- c(3, 4, 5) -B <- c(3, 4, 29) -C <- c(9, -18, 8) -AB <- B - A -AC <- C - A - -sum(AB^2)^0.5 -#> [1] 24 - -sum(AC^2)^0.5 -#> [1] 23 -``` - -### 3.5.2 マンハッタン距離 - -```{r} -sum(abs(AB)) -#> [1] 24 - -sum(abs(AC)) -#> [1] 31 -``` - -### 3.5.3 コサイン類似度 - -```{r} -sum(A * B) / - sum(A * A)^0.5 / sum(B * B)^0.5 -#> [1] 0.8169679 - -sum(A * C) / - sum(A * A)^0.5 / sum(C * C)^0.5 -#> [1] -0.03265116 -``` - -### 3.5.4 相関係数 - -```{r} -cor(A, B) -#> [1] 0.8824975 - -cor(A, C) -#> [1] -0.03266277 -``` - -#### 3.5.4.1 データフレームを使う方法 - -```{r} -library(tidyverse) - - - -my_df <- data.frame( - x = c(3, 3, 9), - y = c(4, 4, -18), - z = c(5, 29, 8), - row.names = c("A", "B", "C")) - -# ユークリッド距離 -my_df %>% proxy::dist("Euclidean") -#> A B -#> B 24 -#> C 23 31 - - -# マンハッタン距離 -my_df %>% proxy::dist("Manhattan") -#> A B -#> B 24 -#> C 31 49 - - -# コサイン類似度 -my_df %>% proxy::simil("cosine") -#> A B -#> B 0.81696786 -#> C -0.03265116 0.29342441 - - -# 相関係数 -my_df %>% proxy::simil("correlation") -#> A B -#> B 0.88249750 -#> C -0.03266277 0.44124132 -``` - diff --git a/code/Rmd/ch03/03.06.Rmd b/code/Rmd/ch03/03.06.Rmd deleted file mode 100644 index 57d7fb7..0000000 --- a/code/Rmd/ch03/03.06.Rmd +++ /dev/null @@ -1,10 +0,0 @@ -## 3.6 Rのパッケージ,Pythonのモジュール - -### 3.6.1 Rのパッケージ - -```{r} -library(tidyverse) -``` - -### 3.6.2 Pythonのモジュール - diff --git a/code/Rmd/ch03/03.07.Rmd b/code/Rmd/ch03/03.07.Rmd deleted file mode 100644 index 4665f44..0000000 --- a/code/Rmd/ch03/03.07.Rmd +++ /dev/null @@ -1,127 +0,0 @@ -## 3.7 反復処理 - -```{r} -library(tidyverse) -``` - -### 3.7.1 指定した回数→1次元データ - -```{r} -f1 <- function(x) { - tmp <- runif(x) - mean(tmp) -} - -f1(10) # 動作確認 -#> [1] 0.5776604 # 結果の例 -``` - -```{r} -replicate(n = 3, expr = f1(10)) -#> [1] 0.4672766 0.4712016 0.5579449 -``` - -```{r} -rep(x = f1(10), times = 3) -#> [1] 0.481329 0.481329 0.481329 -``` - -### 3.7.2 1次元データ→1次元データ - -```{r} -v <- c(5, 10, 100) -v %>% map_dbl(f1) -#> [1] 0.4857329 0.5322183 0.5084124 -``` - -```{r} -rep(x = 10, times = 3) %>% map_dbl(f1) -# 結果は割愛 -``` - -### 3.7.3 1次元データ→データフレーム - -```{r} -f2 <- function(n) { - tmp <- runif(n) - list(x = n, - p = mean(tmp), - q = sd(tmp)) -} - -f2(10) # 動作確認 -#> $x -#> [1] 10 -#> -#> $p -#> [1] 0.6840032 (平均の例) -#> -#> $q -#> [1] 0.3750788 (標準偏差の例) -``` - -```{r} -v <- c(5, 10, 100) -v %>% map_dfr(f2) -#> x p q -#> -#> 1 5 0.560 0.320 -#> 2 10 0.559 0.271 -#> 3 100 0.507 0.283 -``` - -### 3.7.4 データフレーム→データフレーム - -```{r} -f3 <- function(x, y) { - tmp <- runif(x, min = 1, - max = y + 1) %>% - as.integer - list(x = x, - y = y, - p = mean(tmp), - q = sd(tmp)) -} - -f3(x = 10, y = 6) # 動作確認 -#> $x -#> [1] 10 -#> -#> $y -#> [1] 6 -#> -#> $p -#> [1] 3.2 (平均の例) -#> -#> $q -#> [1] 1.316561 (標準偏差の例) -``` - -```{r} -my_df <- data.frame( - x = c(5, 10, 100, 5, 10, 100), - y = c(6, 6, 6, 12, 12, 12)) - -my_df %>% pmap_dfr(f3) -#> x y p q -#> -#> 1 5 6 3 1.41 -#> 2 10 6 3 1.49 -#> 3 100 6 3.57 1.78 -#> 4 5 12 7.6 5.22 -#> 5 10 12 5.7 3.77 -#> 6 100 12 6.36 3.59 -``` - -### 3.7.5 補足:反復処理の並列化 - -```{r} -library(furrr) -plan(multisession) # 準備 - -v <- c(5, 10, 100) -v %>% future_map_dbl(f1, .options = - furrr_options(seed = TRUE)) -# 結果は割愛 -``` - diff --git a/code/Rmd/ch03/03.08.Rmd b/code/Rmd/ch03/03.08.Rmd deleted file mode 100644 index 7792937..0000000 --- a/code/Rmd/ch03/03.08.Rmd +++ /dev/null @@ -1,34 +0,0 @@ -## 3.8 その他 - -### 3.8.1 よく遭遇するエラーとその対処方法 - -### 3.8.2 変数や関数についての調査 - -```{r} -x <- 123 -typeof(x) -#> [1] "double" -``` - -```{r} -?log -# あるいは -help(log) -``` - -### 3.8.3 RのNA,Pythonのnan - -```{r} -v <- c(1, NA, 3) -v -#> [1] 1 NA 3 -``` - -```{r} -is.na(v[2]) -#> [1] TRUE - -v[2] == NA # 誤り -#> [1] NA -``` - diff --git a/code/Rmd/ch03/03.Rmd b/code/Rmd/ch03/03.Rmd deleted file mode 100644 index f2476f3..0000000 --- a/code/Rmd/ch03/03.Rmd +++ /dev/null @@ -1,1005 +0,0 @@ -## 3.1 入門 - -### 3.1.1 数値 - -```{r} -0x10 -#> [1] 16 -``` - -```{r} -1.23e5 -#> [1] 123000 -``` - -```{r} -2 * 3 -#> [1] 6 -``` - -```{r} -10 / 3 -#> [1] 3.333333 -``` - -```{r} -10 %/% 3 # 商 -#> [1] 3 - -10 %% 3 # 余り -#> [1] 1 -``` - -### 3.1.2 変数 - -```{r} -x <- 2 -y <- 3 -x * y -#> [1] 6 - -keras::`%<-%`(c(x, y), c(20, 30)) # まとめて名付け -x * y -#> [1] 600 -``` - -```{r} -x <- 1 + 1 -# この段階では結果は表示されない - -x # 変数名を評価する. -#> [1] 2 -``` - -### 3.1.3 文字列 - -```{r} -my_s <- "abcde" -``` - -```{r} -nchar(my_s) -#> [1] 5 -``` - -```{r} -library(tidyverse) -str_c("This is ", "a", " pen.") -#> [1] "This is a pen." -``` - -```{r} -substr(x = my_s, start = 2, stop = 4) -#> [1] "bcd" -``` - -```{r} -tmp <- "%s is %s." -sprintf(tmp, "This", "a pen") -#> [1] "This is a pen." -``` - -### 3.1.4 論理値 - -```{r} -1 <= 2 -#> [1] TRUE - -1 < 0 -#> [1] FALSE -``` - -```{r} -0.1 + 0.1 + 0.1 == 0.3 -#> [1] FALSE - -all.equal(0.1 + 0.1 + 0.1, 0.3) -#> [1] TRUE -``` - -```{r} -TRUE & FALSE # 論理積(かつ) -#> [1] FALSE - -TRUE | FALSE # 論理和(または) -#> [1] TRUE - -!TRUE # 否定(でない) -#> [1] FALSE -``` - -#### 3.1.4.1 条件演算子 - -```{r} -ifelse(3 < 5, 0, 10) -#> 0 -``` - -### 3.1.5 作業ディレクトリ - -```{r} -getwd() -#> '/home/jovyan/work' -``` - -```{r} -setwd("..") -getwd() -#> '/home/jovyan' -``` - - -## 3.2 関数 - -### 3.2.1 関数の利用 - -```{r} -sqrt(4) -#> [1] 2 -``` - -```{r} -log(100, 10) -#> [1] 2 -``` - -```{r} -log(100) # 自然対数 -# あるいは -log(100, exp(1)) # 省略しない場合 - -#> [1] 4.60517 -``` - -```{r} -log10(100) # 常用対数 -#> [1] 2 - -log2(1024) # 底が2の対数 -#> [1] 10 -``` - -#### 3.2.1.1 パイプ(Rのみ) - -```{r} -library(tidyverse) -4 %>% sqrt -``` - -```{r} -exp(log(5)) # 通常の書き方 -# あるいは -5 %>% log %>% exp # パイプを使う書き方 - -#> 5 -``` - -### 3.2.2 関数の定義 - -```{r} -f <- function(a, b) { - a - b -} -``` - -```{r} -f(3, 5) -#> [1] -2 -``` - -#### 3.2.2.1 デフォルト引数 - -```{r} -f <- function(a, b = 5) { - a - b -} - -f(3) # f(3, 5)と同じこと -#> [1] -2 -``` - -#### 3.2.2.2 無名関数 - -```{r} -(function(a, b) { a - b })(3, 5) -#> [1] -2 -``` - - -## 3.3 コレクション - -### 3.3.1 1次元データ - -```{r} -x <- c("foo", "bar", "baz") -``` - -```{r} -length(x) -#> [1] 3 -``` - -```{r} -x[2] -#> [1] "bar" -``` - -```{r} -x[2] <- "BAR" -x # 結果の確認 -#> [1] "foo" "BAR" "baz" - -x[2] <- "bar" # 元に戻す. -``` - -```{r} -x[-2] -#> [1] "foo" "baz" -``` - -```{r} -c(x, "qux") -#> [1] "foo" "bar" "baz" "qux" -``` - -```{r} -x <- c(x, "qux") -x # 結果の確認 -#> [1] "foo" "bar" "baz" "qux" -``` - -#### 3.3.1.1 等間隔の数値からなる1次元データ - -```{r} -1:5 -#> [1] 1 2 3 4 5 -``` - -```{r} -seq(from = 0, to = 10, by = 2) -#> [1] 0 2 4 6 8 10 -``` - -```{r} -seq(from = 0, to = 1, by = 0.5) -#> [1] 0.0 0.5 1.0 -``` - -```{r} -seq(from = 0, to = 100, length.out = 5) -#> [1] 0 25 50 75 100 -``` - -```{r} -rep(x = 10, times = 5) -#> [1] 10 10 10 10 10 -``` - -#### 3.3.1.2 ファクタ(Rのみ) - -```{r} -tmp <- c("グー", "パー", "グー", "パー") -x <- factor(tmp, levels = c("グー", "チョキ", "パー")) -x -#> [1] グー パー グー パー -#> Levels: グー チョキ パー -``` - -### 3.3.2 数値計算やデータ解析用の1次元データ - -```{r} -x <- c(2, 3, 5, 7) - -x + 10 # 加算 -#> [1] 12 13 15 17 - -x * 10 # 乗算 -#> [1] 20 30 50 70 -``` - -```{r} -x <- c(2, 3) -sin(x) -#> [1] 0.9092974 0.1411200 -``` - -```{r} -x <- c(2, 3, 5, 7) -y <- c(1, 10, 100, 1000) -x + y -#> [1] 3 13 105 1007 - -x * y -#> [1] 2 30 500 7000 -``` - -```{r} -sum(x * y) -#> [1] 7532 -``` - -```{r} -x <- c(TRUE, FALSE) -y <- c(TRUE, TRUE) -x & y -#> [1] TRUE FALSE -``` - -#### 3.3.2.1 1次元データ同士の比較 - -```{r} -u <- c(1, 2, 3) -v <- c(1, 2, 3) -w <- c(1, 2, 4) - -identical(u, v) # 全体の比較 -#> [1] TRUE - -identical(u, w) # 全体の比較 -#> [1] FALSE - -u == v # 要素ごとの比較 -#> [1] TRUE TRUE TRUE - -u == w # 要素ごとの比較 -#> [1] TRUE TRUE FALSE -``` - -```{r} -sum(u == w) # 同じ要素の数 -#> [1] 2 - -mean(u == w) # 同じ要素の割合 -#> [1] 0.6666667 -``` - -### 3.3.3 複数種類のデータをひとまとめにする - -```{r} -x <- list(1, "two") -``` - -```{r} -x[[2]] -#> [1] "two" -``` - -### 3.3.4 文字列と値のペアのコレクション - -```{r} -x <- list("apple" = "りんご", - "orange" = "みかん") -``` - -```{r} -x[["grape"]] <- "ぶどう" -``` - -```{r} -x$apple -# あるいは -x$"apple" -# あるいは -x[["apple"]] -# あるいは -tmp <- "apple" -x[[tmp]] - -#> [1] "りんご" -``` - -### 3.3.5 補足:コピーと参照 - -```{r} -x <- c("foo", "bar", "baz") -y <- x -y[2] <- "BAR" # yを更新する. -y -#> [1] "foo" "BAR" "baz" - -x # xは変わらない. -#> [1] "foo" "bar" "baz" -``` - - -## 3.4 データフレーム - -### 3.4.1 データフレームの作成 - -```{r} -library(tidyverse) -``` - -#### 3.4.1.1 データを列ごとに記述する方法 - -```{r} -my_df <- data.frame( - name = c("A", "B", "C", "D"), - english = c( 60, 90, 70, 90), - math = c( 70, 80, 90, 100), - gender = c("f", "m", "m", "f")) -``` - -#### 3.4.1.2 データを見た目のとおりに記述する方法 - -```{r} -my_df <- tribble( - ~name, ~english, ~math, ~gender, - "A", 60, 70, "f", - "B", 90, 80, "m", - "C", 70, 90, "m", - "D", 90, 100, "f") -``` - -```{r} -head(my_df) -# 結果は割愛 -``` - -#### 3.4.1.3 データフレームのサイズ - -```{r} -dim(my_df) # 行数と列数 -#> [1] 4 4 - -nrow(my_df) # 行数 -#> [1] 4 - -ncol(my_df) # 列数 -#> [1] 4 -``` - -#### 3.4.1.4 組合せ - -```{r} -my_df2 <- expand.grid( - X = c(1, 2, 3), - Y = c(10, 100)) -my_df2 -#> X Y -#> 1 1 10 -#> 2 2 10 -#> 3 3 10 -#> 4 1 100 -#> 5 2 100 -#> 6 3 100 -``` - -#### 3.4.1.5 列と行の名前 - -```{r} -colnames(my_df2) -#> [1] "X" "Y" -``` - -```{r} -colnames(my_df2) <- c("P", "Q") -my_df2 -#> P Q -#> 1 1 10 -#> 2 2 10 -# 以下省略 -``` - -```{r} -row.names(my_df) -#> [1] "1" "2" "3" "4" -``` - -```{r} -row.names(my_df2) <- - c("a", "b", "c", "d", "e", "f") -my_df2 -#> P Q -#> a 1 10 -#> b 2 10 -#> c 3 10 -# 以下省略 -``` - -```{r} -my_df3 <- data.frame( - english = c( 60, 90, 70, 90), - math = c( 70, 80, 90, 100), - gender = c("f", "m", "m", "f"), - row.names = c("A", "B", "C", "D")) -my_df3 -#> english math gender -#> A 60 70 f -#> B 90 80 m -#> C 70 90 m -#> D 90 100 f -``` - -### 3.4.2 データの追加 - -#### 3.4.2.1 行の追加(データフレームの結合) - -```{r} -tmp <- data.frame( - name = "E", - english = 80, - math = 80, - gender = "m") -my_df2 <- rbind(my_df, tmp) -``` - -#### 3.4.2.2 列の追加 - -```{r} -my_df2 <- my_df %>% - mutate(id = c(1, 2, 3, 4)) -``` - -```{r} -my_df3 <- my_df # コピー -my_df3["id"] <- c(1, 2, 3, 4) # 更新 -my_df3 # 結果の確認(割愛) -``` - -### 3.4.3 データの取り出し - -#### 3.4.3.1 観測値の取り出し - -```{r} -my_df[1, 2] -#> [1] 60 -``` - -#### 3.4.3.2 1列の取り出し(結果は1次元データ) - -```{r} -x <- my_df[, 2] -# あるいは -x <- my_df$english -# あるいは -x <- my_df$"english" -# あるいは -x <- my_df[["english"]] -# あるいは -tmp <- "english" -x <- my_df[[tmp]] - -x # 結果の確認(割愛) -``` - -#### 3.4.3.3 複数列の取り出し(結果はデータフレーム) - -```{r} -x <- my_df %>% select(name, math) -``` - -```{r} -x <- my_df[, c(1, 3)] -``` - -```{r} -x <- my_df %>% - select(-c(english, gender)) -# あるいは -x <- my_df[, -c(2, 4)] -``` - -#### 3.4.3.4 複数行の取り出し(結果はデータフレーム) - -```{r} -x <- my_df[c(1, 3), ] -``` - -```{r} -x <- my_df[-c(2, 4), ] -``` - -#### 3.4.3.5 検索 - -```{r} -x <- my_df[my_df$gender == "m", ] -# あるいは -x <- my_df %>% filter(gender == "m") -``` - -```{r} -x <- my_df[my_df$english > 80 & my_df$gender == "m", ] -# あるいは -x <- my_df %>% filter(english > 80 & gender == "m") -``` - -```{r} -x <- my_df[my_df$english == max(my_df$english), ] -# あるいは -x <- my_df %>% filter(english == max(my_df$english)) -``` - -```{r} -my_df2 <- my_df # コピー -my_df2[my_df$gender == "m", ]$gender <- "M" -``` - -```{r} -my_df2 -#> name english math gender -#> 1 A 60 70 f -#> 2 B 90 80 M -#> 3 C 70 90 M -#> 4 D 90 100 f -``` - -#### 3.4.3.6 並べ替え - -```{r} -x <- my_df %>% arrange(english) -``` - -```{r} -x <- my_df %>% arrange(-english) -``` - -### 3.4.4 補足:行列 - -#### 3.4.4.1 行列の生成 - -```{r} -x <- c(2, 3, 5, 7, 11, 13, 17, 19, 23, - 29, 31, 37) -A <- matrix( - data = x, # 1次元データ - nrow = 3, # 行数 - byrow = TRUE) # 行ごとの生成 -A -#> [,1] [,2] [,3] [,4] -#> [1,] 2 3 5 7 -#> [2,] 11 13 17 19 -#> [3,] 23 29 31 37 -``` - -#### 3.4.4.2 データフレームと行列 - -```{r} -A <- my_df[, c(2, 3)] %>% as.matrix -A -#> english math -#> [1,] 60 70 -#> [2,] 90 80 -#> [3,] 70 90 -#> [4,] 90 100 -``` - -```{r} -as.data.frame(A) -#> english math -#> 1 60 70 -#> 2 90 80 -#> 3 70 90 -#> 4 90 100 -``` - -#### 3.4.4.3 行列の変形 - -```{r} -t(A) -#> [,1] [,2] [,3] [,4] -#> english 60 90 70 90 -#> math 70 80 90 100 -``` - -#### 3.4.4.4 行列の積 - -```{r} -t(A) %*% A -#> english math -#> english 24700 26700 -#> math 26700 29400 -``` - -### 3.4.5 縦型と横型 - -```{r} -my_wider <- data.frame( - day = c(25, 26, 27), - min = c(20, 21, 15), - max = c(24, 27, 21)) -``` - -```{r} -my_longer <- my_wider %>% - pivot_longer(-day) -my_longer -#> # A tibble: 6 x 3 -#> day name value -#> -#> 1 25 min 20 -#> 2 25 max 24 -#> 3 26 min 21 -#> 4 26 max 27 -#> 5 27 min 15 -#> 6 27 max 21 -``` - -```{r} -my_longer %>% pivot_wider() -#> # A tibble: 3 x 3 -#> day min max -#> -#> 1 25 20 24 -#> 2 26 21 27 -#> 3 27 15 21 -``` - -```{r} -my_longer %>% - ggplot(aes(x = day, y = value, - color = name)) + - geom_point() + - geom_line() + - ylab("temperature") + # y軸ラベル - scale_x_continuous( - breaks = my_longer$day) # x軸目盛り -``` - - -## 3.5 1次元データの(非)類似度 - -### 3.5.1 ユークリッド距離 - -```{r} -A <- c(3, 4, 5) -B <- c(3, 4, 29) -C <- c(9, -18, 8) -AB <- B - A -AC <- C - A - -sum(AB^2)^0.5 -#> [1] 24 - -sum(AC^2)^0.5 -#> [1] 23 -``` - -### 3.5.2 マンハッタン距離 - -```{r} -sum(abs(AB)) -#> [1] 24 - -sum(abs(AC)) -#> [1] 31 -``` - -### 3.5.3 コサイン類似度 - -```{r} -sum(A * B) / - sum(A * A)^0.5 / sum(B * B)^0.5 -#> [1] 0.8169679 - -sum(A * C) / - sum(A * A)^0.5 / sum(C * C)^0.5 -#> [1] -0.03265116 -``` - -### 3.5.4 相関係数 - -```{r} -cor(A, B) -#> [1] 0.8824975 - -cor(A, C) -#> [1] -0.03266277 -``` - -#### 3.5.4.1 データフレームを使う方法 - -```{r} -library(tidyverse) - - - -my_df <- data.frame( - x = c(3, 3, 9), - y = c(4, 4, -18), - z = c(5, 29, 8), - row.names = c("A", "B", "C")) - -# ユークリッド距離 -my_df %>% proxy::dist("Euclidean") -#> A B -#> B 24 -#> C 23 31 - - -# マンハッタン距離 -my_df %>% proxy::dist("Manhattan") -#> A B -#> B 24 -#> C 31 49 - - -# コサイン類似度 -my_df %>% proxy::simil("cosine") -#> A B -#> B 0.81696786 -#> C -0.03265116 0.29342441 - - -# 相関係数 -my_df %>% proxy::simil("correlation") -#> A B -#> B 0.88249750 -#> C -0.03266277 0.44124132 -``` - - -## 3.6 Rのパッケージ,Pythonのモジュール - -### 3.6.1 Rのパッケージ - -```{r} -library(tidyverse) -``` - -### 3.6.2 Pythonのモジュール - - -## 3.7 反復処理 - -```{r} -library(tidyverse) -``` - -### 3.7.1 指定した回数→1次元データ - -```{r} -f1 <- function(x) { - tmp <- runif(x) - mean(tmp) -} - -f1(10) # 動作確認 -#> [1] 0.5776604 # 結果の例 -``` - -```{r} -replicate(n = 3, expr = f1(10)) -#> [1] 0.4672766 0.4712016 0.5579449 -``` - -```{r} -rep(x = f1(10), times = 3) -#> [1] 0.481329 0.481329 0.481329 -``` - -### 3.7.2 1次元データ→1次元データ - -```{r} -v <- c(5, 10, 100) -v %>% map_dbl(f1) -#> [1] 0.4857329 0.5322183 0.5084124 -``` - -```{r} -rep(x = 10, times = 3) %>% map_dbl(f1) -# 結果は割愛 -``` - -### 3.7.3 1次元データ→データフレーム - -```{r} -f2 <- function(n) { - tmp <- runif(n) - list(x = n, - p = mean(tmp), - q = sd(tmp)) -} - -f2(10) # 動作確認 -#> $x -#> [1] 10 -#> -#> $p -#> [1] 0.6840032 (平均の例) -#> -#> $q -#> [1] 0.3750788 (標準偏差の例) -``` - -```{r} -v <- c(5, 10, 100) -v %>% map_dfr(f2) -#> x p q -#> -#> 1 5 0.560 0.320 -#> 2 10 0.559 0.271 -#> 3 100 0.507 0.283 -``` - -### 3.7.4 データフレーム→データフレーム - -```{r} -f3 <- function(x, y) { - tmp <- runif(x, min = 1, - max = y + 1) %>% - as.integer - list(x = x, - y = y, - p = mean(tmp), - q = sd(tmp)) -} - -f3(x = 10, y = 6) # 動作確認 -#> $x -#> [1] 10 -#> -#> $y -#> [1] 6 -#> -#> $p -#> [1] 3.2 (平均の例) -#> -#> $q -#> [1] 1.316561 (標準偏差の例) -``` - -```{r} -my_df <- data.frame( - x = c(5, 10, 100, 5, 10, 100), - y = c(6, 6, 6, 12, 12, 12)) - -my_df %>% pmap_dfr(f3) -#> x y p q -#> -#> 1 5 6 3 1.41 -#> 2 10 6 3 1.49 -#> 3 100 6 3.57 1.78 -#> 4 5 12 7.6 5.22 -#> 5 10 12 5.7 3.77 -#> 6 100 12 6.36 3.59 -``` - -### 3.7.5 補足:反復処理の並列化 - -```{r} -library(furrr) -plan(multisession) # 準備 - -v <- c(5, 10, 100) -v %>% future_map_dbl(f1, .options = - furrr_options(seed = TRUE)) -# 結果は割愛 -``` - - -## 3.8 その他 - -### 3.8.1 よく遭遇するエラーとその対処方法 - -### 3.8.2 変数や関数についての調査 - -```{r} -x <- 123 -typeof(x) -#> [1] "double" -``` - -```{r} -?log -# あるいは -help(log) -``` - -### 3.8.3 RのNA,Pythonのnan - -```{r} -v <- c(1, NA, 3) -v -#> [1] 1 NA 3 -``` - -```{r} -is.na(v[2]) -#> [1] TRUE - -v[2] == NA # 誤り -#> [1] NA -``` - - diff --git a/code/Rmd/ch04/04.01.Rmd b/code/Rmd/ch04/04.01.Rmd deleted file mode 100644 index d58d2e7..0000000 --- a/code/Rmd/ch04/04.01.Rmd +++ /dev/null @@ -1,203 +0,0 @@ -## 4.1 記述統計 - -### 4.1.1 平均・分散・標準偏差 - -```{r} -x <- c(165, 170, 175, 180, 185) -mean(x) # 平均 -#> [1] 175 -``` - -```{r} -n <- length(x) # サンプルサイズ -sum(x) / n -#> [1] 175 -``` - -```{r} -y <- c(173, 174, 175, 176, 177) -mean(y) -#> [1] 175 -``` - -```{r} -var(x) # xの分散 -#> [1] 62.5 - -var(y) # yの分散 -#> [1] 2.5 -``` - -```{r} -sum((x - mean(x))^2) / (n - 1) -#> [1] 62.5 -``` - -```{r} -sd(x) # xの標準偏差 -#> [1] 7.905694 - -sd(y) # yの標準偏差 -#> [1] 1.581139 -``` - -```{r} -var(x)**0.5 # xの標準偏差 -#> [1] 7.905694 -``` - -```{r} -psych::describe(x) -#> vars n mean sd ... -#> X1 1 5 175 7.91 ... - -# あるいは - -pastecs::stat.desc(x) -#> nbr.val ... std.dev ... -#> 5.0000000 ... 7.9056942 ... -``` - -```{r} -quantile(x) -#> 0% 25% 50% 75% 100% -#> 165 170 175 180 185 -``` - -#### 4.1.1.1 不偏分散とその非負の平方根 - -```{r} -x <- c(165, 170, 175, 180, 185) - -var(x) # 不偏分散 -#> [1] 62.5 - -mean((x - mean(x))^2) # 標本分散 -# あるいは -n <- length(x) -var(x) * (n - 1) / n # 標本分散 -#> [1] 50 -``` - -```{r} -sd(x) # √不偏分散 -#> [1] 7.905694 - -mean((x - mean(x))^2)^0.5 # √標本分散 -# あるいは -sd(x) * sqrt((n - 1) / n) # √標本分散 -#> [1] 7.071068 -``` - -```{r} -sd(x) / length(x)**0.5 -#> [1] 3.535534 -``` - -### 4.1.2 データフレームの統計処理 - -```{r} -library(tidyverse) - -my_df <- data.frame( - name = c("A", "B", "C", "D"), - english = c( 60, 90, 70, 90), - math = c( 70, 80, 90, 100), - gender = c("f", "m", "m", "f")) -``` - -#### 4.1.2.1 列ごとの集計 - -```{r} -var(my_df$english) -#> [1] 225 -``` - -```{r} -# 結果はベクタ -my_df[, c(2, 3)] %>% sapply(var) -#> english math -#> 225.0000 166.6667 - -# 結果はリスト -my_df[, c(2, 3)] %>% lapply(var) -#> $english -#> [1] 225 -#> -#> $math -#> [1] 166.6667 - -# 結果はデータフレーム -my_df[, c(2, 3)] %>% # 2, 3列目 - summarize(across( # の - everything(), # 全ての - var)) # 不偏分散 -# あるいは -my_df %>% # データフレーム - summarize(across( # の - where(is.numeric), # 数値の列の - var)) # 不偏分散 -# あるいは -my_df %>% # データフレーム - summarize(across( # の - where(is.numeric), # 数値の列の - function(x) { var(x) })) # 不偏分散 - -#> english math -#> 1 225 166.6667 -``` - -```{r} -psych::describe(my_df) -#> vars n mean sd ... -#> name* 1 4 2.5 1.29 ... -#> english 2 4 77.5 15.00 ... -#> math 3 4 85.0 12.91 ... -#> gender* 4 4 1.5 0.58 ... - -# あるいは - -pastecs::stat.desc(my_df) -#> name english ... -#> nbr.val NA 4.0000000 ... -#> nbr.null NA 0.0000000 ... -#> nbr.na NA 0.0000000 ... -#> min NA 60.0000000 ... -#> max NA 90.0000000 ... -# 以下省略 -``` - -#### 4.1.2.2 分割表とグループごとの集計 - -```{r} -table(my_df$gender) - -#> f m -#> 2 2 -``` - -```{r} -my_df2 <- data.frame( - gender = my_df$gender, - excel = my_df$math >= 80) -table(my_df2) - -#> excel -#> gender FALSE TRUE -#> f 1 1 -#> m 0 2 -``` - -```{r} -my_df %>% group_by(gender) %>% - summarize(across( - where(is.numeric), mean), - .groups = "drop") # グループ化解除 - -#> # A tibble: 2 x 3 -#> gender english math -#> -#> 1 f 75 85 -#> 2 m 80 85 -``` - diff --git a/code/Rmd/ch04/04.02.Rmd b/code/Rmd/ch04/04.02.Rmd deleted file mode 100644 index bdb95ba..0000000 --- a/code/Rmd/ch04/04.02.Rmd +++ /dev/null @@ -1,189 +0,0 @@ -## 4.2 データの可視化 - -```{r} -head(iris) -#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species -#> 1 5.1 3.5 1.4 0.2 setosa -#> 2 4.9 3.0 1.4 0.2 setosa -#> 3 4.7 3.2 1.3 0.2 setosa -#> 4 4.6 3.1 1.5 0.2 setosa -#> 5 5.0 3.6 1.4 0.2 setosa -#> 6 5.4 3.9 1.7 0.4 setosa -``` - -### 4.2.1 ヒストグラム - -```{r} -hist(iris$Sepal.Length) -``` - -```{r} -x <- c(10, 20, 30) -hist(x, breaks = 2) # 階級数は2 -``` - -```{r} -x <- iris$Sepal.Length -tmp <- seq(min(x), max(x), - length.out = 10) -hist(x, breaks = tmp, right = FALSE) -``` - -### 4.2.2 散布図 - -```{r} -plot(iris$Sepal.Length, - iris$Sepal.Width) -``` - -### 4.2.3 箱ひげ図 - -```{r} -boxplot(iris[, -5]) -``` - -### 4.2.4 棒グラフとエラーバー - -```{r} -library(tidyverse) -my_df <- psych::describe(iris[, -5]) -my_df %>% select(mean, sd, se) -#> mean sd se -#> Sepal.Length 5.84 0.83 0.07 -#> Sepal.Width 3.06 0.44 0.04 -#> Petal.Length 3.76 1.77 0.14 -#> Petal.Width 1.20 0.76 0.06 -``` - -```{r} -tmp <- rownames(my_df) -my_df %>% ggplot(aes(x = factor(tmp, levels = tmp), y = mean)) + - geom_col() + - geom_errorbar(aes(ymin = mean - se, ymax = mean + se)) + - xlab(NULL) -``` - -```{r} -my_group <- iris %>% group_by(Species) # 品種ごとに, - -my_df <- my_group %>% # 各変数の,平均と - summarize(across(everything(), mean)) %>% - pivot_longer(-Species) - -tmp <- my_group %>% # 標準誤差を求める. - summarize(across(everything(), ~ sd(.) / length(.)**0.5)) %>% - pivot_longer(-Species) - -my_df$se <- tmp$value -head(my_df) -#> # A tibble: 6 x 4 -#> Species name value se -#> -#> 1 setosa Sepal.Length 5.01 0.0498 -#> 2 setosa Sepal.Width 3.43 0.0536 -#> 3 setosa Petal.Length 1.46 0.0246 -#> 4 setosa Petal.Width 0.246 0.0149 -#> 5 versicolor Sepal.Length 5.94 0.0730 -#> 6 versicolor Sepal.Width 2.77 0.0444 -``` - -```{r} -my_df %>% - ggplot(aes(x = Species, y = value, fill = name)) + - geom_col(position = "dodge") + - geom_errorbar(aes(ymin = value - se, ymax = value + se), position = "dodge") -``` - -```{r} -# 各変数の平均 -iris %>% pivot_longer(-Species) %>% - ggplot(aes(x = name, y = value)) + - geom_bar(stat = "summary", fun = mean) + - stat_summary(geom = "errorbar", fun.data = mean_se) + - xlab(NULL) - -# 各変数の平均(品種ごと) -iris %>% pivot_longer(-Species) %>% - ggplot(aes(x = Species, y = value, fill = name)) + - geom_bar(stat = "summary", fun = mean, position = "dodge") + - stat_summary(geom = "errorbar", fun.data = mean_se, position = "dodge") -``` - -### 4.2.5 モザイクプロット - -```{r} -my_df <- data.frame( - Species = iris$Species, - w_Sepal = iris$Sepal.Width > 3) -table(my_df) # 分割表 -#> w_Sepal -#> Species FALSE TRUE -#> setosa 8 42 -#> versicolor 42 8 -#> virginica 33 17 - -mosaicplot( - formula = ~ Species + w_Sepal, - data = my_df) -``` - -```{r} -library(vcd) -vcd::mosaic(formula = ~w_Sepal + Species, data = my_df, - labeling = labeling_values) -``` - -### 4.2.6 関数のグラフ - -```{r} -curve(x^3 - x, -2, 2) -``` - -### 4.2.7 ggplot2 (R) - -```{r} -x <- iris$Sepal.Length -tmp <- seq(min(x), max(x), - length.out = 10) -iris %>% - ggplot(aes(x = Sepal.Length)) + - geom_histogram(breaks = tmp, - closed = "left") -``` - -```{r} -iris %>% - ggplot(aes(x = Sepal.Length, - y = Sepal.Width)) + - geom_point() -``` - -```{r} -iris %>% - pivot_longer(-Species) %>% - ggplot(aes( - x = factor(name, - levels = names(iris)), - y = value)) + - geom_boxplot() + - xlab(NULL) -``` - -```{r} -library(ggmosaic) -my_df <- data.frame( - Species = iris$Species, - w_Sepal = iris$Sepal.Width > 3) -my_df %>% - ggplot() + - geom_mosaic( - aes(x = product(w_Sepal, Species))) -``` - -```{r} -f <- function(x) { x^3 - x } -data.frame(x = c(-2, 2)) %>% - ggplot(aes(x = x)) + - stat_function(fun = f) -``` - diff --git a/code/Rmd/ch04/04.03.Rmd b/code/Rmd/ch04/04.03.Rmd deleted file mode 100644 index c3f9a9a..0000000 --- a/code/Rmd/ch04/04.03.Rmd +++ /dev/null @@ -1,103 +0,0 @@ -## 4.3 乱数 - -### 4.3.1 一様乱数(離散) - -```{r} -x <- sample(x = 1:6, # 範囲 - size = 10000, # 乱数の数 - replace = TRUE) # 重複あり -hist(x, breaks = 0:6) # ヒストグラム -``` - -### 4.3.2 一様乱数(連続) - -```{r} -x <- runif(min = 0, # 最小 - max = 1, # 最大 - n = 1000) # 乱数の数 -hist(x) -``` - -```{r} -x <- as.integer( # 整数に変換 - runif(min = 1, # 最小 - max = 7, # 最大 + 1 - n = 1000)) # 乱数の数 -hist(x, breaks = 0:6) # 結果は割愛 -``` - -### 4.3.3 二項乱数 - -```{r} -n <- 100 -p <- 0.5 -r <- 10000 -x <- rbinom(size = n, # 試行回数 - prob = p, # 確率 - n = r) # 乱数の数 -hist(x, breaks = max(x) - min(x)) -``` - -### 4.3.4 正規乱数 - -```{r} -r <- 10000 -x <- rnorm(mean = 50, # 平均 - sd = 5, # 標準偏差 - n = r) # 乱数の数 -hist(x, breaks = 40) -``` - -#### 4.3.4.1 補足:不偏性の具体例 - -```{r} -library(tidyverse) - -f <- function(k) { - n <- 10000 - tmp <- replicate(n = n, expr = g(rnorm(n = k, sd = 3))) - list(k = k, - mean = mean(tmp), # 平均 - se = sd(tmp) / sqrt(n)) # 標準誤差 -} -``` - -```{r} -g <- var -c(10, 20, 30) %>% map_dfr(f) -#> # A tibble: 3 x 3 -#> k mean se -#> -#> 1 10 8.98 0.0427 -#> 2 20 8.97 0.0288 -#> 3 30 9.03 0.0233 -``` - -```{r} -g <- sd -c(5, 10, 15, 20) %>% map_dfr(f) -#> # A tibble: 3 x 3 -#> k mean se -#> -#> 1 10 2.92 0.00701 -#> 2 20 2.95 0.00481 -#> 3 30 2.97 0.00394 -``` - -```{r} -g <- function(x) { - n <- length(x) - sd(x) * - sqrt((n - 1) / 2) * - gamma((n - 1) / 2) / - gamma(n / 2) -} -c(10, 20, 30) %>% map_dfr(f) -#> # A tibble: 3 x 3 -#> k mean se -#> -#> 1 10 3.00 0.00717 -#> 2 20 2.99 0.00488 -#> 3 30 3.00 0.00396 -``` - diff --git a/code/Rmd/ch04/04.04.Rmd b/code/Rmd/ch04/04.04.Rmd deleted file mode 100644 index 51b2ff1..0000000 --- a/code/Rmd/ch04/04.04.Rmd +++ /dev/null @@ -1,178 +0,0 @@ -## 4.4 統計的推測 - -### 4.4.1 検定 - -```{r} -library(exactci) -library(tidyverse) - -a <- 0.05 # 有意水準 -binom.exact(x = 2, # 当たった回数 - n = 15, # くじを引いた回数 - p = 4 / 10, # 当たる確率(仮説) - plot = TRUE, # p値の描画(結果は次項に掲載) - conf.level = 1 - a, # 信頼係数(デフォルト) - tsmethod = "minlike", # p値の定義 - alternative = "two.sided") # 両側検定(デフォルト) - # 左片側検定なら'less' - # 右片側検定なら'greater' - -#> Exact two-sided binomial test (central method) -#> -#> data: 2 and 15 -#> number of successes = 2, number of trials = 15, -#> p-value = 0.03646 -#> alternative hypothesis: true probability of success is not equal to 0.4 -#> 95 percent confidence interval: -#> 0.0242 0.3967 -#> sample estimates: -#> probability of success -#> 0.1333333 -``` - -#### 4.4.1.1 補足:p値とは何か - -```{r} -t <- 4 / 10 # 当たる確率 -n <- 15 # くじを引いた回数 -x <- 0:n # 当たった回数 -my_pr <- dbinom(x, n, t) # x回当たる確率 -my_pr2 <- dbinom(2, n, t) # 2回当たる確率 - -my_data <- data.frame(x = x, - probability = my_pr, - color = my_pr <= my_pr2) # 当たる確率が,2回当たる確率以下 - -my_data %>% ggplot(aes(x = x, y = probability, color = color)) + - geom_point(size = 3) + - geom_linerange(aes(ymin = 0, ymax = probability), ) + # 垂直線 - geom_hline(yintercept = my_pr2) + # 水平線 - theme(legend.position = "none") # 凡例を表示しない. -``` - -### 4.4.2 推定 - -```{r} -# 前項の結果(再掲) -#> 95 percent confidence interval: -#> 0.0242 0.3967 -``` - -```{r} -# 前項冒頭のコード -``` - -### 4.4.3 平均の差の検定と推定(t検定) - -```{r} -X <- c(32.1, 26.2, 27.5, 31.8, 32.1, 31.2, 30.1, 32.4, 32.3, 29.9, - 29.6, 26.6, 31.2, 30.9, 29.3) -Y <- c(35.4, 34.6, 31.1, 32.4, 33.3, 34.7, 35.3, 34.3, 32.1, 28.3, - 33.3, 30.5, 32.6, 33.3, 32.2) - -t.test(x = X, y = Y, - conf.level = 0.95, # 信頼係数(デフォルト) - paired = TRUE, # 対標本である. - alternative = "two.sided") # 両側検定(デフォルト) - # 左片側検定なら'less' - # 右片側検定なら'greater' - -#> Paired t-test -#> -#> data: X and Y -#> t = -4.3694, df = 14, p-value = 0.0006416 -#> alternative hypothesis: true difference in means is not equal to 0 -#> 95 percent confidence interval: -#> -3.995525 -1.364475 -#> sample estimates: -#> mean of the differences -#> -2.68 -``` - -```{r} -t.test(x = X, y = Y, - paired = FALSE, # 対標本ではない(デフォルト). - var.equal = TRUE, # 等分散を仮定する.仮定しないならFALSE(デフォルト). - alternative = "two.sided", - conf.level = 0.95) - -#> Two Sample t-test -#> -#> data: X and Y -#> t = -3.6821, df = 28, p-value = 0.0009785 -#> alternative hypothesis: true difference in means is not equal to 0 -#> 95 percent confidence interval: -#> -4.170906 -1.189094 -#> sample estimates: -#> mean of x mean of y -#> 30.21333 32.89333 -``` - -### 4.4.4 独立性の検定(カイ2乗検定) - -```{r} -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/smoker.csv") -my_data <- read_csv(my_url) -``` - -```{r} -head(my_data) -#> alive smoker -#> 1 Yes No -#> 2 Yes No -#> 3 Yes No -#> 4 Yes No -#> 5 Yes No -#> 6 Yes No -``` - -```{r} -my_table <- table(my_data) -my_table -#> smoker -#> alive No Yes -#> No 117 54 -#> Yes 950 348 -``` - -```{r} -chisq.test(my_table, correct = FALSE) - -#> Pearson's Chi-squared test -#> -#> data: my_data -#> X-squared = 1.7285, df = 1, p-value = 0.1886 -``` - -### 4.4.5 ブートストラップ - -#### 4.4.5.1 15回引いて2回当たったくじ - -```{r} -X <- rep(0:1, c(13, 2)) # 手順1 -X -#> [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 - -tmp <- sample(X, size = length(X), replace = TRUE) # 手順2 -tmp -#> [1] 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 - -sum(tmp) # 手順3 -#> [1] 2 - -n <- 10^5 -result <- replicate(n, sum(sample(X, size = length(X), replace = TRUE))) # 手順4 -``` - -```{r} -hist(x = result, breaks = 0:15, - right = FALSE) -``` - -```{r} -quantile(result, c(0.025, 0.975)) -#> 2.5% 97.5% -#> 0 5 -``` - diff --git a/code/Rmd/ch04/04.Rmd b/code/Rmd/ch04/04.Rmd deleted file mode 100644 index aa29e0f..0000000 --- a/code/Rmd/ch04/04.Rmd +++ /dev/null @@ -1,677 +0,0 @@ -## 4.1 記述統計 - -### 4.1.1 平均・分散・標準偏差 - -```{r} -x <- c(165, 170, 175, 180, 185) -mean(x) # 平均 -#> [1] 175 -``` - -```{r} -n <- length(x) # サンプルサイズ -sum(x) / n -#> [1] 175 -``` - -```{r} -y <- c(173, 174, 175, 176, 177) -mean(y) -#> [1] 175 -``` - -```{r} -var(x) # xの分散 -#> [1] 62.5 - -var(y) # yの分散 -#> [1] 2.5 -``` - -```{r} -sum((x - mean(x))^2) / (n - 1) -#> [1] 62.5 -``` - -```{r} -sd(x) # xの標準偏差 -#> [1] 7.905694 - -sd(y) # yの標準偏差 -#> [1] 1.581139 -``` - -```{r} -var(x)**0.5 # xの標準偏差 -#> [1] 7.905694 -``` - -```{r} -psych::describe(x) -#> vars n mean sd ... -#> X1 1 5 175 7.91 ... - -# あるいは - -pastecs::stat.desc(x) -#> nbr.val ... std.dev ... -#> 5.0000000 ... 7.9056942 ... -``` - -```{r} -quantile(x) -#> 0% 25% 50% 75% 100% -#> 165 170 175 180 185 -``` - -#### 4.1.1.1 不偏分散とその非負の平方根 - -```{r} -x <- c(165, 170, 175, 180, 185) - -var(x) # 不偏分散 -#> [1] 62.5 - -mean((x - mean(x))^2) # 標本分散 -# あるいは -n <- length(x) -var(x) * (n - 1) / n # 標本分散 -#> [1] 50 -``` - -```{r} -sd(x) # √不偏分散 -#> [1] 7.905694 - -mean((x - mean(x))^2)^0.5 # √標本分散 -# あるいは -sd(x) * sqrt((n - 1) / n) # √標本分散 -#> [1] 7.071068 -``` - -```{r} -sd(x) / length(x)**0.5 -#> [1] 3.535534 -``` - -### 4.1.2 データフレームの統計処理 - -```{r} -library(tidyverse) - -my_df <- data.frame( - name = c("A", "B", "C", "D"), - english = c( 60, 90, 70, 90), - math = c( 70, 80, 90, 100), - gender = c("f", "m", "m", "f")) -``` - -#### 4.1.2.1 列ごとの集計 - -```{r} -var(my_df$english) -#> [1] 225 -``` - -```{r} -# 結果はベクタ -my_df[, c(2, 3)] %>% sapply(var) -#> english math -#> 225.0000 166.6667 - -# 結果はリスト -my_df[, c(2, 3)] %>% lapply(var) -#> $english -#> [1] 225 -#> -#> $math -#> [1] 166.6667 - -# 結果はデータフレーム -my_df[, c(2, 3)] %>% # 2, 3列目 - summarize(across( # の - everything(), # 全ての - var)) # 不偏分散 -# あるいは -my_df %>% # データフレーム - summarize(across( # の - where(is.numeric), # 数値の列の - var)) # 不偏分散 -# あるいは -my_df %>% # データフレーム - summarize(across( # の - where(is.numeric), # 数値の列の - function(x) { var(x) })) # 不偏分散 - -#> english math -#> 1 225 166.6667 -``` - -```{r} -psych::describe(my_df) -#> vars n mean sd ... -#> name* 1 4 2.5 1.29 ... -#> english 2 4 77.5 15.00 ... -#> math 3 4 85.0 12.91 ... -#> gender* 4 4 1.5 0.58 ... - -# あるいは - -pastecs::stat.desc(my_df) -#> name english ... -#> nbr.val NA 4.0000000 ... -#> nbr.null NA 0.0000000 ... -#> nbr.na NA 0.0000000 ... -#> min NA 60.0000000 ... -#> max NA 90.0000000 ... -# 以下省略 -``` - -#### 4.1.2.2 分割表とグループごとの集計 - -```{r} -table(my_df$gender) - -#> f m -#> 2 2 -``` - -```{r} -my_df2 <- data.frame( - gender = my_df$gender, - excel = my_df$math >= 80) -table(my_df2) - -#> excel -#> gender FALSE TRUE -#> f 1 1 -#> m 0 2 -``` - -```{r} -my_df %>% group_by(gender) %>% - summarize(across( - where(is.numeric), mean), - .groups = "drop") # グループ化解除 - -#> # A tibble: 2 x 3 -#> gender english math -#> -#> 1 f 75 85 -#> 2 m 80 85 -``` - - -## 4.2 データの可視化 - -```{r} -head(iris) -#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species -#> 1 5.1 3.5 1.4 0.2 setosa -#> 2 4.9 3.0 1.4 0.2 setosa -#> 3 4.7 3.2 1.3 0.2 setosa -#> 4 4.6 3.1 1.5 0.2 setosa -#> 5 5.0 3.6 1.4 0.2 setosa -#> 6 5.4 3.9 1.7 0.4 setosa -``` - -### 4.2.1 ヒストグラム - -```{r} -hist(iris$Sepal.Length) -``` - -```{r} -x <- c(10, 20, 30) -hist(x, breaks = 2) # 階級数は2 -``` - -```{r} -x <- iris$Sepal.Length -tmp <- seq(min(x), max(x), - length.out = 10) -hist(x, breaks = tmp, right = FALSE) -``` - -### 4.2.2 散布図 - -```{r} -plot(iris$Sepal.Length, - iris$Sepal.Width) -``` - -### 4.2.3 箱ひげ図 - -```{r} -boxplot(iris[, -5]) -``` - -### 4.2.4 棒グラフとエラーバー - -```{r} -library(tidyverse) -my_df <- psych::describe(iris[, -5]) -my_df %>% select(mean, sd, se) -#> mean sd se -#> Sepal.Length 5.84 0.83 0.07 -#> Sepal.Width 3.06 0.44 0.04 -#> Petal.Length 3.76 1.77 0.14 -#> Petal.Width 1.20 0.76 0.06 -``` - -```{r} -tmp <- rownames(my_df) -my_df %>% ggplot(aes(x = factor(tmp, levels = tmp), y = mean)) + - geom_col() + - geom_errorbar(aes(ymin = mean - se, ymax = mean + se)) + - xlab(NULL) -``` - -```{r} -my_group <- iris %>% group_by(Species) # 品種ごとに, - -my_df <- my_group %>% # 各変数の,平均と - summarize(across(everything(), mean)) %>% - pivot_longer(-Species) - -tmp <- my_group %>% # 標準誤差を求める. - summarize(across(everything(), ~ sd(.) / length(.)**0.5)) %>% - pivot_longer(-Species) - -my_df$se <- tmp$value -head(my_df) -#> # A tibble: 6 x 4 -#> Species name value se -#> -#> 1 setosa Sepal.Length 5.01 0.0498 -#> 2 setosa Sepal.Width 3.43 0.0536 -#> 3 setosa Petal.Length 1.46 0.0246 -#> 4 setosa Petal.Width 0.246 0.0149 -#> 5 versicolor Sepal.Length 5.94 0.0730 -#> 6 versicolor Sepal.Width 2.77 0.0444 -``` - -```{r} -my_df %>% - ggplot(aes(x = Species, y = value, fill = name)) + - geom_col(position = "dodge") + - geom_errorbar(aes(ymin = value - se, ymax = value + se), position = "dodge") -``` - -```{r} -# 各変数の平均 -iris %>% pivot_longer(-Species) %>% - ggplot(aes(x = name, y = value)) + - geom_bar(stat = "summary", fun = mean) + - stat_summary(geom = "errorbar", fun.data = mean_se) + - xlab(NULL) - -# 各変数の平均(品種ごと) -iris %>% pivot_longer(-Species) %>% - ggplot(aes(x = Species, y = value, fill = name)) + - geom_bar(stat = "summary", fun = mean, position = "dodge") + - stat_summary(geom = "errorbar", fun.data = mean_se, position = "dodge") -``` - -### 4.2.5 モザイクプロット - -```{r} -my_df <- data.frame( - Species = iris$Species, - w_Sepal = iris$Sepal.Width > 3) -table(my_df) # 分割表 -#> w_Sepal -#> Species FALSE TRUE -#> setosa 8 42 -#> versicolor 42 8 -#> virginica 33 17 - -mosaicplot( - formula = ~ Species + w_Sepal, - data = my_df) -``` - -```{r} -library(vcd) -vcd::mosaic(formula = ~w_Sepal + Species, data = my_df, - labeling = labeling_values) -``` - -### 4.2.6 関数のグラフ - -```{r} -curve(x^3 - x, -2, 2) -``` - -### 4.2.7 ggplot2 (R) - -```{r} -x <- iris$Sepal.Length -tmp <- seq(min(x), max(x), - length.out = 10) -iris %>% - ggplot(aes(x = Sepal.Length)) + - geom_histogram(breaks = tmp, - closed = "left") -``` - -```{r} -iris %>% - ggplot(aes(x = Sepal.Length, - y = Sepal.Width)) + - geom_point() -``` - -```{r} -iris %>% - pivot_longer(-Species) %>% - ggplot(aes( - x = factor(name, - levels = names(iris)), - y = value)) + - geom_boxplot() + - xlab(NULL) -``` - -```{r} -library(ggmosaic) -my_df <- data.frame( - Species = iris$Species, - w_Sepal = iris$Sepal.Width > 3) -my_df %>% - ggplot() + - geom_mosaic( - aes(x = product(w_Sepal, Species))) -``` - -```{r} -f <- function(x) { x^3 - x } -data.frame(x = c(-2, 2)) %>% - ggplot(aes(x = x)) + - stat_function(fun = f) -``` - - -## 4.3 乱数 - -### 4.3.1 一様乱数(離散) - -```{r} -x <- sample(x = 1:6, # 範囲 - size = 10000, # 乱数の数 - replace = TRUE) # 重複あり -hist(x, breaks = 0:6) # ヒストグラム -``` - -### 4.3.2 一様乱数(連続) - -```{r} -x <- runif(min = 0, # 最小 - max = 1, # 最大 - n = 1000) # 乱数の数 -hist(x) -``` - -```{r} -x <- as.integer( # 整数に変換 - runif(min = 1, # 最小 - max = 7, # 最大 + 1 - n = 1000)) # 乱数の数 -hist(x, breaks = 0:6) # 結果は割愛 -``` - -### 4.3.3 二項乱数 - -```{r} -n <- 100 -p <- 0.5 -r <- 10000 -x <- rbinom(size = n, # 試行回数 - prob = p, # 確率 - n = r) # 乱数の数 -hist(x, breaks = max(x) - min(x)) -``` - -### 4.3.4 正規乱数 - -```{r} -r <- 10000 -x <- rnorm(mean = 50, # 平均 - sd = 5, # 標準偏差 - n = r) # 乱数の数 -hist(x, breaks = 40) -``` - -#### 4.3.4.1 補足:不偏性の具体例 - -```{r} -library(tidyverse) - -f <- function(k) { - n <- 10000 - tmp <- replicate(n = n, expr = g(rnorm(n = k, sd = 3))) - list(k = k, - mean = mean(tmp), # 平均 - se = sd(tmp) / sqrt(n)) # 標準誤差 -} -``` - -```{r} -g <- var -c(10, 20, 30) %>% map_dfr(f) -#> # A tibble: 3 x 3 -#> k mean se -#> -#> 1 10 8.98 0.0427 -#> 2 20 8.97 0.0288 -#> 3 30 9.03 0.0233 -``` - -```{r} -g <- sd -c(5, 10, 15, 20) %>% map_dfr(f) -#> # A tibble: 3 x 3 -#> k mean se -#> -#> 1 10 2.92 0.00701 -#> 2 20 2.95 0.00481 -#> 3 30 2.97 0.00394 -``` - -```{r} -g <- function(x) { - n <- length(x) - sd(x) * - sqrt((n - 1) / 2) * - gamma((n - 1) / 2) / - gamma(n / 2) -} -c(10, 20, 30) %>% map_dfr(f) -#> # A tibble: 3 x 3 -#> k mean se -#> -#> 1 10 3.00 0.00717 -#> 2 20 2.99 0.00488 -#> 3 30 3.00 0.00396 -``` - - -## 4.4 統計的推測 - -### 4.4.1 検定 - -```{r} -library(exactci) -library(tidyverse) - -a <- 0.05 # 有意水準 -binom.exact(x = 2, # 当たった回数 - n = 15, # くじを引いた回数 - p = 4 / 10, # 当たる確率(仮説) - plot = TRUE, # p値の描画(結果は次項に掲載) - conf.level = 1 - a, # 信頼係数(デフォルト) - tsmethod = "minlike", # p値の定義 - alternative = "two.sided") # 両側検定(デフォルト) - # 左片側検定なら'less' - # 右片側検定なら'greater' - -#> Exact two-sided binomial test (central method) -#> -#> data: 2 and 15 -#> number of successes = 2, number of trials = 15, -#> p-value = 0.03646 -#> alternative hypothesis: true probability of success is not equal to 0.4 -#> 95 percent confidence interval: -#> 0.0242 0.3967 -#> sample estimates: -#> probability of success -#> 0.1333333 -``` - -#### 4.4.1.1 補足:p値とは何か - -```{r} -t <- 4 / 10 # 当たる確率 -n <- 15 # くじを引いた回数 -x <- 0:n # 当たった回数 -my_pr <- dbinom(x, n, t) # x回当たる確率 -my_pr2 <- dbinom(2, n, t) # 2回当たる確率 - -my_data <- data.frame(x = x, - probability = my_pr, - color = my_pr <= my_pr2) # 当たる確率が,2回当たる確率以下 - -my_data %>% ggplot(aes(x = x, y = probability, color = color)) + - geom_point(size = 3) + - geom_linerange(aes(ymin = 0, ymax = probability), ) + # 垂直線 - geom_hline(yintercept = my_pr2) + # 水平線 - theme(legend.position = "none") # 凡例を表示しない. -``` - -### 4.4.2 推定 - -```{r} -# 前項の結果(再掲) -#> 95 percent confidence interval: -#> 0.0242 0.3967 -``` - -```{r} -# 前項冒頭のコード -``` - -### 4.4.3 平均の差の検定と推定(t検定) - -```{r} -X <- c(32.1, 26.2, 27.5, 31.8, 32.1, 31.2, 30.1, 32.4, 32.3, 29.9, - 29.6, 26.6, 31.2, 30.9, 29.3) -Y <- c(35.4, 34.6, 31.1, 32.4, 33.3, 34.7, 35.3, 34.3, 32.1, 28.3, - 33.3, 30.5, 32.6, 33.3, 32.2) - -t.test(x = X, y = Y, - conf.level = 0.95, # 信頼係数(デフォルト) - paired = TRUE, # 対標本である. - alternative = "two.sided") # 両側検定(デフォルト) - # 左片側検定なら'less' - # 右片側検定なら'greater' - -#> Paired t-test -#> -#> data: X and Y -#> t = -4.3694, df = 14, p-value = 0.0006416 -#> alternative hypothesis: true difference in means is not equal to 0 -#> 95 percent confidence interval: -#> -3.995525 -1.364475 -#> sample estimates: -#> mean of the differences -#> -2.68 -``` - -```{r} -t.test(x = X, y = Y, - paired = FALSE, # 対標本ではない(デフォルト). - var.equal = TRUE, # 等分散を仮定する.仮定しないならFALSE(デフォルト). - alternative = "two.sided", - conf.level = 0.95) - -#> Two Sample t-test -#> -#> data: X and Y -#> t = -3.6821, df = 28, p-value = 0.0009785 -#> alternative hypothesis: true difference in means is not equal to 0 -#> 95 percent confidence interval: -#> -4.170906 -1.189094 -#> sample estimates: -#> mean of x mean of y -#> 30.21333 32.89333 -``` - -### 4.4.4 独立性の検定(カイ2乗検定) - -```{r} -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/smoker.csv") -my_data <- read_csv(my_url) -``` - -```{r} -head(my_data) -#> alive smoker -#> 1 Yes No -#> 2 Yes No -#> 3 Yes No -#> 4 Yes No -#> 5 Yes No -#> 6 Yes No -``` - -```{r} -my_table <- table(my_data) -my_table -#> smoker -#> alive No Yes -#> No 117 54 -#> Yes 950 348 -``` - -```{r} -chisq.test(my_table, correct = FALSE) - -#> Pearson's Chi-squared test -#> -#> data: my_data -#> X-squared = 1.7285, df = 1, p-value = 0.1886 -``` - -### 4.4.5 ブートストラップ - -#### 4.4.5.1 15回引いて2回当たったくじ - -```{r} -X <- rep(0:1, c(13, 2)) # 手順1 -X -#> [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 - -tmp <- sample(X, size = length(X), replace = TRUE) # 手順2 -tmp -#> [1] 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 - -sum(tmp) # 手順3 -#> [1] 2 - -n <- 10^5 -result <- replicate(n, sum(sample(X, size = length(X), replace = TRUE))) # 手順4 -``` - -```{r} -hist(x = result, breaks = 0:15, - right = FALSE) -``` - -```{r} -quantile(result, c(0.025, 0.975)) -#> 2.5% 97.5% -#> 0 5 -``` - - diff --git a/code/Rmd/ch05/05.01.Rmd b/code/Rmd/ch05/05.01.Rmd deleted file mode 100644 index 084d5a0..0000000 --- a/code/Rmd/ch05/05.01.Rmd +++ /dev/null @@ -1,179 +0,0 @@ -## 5.1 データの読み込み - -### 5.1.1 CSV - -```{r} -library(tidyverse) -system(str_c("wget https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/exam.csv")) -``` - -#### 5.1.1.1 CSVの読み込み - -```{r} -my_df <- read_csv("exam.csv") -# あるいは -my_df <- read.csv("exam.csv", - stringsAsFactors = FALSE) - -my_df -#> name english math gender -#> 1 A 60 70 f -#> 2 B 90 80 m -#> 3 C 70 90 m -#> 4 D 90 100 f -``` - -```{r} -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/exam.csv") -my_df <- read_csv(my_url) -# あるいは -my_df <- read.csv(my_url, stringsAsFactors = FALSE) -``` - -```{r} -my_df2 <- read.csv( - file = "exam.csv", - stringsAsFactors = FALSE, - row.names = 1) -my_df2 -#> english math gender -#> A 60 70 f -#> B 90 80 m -#> C 70 90 m -#> D 90 100 f -``` - -#### 5.1.1.2 CSVファイルへの書き出し - -```{r} -my_df %>% write_csv("exam2.csv") -# あるいは -my_df %>% write.csv( - file = "exam2.csv", - row.names = FALSE) -``` - -```{r} -my_df2 %>% write.csv("exam3.csv") -``` - -### 5.1.2 文字コード - -```{r} -my_df <- read_csv(file = "exam.csv", - locale = locale(encoding = "UTF-8")) -# あるいは -my_df <- read.csv(file = "exam.csv", - stringsAsFactors = FALSE, - fileEncoding = "UTF-8") -``` - -```{r} -my_df %>% write_csv("exam2.csv") -# あるいは -my_df %>% write.csv(file = "exam2.csv", row.names = FALSE, - fileEncoding = "UTF-8") -``` - -### 5.1.3 ウェブ上の表 - -```{r} -my_url <- "https://taroyabuki.github.io/fromzero/exam.html" -my_tables <- xml2::read_html(my_url) %>% rvest::html_table() -``` - -```{r} -my_tables -#> [[1]] -#> X1 X2 X3 X4 X5 -#> 1 NA name english math gender -#> 2 NA A 60 70 f -#> 3 NA B 90 80 m -#> 4 NA C 70 90 m -#> 5 NA D 90 100 f -``` - -```{r} -tmp <- my_tables[[1]] -tmp -#> X1 X2 X3 X4 X5 -#> 1 NA name english math gender -#> 2 NA A 60 70 f -#> 3 NA B 90 80 m -#> 4 NA C 70 90 m -#> 5 NA D 90 100 f -``` - -```{r} -# 1行目のデータを使って列の名前を付け直す. -colnames(tmp) <- tmp[1, ] - -# 1行目と1列目を削除する. -my_data <- tmp[-1, -1] -my_data -#> name english math gender -#> 2 A 60 70 f -#> 3 B 90 80 m -#> 4 C 70 90 m -#> 5 D 90 100 f -``` - -### 5.1.4 JSONとXML - -#### 5.1.4.1 JSONデータの読み込み - -```{r} -library(jsonlite) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/exam.json") -my_data <- fromJSON(my_url) -#my_data <- fromJSON("exam.json") # (ファイルを使う場合) -my_data -#> name english math gender -#> 1 A 60 70 f -#> 2 B 90 80 m -#> 3 C 70 90 m -#> 4 D 90 100 f -``` - -#### 5.1.4.2 XMLデータの読み込み - -```{r} -library(xml2) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/exam.xml") -my_xml <- read_xml(my_url) # XMLデータの読み込み -#my_xml <- read_xml("exam.xml") # (ファイルを使う場合) -xml_ns(my_xml) # 名前空間の確認(d1) -#> d1 <-> https://www.example.net/ns/1.0 -``` - -```{r} -my_records <- xml_find_all(my_xml, ".//d1:record") -``` - -```{r} -f <- function(record) { - tmp <- xml_attrs(record) # 属性を全て取り出し, - xml_children(record) %>% walk(function(e) { - tmp[xml_name(e)] <<- xml_text(e) # 子要素の名前と内容を追加する. - }) - tmp -} -``` - -```{r} -my_data <- my_records %>% map_dfr(f) -my_data$english <- as.numeric(my_data$english) -my_data$math <- as.numeric(my_data$math) -my_data -#> english math gender name -#> -#> 1 60 70 f A -#> 2 90 80 m B -#> 3 70 90 m C -#> 4 90 100 f D -``` - diff --git a/code/Rmd/ch05/05.02.Rmd b/code/Rmd/ch05/05.02.Rmd deleted file mode 100644 index c24f993..0000000 --- a/code/Rmd/ch05/05.02.Rmd +++ /dev/null @@ -1,83 +0,0 @@ -## 5.2 データの変換 - -### 5.2.1 標準化 - -```{r} -x1 <- c(1, 2, 3) - -z1 <- scale(x1) -# あるいは -z1 <- (x1 - mean(x1)) / sd(x1) - -z1 -#> [1] -1 0 1 -``` - -```{r} -c(mean(z1), sd(z1)) -#> [1] 0 1 -``` - -```{r} -z1 * sd(x1) + mean(x1) -#> [1] 1 2 3 -``` - -```{r} -x2 <- c(1, 3, 5) -z2 <- (x2 - mean(x1)) / sd(x1) -c(mean(z2), sd(z2)) -#> [1] 1 2 -``` - -### 5.2.2 ワンホットエンコーディング - -```{r} -library(caret) -library(tidyverse) - -my_df <- data.frame( - id = c(1, 2, 3), - class = as.factor( - c("A", "B", "C"))) - -my_enc <- my_df %>% - dummyVars(formula = ~ .) - -my_enc %>% predict(my_df) -#> id class.A class.B class.C -#> 1 1 1 0 0 -#> 2 2 0 1 0 -#> 3 3 0 0 1 -``` - -```{r} -my_df2 <- data.frame( - id = c( 4 , 5 , 6 ), - class = c("B", "C", "B")) -my_enc %>% predict(my_df2) -#> id class.A class.B class.C -#> 1 4 0 1 0 -#> 2 5 0 0 1 -#> 3 6 0 1 0 -``` - -#### 5.2.2.1 補足:冗長性の排除 - -```{r} -my_enc <- my_df %>% - dummyVars(formula = ~ ., - fullRank = TRUE) -my_enc %>% predict(my_df) -#> id class.B class.C -#> 1 1 0 0 -#> 2 2 1 0 -#> 3 3 0 1 - -my_enc %>% predict(my_df2) -#> id class.B class.C -#> 1 4 1 0 -#> 2 5 0 1 -#> 3 6 1 0 -``` - diff --git a/code/Rmd/ch05/05.Rmd b/code/Rmd/ch05/05.Rmd deleted file mode 100644 index ecc5b89..0000000 --- a/code/Rmd/ch05/05.Rmd +++ /dev/null @@ -1,264 +0,0 @@ -## 5.1 データの読み込み - -### 5.1.1 CSV - -```{r} -library(tidyverse) -system(str_c("wget https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/exam.csv")) -``` - -#### 5.1.1.1 CSVの読み込み - -```{r} -my_df <- read_csv("exam.csv") -# あるいは -my_df <- read.csv("exam.csv", - stringsAsFactors = FALSE) - -my_df -#> name english math gender -#> 1 A 60 70 f -#> 2 B 90 80 m -#> 3 C 70 90 m -#> 4 D 90 100 f -``` - -```{r} -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/exam.csv") -my_df <- read_csv(my_url) -# あるいは -my_df <- read.csv(my_url, stringsAsFactors = FALSE) -``` - -```{r} -my_df2 <- read.csv( - file = "exam.csv", - stringsAsFactors = FALSE, - row.names = 1) -my_df2 -#> english math gender -#> A 60 70 f -#> B 90 80 m -#> C 70 90 m -#> D 90 100 f -``` - -#### 5.1.1.2 CSVファイルへの書き出し - -```{r} -my_df %>% write_csv("exam2.csv") -# あるいは -my_df %>% write.csv( - file = "exam2.csv", - row.names = FALSE) -``` - -```{r} -my_df2 %>% write.csv("exam3.csv") -``` - -### 5.1.2 文字コード - -```{r} -my_df <- read_csv(file = "exam.csv", - locale = locale(encoding = "UTF-8")) -# あるいは -my_df <- read.csv(file = "exam.csv", - stringsAsFactors = FALSE, - fileEncoding = "UTF-8") -``` - -```{r} -my_df %>% write_csv("exam2.csv") -# あるいは -my_df %>% write.csv(file = "exam2.csv", row.names = FALSE, - fileEncoding = "UTF-8") -``` - -### 5.1.3 ウェブ上の表 - -```{r} -my_url <- "https://taroyabuki.github.io/fromzero/exam.html" -my_tables <- xml2::read_html(my_url) %>% rvest::html_table() -``` - -```{r} -my_tables -#> [[1]] -#> X1 X2 X3 X4 X5 -#> 1 NA name english math gender -#> 2 NA A 60 70 f -#> 3 NA B 90 80 m -#> 4 NA C 70 90 m -#> 5 NA D 90 100 f -``` - -```{r} -tmp <- my_tables[[1]] -tmp -#> X1 X2 X3 X4 X5 -#> 1 NA name english math gender -#> 2 NA A 60 70 f -#> 3 NA B 90 80 m -#> 4 NA C 70 90 m -#> 5 NA D 90 100 f -``` - -```{r} -# 1行目のデータを使って列の名前を付け直す. -colnames(tmp) <- tmp[1, ] - -# 1行目と1列目を削除する. -my_data <- tmp[-1, -1] -my_data -#> name english math gender -#> 2 A 60 70 f -#> 3 B 90 80 m -#> 4 C 70 90 m -#> 5 D 90 100 f -``` - -### 5.1.4 JSONとXML - -#### 5.1.4.1 JSONデータの読み込み - -```{r} -library(jsonlite) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/exam.json") -my_data <- fromJSON(my_url) -#my_data <- fromJSON("exam.json") # (ファイルを使う場合) -my_data -#> name english math gender -#> 1 A 60 70 f -#> 2 B 90 80 m -#> 3 C 70 90 m -#> 4 D 90 100 f -``` - -#### 5.1.4.2 XMLデータの読み込み - -```{r} -library(xml2) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/exam.xml") -my_xml <- read_xml(my_url) # XMLデータの読み込み -#my_xml <- read_xml("exam.xml") # (ファイルを使う場合) -xml_ns(my_xml) # 名前空間の確認(d1) -#> d1 <-> https://www.example.net/ns/1.0 -``` - -```{r} -my_records <- xml_find_all(my_xml, ".//d1:record") -``` - -```{r} -f <- function(record) { - tmp <- xml_attrs(record) # 属性を全て取り出し, - xml_children(record) %>% walk(function(e) { - tmp[xml_name(e)] <<- xml_text(e) # 子要素の名前と内容を追加する. - }) - tmp -} -``` - -```{r} -my_data <- my_records %>% map_dfr(f) -my_data$english <- as.numeric(my_data$english) -my_data$math <- as.numeric(my_data$math) -my_data -#> english math gender name -#> -#> 1 60 70 f A -#> 2 90 80 m B -#> 3 70 90 m C -#> 4 90 100 f D -``` - - -## 5.2 データの変換 - -### 5.2.1 標準化 - -```{r} -x1 <- c(1, 2, 3) - -z1 <- scale(x1) -# あるいは -z1 <- (x1 - mean(x1)) / sd(x1) - -z1 -#> [1] -1 0 1 -``` - -```{r} -c(mean(z1), sd(z1)) -#> [1] 0 1 -``` - -```{r} -z1 * sd(x1) + mean(x1) -#> [1] 1 2 3 -``` - -```{r} -x2 <- c(1, 3, 5) -z2 <- (x2 - mean(x1)) / sd(x1) -c(mean(z2), sd(z2)) -#> [1] 1 2 -``` - -### 5.2.2 ワンホットエンコーディング - -```{r} -library(caret) -library(tidyverse) - -my_df <- data.frame( - id = c(1, 2, 3), - class = as.factor( - c("A", "B", "C"))) - -my_enc <- my_df %>% - dummyVars(formula = ~ .) - -my_enc %>% predict(my_df) -#> id class.A class.B class.C -#> 1 1 1 0 0 -#> 2 2 0 1 0 -#> 3 3 0 0 1 -``` - -```{r} -my_df2 <- data.frame( - id = c( 4 , 5 , 6 ), - class = c("B", "C", "B")) -my_enc %>% predict(my_df2) -#> id class.A class.B class.C -#> 1 4 0 1 0 -#> 2 5 0 0 1 -#> 3 6 0 1 0 -``` - -#### 5.2.2.1 補足:冗長性の排除 - -```{r} -my_enc <- my_df %>% - dummyVars(formula = ~ ., - fullRank = TRUE) -my_enc %>% predict(my_df) -#> id class.B class.C -#> 1 1 0 0 -#> 2 2 1 0 -#> 3 3 0 1 - -my_enc %>% predict(my_df2) -#> id class.B class.C -#> 1 4 1 0 -#> 2 5 0 1 -#> 3 6 1 0 -``` - - diff --git a/code/Rmd/ch06/06.01.Rmd b/code/Rmd/ch06/06.01.Rmd deleted file mode 100644 index 3226609..0000000 --- a/code/Rmd/ch06/06.01.Rmd +++ /dev/null @@ -1,2 +0,0 @@ -## 6.1 機械学習の目的(本書の場合) - diff --git a/code/Rmd/ch06/06.02.Rmd b/code/Rmd/ch06/06.02.Rmd deleted file mode 100644 index b9e4160..0000000 --- a/code/Rmd/ch06/06.02.Rmd +++ /dev/null @@ -1,23 +0,0 @@ -## 6.2 機械学習のためのデータ - -### 6.2.1 機械学習を学ぶのに使うデータセット - -#### 6.2.1.1 教師データあり - -#### 6.2.1.2 時系列データ(第\ref{時系列予測 - -#### 6.2.1.3 教師データなし(第\ref{教師なし学習 - -### 6.2.2 補足:アヤメのデータ - -#### 6.2.2.1 R - -```{r} -iris -#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species -#> 1 5.1 3.5 1.4 0.2 setosa -# 以下省略 -``` - -#### 6.2.2.2 Python - diff --git a/code/Rmd/ch06/06.03.Rmd b/code/Rmd/ch06/06.03.Rmd deleted file mode 100644 index bfa3d2f..0000000 --- a/code/Rmd/ch06/06.03.Rmd +++ /dev/null @@ -1,6 +0,0 @@ -## 6.3 機械学習のための手法 - -### 6.3.1 教師あり学習のためのフレームワーク - -### 6.3.2 本書で勧める手法とデータセットの組合せ - diff --git a/code/Rmd/ch06/06.Rmd b/code/Rmd/ch06/06.Rmd deleted file mode 100644 index bc31c3f..0000000 --- a/code/Rmd/ch06/06.Rmd +++ /dev/null @@ -1,34 +0,0 @@ -## 6.1 機械学習の目的(本書の場合) - - -## 6.2 機械学習のためのデータ - -### 6.2.1 機械学習を学ぶのに使うデータセット - -#### 6.2.1.1 教師データあり - -#### 6.2.1.2 時系列データ(第\ref{時系列予測 - -#### 6.2.1.3 教師データなし(第\ref{教師なし学習 - -### 6.2.2 補足:アヤメのデータ - -#### 6.2.2.1 R - -```{r} -iris -#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species -#> 1 5.1 3.5 1.4 0.2 setosa -# 以下省略 -``` - -#### 6.2.2.2 Python - - -## 6.3 機械学習のための手法 - -### 6.3.1 教師あり学習のためのフレームワーク - -### 6.3.2 本書で勧める手法とデータセットの組合せ - - diff --git a/code/Rmd/ch07/07.01.Rmd b/code/Rmd/ch07/07.01.Rmd deleted file mode 100644 index 00d7f04..0000000 --- a/code/Rmd/ch07/07.01.Rmd +++ /dev/null @@ -1,2 +0,0 @@ -## 7.1 自動車の停止距離 - diff --git a/code/Rmd/ch07/07.02.Rmd b/code/Rmd/ch07/07.02.Rmd deleted file mode 100644 index 35becd5..0000000 --- a/code/Rmd/ch07/07.02.Rmd +++ /dev/null @@ -1,50 +0,0 @@ -## 7.2 データの確認 - -```{r} -library(caret) -library(tidyverse) -my_data <- cars -``` - -```{r} -dim(my_data) -#> [1] 50 2 -``` - -```{r} -head(my_data) -#> speed dist -#> 1 4 2 -#> 2 4 10 -#> 3 7 4 -#> 4 7 22 -#> 5 8 16 -#> 6 9 10 -``` - -```{r} -options(digits = 3) -pastecs::stat.desc(my_data) -#> speed dist -#> nbr.val 50.000 50.00 -#> nbr.null 0.000 0.00 -#> nbr.na 0.000 0.00 -#> min 4.000 2.00 -#> max 25.000 120.00 -#> range 21.000 118.00 -#> sum 770.000 2149.00 -#> median 15.000 36.00 -#> mean 15.400 42.98 -#> SE.mean 0.748 3.64 -#> CI.mean.0.95 1.503 7.32 -#> var 27.959 664.06 -#> std.dev 5.288 25.77 -#> coef.var 0.343 0.60 -``` - -```{r} -my_data %>% - ggplot(aes(x = speed, y = dist)) + - geom_point() -``` - diff --git a/code/Rmd/ch07/07.03.Rmd b/code/Rmd/ch07/07.03.Rmd deleted file mode 100644 index 72f3a52..0000000 --- a/code/Rmd/ch07/07.03.Rmd +++ /dev/null @@ -1,68 +0,0 @@ -## 7.3 回帰分析 - -### 7.3.1 回帰分析とは何か - -### 7.3.2 線形単回帰分析 - -```{r} -library(tidyverse) - -my_data <- cars -tmp <- data.frame(speed = 21.5, dist = 67) -my_data %>% ggplot(aes(x = speed, y = dist)) + - coord_cartesian(xlim = c(4, 25), ylim = c(0, 120)) + - geom_point() + - stat_smooth(formula = y ~ x, method = "lm") + - geom_pointrange(data = tmp, aes(ymin = -9, ymax = dist), linetype = "dotted") + - geom_pointrange(data = tmp, aes(xmin = 0, xmax = speed), linetype = "dotted") -``` - -### 7.3.3 回帰分析の実践 - -#### 7.3.3.1 データの用意 - -```{r} -library(caret) -library(tidyverse) -my_data <- cars -``` - -#### 7.3.3.2 訓練 - -```{r} -my_model <- train(form = dist ~ speed, # モデル式(出力変数と入力変数の関係) - data = my_data, # データ - method = "lm") # 手法 -``` - -```{r} -coef(my_model$finalModel) -#> (Intercept) speed -#> -17.579095 3.932409 -``` - -#### 7.3.3.3 予測 - -```{r} -tmp <- data.frame(speed = 21.5) -my_model %>% predict(tmp) -#> 1 -#> 66.96769 -``` - -#### 7.3.3.4 モデルの可視化 - -```{r} -f <- function(x) { my_model %>% predict(data.frame(speed = x)) } -``` - -```{r} -my_data %>% - ggplot(aes(x = speed, y = dist, - color = "data")) + - geom_point() + - stat_function( - fun = f, - mapping = aes(color = "model")) -``` - diff --git a/code/Rmd/ch07/07.04.Rmd b/code/Rmd/ch07/07.04.Rmd deleted file mode 100644 index 1441590..0000000 --- a/code/Rmd/ch07/07.04.Rmd +++ /dev/null @@ -1,118 +0,0 @@ -## 7.4 当てはまりの良さの指標 - -### 7.4.1 RMSE - -```{r} -library(caret) -library(tidyverse) -my_data <- cars -my_model <- train(form = dist ~ speed, data = my_data, method = "lm") - -y <- my_data$dist -y_ <- my_model %>% predict(my_data) -my_data$y_ <- y_ -``` - -```{r} -my_data$residual <- y - y_ -head(my_data) -#> speed dist y_ residual -#> 1 4 2 -1.849460 3.849460 -#> 2 4 10 -1.849460 11.849460 -#> 3 7 4 9.947766 -5.947766 -#> 4 7 22 9.947766 12.052234 -#> 5 8 16 13.880175 2.119825 -#> 6 9 10 17.812584 -7.812584 -``` - -```{r} -my_data %>% - ggplot(aes(x = speed, y = dist)) + - geom_point() + - geom_line(aes(x = speed, y = y_)) + - geom_linerange(mapping = aes(ymin = y_, ymax = dist), linetype = "dotted") -``` - -```{r} -RMSE(y_, y) -# あるいは -mean((my_data$residual^2))**0.5 - -#> [1] 15.06886 -``` - -### 7.4.2 決定係数 - -```{r} -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 0.6510794 -``` - -```{r} -R2(pred = y_, obs = y, - form = "corr") -# あるいは -summary(my_model$finalModel)$r.squared -#> [1] 0.6510794 -``` - -```{r} -my_test <- my_data[1:3, ] -y <- my_test$dist -y_ <- my_model %>% predict(my_test) - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] -4.498191 # 決定係数1 - -R2(pred = y_, obs = y, - form = "corr") -#> [1] 0.07692308 # 決定係数6 -``` - -### 7.4.3 当てはまりの良さの指標の問題点 - -```{r} -library(caret) -library(tidyverse) -my_data <- cars -my_idx <- c(2, 11, 27, 34, 39, 44) -my_sample <- my_data[my_idx, ] -``` - -```{r} -options(warn = -1) # これ以降,警告を表示しない. -my_model <- train(form = dist ~ poly(speed, degree = 5, raw = TRUE), - data = my_sample, - method = "lm") -options(warn = 0) # これ以降,警告を表示する. - -y <- my_sample$dist -y_ <- my_model %>% predict(my_sample) -``` - -```{r} -RMSE(y_, y) -#> [1] 1.042275e-10 # RMSE - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 1 # 決定係数1 - -R2(pred = y_, obs = y, - form = "corr") -#> [1] 1 # 決定係数6 -``` - -```{r} -f <- function(x) { my_model %>% predict(data.frame(speed = x)) } - -my_data %>% - ggplot(aes(x = speed, y = dist, color = "data")) + - geom_point() + - geom_point(data = my_sample, mapping = aes(color = "sample")) + - stat_function(fun = f, mapping = aes(color = "model")) + - coord_cartesian(ylim = c(0, 120)) -``` - diff --git a/code/Rmd/ch07/07.05.Rmd b/code/Rmd/ch07/07.05.Rmd deleted file mode 100644 index 93a1fa4..0000000 --- a/code/Rmd/ch07/07.05.Rmd +++ /dev/null @@ -1,46 +0,0 @@ -## 7.5 K最近傍法 - -### 7.5.1 K最近傍法とは何か - -### 7.5.2 K最近傍法の実践 - -```{r} -# 準備 -library(caret) -library(tidyverse) -my_data <- cars - -# 訓練 -my_model <- train(form = dist ~ speed, data = my_data, method = "knn") - -# 可視化の準備 -f <- function(x) { my_model %>% predict(data.frame(speed = x))} -``` - -```{r} -my_data %>% - ggplot(aes(x = speed, - y = dist, - color = "data")) + - geom_point() + - stat_function( - fun = f, - mapping = aes(color = "model")) -``` - -```{r} -y <- my_data$dist -y_ <- my_model %>% predict(my_data) - -RMSE(y_, y) -#> [1] 13.96845 # RMSE - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 0.7001789 # 決定係数1 - -R2(pred = y_, obs = y, - form = "corr") -#> [1] 0.7017314 # 決定係数6 -``` - diff --git a/code/Rmd/ch07/07.06.Rmd b/code/Rmd/ch07/07.06.Rmd deleted file mode 100644 index f57f202..0000000 --- a/code/Rmd/ch07/07.06.Rmd +++ /dev/null @@ -1,177 +0,0 @@ -## 7.6 検証 - -### 7.6.1 訓練データ・検証データ・テストデータ - -### 7.6.2 検証とは何か - -### 7.6.3 検証の実践 - -```{r} -library(caret) -library(tidyverse) -my_data <- cars -my_model <- train(form = dist ~ speed, data = my_data, method = "lm") - -my_model$results -#> intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD -#> 1 TRUE 16.0206 0.6662176 12.14701 2.518604 0.09249158 1.920564 -``` - -```{r} -my_model <- train(form = dist ~ speed, data = my_data, method = "lm", - trControl = trainControl(method = "cv", number = 5)) -my_model$results -#> intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD -#> 1 TRUE 15.06708 0.6724501 12.12448 4.75811 0.1848932 3.052435 -``` - -```{r} -my_model <- train(form = dist ~ speed, data = my_data, method = "lm", - trControl = trainControl(method = "LOOCV")) -my_model$results -#> intercept RMSE Rsquared MAE -#> 1 TRUE 15.69731 0.6217139 12.05918 -``` - -### 7.6.4 検証の並列化 - -```{r} -library(doParallel) -cl <- makeCluster(detectCores()) -registerDoParallel(cl) -``` - -### 7.6.5 指標のまとめ - -#### 7.6.5.1 準備 - -```{r} -library(caret) -library(tidyverse) -my_data <- cars -my_model <- train(form = dist ~ speed, data = my_data, method = "lm") -y <- my_data$dist -y_ <- my_model %>% predict(my_data) -``` - -#### 7.6.5.2 当てはまりの良さの指標 - -```{r} -# RMSE(訓練) -RMSE(y_, y) -#> [1] 15.06886 - -# 決定係数1(訓練) -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 0.6510794 - -# 決定係数6(訓練) -R2(pred = y_, obs = y, - form = "corr") -#> [1] 0.6510794 -``` - -```{r} -postResample(pred = y_, obs = y) -#> RMSE Rsquared MAE -#> 15.0688560 0.6510794 11.5801191 -``` - -#### 7.6.5.3 予測性能の指標(簡単に求められるもの) - -```{r} -my_model <- train(form = dist ~ speed, data = my_data, method = "lm") -my_model$results -#> intercept RMSE Rsquared MAE ... -#> 1 TRUE 14.88504 0.6700353 11.59226 ... -# 左から,RMSE(検証),決定係数6(検証),MAE(検証) -``` - -#### 7.6.5.4 予測性能の指標(RとPythonで同じ結果を得る) - -```{r} -my_model <- train(form = dist ~ speed, data = my_data, method = "lm", - trControl = trainControl(method = "LOOCV")) - -# 方法1 -my_model$results -#> intercept RMSE Rsquared MAE -#> 1 TRUE 15.69731 0.6217139 12.05918 - -# 方法2 -y <- my_model$pred$obs -y_ <- my_model$pred$pred -mean((y - y_)^2)**0.5 -#> [1] 15.69731 -``` - -```{r} -mean(((y - y_)^2)**0.5) -#> [1] 12.05918 -``` - -### 7.6.6 補足:検証による手法の比較 - -```{r} -library(caret) -library(tidyverse) -my_data <- cars - -my_lm_model <- train(form = dist ~ speed, data = my_data, method = "lm", - trControl = trainControl(method = "LOOCV")) - -my_knn_model <- train(form = dist ~ speed, data = my_data, method = "knn", - tuneGrid = data.frame(k = 5), - trControl = trainControl(method = "LOOCV")) -``` - -```{r} -my_lm_model$results$RMSE -#> [1] 15.69731 # 線形回帰分析 - -my_knn_model$results$RMSE -#> [1] 15.79924 # K最近傍法 -``` - -```{r} -y <- my_data$dist -y_lm <- my_lm_model$pred$pred -y_knn <- my_knn_model$pred$pred - -my_df <- data.frame( - lm = (y - y_lm)^2, - knn = (y - y_knn)^2) - -head(my_df) -#> lm knn -#> 1 18.913720 108.1600 -#> 2 179.215044 0.6400 -#> 3 41.034336 175.5625 -#> 4 168.490212 49.0000 -#> 5 5.085308 9.0000 -#> 6 67.615888 112.8906 -``` - -```{r} -boxplot(my_df, ylab = "r^2") -``` - -```{r} -t.test(x = my_df$lm, y = my_df$knn, - conf.level = 0.95, - paired = TRUE, - alternative = "two.sided") - -#> Paired t-test -#> -#> data: my_df$lm and my_df$knn -#> t = -0.12838, df = 49, p-value = 0.8984 -#> alternative hypothesis: true difference in means is not equal to 0 -#> 95 percent confidence interval: -#> -53.46930 47.04792 -#> sample estimates: -#> mean of the differences -#> -3.210688 -``` - diff --git a/code/Rmd/ch07/07.07.Rmd b/code/Rmd/ch07/07.07.Rmd deleted file mode 100644 index 06bd595..0000000 --- a/code/Rmd/ch07/07.07.Rmd +++ /dev/null @@ -1,89 +0,0 @@ -## 7.7 パラメータチューニング - -```{r} -library(caret) -library(tidyverse) -my_data <- cars -my_model <- train(form = dist ~ speed, data = my_data, method = "knn") -my_model$results -#> k RMSE Rsquared MAE RMSESD RsquaredSD MAESD -#> 1 5 15.72114 0.6615765 12.54588 3.013243 0.11043907 2.372245 -#> 2 7 16.19047 0.6601173 12.68464 3.165330 0.09990158 2.329326 -#> 3 9 16.30276 0.6556700 12.84811 3.367423 0.09645747 2.471620 -``` - -```{r} -my_params <- expand.grid(k = 1:15) - -my_model <- train(form = dist ~ speed, data = my_data, method = "knn", - tuneGrid = my_params, - trControl = trainControl(method = "LOOCV")) -``` - -```{r} -head(my_model$results) -#> k RMSE Rsquared MAE -#> 1 1 17.22299 0.5777197 13.84900 -#> 2 2 16.81462 0.5936438 13.03469 -#> 3 3 16.32874 0.6218866 12.74524 -#> 4 4 15.98970 0.6086993 12.27888 -#> 5 5 15.79924 0.6169267 11.96067 -#> 6 6 15.98720 0.6079396 12.26667 -``` - -```{r} -ggplot(my_model) -``` - -```{r} -my_model$bestTune -#> k -#> 5 5 -``` - -```{r} -my_model$results %>% - filter(RMSE == min(RMSE)) -#> k RMSE Rsquared MAE -#> 1 5 15.79924 0.6169267 11.96067 -``` - -```{r} -y <- my_data$dist -y_ <- my_model %>% predict(my_data) -RMSE(y_, y) -#> [1] 13.96845 -``` - -### 7.7.1 補足:ハイパーパラメータとRMSE(訓練) - -```{r} -library(caret) -library(tidyverse) -my_data <- cars - -my_loocv <- function(k) { - my_model <- train(form = dist ~ speed, data = my_data, method = "knn", - tuneGrid = data.frame(k = k), - trControl = trainControl(method = "LOOCV")) - y <- my_data$dist - y_ <- my_model %>% predict(my_data) - list(k = k, - training = RMSE(y_, y), # RMSE(訓練) - validation = my_model$results$RMSE) # RMSE(検証) -} - -my_results <- 1:15 %>% map_dfr(my_loocv) -``` - -```{r} -my_results %>% - pivot_longer(-k) %>% - ggplot(aes(x = k, y = value, - color = name)) + - geom_line() + geom_point() + - xlab("#Neighbors") + ylab("RMSE") + - theme(legend.position = c(1, 0), - legend.justification = c(1, 0)) -``` - diff --git a/code/Rmd/ch07/07.Rmd b/code/Rmd/ch07/07.Rmd deleted file mode 100644 index daed6be..0000000 --- a/code/Rmd/ch07/07.Rmd +++ /dev/null @@ -1,557 +0,0 @@ -## 7.1 自動車の停止距離 - - -## 7.2 データの確認 - -```{r} -library(caret) -library(tidyverse) -my_data <- cars -``` - -```{r} -dim(my_data) -#> [1] 50 2 -``` - -```{r} -head(my_data) -#> speed dist -#> 1 4 2 -#> 2 4 10 -#> 3 7 4 -#> 4 7 22 -#> 5 8 16 -#> 6 9 10 -``` - -```{r} -options(digits = 3) -pastecs::stat.desc(my_data) -#> speed dist -#> nbr.val 50.000 50.00 -#> nbr.null 0.000 0.00 -#> nbr.na 0.000 0.00 -#> min 4.000 2.00 -#> max 25.000 120.00 -#> range 21.000 118.00 -#> sum 770.000 2149.00 -#> median 15.000 36.00 -#> mean 15.400 42.98 -#> SE.mean 0.748 3.64 -#> CI.mean.0.95 1.503 7.32 -#> var 27.959 664.06 -#> std.dev 5.288 25.77 -#> coef.var 0.343 0.60 -``` - -```{r} -my_data %>% - ggplot(aes(x = speed, y = dist)) + - geom_point() -``` - - -## 7.3 回帰分析 - -### 7.3.1 回帰分析とは何か - -### 7.3.2 線形単回帰分析 - -```{r} -library(tidyverse) - -my_data <- cars -tmp <- data.frame(speed = 21.5, dist = 67) -my_data %>% ggplot(aes(x = speed, y = dist)) + - coord_cartesian(xlim = c(4, 25), ylim = c(0, 120)) + - geom_point() + - stat_smooth(formula = y ~ x, method = "lm") + - geom_pointrange(data = tmp, aes(ymin = -9, ymax = dist), linetype = "dotted") + - geom_pointrange(data = tmp, aes(xmin = 0, xmax = speed), linetype = "dotted") -``` - -### 7.3.3 回帰分析の実践 - -#### 7.3.3.1 データの用意 - -```{r} -library(caret) -library(tidyverse) -my_data <- cars -``` - -#### 7.3.3.2 訓練 - -```{r} -my_model <- train(form = dist ~ speed, # モデル式(出力変数と入力変数の関係) - data = my_data, # データ - method = "lm") # 手法 -``` - -```{r} -coef(my_model$finalModel) -#> (Intercept) speed -#> -17.579095 3.932409 -``` - -#### 7.3.3.3 予測 - -```{r} -tmp <- data.frame(speed = 21.5) -my_model %>% predict(tmp) -#> 1 -#> 66.96769 -``` - -#### 7.3.3.4 モデルの可視化 - -```{r} -f <- function(x) { my_model %>% predict(data.frame(speed = x)) } -``` - -```{r} -my_data %>% - ggplot(aes(x = speed, y = dist, - color = "data")) + - geom_point() + - stat_function( - fun = f, - mapping = aes(color = "model")) -``` - - -## 7.4 当てはまりの良さの指標 - -### 7.4.1 RMSE - -```{r} -library(caret) -library(tidyverse) -my_data <- cars -my_model <- train(form = dist ~ speed, data = my_data, method = "lm") - -y <- my_data$dist -y_ <- my_model %>% predict(my_data) -my_data$y_ <- y_ -``` - -```{r} -my_data$residual <- y - y_ -head(my_data) -#> speed dist y_ residual -#> 1 4 2 -1.849460 3.849460 -#> 2 4 10 -1.849460 11.849460 -#> 3 7 4 9.947766 -5.947766 -#> 4 7 22 9.947766 12.052234 -#> 5 8 16 13.880175 2.119825 -#> 6 9 10 17.812584 -7.812584 -``` - -```{r} -my_data %>% - ggplot(aes(x = speed, y = dist)) + - geom_point() + - geom_line(aes(x = speed, y = y_)) + - geom_linerange(mapping = aes(ymin = y_, ymax = dist), linetype = "dotted") -``` - -```{r} -RMSE(y_, y) -# あるいは -mean((my_data$residual^2))**0.5 - -#> [1] 15.06886 -``` - -### 7.4.2 決定係数 - -```{r} -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 0.6510794 -``` - -```{r} -R2(pred = y_, obs = y, - form = "corr") -# あるいは -summary(my_model$finalModel)$r.squared -#> [1] 0.6510794 -``` - -```{r} -my_test <- my_data[1:3, ] -y <- my_test$dist -y_ <- my_model %>% predict(my_test) - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] -4.498191 # 決定係数1 - -R2(pred = y_, obs = y, - form = "corr") -#> [1] 0.07692308 # 決定係数6 -``` - -### 7.4.3 当てはまりの良さの指標の問題点 - -```{r} -library(caret) -library(tidyverse) -my_data <- cars -my_idx <- c(2, 11, 27, 34, 39, 44) -my_sample <- my_data[my_idx, ] -``` - -```{r} -options(warn = -1) # これ以降,警告を表示しない. -my_model <- train(form = dist ~ poly(speed, degree = 5, raw = TRUE), - data = my_sample, - method = "lm") -options(warn = 0) # これ以降,警告を表示する. - -y <- my_sample$dist -y_ <- my_model %>% predict(my_sample) -``` - -```{r} -RMSE(y_, y) -#> [1] 1.042275e-10 # RMSE - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 1 # 決定係数1 - -R2(pred = y_, obs = y, - form = "corr") -#> [1] 1 # 決定係数6 -``` - -```{r} -f <- function(x) { my_model %>% predict(data.frame(speed = x)) } - -my_data %>% - ggplot(aes(x = speed, y = dist, color = "data")) + - geom_point() + - geom_point(data = my_sample, mapping = aes(color = "sample")) + - stat_function(fun = f, mapping = aes(color = "model")) + - coord_cartesian(ylim = c(0, 120)) -``` - - -## 7.5 K最近傍法 - -### 7.5.1 K最近傍法とは何か - -### 7.5.2 K最近傍法の実践 - -```{r} -# 準備 -library(caret) -library(tidyverse) -my_data <- cars - -# 訓練 -my_model <- train(form = dist ~ speed, data = my_data, method = "knn") - -# 可視化の準備 -f <- function(x) { my_model %>% predict(data.frame(speed = x))} -``` - -```{r} -my_data %>% - ggplot(aes(x = speed, - y = dist, - color = "data")) + - geom_point() + - stat_function( - fun = f, - mapping = aes(color = "model")) -``` - -```{r} -y <- my_data$dist -y_ <- my_model %>% predict(my_data) - -RMSE(y_, y) -#> [1] 13.96845 # RMSE - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 0.7001789 # 決定係数1 - -R2(pred = y_, obs = y, - form = "corr") -#> [1] 0.7017314 # 決定係数6 -``` - - -## 7.6 検証 - -### 7.6.1 訓練データ・検証データ・テストデータ - -### 7.6.2 検証とは何か - -### 7.6.3 検証の実践 - -```{r} -library(caret) -library(tidyverse) -my_data <- cars -my_model <- train(form = dist ~ speed, data = my_data, method = "lm") - -my_model$results -#> intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD -#> 1 TRUE 16.0206 0.6662176 12.14701 2.518604 0.09249158 1.920564 -``` - -```{r} -my_model <- train(form = dist ~ speed, data = my_data, method = "lm", - trControl = trainControl(method = "cv", number = 5)) -my_model$results -#> intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD -#> 1 TRUE 15.06708 0.6724501 12.12448 4.75811 0.1848932 3.052435 -``` - -```{r} -my_model <- train(form = dist ~ speed, data = my_data, method = "lm", - trControl = trainControl(method = "LOOCV")) -my_model$results -#> intercept RMSE Rsquared MAE -#> 1 TRUE 15.69731 0.6217139 12.05918 -``` - -### 7.6.4 検証の並列化 - -```{r} -library(doParallel) -cl <- makeCluster(detectCores()) -registerDoParallel(cl) -``` - -### 7.6.5 指標のまとめ - -#### 7.6.5.1 準備 - -```{r} -library(caret) -library(tidyverse) -my_data <- cars -my_model <- train(form = dist ~ speed, data = my_data, method = "lm") -y <- my_data$dist -y_ <- my_model %>% predict(my_data) -``` - -#### 7.6.5.2 当てはまりの良さの指標 - -```{r} -# RMSE(訓練) -RMSE(y_, y) -#> [1] 15.06886 - -# 決定係数1(訓練) -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 0.6510794 - -# 決定係数6(訓練) -R2(pred = y_, obs = y, - form = "corr") -#> [1] 0.6510794 -``` - -```{r} -postResample(pred = y_, obs = y) -#> RMSE Rsquared MAE -#> 15.0688560 0.6510794 11.5801191 -``` - -#### 7.6.5.3 予測性能の指標(簡単に求められるもの) - -```{r} -my_model <- train(form = dist ~ speed, data = my_data, method = "lm") -my_model$results -#> intercept RMSE Rsquared MAE ... -#> 1 TRUE 14.88504 0.6700353 11.59226 ... -# 左から,RMSE(検証),決定係数6(検証),MAE(検証) -``` - -#### 7.6.5.4 予測性能の指標(RとPythonで同じ結果を得る) - -```{r} -my_model <- train(form = dist ~ speed, data = my_data, method = "lm", - trControl = trainControl(method = "LOOCV")) - -# 方法1 -my_model$results -#> intercept RMSE Rsquared MAE -#> 1 TRUE 15.69731 0.6217139 12.05918 - -# 方法2 -y <- my_model$pred$obs -y_ <- my_model$pred$pred -mean((y - y_)^2)**0.5 -#> [1] 15.69731 -``` - -```{r} -mean(((y - y_)^2)**0.5) -#> [1] 12.05918 -``` - -### 7.6.6 補足:検証による手法の比較 - -```{r} -library(caret) -library(tidyverse) -my_data <- cars - -my_lm_model <- train(form = dist ~ speed, data = my_data, method = "lm", - trControl = trainControl(method = "LOOCV")) - -my_knn_model <- train(form = dist ~ speed, data = my_data, method = "knn", - tuneGrid = data.frame(k = 5), - trControl = trainControl(method = "LOOCV")) -``` - -```{r} -my_lm_model$results$RMSE -#> [1] 15.69731 # 線形回帰分析 - -my_knn_model$results$RMSE -#> [1] 15.79924 # K最近傍法 -``` - -```{r} -y <- my_data$dist -y_lm <- my_lm_model$pred$pred -y_knn <- my_knn_model$pred$pred - -my_df <- data.frame( - lm = (y - y_lm)^2, - knn = (y - y_knn)^2) - -head(my_df) -#> lm knn -#> 1 18.913720 108.1600 -#> 2 179.215044 0.6400 -#> 3 41.034336 175.5625 -#> 4 168.490212 49.0000 -#> 5 5.085308 9.0000 -#> 6 67.615888 112.8906 -``` - -```{r} -boxplot(my_df, ylab = "r^2") -``` - -```{r} -t.test(x = my_df$lm, y = my_df$knn, - conf.level = 0.95, - paired = TRUE, - alternative = "two.sided") - -#> Paired t-test -#> -#> data: my_df$lm and my_df$knn -#> t = -0.12838, df = 49, p-value = 0.8984 -#> alternative hypothesis: true difference in means is not equal to 0 -#> 95 percent confidence interval: -#> -53.46930 47.04792 -#> sample estimates: -#> mean of the differences -#> -3.210688 -``` - - -## 7.7 パラメータチューニング - -```{r} -library(caret) -library(tidyverse) -my_data <- cars -my_model <- train(form = dist ~ speed, data = my_data, method = "knn") -my_model$results -#> k RMSE Rsquared MAE RMSESD RsquaredSD MAESD -#> 1 5 15.72114 0.6615765 12.54588 3.013243 0.11043907 2.372245 -#> 2 7 16.19047 0.6601173 12.68464 3.165330 0.09990158 2.329326 -#> 3 9 16.30276 0.6556700 12.84811 3.367423 0.09645747 2.471620 -``` - -```{r} -my_params <- expand.grid(k = 1:15) - -my_model <- train(form = dist ~ speed, data = my_data, method = "knn", - tuneGrid = my_params, - trControl = trainControl(method = "LOOCV")) -``` - -```{r} -head(my_model$results) -#> k RMSE Rsquared MAE -#> 1 1 17.22299 0.5777197 13.84900 -#> 2 2 16.81462 0.5936438 13.03469 -#> 3 3 16.32874 0.6218866 12.74524 -#> 4 4 15.98970 0.6086993 12.27888 -#> 5 5 15.79924 0.6169267 11.96067 -#> 6 6 15.98720 0.6079396 12.26667 -``` - -```{r} -ggplot(my_model) -``` - -```{r} -my_model$bestTune -#> k -#> 5 5 -``` - -```{r} -my_model$results %>% - filter(RMSE == min(RMSE)) -#> k RMSE Rsquared MAE -#> 1 5 15.79924 0.6169267 11.96067 -``` - -```{r} -y <- my_data$dist -y_ <- my_model %>% predict(my_data) -RMSE(y_, y) -#> [1] 13.96845 -``` - -### 7.7.1 補足:ハイパーパラメータとRMSE(訓練) - -```{r} -library(caret) -library(tidyverse) -my_data <- cars - -my_loocv <- function(k) { - my_model <- train(form = dist ~ speed, data = my_data, method = "knn", - tuneGrid = data.frame(k = k), - trControl = trainControl(method = "LOOCV")) - y <- my_data$dist - y_ <- my_model %>% predict(my_data) - list(k = k, - training = RMSE(y_, y), # RMSE(訓練) - validation = my_model$results$RMSE) # RMSE(検証) -} - -my_results <- 1:15 %>% map_dfr(my_loocv) -``` - -```{r} -my_results %>% - pivot_longer(-k) %>% - ggplot(aes(x = k, y = value, - color = name)) + - geom_line() + geom_point() + - xlab("#Neighbors") + ylab("RMSE") + - theme(legend.position = c(1, 0), - legend.justification = c(1, 0)) -``` - - diff --git a/code/Rmd/ch08/08.01.Rmd b/code/Rmd/ch08/08.01.Rmd deleted file mode 100644 index 81fe4f8..0000000 --- a/code/Rmd/ch08/08.01.Rmd +++ /dev/null @@ -1,49 +0,0 @@ -## 8.1 ブドウの生育条件とワインの価格 - -```{r} -library(tidyverse) -my_url <- "http://www.liquidasset.com/winedata.html" -tmp <- read.table(file = my_url, # 読み込む対象 - header = TRUE, # 1行目は変数名 - na.string = ".", # 欠損値を表す文字列 - skip = 62, # 読み飛ばす行数 - nrows = 38) # 読み込む行数 -psych::describe(tmp) -#> vars n mean sd median trimmed mad min max ... -#> OBS 1 38 19.50 11.11 19.50 19.50 14.08 1.00 38.00 ... -#> VINT 2 38 1970.50 11.11 1970.50 1970.50 14.08 1952.00 1989.00 ... -#> LPRICE2 3 27 -1.45 0.63 -1.51 -1.49 0.72 -2.29 0.00 ... -#> WRAIN 4 38 605.00 135.28 586.50 603.06 174.95 376.00 845.00 ... -#> DEGREES 5 37 16.52 0.66 16.53 16.55 0.67 14.98 17.65 ... -#> HRAIN 6 38 137.00 66.74 120.50 132.19 59.30 38.00 292.00 ... -#> TIME_SV 7 38 12.50 11.11 12.50 12.50 14.08 -6.00 31.00 ... -``` - -```{r} -my_data <- na.omit(tmp[, -c(1, 2)]) -head(my_data) -#> LPRICE2 WRAIN DEGREES ... -#> 1 -0.99868 600 17.1167 ... -#> 2 -0.45440 690 16.7333 ... -#> 4 -0.80796 502 17.1500 ... -#> 6 -1.50926 420 16.1333 ... -#> 7 -1.71655 582 16.4167 ... -#> 8 -0.41800 485 17.4833 ... -``` - -```{r} -dim(my_data) -#> [1] 27 5 -``` - -```{r} -my_data %>% write_csv("wine.csv") -``` - -```{r} -#my_data <- read_csv("wine.csv") # 作ったファイルを使う場合 -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) -``` - diff --git a/code/Rmd/ch08/08.02.Rmd b/code/Rmd/ch08/08.02.Rmd deleted file mode 100644 index 8e17660..0000000 --- a/code/Rmd/ch08/08.02.Rmd +++ /dev/null @@ -1,73 +0,0 @@ -## 8.2 重回帰分析 - -```{r} -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) - -my_model <- train(form = LPRICE2 ~ WRAIN + DEGREES + HRAIN + TIME_SV, - data = my_data, - method = "lm", - trControl = trainControl(method = "LOOCV")) -``` - -```{r} -coef(my_model$finalModel) %>% - as.data.frame -#> . -#> (Intercept) -12.145333577 -#> WRAIN 0.001166782 -#> DEGREES 0.616392441 -#> HRAIN -0.003860554 -#> TIME_SV 0.023847413 -``` - -```{r} -my_test <- data.frame( - WRAIN = 500, DEGREES = 17, - HRAIN = 120, TIME_SV = 2) -my_model %>% predict(my_test) -#> 1 -#> -1.498843 -``` - -```{r} -y <- my_data$LPRICE2 -y_ <- my_model %>% predict(my_data) - -RMSE(y_, y) -#> [1] 0.2586167 # RMSE(訓練) - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 0.8275278 # 決定係数1(訓練) - -R2(pred = y_, obs = y, - form = "corr") -#> [1] 0.8275278 # 決定係数6(訓練) -``` - -```{r} -my_model$results -#> intercept RMSE Rsquared MAE -#> 1 TRUE 0.3230043 0.7361273 0.2767282 -``` - -### 8.2.1 補足:行列計算による再現 - -```{r} -M <- my_data[, -1] %>% - mutate(b0 = 1) %>% as.matrix -b <- MASS::ginv(M) %*% y -matrix(b, - dimnames = list(colnames(M))) -#> [,1] -#> WRAIN 0.001166782 -#> DEGREES 0.616392441 -#> HRAIN -0.003860554 -#> TIME_SV 0.023847413 -#> b0 -12.145333577 -``` - diff --git a/code/Rmd/ch08/08.03.Rmd b/code/Rmd/ch08/08.03.Rmd deleted file mode 100644 index cf88116..0000000 --- a/code/Rmd/ch08/08.03.Rmd +++ /dev/null @@ -1,46 +0,0 @@ -## 8.3 標準化 - -```{r} -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) - -my_data %>% - mutate_if(is.numeric, scale) %>% # 数値の列の標準化 - pivot_longer(-LPRICE2) %>% - ggplot(aes(x = name, y = value)) + - geom_boxplot() + - stat_summary(fun = mean, geom = "point", size = 3) + - xlab(NULL) -``` - -```{r} -my_model <- train( - form = LPRICE2 ~ ., - data = my_data, - method = "lm", - preProcess = c("center", "scale")) -``` - -```{r} -coef(my_model$finalModel) %>% - as.data.frame -#> . -#> (Intercept) -1.4517652 -#> WRAIN 0.1505557 -#> DEGREES 0.4063194 -#> HRAIN -0.2820746 -#> TIME_SV 0.1966549 -``` - -```{r} -my_test <- data.frame( - WRAIN = 500, DEGREES = 17, - HRAIN = 120, TIME_SV = 2) -my_model %>% predict(my_test) -#> 1 -#> -1.498843 -``` - diff --git a/code/Rmd/ch08/08.04.Rmd b/code/Rmd/ch08/08.04.Rmd deleted file mode 100644 index a85f441..0000000 --- a/code/Rmd/ch08/08.04.Rmd +++ /dev/null @@ -1,37 +0,0 @@ -## 8.4 入力変数の数とモデルの良さ - -```{r} -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) - -n <- nrow(my_data) -my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2, - v2 = 0:(n - 1) %% 3) -head(my_data2) -#> # A tibble: 6 x 7 -#> LPRICE2 WRAIN DEGREES HRAIN TIME_SV v1 v2 -#> -#> 1 -0.999 600 17.1 160 31 0 0 -#> 2 -0.454 690 16.7 80 30 1 1 -#> 3 -0.808 502 17.2 130 28 0 2 -#> 4 -1.51 420 16.1 110 26 1 0 -#> 5 -1.72 582 16.4 187 25 0 1 -#> 6 -0.418 485 17.5 187 24 1 2 -``` - -```{r} -my_model2 <- train(form = LPRICE2 ~ ., data = my_data2, method = "lm", - trControl = trainControl(method = "LOOCV")) -y <- my_data2$LPRICE2 -y_ <- my_model2 %>% predict(my_data2) - -RMSE(y_, y) -#> [1] 0.256212 # RMSE(訓練) - -my_model2$results$RMSE -#> [1] 0.3569918 # RMSE(検証) -``` - diff --git a/code/Rmd/ch08/08.05.Rmd b/code/Rmd/ch08/08.05.Rmd deleted file mode 100644 index 9f37a92..0000000 --- a/code/Rmd/ch08/08.05.Rmd +++ /dev/null @@ -1,27 +0,0 @@ -## 8.5 変数選択 - -```{r} -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) -n <- nrow(my_data) -my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2, - v2 = 0:(n - 1) %% 3) -``` - -```{r} -my_model <- train(form = LPRICE2 ~ ., - data = my_data2, - method = "leapForward", # 変数増加法 - trControl = trainControl(method = "LOOCV"), - tuneGrid = data.frame(nvmax = 1:6)) # 選択する変数の上限 -summary(my_model$finalModel)$outmat -#> WRAIN DEGREES HRAIN TIME_SV v1 v2 -#> 1 ( 1 ) " " "*" " " " " " " " " -#> 2 ( 1 ) " " "*" "*" " " " " " " -#> 3 ( 1 ) " " "*" "*" "*" " " " " -#> 4 ( 1 ) "*" "*" "*" "*" " " " " -``` - diff --git a/code/Rmd/ch08/08.06.Rmd b/code/Rmd/ch08/08.06.Rmd deleted file mode 100644 index c3748b6..0000000 --- a/code/Rmd/ch08/08.06.Rmd +++ /dev/null @@ -1,97 +0,0 @@ -## 8.6 補足:正則化 - -```{r} -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) -``` - -### 8.6.1 正則化の実践 - -```{r} -A <- 2 -B <- 0.1 - -my_model <- train( - form = LPRICE2 ~ ., - data = my_data, - method = "glmnet", - standardize = TRUE, - tuneGrid = data.frame( - lambda = A, - alpha = B)) -``` - -```{r} -coef(my_model$finalModel, A) -#> 1 -#> (Intercept) -2.8015519302 -#> WRAIN . -#> DEGREES 0.0832910512 -#> HRAIN -0.0004147386 -#> TIME_SV 0.0023104647 -``` - -```{r} -my_test <- data.frame( - WRAIN = 500, DEGREES = 17, - HRAIN = 120, TIME_SV = 2) -my_model %>% predict(my_test) -#> [1] -1.430752 -``` - -### 8.6.2 ペナルティの強さと係数の関係 - -```{r} -library(ggfortify) -library(glmnetUtils) - -my_data2 <- my_data %>% scale %>% - as.data.frame - -B <- 0.1 - -glmnet( - form = LPRICE2 ~ ., - data = my_data2, - alpha = B) %>% - autoplot(xvar = "lambda") + - xlab("log A ( = log lambda)") + - theme(legend.position = c(0.15, 0.25)) -``` - -### 8.6.3 パラメータの決定 - -```{r} -As <- seq(0, 0.1, length.out = 21) -Bs <- seq(0, 0.1, length.out = 6) - -my_model <- train( - form = LPRICE2 ~ ., data = my_data, method = "glmnet", standardize = TRUE, - trControl = trainControl(method = "LOOCV"), - tuneGrid = expand.grid(lambda = As, alpha = Bs)) - -my_model$bestTune -#> alpha lambda -#> 8 0 0.035 -``` - -```{r} -tmp <- "B ( = alpha)" -ggplot(my_model) + - theme(legend.position = c(0, 1), legend.justification = c(0, 1)) + - xlab("A ( = lambda)") + - guides(shape = guide_legend(tmp), color = guide_legend(tmp)) -``` - -```{r} -my_model$results %>% - filter(RMSE == min(RMSE)) -#> alpha lambda RMSE ... -#> 1 0 0.0595 0.3117092 ... -``` - -### 8.6.4 補足:RとPythonで結果を同じにする方法 - diff --git a/code/Rmd/ch08/08.07.Rmd b/code/Rmd/ch08/08.07.Rmd deleted file mode 100644 index 6e1ebb8..0000000 --- a/code/Rmd/ch08/08.07.Rmd +++ /dev/null @@ -1,56 +0,0 @@ -## 8.7 ニューラルネットワーク - -### 8.7.1 ニューラルネットワークとは何か - -```{r} -curve(1 / (1 + exp(-x)), -6, 6) -``` - -### 8.7.2 ニューラルネットワークの訓練 - -```{r} -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) -``` - -```{r} -my_model <- train(form = LPRICE2 ~ ., - data = my_data, - method = "neuralnet", # ニューラルネットワーク - preProcess = c("center", "scale"), # 標準化 - trControl = trainControl(method = "LOOCV")) -plot(my_model$finalModel) # 訓練済ネットワークの描画 -``` - -```{r} -my_model$results -#> layer1 layer2 layer3 RMSE ... -#> 1 1 0 0 0.3504016 ... -#> 2 3 0 0 0.4380399 ... -#> 3 5 0 0 0.4325535 ... -``` - -### 8.7.3 ニューラルネットワークのチューニング - -```{r} -my_model <- train( - form = LPRICE2 ~ ., - data = my_data, - method = "neuralnet", - preProcess = c("center", "scale"), - trControl = trainControl(method = "LOOCV"), - tuneGrid = expand.grid(layer1 = 1:5, - layer2 = 0:2, - layer3 = 0)) -``` - -```{r} -my_model$results %>% - filter(RMSE == min(RMSE)) -#> layer1 layer2 layer3 RMSE ... -#> 1 2 0 0 0.3165704 ... -``` - diff --git a/code/Rmd/ch08/08.Rmd b/code/Rmd/ch08/08.Rmd deleted file mode 100644 index c1b608b..0000000 --- a/code/Rmd/ch08/08.Rmd +++ /dev/null @@ -1,392 +0,0 @@ -## 8.1 ブドウの生育条件とワインの価格 - -```{r} -library(tidyverse) -my_url <- "http://www.liquidasset.com/winedata.html" -tmp <- read.table(file = my_url, # 読み込む対象 - header = TRUE, # 1行目は変数名 - na.string = ".", # 欠損値を表す文字列 - skip = 62, # 読み飛ばす行数 - nrows = 38) # 読み込む行数 -psych::describe(tmp) -#> vars n mean sd median trimmed mad min max ... -#> OBS 1 38 19.50 11.11 19.50 19.50 14.08 1.00 38.00 ... -#> VINT 2 38 1970.50 11.11 1970.50 1970.50 14.08 1952.00 1989.00 ... -#> LPRICE2 3 27 -1.45 0.63 -1.51 -1.49 0.72 -2.29 0.00 ... -#> WRAIN 4 38 605.00 135.28 586.50 603.06 174.95 376.00 845.00 ... -#> DEGREES 5 37 16.52 0.66 16.53 16.55 0.67 14.98 17.65 ... -#> HRAIN 6 38 137.00 66.74 120.50 132.19 59.30 38.00 292.00 ... -#> TIME_SV 7 38 12.50 11.11 12.50 12.50 14.08 -6.00 31.00 ... -``` - -```{r} -my_data <- na.omit(tmp[, -c(1, 2)]) -head(my_data) -#> LPRICE2 WRAIN DEGREES ... -#> 1 -0.99868 600 17.1167 ... -#> 2 -0.45440 690 16.7333 ... -#> 4 -0.80796 502 17.1500 ... -#> 6 -1.50926 420 16.1333 ... -#> 7 -1.71655 582 16.4167 ... -#> 8 -0.41800 485 17.4833 ... -``` - -```{r} -dim(my_data) -#> [1] 27 5 -``` - -```{r} -my_data %>% write_csv("wine.csv") -``` - -```{r} -#my_data <- read_csv("wine.csv") # 作ったファイルを使う場合 -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) -``` - - -## 8.2 重回帰分析 - -```{r} -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) - -my_model <- train(form = LPRICE2 ~ WRAIN + DEGREES + HRAIN + TIME_SV, - data = my_data, - method = "lm", - trControl = trainControl(method = "LOOCV")) -``` - -```{r} -coef(my_model$finalModel) %>% - as.data.frame -#> . -#> (Intercept) -12.145333577 -#> WRAIN 0.001166782 -#> DEGREES 0.616392441 -#> HRAIN -0.003860554 -#> TIME_SV 0.023847413 -``` - -```{r} -my_test <- data.frame( - WRAIN = 500, DEGREES = 17, - HRAIN = 120, TIME_SV = 2) -my_model %>% predict(my_test) -#> 1 -#> -1.498843 -``` - -```{r} -y <- my_data$LPRICE2 -y_ <- my_model %>% predict(my_data) - -RMSE(y_, y) -#> [1] 0.2586167 # RMSE(訓練) - -R2(pred = y_, obs = y, - form = "traditional") -#> [1] 0.8275278 # 決定係数1(訓練) - -R2(pred = y_, obs = y, - form = "corr") -#> [1] 0.8275278 # 決定係数6(訓練) -``` - -```{r} -my_model$results -#> intercept RMSE Rsquared MAE -#> 1 TRUE 0.3230043 0.7361273 0.2767282 -``` - -### 8.2.1 補足:行列計算による再現 - -```{r} -M <- my_data[, -1] %>% - mutate(b0 = 1) %>% as.matrix -b <- MASS::ginv(M) %*% y -matrix(b, - dimnames = list(colnames(M))) -#> [,1] -#> WRAIN 0.001166782 -#> DEGREES 0.616392441 -#> HRAIN -0.003860554 -#> TIME_SV 0.023847413 -#> b0 -12.145333577 -``` - - -## 8.3 標準化 - -```{r} -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) - -my_data %>% - mutate_if(is.numeric, scale) %>% # 数値の列の標準化 - pivot_longer(-LPRICE2) %>% - ggplot(aes(x = name, y = value)) + - geom_boxplot() + - stat_summary(fun = mean, geom = "point", size = 3) + - xlab(NULL) -``` - -```{r} -my_model <- train( - form = LPRICE2 ~ ., - data = my_data, - method = "lm", - preProcess = c("center", "scale")) -``` - -```{r} -coef(my_model$finalModel) %>% - as.data.frame -#> . -#> (Intercept) -1.4517652 -#> WRAIN 0.1505557 -#> DEGREES 0.4063194 -#> HRAIN -0.2820746 -#> TIME_SV 0.1966549 -``` - -```{r} -my_test <- data.frame( - WRAIN = 500, DEGREES = 17, - HRAIN = 120, TIME_SV = 2) -my_model %>% predict(my_test) -#> 1 -#> -1.498843 -``` - - -## 8.4 入力変数の数とモデルの良さ - -```{r} -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) - -n <- nrow(my_data) -my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2, - v2 = 0:(n - 1) %% 3) -head(my_data2) -#> # A tibble: 6 x 7 -#> LPRICE2 WRAIN DEGREES HRAIN TIME_SV v1 v2 -#> -#> 1 -0.999 600 17.1 160 31 0 0 -#> 2 -0.454 690 16.7 80 30 1 1 -#> 3 -0.808 502 17.2 130 28 0 2 -#> 4 -1.51 420 16.1 110 26 1 0 -#> 5 -1.72 582 16.4 187 25 0 1 -#> 6 -0.418 485 17.5 187 24 1 2 -``` - -```{r} -my_model2 <- train(form = LPRICE2 ~ ., data = my_data2, method = "lm", - trControl = trainControl(method = "LOOCV")) -y <- my_data2$LPRICE2 -y_ <- my_model2 %>% predict(my_data2) - -RMSE(y_, y) -#> [1] 0.256212 # RMSE(訓練) - -my_model2$results$RMSE -#> [1] 0.3569918 # RMSE(検証) -``` - - -## 8.5 変数選択 - -```{r} -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) -n <- nrow(my_data) -my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2, - v2 = 0:(n - 1) %% 3) -``` - -```{r} -my_model <- train(form = LPRICE2 ~ ., - data = my_data2, - method = "leapForward", # 変数増加法 - trControl = trainControl(method = "LOOCV"), - tuneGrid = data.frame(nvmax = 1:6)) # 選択する変数の上限 -summary(my_model$finalModel)$outmat -#> WRAIN DEGREES HRAIN TIME_SV v1 v2 -#> 1 ( 1 ) " " "*" " " " " " " " " -#> 2 ( 1 ) " " "*" "*" " " " " " " -#> 3 ( 1 ) " " "*" "*" "*" " " " " -#> 4 ( 1 ) "*" "*" "*" "*" " " " " -``` - - -## 8.6 補足:正則化 - -```{r} -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) -``` - -### 8.6.1 正則化の実践 - -```{r} -A <- 2 -B <- 0.1 - -my_model <- train( - form = LPRICE2 ~ ., - data = my_data, - method = "glmnet", - standardize = TRUE, - tuneGrid = data.frame( - lambda = A, - alpha = B)) -``` - -```{r} -coef(my_model$finalModel, A) -#> 1 -#> (Intercept) -2.8015519302 -#> WRAIN . -#> DEGREES 0.0832910512 -#> HRAIN -0.0004147386 -#> TIME_SV 0.0023104647 -``` - -```{r} -my_test <- data.frame( - WRAIN = 500, DEGREES = 17, - HRAIN = 120, TIME_SV = 2) -my_model %>% predict(my_test) -#> [1] -1.430752 -``` - -### 8.6.2 ペナルティの強さと係数の関係 - -```{r} -library(ggfortify) -library(glmnetUtils) - -my_data2 <- my_data %>% scale %>% - as.data.frame - -B <- 0.1 - -glmnet( - form = LPRICE2 ~ ., - data = my_data2, - alpha = B) %>% - autoplot(xvar = "lambda") + - xlab("log A ( = log lambda)") + - theme(legend.position = c(0.15, 0.25)) -``` - -### 8.6.3 パラメータの決定 - -```{r} -As <- seq(0, 0.1, length.out = 21) -Bs <- seq(0, 0.1, length.out = 6) - -my_model <- train( - form = LPRICE2 ~ ., data = my_data, method = "glmnet", standardize = TRUE, - trControl = trainControl(method = "LOOCV"), - tuneGrid = expand.grid(lambda = As, alpha = Bs)) - -my_model$bestTune -#> alpha lambda -#> 8 0 0.035 -``` - -```{r} -tmp <- "B ( = alpha)" -ggplot(my_model) + - theme(legend.position = c(0, 1), legend.justification = c(0, 1)) + - xlab("A ( = lambda)") + - guides(shape = guide_legend(tmp), color = guide_legend(tmp)) -``` - -```{r} -my_model$results %>% - filter(RMSE == min(RMSE)) -#> alpha lambda RMSE ... -#> 1 0 0.0595 0.3117092 ... -``` - -### 8.6.4 補足:RとPythonで結果を同じにする方法 - - -## 8.7 ニューラルネットワーク - -### 8.7.1 ニューラルネットワークとは何か - -```{r} -curve(1 / (1 + exp(-x)), -6, 6) -``` - -### 8.7.2 ニューラルネットワークの訓練 - -```{r} -library(caret) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) -``` - -```{r} -my_model <- train(form = LPRICE2 ~ ., - data = my_data, - method = "neuralnet", # ニューラルネットワーク - preProcess = c("center", "scale"), # 標準化 - trControl = trainControl(method = "LOOCV")) -plot(my_model$finalModel) # 訓練済ネットワークの描画 -``` - -```{r} -my_model$results -#> layer1 layer2 layer3 RMSE ... -#> 1 1 0 0 0.3504016 ... -#> 2 3 0 0 0.4380399 ... -#> 3 5 0 0 0.4325535 ... -``` - -### 8.7.3 ニューラルネットワークのチューニング - -```{r} -my_model <- train( - form = LPRICE2 ~ ., - data = my_data, - method = "neuralnet", - preProcess = c("center", "scale"), - trControl = trainControl(method = "LOOCV"), - tuneGrid = expand.grid(layer1 = 1:5, - layer2 = 0:2, - layer3 = 0)) -``` - -```{r} -my_model$results %>% - filter(RMSE == min(RMSE)) -#> layer1 layer2 layer3 RMSE ... -#> 1 2 0 0 0.3165704 ... -``` - - diff --git a/code/Rmd/ch09/09.01.Rmd b/code/Rmd/ch09/09.01.Rmd deleted file mode 100644 index 7ad0887..0000000 --- a/code/Rmd/ch09/09.01.Rmd +++ /dev/null @@ -1,24 +0,0 @@ -## 9.1 アヤメのデータ - -```{r} -my_data <- iris -head(my_data) -#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species -#> 1 5.1 3.5 1.4 0.2 setosa -#> 2 4.9 3.0 1.4 0.2 setosa -#> 3 4.7 3.2 1.3 0.2 setosa -#> 4 4.6 3.1 1.5 0.2 setosa -#> 5 5.0 3.6 1.4 0.2 setosa -#> 6 5.4 3.9 1.7 0.4 setosa -``` - -```{r} -psych::describe(my_data) -#> vars n mean sd median trimmed mad min max range ... -#> Sepal.Length 1 150 5.84 0.83 5.80 5.81 1.04 4.3 7.9 3.6 ... -#> Sepal.Width 2 150 3.06 0.44 3.00 3.04 0.44 2.0 4.4 2.4 ... -#> Petal.Length 3 150 3.76 1.77 4.35 3.76 1.85 1.0 6.9 5.9 ... -#> Petal.Width 4 150 1.20 0.76 1.30 1.18 1.04 0.1 2.5 2.4 ... -#> Species* 5 150 2.00 0.82 2.00 2.00 1.48 1.0 3.0 2.0 ... -``` - diff --git a/code/Rmd/ch09/09.02.Rmd b/code/Rmd/ch09/09.02.Rmd deleted file mode 100644 index fac1281..0000000 --- a/code/Rmd/ch09/09.02.Rmd +++ /dev/null @@ -1,34 +0,0 @@ -## 9.2 木による分類 - -### 9.2.1 分類木の作成と利用 - -```{r} -library(caret) -library(tidyverse) -my_data <- iris -my_model <- train(form = Species ~ ., data = my_data, method = "rpart") -``` - -```{r} -rpart.plot::rpart.plot(my_model$finalModel, extra = 1) -``` - -```{r} -my_test <- tribble( -~Sepal.Length, ~Sepal.Width, ~Petal.Length, ~Petal.Width, - 5.0, 3.5, 1.5, 0.5, - 6.5, 3.0, 5.0, 2.0) - -my_model %>% predict(my_test) -#> [1] setosa virginica -#> Levels: setosa versicolor virginica -``` - -```{r} -my_model %>% predict(my_test, - type = "prob") -#> setosa versicolor virginica -#> 1 1 0.00000000 0.0000000 -#> 2 0 0.02173913 0.9782609 -``` - diff --git a/code/Rmd/ch09/09.03.Rmd b/code/Rmd/ch09/09.03.Rmd deleted file mode 100644 index e3b3942..0000000 --- a/code/Rmd/ch09/09.03.Rmd +++ /dev/null @@ -1,108 +0,0 @@ -## 9.3 正解率 - -### 9.3.1 混同行列 - -```{r} -library(caret) -library(tidyverse) -my_data <- iris -my_model <- train(form = Species ~ ., data = my_data, method = "rpart2") - -y <- my_data$Species -y_ <- my_model %>% predict(my_data) -confusionMatrix(data = y_, reference = y) -#> Confusion Matrix and Statistics -#> -#> Reference -#> Prediction setosa versicolor virginica -#> setosa 50 0 0 -#> versicolor 0 49 1 -#> virginica 0 5 45 -# 以下は割愛 -``` - -### 9.3.2 正解率(訓練) - -```{r} -y <- my_data$Species -y_ <- my_model %>% predict(my_data) -mean(y_ == y) -#> [1] 0.96 -``` - -### 9.3.3 正解率(検証) - -```{r} -my_model <- train(form = Species ~ ., data = my_data, method = "rpart2", - trControl = trainControl(method = "LOOCV")) -my_model$results -#> maxdepth Accuracy Kappa -#> 1 1 0.3333333 0.00 -#> 2 2 0.9533333 0.93 -``` - -### 9.3.4 パラメータチューニング - -```{r} -my_model <- train(form = Species ~ ., data = my_data, method = "rpart2", - tuneGrid = data.frame(maxdepth = 1:10), - trControl = trainControl(method = "LOOCV")) -my_model$results %>% filter(Accuracy == max(Accuracy)) -#> maxdepth Accuracy Kappa -#> 1 2 0.9533333 0.93 -``` - -### 9.3.5 補足:木の複雑さの制限 - -```{r} -# パラメータを与えると正解率(LOOCV)を返す関数 -my_loocv <- function(maxdepth, minbucket, minsplit) { - my_model <- train(form = Species ~ ., data = my_data, method = "rpart2", - trControl = trainControl(method = "LOOCV"), - tuneGrid = data.frame(maxdepth = maxdepth), - control = rpart::rpart.control(cp = 0.01, - minbucket = minbucket, - minsplit = minsplit)) - list(maxdepth = maxdepth, - minbucket = minbucket, - minsplit = minsplit, - Accuracy = my_model$results$Accuracy) -} -``` - -```{r} -my_params <- expand.grid( - maxdepth = 2:5, - minbucket = 1:7, - minsplit = c(2, 20)) - -library(furrr) -plan(multisession) # 並列処理の準備 -my_results <- my_params %>% future_pmap_dfr(my_loocv, # 実行 - .options = furrr_options(seed = TRUE)) - -my_results %>% filter(Accuracy == max(Accuracy)) # 正解率(検証)の最大値 -#> maxdepth minbucket minsplit Accuracy -#> -#> 1 3 5 2 0.973 -#> 2 4 5 2 0.973 -#> 3 5 5 2 0.973 -#> 4 3 5 20 0.973 -#> 5 4 5 20 0.973 -#> 6 5 5 20 0.973 -``` - -```{r} -my_model <- train(form = Species ~ ., data = my_data, method = "rpart2", - trControl = trainControl(method = "none"), - tuneGrid = data.frame(maxdepth = 3), - control = rpart::rpart.control(cp = 0.01, - minbucket = 5, - minsplit = 2)) -``` - -```{r} -rpart.plot::rpart.plot( - my_model$finalModel, extra = 1) -``` - diff --git a/code/Rmd/ch09/09.04.Rmd b/code/Rmd/ch09/09.04.Rmd deleted file mode 100644 index 201fb1f..0000000 --- a/code/Rmd/ch09/09.04.Rmd +++ /dev/null @@ -1,55 +0,0 @@ -## 9.4 複数の木を使う方法 - -### 9.4.1 ランダムフォレスト - -```{r} -library(caret) -library(tidyverse) -my_data <- iris - -my_model <- train(form = Species ~ ., data = my_data, method = "rf", - tuneGrid = data.frame(mtry = 2:4), # 省略可 - trControl = trainControl(method = "LOOCV")) -my_model$results -#> mtry Accuracy Kappa -#> 1 2 0.96 0.94 -#> 2 3 0.96 0.94 -#> 3 4 0.96 0.94 -``` - -### 9.4.2 ブースティング - -```{r} -my_model <- train( - form = Species ~ ., data = my_data, method = "xgbTree", - tuneGrid = expand.grid( - nrounds = c(50, 100, 150), - max_depth = c(1, 2, 3), - eta = c(0.3, 0.4), - gamma = 0, - colsample_bytree = c(0.6, 0.8), - min_child_weight = 1, - subsample = c(0.5, 0.75, 1)), - trControl = trainControl(method = "cv", number = 5)) # 5分割交差検証 -my_model$results %>% filter(Accuracy == max(Accuracy)) %>% head(5) %>% t -#> 1 2 3 4 5 -#> eta 0.30000000 0.30000000 0.30000000 0.40000000 0.30000000 -#> max_depth 1.00000000 1.00000000 1.00000000 1.00000000 3.00000000 -#> gamma 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 -#> colsample_bytree 0.60000000 0.60000000 0.80000000 0.60000000 0.80000000 -#> min_child_weight 1.00000000 1.00000000 1.00000000 1.00000000 1.00000000 -#> subsample 0.50000000 0.75000000 0.75000000 0.50000000 0.50000000 -#> nrounds 50.00000000 50.00000000 50.00000000 50.00000000 50.00000000 -#> Accuracy 0.96000000 0.96000000 0.96000000 0.96000000 0.96000000 -#> Kappa 0.94000000 0.94000000 0.94000000 0.94000000 0.94000000 -#> AccuracySD 0.02788867 0.02788867 0.02788867 0.01490712 0.01490712 -#> KappaSD 0.04183300 0.04183300 0.04183300 0.02236068 0.02236068 -``` - -### 9.4.3 入力変数の重要度 - -```{r} -my_model <- train(form = Species ~ ., data = my_data, method = "rf") -ggplot(varImp(my_model)) -``` - diff --git a/code/Rmd/ch09/09.05.Rmd b/code/Rmd/ch09/09.05.Rmd deleted file mode 100644 index 38aee5b..0000000 --- a/code/Rmd/ch09/09.05.Rmd +++ /dev/null @@ -1,47 +0,0 @@ -## 9.5 欠損のあるデータでの学習 - -### 9.5.1 欠損のあるデータの準備 - -```{r} -library(caret) -library(tidyverse) -my_data <- iris - -n <- nrow(my_data) -my_data$Petal.Length[0:(n - 1) %% 10 == 0] <- NA -my_data$Petal.Width[ 0:(n - 1) %% 10 == 1] <- NA - -psych::describe(my_data) # nの値が135の変数に,150 - 135 = 15個の欠損がある. -#> vars n mean sd median trimmed mad min max range ... -#> Sepal.Length 1 150 5.84 0.83 5.8 5.81 1.04 4.3 7.9 3.6 ... -#> Sepal.Width 2 150 3.06 0.44 3.0 3.04 0.44 2.0 4.4 2.4 ... -#> Petal.Length 3 135 3.75 1.76 4.3 3.75 1.78 1.0 6.9 5.9 ... -#> Petal.Width 4 135 1.20 0.77 1.3 1.18 1.04 0.1 2.5 2.4 ... -#> Species* 5 150 2.00 0.82 2.0 2.00 1.48 1.0 3.0 2.0 ... -``` - -### 9.5.2 方針1:欠損を埋めて学習する. - -```{r} -my_model <- train( - form = Species ~ ., data = my_data, method = "rpart2", - na.action = na.pass, # 欠損があっても学習を止めない. - preProcess = "medianImpute", # 欠損を中央値で埋める. - trControl = trainControl(method = "LOOCV"), - tuneGrid = data.frame(maxdepth = 20), # 木の高さの上限 - control = rpart::rpart.control(minsplit = 2, # 分岐の条件 - minbucket = 1)) # 終端ノードの条件 -max(my_model$results$Accuracy) -#> [1] 0.9266667 -``` - -### 9.5.3 方針2:欠損があっても使える手法で学習する. - -```{r} -my_model <- train(form = Species ~ ., data = my_data, method = "xgbTree", - na.action = na.pass, - trControl = trainControl(method = "cv", number = 5)) -max(my_model$results$Accuracy) -#> [1] 0.966666666666667 -``` - diff --git a/code/Rmd/ch09/09.06.Rmd b/code/Rmd/ch09/09.06.Rmd deleted file mode 100644 index dc74c4f..0000000 --- a/code/Rmd/ch09/09.06.Rmd +++ /dev/null @@ -1,33 +0,0 @@ -## 9.6 他の分類手法 - -### 9.6.1 K最近傍法 - -```{r} -library(caret) -library(tidyverse) -my_data <- iris - -my_model <- train(form = Species ~ ., data = my_data, method = "knn", - trControl = trainControl(method = "LOOCV")) -my_model$results %>% filter(Accuracy == max(Accuracy)) -#> k Accuracy Kappa -#> 1 9 0.9733333 0.96 -``` - -### 9.6.2 ニューラルネットワーク - -```{r} -library(caret) -library(tidyverse) -my_data <- iris - -my_model <- train(form = Species ~ ., data = my_data, method = "nnet", - preProcess = c("center", "scale"), # 標準化 - trControl = trainControl(method = "LOOCV"), - trace = FALSE) # 途中経過を表示しない -my_model$results %>% filter(Accuracy == max(Accuracy)) -#> size decay Accuracy Kappa -#> 1 3 0.1 0.9733333 0.96 -#> 2 5 0.1 0.9733333 0.96 -``` - diff --git a/code/Rmd/ch09/09.Rmd b/code/Rmd/ch09/09.Rmd deleted file mode 100644 index 913460a..0000000 --- a/code/Rmd/ch09/09.Rmd +++ /dev/null @@ -1,307 +0,0 @@ -## 9.1 アヤメのデータ - -```{r} -my_data <- iris -head(my_data) -#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species -#> 1 5.1 3.5 1.4 0.2 setosa -#> 2 4.9 3.0 1.4 0.2 setosa -#> 3 4.7 3.2 1.3 0.2 setosa -#> 4 4.6 3.1 1.5 0.2 setosa -#> 5 5.0 3.6 1.4 0.2 setosa -#> 6 5.4 3.9 1.7 0.4 setosa -``` - -```{r} -psych::describe(my_data) -#> vars n mean sd median trimmed mad min max range ... -#> Sepal.Length 1 150 5.84 0.83 5.80 5.81 1.04 4.3 7.9 3.6 ... -#> Sepal.Width 2 150 3.06 0.44 3.00 3.04 0.44 2.0 4.4 2.4 ... -#> Petal.Length 3 150 3.76 1.77 4.35 3.76 1.85 1.0 6.9 5.9 ... -#> Petal.Width 4 150 1.20 0.76 1.30 1.18 1.04 0.1 2.5 2.4 ... -#> Species* 5 150 2.00 0.82 2.00 2.00 1.48 1.0 3.0 2.0 ... -``` - - -## 9.2 木による分類 - -### 9.2.1 分類木の作成と利用 - -```{r} -library(caret) -library(tidyverse) -my_data <- iris -my_model <- train(form = Species ~ ., data = my_data, method = "rpart") -``` - -```{r} -rpart.plot::rpart.plot(my_model$finalModel, extra = 1) -``` - -```{r} -my_test <- tribble( -~Sepal.Length, ~Sepal.Width, ~Petal.Length, ~Petal.Width, - 5.0, 3.5, 1.5, 0.5, - 6.5, 3.0, 5.0, 2.0) - -my_model %>% predict(my_test) -#> [1] setosa virginica -#> Levels: setosa versicolor virginica -``` - -```{r} -my_model %>% predict(my_test, - type = "prob") -#> setosa versicolor virginica -#> 1 1 0.00000000 0.0000000 -#> 2 0 0.02173913 0.9782609 -``` - - -## 9.3 正解率 - -### 9.3.1 混同行列 - -```{r} -library(caret) -library(tidyverse) -my_data <- iris -my_model <- train(form = Species ~ ., data = my_data, method = "rpart2") - -y <- my_data$Species -y_ <- my_model %>% predict(my_data) -confusionMatrix(data = y_, reference = y) -#> Confusion Matrix and Statistics -#> -#> Reference -#> Prediction setosa versicolor virginica -#> setosa 50 0 0 -#> versicolor 0 49 1 -#> virginica 0 5 45 -# 以下は割愛 -``` - -### 9.3.2 正解率(訓練) - -```{r} -y <- my_data$Species -y_ <- my_model %>% predict(my_data) -mean(y_ == y) -#> [1] 0.96 -``` - -### 9.3.3 正解率(検証) - -```{r} -my_model <- train(form = Species ~ ., data = my_data, method = "rpart2", - trControl = trainControl(method = "LOOCV")) -my_model$results -#> maxdepth Accuracy Kappa -#> 1 1 0.3333333 0.00 -#> 2 2 0.9533333 0.93 -``` - -### 9.3.4 パラメータチューニング - -```{r} -my_model <- train(form = Species ~ ., data = my_data, method = "rpart2", - tuneGrid = data.frame(maxdepth = 1:10), - trControl = trainControl(method = "LOOCV")) -my_model$results %>% filter(Accuracy == max(Accuracy)) -#> maxdepth Accuracy Kappa -#> 1 2 0.9533333 0.93 -``` - -### 9.3.5 補足:木の複雑さの制限 - -```{r} -# パラメータを与えると正解率(LOOCV)を返す関数 -my_loocv <- function(maxdepth, minbucket, minsplit) { - my_model <- train(form = Species ~ ., data = my_data, method = "rpart2", - trControl = trainControl(method = "LOOCV"), - tuneGrid = data.frame(maxdepth = maxdepth), - control = rpart::rpart.control(cp = 0.01, - minbucket = minbucket, - minsplit = minsplit)) - list(maxdepth = maxdepth, - minbucket = minbucket, - minsplit = minsplit, - Accuracy = my_model$results$Accuracy) -} -``` - -```{r} -my_params <- expand.grid( - maxdepth = 2:5, - minbucket = 1:7, - minsplit = c(2, 20)) - -library(furrr) -plan(multisession) # 並列処理の準備 -my_results <- my_params %>% future_pmap_dfr(my_loocv, # 実行 - .options = furrr_options(seed = TRUE)) - -my_results %>% filter(Accuracy == max(Accuracy)) # 正解率(検証)の最大値 -#> maxdepth minbucket minsplit Accuracy -#> -#> 1 3 5 2 0.973 -#> 2 4 5 2 0.973 -#> 3 5 5 2 0.973 -#> 4 3 5 20 0.973 -#> 5 4 5 20 0.973 -#> 6 5 5 20 0.973 -``` - -```{r} -my_model <- train(form = Species ~ ., data = my_data, method = "rpart2", - trControl = trainControl(method = "none"), - tuneGrid = data.frame(maxdepth = 3), - control = rpart::rpart.control(cp = 0.01, - minbucket = 5, - minsplit = 2)) -``` - -```{r} -rpart.plot::rpart.plot( - my_model$finalModel, extra = 1) -``` - - -## 9.4 複数の木を使う方法 - -### 9.4.1 ランダムフォレスト - -```{r} -library(caret) -library(tidyverse) -my_data <- iris - -my_model <- train(form = Species ~ ., data = my_data, method = "rf", - tuneGrid = data.frame(mtry = 2:4), # 省略可 - trControl = trainControl(method = "LOOCV")) -my_model$results -#> mtry Accuracy Kappa -#> 1 2 0.96 0.94 -#> 2 3 0.96 0.94 -#> 3 4 0.96 0.94 -``` - -### 9.4.2 ブースティング - -```{r} -my_model <- train( - form = Species ~ ., data = my_data, method = "xgbTree", - tuneGrid = expand.grid( - nrounds = c(50, 100, 150), - max_depth = c(1, 2, 3), - eta = c(0.3, 0.4), - gamma = 0, - colsample_bytree = c(0.6, 0.8), - min_child_weight = 1, - subsample = c(0.5, 0.75, 1)), - trControl = trainControl(method = "cv", number = 5)) # 5分割交差検証 -my_model$results %>% filter(Accuracy == max(Accuracy)) %>% head(5) %>% t -#> 1 2 3 4 5 -#> eta 0.30000000 0.30000000 0.30000000 0.40000000 0.30000000 -#> max_depth 1.00000000 1.00000000 1.00000000 1.00000000 3.00000000 -#> gamma 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 -#> colsample_bytree 0.60000000 0.60000000 0.80000000 0.60000000 0.80000000 -#> min_child_weight 1.00000000 1.00000000 1.00000000 1.00000000 1.00000000 -#> subsample 0.50000000 0.75000000 0.75000000 0.50000000 0.50000000 -#> nrounds 50.00000000 50.00000000 50.00000000 50.00000000 50.00000000 -#> Accuracy 0.96000000 0.96000000 0.96000000 0.96000000 0.96000000 -#> Kappa 0.94000000 0.94000000 0.94000000 0.94000000 0.94000000 -#> AccuracySD 0.02788867 0.02788867 0.02788867 0.01490712 0.01490712 -#> KappaSD 0.04183300 0.04183300 0.04183300 0.02236068 0.02236068 -``` - -### 9.4.3 入力変数の重要度 - -```{r} -my_model <- train(form = Species ~ ., data = my_data, method = "rf") -ggplot(varImp(my_model)) -``` - - -## 9.5 欠損のあるデータでの学習 - -### 9.5.1 欠損のあるデータの準備 - -```{r} -library(caret) -library(tidyverse) -my_data <- iris - -n <- nrow(my_data) -my_data$Petal.Length[0:(n - 1) %% 10 == 0] <- NA -my_data$Petal.Width[ 0:(n - 1) %% 10 == 1] <- NA - -psych::describe(my_data) # nの値が135の変数に,150 - 135 = 15個の欠損がある. -#> vars n mean sd median trimmed mad min max range ... -#> Sepal.Length 1 150 5.84 0.83 5.8 5.81 1.04 4.3 7.9 3.6 ... -#> Sepal.Width 2 150 3.06 0.44 3.0 3.04 0.44 2.0 4.4 2.4 ... -#> Petal.Length 3 135 3.75 1.76 4.3 3.75 1.78 1.0 6.9 5.9 ... -#> Petal.Width 4 135 1.20 0.77 1.3 1.18 1.04 0.1 2.5 2.4 ... -#> Species* 5 150 2.00 0.82 2.0 2.00 1.48 1.0 3.0 2.0 ... -``` - -### 9.5.2 方針1:欠損を埋めて学習する. - -```{r} -my_model <- train( - form = Species ~ ., data = my_data, method = "rpart2", - na.action = na.pass, # 欠損があっても学習を止めない. - preProcess = "medianImpute", # 欠損を中央値で埋める. - trControl = trainControl(method = "LOOCV"), - tuneGrid = data.frame(maxdepth = 20), # 木の高さの上限 - control = rpart::rpart.control(minsplit = 2, # 分岐の条件 - minbucket = 1)) # 終端ノードの条件 -max(my_model$results$Accuracy) -#> [1] 0.9266667 -``` - -### 9.5.3 方針2:欠損があっても使える手法で学習する. - -```{r} -my_model <- train(form = Species ~ ., data = my_data, method = "xgbTree", - na.action = na.pass, - trControl = trainControl(method = "cv", number = 5)) -max(my_model$results$Accuracy) -#> [1] 0.966666666666667 -``` - - -## 9.6 他の分類手法 - -### 9.6.1 K最近傍法 - -```{r} -library(caret) -library(tidyverse) -my_data <- iris - -my_model <- train(form = Species ~ ., data = my_data, method = "knn", - trControl = trainControl(method = "LOOCV")) -my_model$results %>% filter(Accuracy == max(Accuracy)) -#> k Accuracy Kappa -#> 1 9 0.9733333 0.96 -``` - -### 9.6.2 ニューラルネットワーク - -```{r} -library(caret) -library(tidyverse) -my_data <- iris - -my_model <- train(form = Species ~ ., data = my_data, method = "nnet", - preProcess = c("center", "scale"), # 標準化 - trControl = trainControl(method = "LOOCV"), - trace = FALSE) # 途中経過を表示しない -my_model$results %>% filter(Accuracy == max(Accuracy)) -#> size decay Accuracy Kappa -#> 1 3 0.1 0.9733333 0.96 -#> 2 5 0.1 0.9733333 0.96 -``` - - diff --git a/code/Rmd/ch10/10.01.Rmd b/code/Rmd/ch10/10.01.Rmd deleted file mode 100644 index 8d1d4ee..0000000 --- a/code/Rmd/ch10/10.01.Rmd +++ /dev/null @@ -1,52 +0,0 @@ -## 10.1 2値分類の性能指標 - -### 10.1.1 陽性と陰性 - -```{r} -y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1) -y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5) -``` - -```{r} -y_ <- ifelse(0.5 <= y_score, 1, 0) -y_ -#> [1] 1 1 0 0 1 1 1 0 0 1 -``` - -```{r} -library(caret) -confusionMatrix(data = as.factor(y_), # 予測 - reference = as.factor(y), # 正解 - positive = "1", # 「1」を陽性とする. - mode = "everything") # 全ての指標を求める. -#> Confusion Matrix and Statistics -#> -#> Reference -#> Prediction 0 1 -#> 0 3 1 -#> 1 2 4 -#> -#> Accuracy : 0.7 -#> 95% CI : (0.3475, 0.9333) -#> No Information Rate : 0.5 -#> P-Value [Acc > NIR] : 0.1719 -#> -#> Kappa : 0.4 -#> -#> Mcnemar's Test P-Value : 1.0000 -#> -#> Sensitivity : 0.8000 -#> Specificity : 0.6000 -#> Pos Pred Value : 0.6667 -#> Neg Pred Value : 0.7500 -#> Precision : 0.6667 -#> Recall : 0.8000 -#> F1 : 0.7273 -#> Prevalence : 0.5000 -#> Detection Rate : 0.4000 -#> Detection Prevalence : 0.6000 -#> Balanced Accuracy : 0.7000 -#> -#> 'Positive' Class : 1 -``` - diff --git a/code/Rmd/ch10/10.02.Rmd b/code/Rmd/ch10/10.02.Rmd deleted file mode 100644 index a192a21..0000000 --- a/code/Rmd/ch10/10.02.Rmd +++ /dev/null @@ -1,53 +0,0 @@ -## 10.2 トレードオフ - -### 10.2.1 偽陽性率と真陽性率のトレードオフ(ROC曲線) - -```{r} -library(PRROC) -library(tidyverse) - -y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1) -y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5) -y_ <- ifelse(0.5 <= y_score, 1, 0) - -c(sum((y == 0) & (y_ == 1)) / sum(y == 0), # FPR - sum((y == 1) & (y_ == 1)) / sum(y == 1)) # TPR -#> [1] 0.4 0.8 -``` - -```{r} -my_roc <- roc.curve(scores.class0 = y_score[y == 1], # 答えが1のもののスコア - scores.class1 = y_score[y == 0], # 答えが0のもののスコア - curve = TRUE) -my_roc %>% plot(xlab = "False Positive Rate", - ylab = "True Positive Rate", - legend = FALSE) -``` - -```{r} -my_roc$auc -#> [1] 0.8 -``` - -### 10.2.2 再現率と精度のトレードオフ(PR曲線) - -```{r} -c(sum((y == 1) & (y_ == 1)) / sum(y == 1), # Recall == TPR - sum((y == 1) & (y_ == 1)) / sum(y_ == 1)) # Precision -#> [1] 0.8000000 0.6666667 -``` - -```{r} -my_pr <- pr.curve(scores.class0 = y_score[y == 1], - scores.class1 = y_score[y == 0], - curve = TRUE) -my_pr %>% plot(xlab = "Recall", - ylab = "Precision", - legend = FALSE) -``` - -```{r} -my_pr$auc.integral -#> [1] 0.8469525 -``` - diff --git a/code/Rmd/ch10/10.03.Rmd b/code/Rmd/ch10/10.03.Rmd deleted file mode 100644 index b23ca3a..0000000 --- a/code/Rmd/ch10/10.03.Rmd +++ /dev/null @@ -1,109 +0,0 @@ -## 10.3 タイタニック - -```{r} -library(caret) -library(PRROC) -library(tidyverse) - -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/titanic.csv") -my_data <- read_csv(my_url) -``` - -```{r} -head(my_data) -#> # A tibble: 6 x 4 -#> Class Sex Age Survived -#> -#> 1 1st Male Child Yes -#> 2 1st Male Child Yes -#> 3 1st Male Child Yes -#> 4 1st Male Child Yes -#> 5 1st Male Child Yes -#> 6 1st Male Adult No -``` - -### 10.3.1 質的入力変数の扱い方 - -### 10.3.2 決定木の訓練 - -```{r} -my_model <- train(form = Survived ~ ., data = my_data, method = "rpart2", - tuneGrid = data.frame(maxdepth = 2), - trControl = trainControl(method = "LOOCV")) -``` - -### 10.3.3 決定木の描画 - -```{r} -rpart.plot::rpart.plot(my_model$finalModel, extra = 1) -``` - -### 10.3.4 決定木の評価 - -```{r} -my_model$results -#> maxdepth Accuracy Kappa -#> 1 2 0.7832803 0.4096365 -``` - -```{r} -y <- my_data$Survived -tmp <- my_model %>% predict(newdata = my_data, type = "prob") -y_score <- tmp$Yes - -my_roc <- roc.curve(scores.class0 = y_score[y == "Yes"], - scores.class1 = y_score[y == "No"], - curve = TRUE) -my_roc$auc -#> [1] 0.7114887 - -my_roc %>% plot(xlab = "False Positive Rate", - ylab = "True Positive Rate", - legend = FALSE) -``` - -### 10.3.5 補足:質的入力変数の扱い - -```{r} -X <- my_data %>% select(Class) # 質的入力変数 -y <- my_data$Survived # 出力変数 - -options(warn = -1) # これ以降,警告を表示しない. -my_model1 <- train(x = X, y = y, method = "rpart2", - tuneGrid = data.frame(maxdepth = 2), - trControl = trainControl(method = "LOOCV")) -options(warn = 0) # これ以降,警告を表示する. - -rpart.plot::rpart.plot(my_model1$finalModel, extra = 1) -my_model1$results -#> maxdepth Accuracy Kappa -#> 1 2 0.7137665 0.2373133 -``` - -```{r} -my_enc <- my_data %>% dummyVars(formula = Survived ~ Class) -my_data2 <- my_enc %>% - predict(my_data) %>% - as.data.frame %>% - mutate(Survived = my_data$Survived) - -my_model2 <- train(form = Survived ~ ., data = my_data2, method = "rpart2", - tuneGrid = data.frame(maxdepth = 2), - trControl = trainControl(method = "LOOCV")) -rpart.plot::rpart.plot(my_model2$finalModel, extra = 1) -my_model2$results -#> maxdepth Accuracy Kappa -#> 1 2 0.7137665 0.2373133 -``` - -```{r} -my_model3 <- train(form = Survived ~ Class, data = my_data, method = "rpart2", - tuneGrid = data.frame(maxdepth = 2), - trControl = trainControl(method = "LOOCV")) -rpart.plot::rpart.plot(my_model3$finalModel, extra = 1) -my_model3$results -#> maxdepth Accuracy Kappa -#> 1 2 0.6915039 0.2674485 -``` - diff --git a/code/Rmd/ch10/10.04.Rmd b/code/Rmd/ch10/10.04.Rmd deleted file mode 100644 index 538af19..0000000 --- a/code/Rmd/ch10/10.04.Rmd +++ /dev/null @@ -1,37 +0,0 @@ -## 10.4 ロジスティック回帰 - -```{r} -curve(1 / (1 + exp(-x)), -6, 6) -``` - -```{r} -library(caret) -library(PRROC) -library(tidyverse) - -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/titanic.csv") -my_data <- read_csv(my_url) - -my_model <- train(form = Survived ~ ., data = my_data, method = "glm", - trControl = trainControl(method = "LOOCV")) -``` - -```{r} -coef(my_model$finalModel) %>% - as.data.frame -#> . -#> (Intercept) 2.0438374 -#> Class2nd -1.0180950 -#> Class3rd -1.7777622 -#> ClassCrew -0.8576762 -#> SexMale -2.4200603 -#> AgeChild 1.0615424 -``` - -```{r} -my_model$results -#> parameter Accuracy Kappa -#> 1 none 0.7782826 0.4448974 -``` - diff --git a/code/Rmd/ch10/10.Rmd b/code/Rmd/ch10/10.Rmd deleted file mode 100644 index 623a77c..0000000 --- a/code/Rmd/ch10/10.Rmd +++ /dev/null @@ -1,255 +0,0 @@ -## 10.1 2値分類の性能指標 - -### 10.1.1 陽性と陰性 - -```{r} -y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1) -y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5) -``` - -```{r} -y_ <- ifelse(0.5 <= y_score, 1, 0) -y_ -#> [1] 1 1 0 0 1 1 1 0 0 1 -``` - -```{r} -library(caret) -confusionMatrix(data = as.factor(y_), # 予測 - reference = as.factor(y), # 正解 - positive = "1", # 「1」を陽性とする. - mode = "everything") # 全ての指標を求める. -#> Confusion Matrix and Statistics -#> -#> Reference -#> Prediction 0 1 -#> 0 3 1 -#> 1 2 4 -#> -#> Accuracy : 0.7 -#> 95% CI : (0.3475, 0.9333) -#> No Information Rate : 0.5 -#> P-Value [Acc > NIR] : 0.1719 -#> -#> Kappa : 0.4 -#> -#> Mcnemar's Test P-Value : 1.0000 -#> -#> Sensitivity : 0.8000 -#> Specificity : 0.6000 -#> Pos Pred Value : 0.6667 -#> Neg Pred Value : 0.7500 -#> Precision : 0.6667 -#> Recall : 0.8000 -#> F1 : 0.7273 -#> Prevalence : 0.5000 -#> Detection Rate : 0.4000 -#> Detection Prevalence : 0.6000 -#> Balanced Accuracy : 0.7000 -#> -#> 'Positive' Class : 1 -``` - - -## 10.2 トレードオフ - -### 10.2.1 偽陽性率と真陽性率のトレードオフ(ROC曲線) - -```{r} -library(PRROC) -library(tidyverse) - -y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1) -y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5) -y_ <- ifelse(0.5 <= y_score, 1, 0) - -c(sum((y == 0) & (y_ == 1)) / sum(y == 0), # FPR - sum((y == 1) & (y_ == 1)) / sum(y == 1)) # TPR -#> [1] 0.4 0.8 -``` - -```{r} -my_roc <- roc.curve(scores.class0 = y_score[y == 1], # 答えが1のもののスコア - scores.class1 = y_score[y == 0], # 答えが0のもののスコア - curve = TRUE) -my_roc %>% plot(xlab = "False Positive Rate", - ylab = "True Positive Rate", - legend = FALSE) -``` - -```{r} -my_roc$auc -#> [1] 0.8 -``` - -### 10.2.2 再現率と精度のトレードオフ(PR曲線) - -```{r} -c(sum((y == 1) & (y_ == 1)) / sum(y == 1), # Recall == TPR - sum((y == 1) & (y_ == 1)) / sum(y_ == 1)) # Precision -#> [1] 0.8000000 0.6666667 -``` - -```{r} -my_pr <- pr.curve(scores.class0 = y_score[y == 1], - scores.class1 = y_score[y == 0], - curve = TRUE) -my_pr %>% plot(xlab = "Recall", - ylab = "Precision", - legend = FALSE) -``` - -```{r} -my_pr$auc.integral -#> [1] 0.8469525 -``` - - -## 10.3 タイタニック - -```{r} -library(caret) -library(PRROC) -library(tidyverse) - -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/titanic.csv") -my_data <- read_csv(my_url) -``` - -```{r} -head(my_data) -#> # A tibble: 6 x 4 -#> Class Sex Age Survived -#> -#> 1 1st Male Child Yes -#> 2 1st Male Child Yes -#> 3 1st Male Child Yes -#> 4 1st Male Child Yes -#> 5 1st Male Child Yes -#> 6 1st Male Adult No -``` - -### 10.3.1 質的入力変数の扱い方 - -### 10.3.2 決定木の訓練 - -```{r} -my_model <- train(form = Survived ~ ., data = my_data, method = "rpart2", - tuneGrid = data.frame(maxdepth = 2), - trControl = trainControl(method = "LOOCV")) -``` - -### 10.3.3 決定木の描画 - -```{r} -rpart.plot::rpart.plot(my_model$finalModel, extra = 1) -``` - -### 10.3.4 決定木の評価 - -```{r} -my_model$results -#> maxdepth Accuracy Kappa -#> 1 2 0.7832803 0.4096365 -``` - -```{r} -y <- my_data$Survived -tmp <- my_model %>% predict(newdata = my_data, type = "prob") -y_score <- tmp$Yes - -my_roc <- roc.curve(scores.class0 = y_score[y == "Yes"], - scores.class1 = y_score[y == "No"], - curve = TRUE) -my_roc$auc -#> [1] 0.7114887 - -my_roc %>% plot(xlab = "False Positive Rate", - ylab = "True Positive Rate", - legend = FALSE) -``` - -### 10.3.5 補足:質的入力変数の扱い - -```{r} -X <- my_data %>% select(Class) # 質的入力変数 -y <- my_data$Survived # 出力変数 - -options(warn = -1) # これ以降,警告を表示しない. -my_model1 <- train(x = X, y = y, method = "rpart2", - tuneGrid = data.frame(maxdepth = 2), - trControl = trainControl(method = "LOOCV")) -options(warn = 0) # これ以降,警告を表示する. - -rpart.plot::rpart.plot(my_model1$finalModel, extra = 1) -my_model1$results -#> maxdepth Accuracy Kappa -#> 1 2 0.7137665 0.2373133 -``` - -```{r} -my_enc <- my_data %>% dummyVars(formula = Survived ~ Class) -my_data2 <- my_enc %>% - predict(my_data) %>% - as.data.frame %>% - mutate(Survived = my_data$Survived) - -my_model2 <- train(form = Survived ~ ., data = my_data2, method = "rpart2", - tuneGrid = data.frame(maxdepth = 2), - trControl = trainControl(method = "LOOCV")) -rpart.plot::rpart.plot(my_model2$finalModel, extra = 1) -my_model2$results -#> maxdepth Accuracy Kappa -#> 1 2 0.7137665 0.2373133 -``` - -```{r} -my_model3 <- train(form = Survived ~ Class, data = my_data, method = "rpart2", - tuneGrid = data.frame(maxdepth = 2), - trControl = trainControl(method = "LOOCV")) -rpart.plot::rpart.plot(my_model3$finalModel, extra = 1) -my_model3$results -#> maxdepth Accuracy Kappa -#> 1 2 0.6915039 0.2674485 -``` - - -## 10.4 ロジスティック回帰 - -```{r} -curve(1 / (1 + exp(-x)), -6, 6) -``` - -```{r} -library(caret) -library(PRROC) -library(tidyverse) - -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/titanic.csv") -my_data <- read_csv(my_url) - -my_model <- train(form = Survived ~ ., data = my_data, method = "glm", - trControl = trainControl(method = "LOOCV")) -``` - -```{r} -coef(my_model$finalModel) %>% - as.data.frame -#> . -#> (Intercept) 2.0438374 -#> Class2nd -1.0180950 -#> Class3rd -1.7777622 -#> ClassCrew -0.8576762 -#> SexMale -2.4200603 -#> AgeChild 1.0615424 -``` - -```{r} -my_model$results -#> parameter Accuracy Kappa -#> 1 none 0.7782826 0.4448974 -``` - - diff --git a/code/Rmd/ch11/11.01.Rmd b/code/Rmd/ch11/11.01.Rmd deleted file mode 100644 index ef774a5..0000000 --- a/code/Rmd/ch11/11.01.Rmd +++ /dev/null @@ -1,73 +0,0 @@ -## 11.1 Kerasによる回帰 - -```{r} -library(keras) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -tmp <- read_csv(my_url) -``` - -```{r} -my_data <- tmp[sample(nrow(tmp)), ] -``` - -```{r} -X <- my_data %>% - select(-LPRICE2) %>% scale -y <- my_data$LPRICE2 -``` - -```{r} -curve(activation_relu(x), -3, 3) -``` - -```{r} -my_model <- keras_model_sequential() %>% - layer_dense(units = 3, activation = "relu", input_shape = c(4)) %>% - layer_dense(units = 1) - -summary(my_model) # ネットワークの概要 -# 割愛(Pythonの結果を参照) -``` - -```{r} -my_model %>% compile( - loss = "mse", - optimizer = "rmsprop") -``` - -```{r} -my_cb <- callback_early_stopping( - patience = 20, - restore_best_weights = TRUE) -``` - -```{r} -my_history <- my_model %>% fit( - x = X, - y = y, - validation_split = 0.25, - batch_size = 10, - epochs = 500, - callbacks = list(my_cb), - verbose = 0) -``` - -```{r} -plot(my_history) -``` - -```{r} -my_history -#> Final epoch (plot to see history): -#> loss: 0.06124 -#> val_loss: 0.1132 -``` - -```{r} -y_ <- my_model %>% predict(X) -mean((y_ - y)^2)**0.5 -#> [1] 0.2724372 -``` - diff --git a/code/Rmd/ch11/11.02.Rmd b/code/Rmd/ch11/11.02.Rmd deleted file mode 100644 index cf7e9c1..0000000 --- a/code/Rmd/ch11/11.02.Rmd +++ /dev/null @@ -1,87 +0,0 @@ -## 11.2 Kerasによる分類 - -```{r} -library(keras) -library(tidyverse) -my_data <- iris[sample(nrow(iris)), ] -``` - -```{r} -X <- my_data %>% - select(-Species) %>% scale -y <- as.integer(my_data$Species) - 1 -``` - -```{r} -my_model <- keras_model_sequential() %>% - layer_dense(units = 3, activation = "relu", input_shape = c(4)) %>% - layer_dense(units = 3, activation = "softmax") -``` - -```{r} -my_model %>% compile(loss = "sparse_categorical_crossentropy", - optimizer = "rmsprop", - metrics = c("accuracy")) -``` - -```{r} -my_cb <- callback_early_stopping( - patience = 20, - restore_best_weights = TRUE) - -my_history <- my_model %>% - fit(x = X, - y = y, - validation_split = 0.25, - batch_size = 10, - epochs = 500, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) -``` - -```{r} -my_history -#> Final epoch (plot to see history): -#> loss: 0.06206 -#> accuracy: 0.9732 -#> val_loss: 0.1269 -#> val_accuracy: 0.9211 -``` - -```{r} -tmp <- my_model %>% predict(X) -y_ <- apply(tmp, 1, which.max) - 1 -mean(y_ == y) -#> [1] 0.9666667 -``` - -### 11.2.1 交差エントロピー - -```{r} --mean(log(c(0.8, 0.7, 0.3, 0.8))) -#> 0.5017337 - --mean(log(c(0.7, 0.6, 0.2, 0.7))) -#> 0.7084034 -``` - -```{r} -y <- c(2, 1, 0, 1) -y_1 <- list(c(0.1, 0.1, 0.8), - c(0.1, 0.7, 0.2), - c(0.3, 0.4, 0.3), - c(0.1, 0.8, 0.1)) -y_2 <- list(c(0.1, 0.2, 0.7), - c(0.2, 0.6, 0.2), - c(0.2, 0.5, 0.3), - c(0.2, 0.7, 0.1)) -``` - -```{r} -c(mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_1))), - mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_2)))) -#> [1] 0.5017337 0.7084033 -``` - diff --git a/code/Rmd/ch11/11.03.Rmd b/code/Rmd/ch11/11.03.Rmd deleted file mode 100644 index cf7d011..0000000 --- a/code/Rmd/ch11/11.03.Rmd +++ /dev/null @@ -1,248 +0,0 @@ -## 11.3 MNIST:手書き数字の分類 - -### 11.3.1 データの形式 - -```{r} -library(keras) -library(tidyverse) -keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist()) -``` - -```{r} -dim(x_train) -#> [1] 60000 28 28 -``` - -```{r} -x_train[5, , ] -``` - -```{r} -plot(as.raster(x = x_train[5, , ], - max = max(x_train))) -``` - -```{r} -head(y_train) -#> [1] 5 0 4 1 9 2 -``` - -```{r} -c(min(x_train), max(x_train)) -#> [1] 0 255 -``` - -```{r} -x_train <- x_train / 255 -x_test <- x_test / 255 -``` - -```{r} -my_index <- sample(1:60000, 6000) -x_train <- x_train[my_index, , ] -y_train <- y_train[my_index] -``` - -### 11.3.2 多層パーセプトロン - -```{r} -my_model <- keras_model_sequential() %>% - layer_flatten(input_shape = c(28, 28)) %>% - layer_dense(units = 256, activation = "relu") %>% - layer_dense(units = 10, activation = "softmax") -summary(my_model) -# 割愛(Pythonの結果を参照) - -my_model %>% compile(loss = "sparse_categorical_crossentropy", - optimizer = "rmsprop", - metrics = c("accuracy")) - -my_cb <- callback_early_stopping(patience = 5, - restore_best_weights = TRUE) -``` - -```{r} -my_history <- my_model %>% - fit(x = x_train, - y = y_train, - validation_split = 0.2, - batch_size = 128, - epochs = 20, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) -``` - -```{r} -tmp <- my_model %>% predict(x_test) -y_ <- apply(tmp, 1, which.max) - 1 -table(y_, y_test) -``` - -```{r} -#> y_test -#> y_ 0 1 2 3 4 5 6 7 8 9 -#> 0 962 0 8 2 0 6 11 0 8 11 -#> 1 0 1110 1 0 3 1 3 8 2 4 -#> 2 0 5 959 13 4 4 2 16 6 1 -#> 3 1 1 22 958 1 27 0 7 33 13 -#> 4 2 0 6 1 905 8 6 6 3 14 -#> 5 5 2 0 12 1 809 9 1 15 4 -#> 6 6 3 8 0 8 11 922 0 5 1 -#> 7 1 1 7 7 1 2 0 963 4 8 -#> 8 2 13 19 13 4 16 5 0 890 5 -#> 9 1 0 2 4 55 8 0 27 8 948 -``` - -```{r} -mean(y_ == y_test) -#> [1] 0.9426000 -``` - -```{r} -my_model %>% - evaluate(x = x_test, y = y_test) -#> loss accuracy -#> 0.2071411 0.9426000 -``` - -### 11.3.3 畳み込みニューラルネットワーク(CNN) - -```{r} -x_train2d <- x_train %>% array_reshape(c(-1, 28, 28, 1)) -x_test2d <- x_test %>% array_reshape(c(-1, 28, 28, 1)) -``` - -#### 11.3.3.1 単純なCNN - -```{r} -my_model <- keras_model_sequential() %>% - layer_conv_2d(filters = 32, kernel_size = 3, # 畳み込み層 - activation = "relu", - input_shape = c(28, 28, 1)) %>% - layer_max_pooling_2d(pool_size = 2) %>% # プーリング層 - layer_flatten() %>% - layer_dense(units = 128, activation = "relu") %>% - layer_dense(units = 10, activation = "softmax") - -summary(my_model) -# 割愛(Python の結果を参照) - -my_model %>% compile(loss = "sparse_categorical_crossentropy", - optimizer = "rmsprop", - metrics = c("accuracy")) - -my_cb <- callback_early_stopping(patience = 5, - restore_best_weights = TRUE) -``` - -```{r} -my_history <- my_model %>% - fit(x = x_train2d, - y = y_train, - validation_split = 0.2, - batch_size = 128, - epochs = 20, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) -``` - -```{r} -my_model %>% - evaluate(x = x_test2d, y = y_test) -#> loss accuracy -#> 0.1392894 0.9607000 -``` - -#### 11.3.3.2 LeNet - -```{r} -my_model <- keras_model_sequential() %>% - layer_conv_2d(filters = 20, kernel_size = 5, activation = "relu", - input_shape = c(28, 28, 1)) %>% - layer_max_pooling_2d(pool_size = 2, strides = 2) %>% - layer_conv_2d(filters = 50, kernel_size = 5, activation = "relu") %>% - layer_max_pooling_2d(pool_size = 2, strides = 2) %>% - layer_dropout(rate = 0.25) %>% - layer_flatten() %>% - layer_dense(units = 500, activation = "relu") %>% - layer_dropout(rate = 0.5) %>% - layer_dense(units = 10, activation = "softmax") - -my_model %>% compile( - loss = "sparse_categorical_crossentropy", - optimizer = "rmsprop", - metrics = c("accuracy")) - -my_cb <- callback_early_stopping(patience = 5, - restore_best_weights = TRUE) -``` - -```{r} -my_history <- my_model %>% - fit(x = x_train2d, - y = y_train, - validation_split = 0.2, - batch_size = 128, - epochs = 20, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) -``` - -```{r} -my_model %>% - evaluate(x = x_test2d, y = y_test) -#> loss accuracy -#> 0.07309694 0.98060000 -``` - -#### 11.3.3.3 補足:LeNetが自信満々で間違う例 - -```{r} -y_prob <- my_model %>% predict(x_test2d) # カテゴリに属する確率 - -my_result <- data.frame( - y_prob = apply(y_prob, 1, max), # 確率の最大値 - y_ = apply(y_prob, 1, which.max) - 1, # 予測カテゴリ - y = y_test, # 正解 - id = seq_len(length(y_test))) %>% # 番号 - filter(y_ != y) %>% # 予測がはずれたものを残す - arrange(desc(y_prob)) # 確率の大きい順に並び替える -``` - -```{r} -head(my_result) -#> y_prob y_ y id -#> 1 0.9998116 9 4 2131 -#> 2 0.9988768 6 5 9730 -#> 3 0.9986107 3 5 2598 -#> 4 0.9971705 3 5 2036 -#> 5 0.9888211 1 6 2655 -#> 6 0.9857675 0 6 2119 -``` - -```{r} -tmp <- my_result[1:5, ]$id -my_labels <- sprintf("%s (%s)", - my_result[1:5, ]$y, tmp) -my_fig <- expand.grid( - label = my_labels, - y = 28:1, - x = 1:28) -my_fig$z <- as.vector( - x_test[tmp, , ]) - -my_fig %>% ggplot( - aes(x = x, y = y, fill = z)) + - geom_raster() + - coord_fixed() + - theme_void() + - theme(legend.position = "none") + - facet_grid(. ~ label) -``` - diff --git a/code/Rmd/ch11/11.04.Rmd b/code/Rmd/ch11/11.04.Rmd deleted file mode 100644 index 4568548..0000000 --- a/code/Rmd/ch11/11.04.Rmd +++ /dev/null @@ -1,110 +0,0 @@ -## 11.4 AutoML - -### 11.4.1 H2Oの起動と停止 - -```{r} -library(h2o) -library(keras) -library(tidyverse) - -h2o.init() -h2o.no_progress() -# h2o.shutdown(prompt = FALSE) # 停止 -``` - -### 11.4.2 H2Oのデータフレーム - -```{r} -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) -my_frame <- as.h2o(my_data) # 通常のデータフレームをH2OFrameに変換する. -# あるいは -my_frame <- h2o.importFile(my_url, header = TRUE) # データを読み込む. -``` - -```{r} -my_frame -#> LPRICE2 WRAIN DEGREES HRAIN ... -#> 1 -0.99868 600 17.1167 160 ... -#> 2 -0.45440 690 16.7333 80 ... -#> 3 -0.80796 502 17.1500 130 ... -#> 4 -1.50926 420 16.1333 110 ... -#> 5 -1.71655 582 16.4167 187 ... -#> 6 -0.41800 485 17.4833 187 ... -#> -#> [27 rows x 5 columns] - -# 通常のデータフレームに戻す. -my_frame %>% as.data.frame %>% head -# 結果は割愛(見た目は同じ) -``` - -### 11.4.3 AutoMLによる回帰 - -```{r} -my_model <- h2o.automl( - y = "LPRICE2", - training_frame = my_frame, - max_runtime_secs = 60) -``` - -```{r} -min(my_model@leaderboard$rmse) -#> [1] 0.2922861 -``` - -```{r} -tmp <- my_model %>% - predict(my_frame) %>% - as.data.frame -y_ <- tmp$predict -y <- my_data$LPRICE2 - -plot(y, y_) -``` - -### 11.4.4 AutoMLによる分類 - -```{r} -keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist()) -my_index <- sample(1:60000, 6000) -x_train <- x_train[my_index, , ] -y_train <- y_train[my_index] -``` - -```{r} -tmp <- x_train %>% - array_reshape(c(-1, 28 * 28)) %>% - as.data.frame -tmp$y <- as.factor(y_train) -my_train <- as.h2o(tmp) - -tmp <- x_test %>% - array_reshape(c(-1, 28 * 28)) %>% - as.data.frame -my_test <- as.h2o(tmp) -``` - -```{r} -my_model <- h2o.automl( - y = "y", - training_frame = my_train, - max_runtime_secs = 120) -``` - -```{r} -min(my_model@leaderboard$ - mean_per_class_error) -#> [1] 0.0806190885648608 -``` - -```{r} -tmp <- my_model %>% - predict(my_test) %>% as.data.frame -y_ <- tmp$predict - -mean(y_ == y_test) -#> [1] 0.9306 -``` - diff --git a/code/Rmd/ch11/11.Rmd b/code/Rmd/ch11/11.Rmd deleted file mode 100644 index ea2ca04..0000000 --- a/code/Rmd/ch11/11.Rmd +++ /dev/null @@ -1,522 +0,0 @@ -## 11.1 Kerasによる回帰 - -```{r} -library(keras) -library(tidyverse) -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -tmp <- read_csv(my_url) -``` - -```{r} -my_data <- tmp[sample(nrow(tmp)), ] -``` - -```{r} -X <- my_data %>% - select(-LPRICE2) %>% scale -y <- my_data$LPRICE2 -``` - -```{r} -curve(activation_relu(x), -3, 3) -``` - -```{r} -my_model <- keras_model_sequential() %>% - layer_dense(units = 3, activation = "relu", input_shape = c(4)) %>% - layer_dense(units = 1) - -summary(my_model) # ネットワークの概要 -# 割愛(Pythonの結果を参照) -``` - -```{r} -my_model %>% compile( - loss = "mse", - optimizer = "rmsprop") -``` - -```{r} -my_cb <- callback_early_stopping( - patience = 20, - restore_best_weights = TRUE) -``` - -```{r} -my_history <- my_model %>% fit( - x = X, - y = y, - validation_split = 0.25, - batch_size = 10, - epochs = 500, - callbacks = list(my_cb), - verbose = 0) -``` - -```{r} -plot(my_history) -``` - -```{r} -my_history -#> Final epoch (plot to see history): -#> loss: 0.06124 -#> val_loss: 0.1132 -``` - -```{r} -y_ <- my_model %>% predict(X) -mean((y_ - y)^2)**0.5 -#> [1] 0.2724372 -``` - - -## 11.2 Kerasによる分類 - -```{r} -library(keras) -library(tidyverse) -my_data <- iris[sample(nrow(iris)), ] -``` - -```{r} -X <- my_data %>% - select(-Species) %>% scale -y <- as.integer(my_data$Species) - 1 -``` - -```{r} -my_model <- keras_model_sequential() %>% - layer_dense(units = 3, activation = "relu", input_shape = c(4)) %>% - layer_dense(units = 3, activation = "softmax") -``` - -```{r} -my_model %>% compile(loss = "sparse_categorical_crossentropy", - optimizer = "rmsprop", - metrics = c("accuracy")) -``` - -```{r} -my_cb <- callback_early_stopping( - patience = 20, - restore_best_weights = TRUE) - -my_history <- my_model %>% - fit(x = X, - y = y, - validation_split = 0.25, - batch_size = 10, - epochs = 500, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) -``` - -```{r} -my_history -#> Final epoch (plot to see history): -#> loss: 0.06206 -#> accuracy: 0.9732 -#> val_loss: 0.1269 -#> val_accuracy: 0.9211 -``` - -```{r} -tmp <- my_model %>% predict(X) -y_ <- apply(tmp, 1, which.max) - 1 -mean(y_ == y) -#> [1] 0.9666667 -``` - -### 11.2.1 交差エントロピー - -```{r} --mean(log(c(0.8, 0.7, 0.3, 0.8))) -#> 0.5017337 - --mean(log(c(0.7, 0.6, 0.2, 0.7))) -#> 0.7084034 -``` - -```{r} -y <- c(2, 1, 0, 1) -y_1 <- list(c(0.1, 0.1, 0.8), - c(0.1, 0.7, 0.2), - c(0.3, 0.4, 0.3), - c(0.1, 0.8, 0.1)) -y_2 <- list(c(0.1, 0.2, 0.7), - c(0.2, 0.6, 0.2), - c(0.2, 0.5, 0.3), - c(0.2, 0.7, 0.1)) -``` - -```{r} -c(mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_1))), - mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_2)))) -#> [1] 0.5017337 0.7084033 -``` - - -## 11.3 MNIST:手書き数字の分類 - -### 11.3.1 データの形式 - -```{r} -library(keras) -library(tidyverse) -keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist()) -``` - -```{r} -dim(x_train) -#> [1] 60000 28 28 -``` - -```{r} -x_train[5, , ] -``` - -```{r} -plot(as.raster(x = x_train[5, , ], - max = max(x_train))) -``` - -```{r} -head(y_train) -#> [1] 5 0 4 1 9 2 -``` - -```{r} -c(min(x_train), max(x_train)) -#> [1] 0 255 -``` - -```{r} -x_train <- x_train / 255 -x_test <- x_test / 255 -``` - -```{r} -my_index <- sample(1:60000, 6000) -x_train <- x_train[my_index, , ] -y_train <- y_train[my_index] -``` - -### 11.3.2 多層パーセプトロン - -```{r} -my_model <- keras_model_sequential() %>% - layer_flatten(input_shape = c(28, 28)) %>% - layer_dense(units = 256, activation = "relu") %>% - layer_dense(units = 10, activation = "softmax") -summary(my_model) -# 割愛(Pythonの結果を参照) - -my_model %>% compile(loss = "sparse_categorical_crossentropy", - optimizer = "rmsprop", - metrics = c("accuracy")) - -my_cb <- callback_early_stopping(patience = 5, - restore_best_weights = TRUE) -``` - -```{r} -my_history <- my_model %>% - fit(x = x_train, - y = y_train, - validation_split = 0.2, - batch_size = 128, - epochs = 20, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) -``` - -```{r} -tmp <- my_model %>% predict(x_test) -y_ <- apply(tmp, 1, which.max) - 1 -table(y_, y_test) -``` - -```{r} -#> y_test -#> y_ 0 1 2 3 4 5 6 7 8 9 -#> 0 962 0 8 2 0 6 11 0 8 11 -#> 1 0 1110 1 0 3 1 3 8 2 4 -#> 2 0 5 959 13 4 4 2 16 6 1 -#> 3 1 1 22 958 1 27 0 7 33 13 -#> 4 2 0 6 1 905 8 6 6 3 14 -#> 5 5 2 0 12 1 809 9 1 15 4 -#> 6 6 3 8 0 8 11 922 0 5 1 -#> 7 1 1 7 7 1 2 0 963 4 8 -#> 8 2 13 19 13 4 16 5 0 890 5 -#> 9 1 0 2 4 55 8 0 27 8 948 -``` - -```{r} -mean(y_ == y_test) -#> [1] 0.9426000 -``` - -```{r} -my_model %>% - evaluate(x = x_test, y = y_test) -#> loss accuracy -#> 0.2071411 0.9426000 -``` - -### 11.3.3 畳み込みニューラルネットワーク(CNN) - -```{r} -x_train2d <- x_train %>% array_reshape(c(-1, 28, 28, 1)) -x_test2d <- x_test %>% array_reshape(c(-1, 28, 28, 1)) -``` - -#### 11.3.3.1 単純なCNN - -```{r} -my_model <- keras_model_sequential() %>% - layer_conv_2d(filters = 32, kernel_size = 3, # 畳み込み層 - activation = "relu", - input_shape = c(28, 28, 1)) %>% - layer_max_pooling_2d(pool_size = 2) %>% # プーリング層 - layer_flatten() %>% - layer_dense(units = 128, activation = "relu") %>% - layer_dense(units = 10, activation = "softmax") - -summary(my_model) -# 割愛(Python の結果を参照) - -my_model %>% compile(loss = "sparse_categorical_crossentropy", - optimizer = "rmsprop", - metrics = c("accuracy")) - -my_cb <- callback_early_stopping(patience = 5, - restore_best_weights = TRUE) -``` - -```{r} -my_history <- my_model %>% - fit(x = x_train2d, - y = y_train, - validation_split = 0.2, - batch_size = 128, - epochs = 20, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) -``` - -```{r} -my_model %>% - evaluate(x = x_test2d, y = y_test) -#> loss accuracy -#> 0.1392894 0.9607000 -``` - -#### 11.3.3.2 LeNet - -```{r} -my_model <- keras_model_sequential() %>% - layer_conv_2d(filters = 20, kernel_size = 5, activation = "relu", - input_shape = c(28, 28, 1)) %>% - layer_max_pooling_2d(pool_size = 2, strides = 2) %>% - layer_conv_2d(filters = 50, kernel_size = 5, activation = "relu") %>% - layer_max_pooling_2d(pool_size = 2, strides = 2) %>% - layer_dropout(rate = 0.25) %>% - layer_flatten() %>% - layer_dense(units = 500, activation = "relu") %>% - layer_dropout(rate = 0.5) %>% - layer_dense(units = 10, activation = "softmax") - -my_model %>% compile( - loss = "sparse_categorical_crossentropy", - optimizer = "rmsprop", - metrics = c("accuracy")) - -my_cb <- callback_early_stopping(patience = 5, - restore_best_weights = TRUE) -``` - -```{r} -my_history <- my_model %>% - fit(x = x_train2d, - y = y_train, - validation_split = 0.2, - batch_size = 128, - epochs = 20, - callbacks = list(my_cb), - verbose = 0) - -plot(my_history) -``` - -```{r} -my_model %>% - evaluate(x = x_test2d, y = y_test) -#> loss accuracy -#> 0.07309694 0.98060000 -``` - -#### 11.3.3.3 補足:LeNetが自信満々で間違う例 - -```{r} -y_prob <- my_model %>% predict(x_test2d) # カテゴリに属する確率 - -my_result <- data.frame( - y_prob = apply(y_prob, 1, max), # 確率の最大値 - y_ = apply(y_prob, 1, which.max) - 1, # 予測カテゴリ - y = y_test, # 正解 - id = seq_len(length(y_test))) %>% # 番号 - filter(y_ != y) %>% # 予測がはずれたものを残す - arrange(desc(y_prob)) # 確率の大きい順に並び替える -``` - -```{r} -head(my_result) -#> y_prob y_ y id -#> 1 0.9998116 9 4 2131 -#> 2 0.9988768 6 5 9730 -#> 3 0.9986107 3 5 2598 -#> 4 0.9971705 3 5 2036 -#> 5 0.9888211 1 6 2655 -#> 6 0.9857675 0 6 2119 -``` - -```{r} -tmp <- my_result[1:5, ]$id -my_labels <- sprintf("%s (%s)", - my_result[1:5, ]$y, tmp) -my_fig <- expand.grid( - label = my_labels, - y = 28:1, - x = 1:28) -my_fig$z <- as.vector( - x_test[tmp, , ]) - -my_fig %>% ggplot( - aes(x = x, y = y, fill = z)) + - geom_raster() + - coord_fixed() + - theme_void() + - theme(legend.position = "none") + - facet_grid(. ~ label) -``` - - -## 11.4 AutoML - -### 11.4.1 H2Oの起動と停止 - -```{r} -library(h2o) -library(keras) -library(tidyverse) - -h2o.init() -h2o.no_progress() -# h2o.shutdown(prompt = FALSE) # 停止 -``` - -### 11.4.2 H2Oのデータフレーム - -```{r} -my_url <- str_c("https://raw.githubusercontent.com/taroyabuki", - "/fromzero/master/data/wine.csv") -my_data <- read_csv(my_url) -my_frame <- as.h2o(my_data) # 通常のデータフレームをH2OFrameに変換する. -# あるいは -my_frame <- h2o.importFile(my_url, header = TRUE) # データを読み込む. -``` - -```{r} -my_frame -#> LPRICE2 WRAIN DEGREES HRAIN ... -#> 1 -0.99868 600 17.1167 160 ... -#> 2 -0.45440 690 16.7333 80 ... -#> 3 -0.80796 502 17.1500 130 ... -#> 4 -1.50926 420 16.1333 110 ... -#> 5 -1.71655 582 16.4167 187 ... -#> 6 -0.41800 485 17.4833 187 ... -#> -#> [27 rows x 5 columns] - -# 通常のデータフレームに戻す. -my_frame %>% as.data.frame %>% head -# 結果は割愛(見た目は同じ) -``` - -### 11.4.3 AutoMLによる回帰 - -```{r} -my_model <- h2o.automl( - y = "LPRICE2", - training_frame = my_frame, - max_runtime_secs = 60) -``` - -```{r} -min(my_model@leaderboard$rmse) -#> [1] 0.2922861 -``` - -```{r} -tmp <- my_model %>% - predict(my_frame) %>% - as.data.frame -y_ <- tmp$predict -y <- my_data$LPRICE2 - -plot(y, y_) -``` - -### 11.4.4 AutoMLによる分類 - -```{r} -keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist()) -my_index <- sample(1:60000, 6000) -x_train <- x_train[my_index, , ] -y_train <- y_train[my_index] -``` - -```{r} -tmp <- x_train %>% - array_reshape(c(-1, 28 * 28)) %>% - as.data.frame -tmp$y <- as.factor(y_train) -my_train <- as.h2o(tmp) - -tmp <- x_test %>% - array_reshape(c(-1, 28 * 28)) %>% - as.data.frame -my_test <- as.h2o(tmp) -``` - -```{r} -my_model <- h2o.automl( - y = "y", - training_frame = my_train, - max_runtime_secs = 120) -``` - -```{r} -min(my_model@leaderboard$ - mean_per_class_error) -#> [1] 0.0806190885648608 -``` - -```{r} -tmp <- my_model %>% - predict(my_test) %>% as.data.frame -y_ <- tmp$predict - -mean(y_ == y_test) -#> [1] 0.9306 -``` - - diff --git a/code/Rmd/ch12/12.01.Rmd b/code/Rmd/ch12/12.01.Rmd deleted file mode 100644 index a169e93..0000000 --- a/code/Rmd/ch12/12.01.Rmd +++ /dev/null @@ -1,29 +0,0 @@ -## 12.1 日時と日時の列 - -### 12.1.1 日時 - -```{r} -as.POSIXct("2021-01-01") -#> [1] "2021-01-01 JST" -``` - -### 12.1.2 等間隔の日時 - -```{r} -library(tsibble) - -seq(from = 2021, to = 2023, by = 1) -#> [1] 2021 2022 2023 - -seq(from = yearmonth("202101"), to = yearmonth("202103"), by = 2) -#> -#> [1] "2021 1" "2021 3" - -seq(from = as.POSIXct("2021-01-01"), to = as.POSIXct("2021-01-03"), by = "1 day") -#> [1] "2021-01-01 JST" "2021-01-02 JST" "2021-01-03 JST" - -seq(from = as.POSIXct("2021-01-01 00:00:00"), - to = as.POSIXct("2021-01-01 03:00:00"), by = "2 hour") -#> [1] "2021-01-01 00:00:00 JST" "2021-01-01 02:00:00 JST" -``` - diff --git a/code/Rmd/ch12/12.02.Rmd b/code/Rmd/ch12/12.02.Rmd deleted file mode 100644 index 3f24e14..0000000 --- a/code/Rmd/ch12/12.02.Rmd +++ /dev/null @@ -1,159 +0,0 @@ -## 12.2 時系列データの予測 - -### 12.2.1 データの準備 - -```{r} -my_data <- as.vector(AirPassengers) -``` - -```{r} -n <- length(my_data) # データ数(144) -k <- 108 # 訓練データ数 -``` - -```{r} -library(tidyverse) -library(tsibble) - -my_ds <- seq( - from = yearmonth("1949/01"), - to = yearmonth("1960/12"), - by = 1) -my_label <- rep( - c("train", "test"), - c(k, n - k)) -my_df <- tsibble( - ds = my_ds, - x = 0:(n - 1), - y = my_data, - label = my_label, - index = ds) # 日時の列の指定 - -head(my_df) -#> # A tsibble: 6 x 4 [1M] -#> ds x y label -#> -#> 1 1949 1 0 112 train -#> 2 1949 2 1 118 train -#> 3 1949 3 2 132 train -#> 4 1949 4 3 129 train -#> 5 1949 5 4 121 train -#> 6 1949 6 5 135 train -``` - -```{r} -my_train <- my_df[ 1:k , ] -my_test <- my_df[-(1:k), ] -y <- my_test$y -``` - -```{r} -my_plot <- my_df %>% - ggplot(aes(x = ds, - y = y, - color = label)) + - geom_line() -my_plot -``` - -### 12.2.2 線形回帰分析による時系列予測 - -```{r} -library(caret) -my_lm_model <- train(form = y ~ x, data = my_train, method = "lm") -y_ <- my_lm_model %>% predict(my_test) -caret::RMSE(y, y_) # RMSE(テスト) -#> [1] 70.63707 -``` - -```{r} -y_ <- my_lm_model %>% predict(my_df) -tmp <- my_df %>% - mutate(y = y_, label = "model") -my_plot + geom_line(data = tmp) -``` - -### 12.2.3 SARIMAによる時系列予測 - -#### 12.2.3.1 モデルの構築 - -```{r} -library(fable) -my_arima_model <- my_train %>% model(ARIMA(y)) -my_arima_model -#> # A mable: 1 x 1 -#> `ARIMA(y)` -#> -#> 1 -``` - -#### 12.2.3.2 予測 - -```{r} -tmp <- my_arima_model %>% forecast(h = "3 years") -head(tmp) -#> # A fable: 6 x 4 [1M] -#> # Key: .model [1] -#> .model ds y .mean -#> -#> 1 ARIMA(y) 1958 1 N(346, 94) 346. -#> 2 ARIMA(y) 1958 2 N(332, 148) 332. -#> 3 ARIMA(y) 1958 3 N(387, 210) 387. -#> 4 ARIMA(y) 1958 4 N(379, 271) 379. -#> 5 ARIMA(y) 1958 5 N(386, 332) 386. -#> 6 ARIMA(y) 1958 6 N(453, 393) 453. -``` - -```{r} -y_ <- tmp$.mean -caret::RMSE(y_, y) -#> [1] 22.13223 -``` - -```{r} -# 予測結果のみでよい場合 -#tmp %>% autoplot - -tmp %>% autoplot + - geom_line(data = my_df, - aes(x = ds, - y = y, - color = label)) -``` - -### 12.2.4 Prophetによる時系列予測 - -```{r} -library(prophet) -my_prophet_model <- my_train %>% - prophet(seasonality.mode = "multiplicative") -``` - -```{r} -tmp <- my_prophet_model %>% predict(my_test) -head(tmp[, c("ds", "yhat", "yhat_lower", "yhat_upper")]) -#> # A tibble: 6 x 4 -#> ds yhat yhat_lower yhat_upper -#> -#> 1 1958-01-01 00:00:00 359. 350. 368. -#> 2 1958-02-01 00:00:00 350. 342. 360. -#> 3 1958-03-01 00:00:00 407. 398. 416. -#> 4 1958-04-01 00:00:00 398. 389. 407. -#> 5 1958-05-01 00:00:00 402. 393. 411. -#> 6 1958-06-01 00:00:00 459. 450. 469. -``` - -```{r} -y_ <- tmp$yhat -caret::RMSE(y_, y) -#> [1] 33.68719 -``` - -```{r} -# my_prophet_model %>% plot(tmp) # 予測結果のみでよい場合 - -my_prophet_model %>% plot(tmp) + - geom_line(data = my_train, aes(x = as.POSIXct(ds))) + - geom_line(data = my_test, aes(x = as.POSIXct(ds)), color = "red") -``` - diff --git a/code/Rmd/ch12/12.Rmd b/code/Rmd/ch12/12.Rmd deleted file mode 100644 index a183e71..0000000 --- a/code/Rmd/ch12/12.Rmd +++ /dev/null @@ -1,190 +0,0 @@ -## 12.1 日時と日時の列 - -### 12.1.1 日時 - -```{r} -as.POSIXct("2021-01-01") -#> [1] "2021-01-01 JST" -``` - -### 12.1.2 等間隔の日時 - -```{r} -library(tsibble) - -seq(from = 2021, to = 2023, by = 1) -#> [1] 2021 2022 2023 - -seq(from = yearmonth("202101"), to = yearmonth("202103"), by = 2) -#> -#> [1] "2021 1" "2021 3" - -seq(from = as.POSIXct("2021-01-01"), to = as.POSIXct("2021-01-03"), by = "1 day") -#> [1] "2021-01-01 JST" "2021-01-02 JST" "2021-01-03 JST" - -seq(from = as.POSIXct("2021-01-01 00:00:00"), - to = as.POSIXct("2021-01-01 03:00:00"), by = "2 hour") -#> [1] "2021-01-01 00:00:00 JST" "2021-01-01 02:00:00 JST" -``` - - -## 12.2 時系列データの予測 - -### 12.2.1 データの準備 - -```{r} -my_data <- as.vector(AirPassengers) -``` - -```{r} -n <- length(my_data) # データ数(144) -k <- 108 # 訓練データ数 -``` - -```{r} -library(tidyverse) -library(tsibble) - -my_ds <- seq( - from = yearmonth("1949/01"), - to = yearmonth("1960/12"), - by = 1) -my_label <- rep( - c("train", "test"), - c(k, n - k)) -my_df <- tsibble( - ds = my_ds, - x = 0:(n - 1), - y = my_data, - label = my_label, - index = ds) # 日時の列の指定 - -head(my_df) -#> # A tsibble: 6 x 4 [1M] -#> ds x y label -#> -#> 1 1949 1 0 112 train -#> 2 1949 2 1 118 train -#> 3 1949 3 2 132 train -#> 4 1949 4 3 129 train -#> 5 1949 5 4 121 train -#> 6 1949 6 5 135 train -``` - -```{r} -my_train <- my_df[ 1:k , ] -my_test <- my_df[-(1:k), ] -y <- my_test$y -``` - -```{r} -my_plot <- my_df %>% - ggplot(aes(x = ds, - y = y, - color = label)) + - geom_line() -my_plot -``` - -### 12.2.2 線形回帰分析による時系列予測 - -```{r} -library(caret) -my_lm_model <- train(form = y ~ x, data = my_train, method = "lm") -y_ <- my_lm_model %>% predict(my_test) -caret::RMSE(y, y_) # RMSE(テスト) -#> [1] 70.63707 -``` - -```{r} -y_ <- my_lm_model %>% predict(my_df) -tmp <- my_df %>% - mutate(y = y_, label = "model") -my_plot + geom_line(data = tmp) -``` - -### 12.2.3 SARIMAによる時系列予測 - -#### 12.2.3.1 モデルの構築 - -```{r} -library(fable) -my_arima_model <- my_train %>% model(ARIMA(y)) -my_arima_model -#> # A mable: 1 x 1 -#> `ARIMA(y)` -#> -#> 1 -``` - -#### 12.2.3.2 予測 - -```{r} -tmp <- my_arima_model %>% forecast(h = "3 years") -head(tmp) -#> # A fable: 6 x 4 [1M] -#> # Key: .model [1] -#> .model ds y .mean -#> -#> 1 ARIMA(y) 1958 1 N(346, 94) 346. -#> 2 ARIMA(y) 1958 2 N(332, 148) 332. -#> 3 ARIMA(y) 1958 3 N(387, 210) 387. -#> 4 ARIMA(y) 1958 4 N(379, 271) 379. -#> 5 ARIMA(y) 1958 5 N(386, 332) 386. -#> 6 ARIMA(y) 1958 6 N(453, 393) 453. -``` - -```{r} -y_ <- tmp$.mean -caret::RMSE(y_, y) -#> [1] 22.13223 -``` - -```{r} -# 予測結果のみでよい場合 -#tmp %>% autoplot - -tmp %>% autoplot + - geom_line(data = my_df, - aes(x = ds, - y = y, - color = label)) -``` - -### 12.2.4 Prophetによる時系列予測 - -```{r} -library(prophet) -my_prophet_model <- my_train %>% - prophet(seasonality.mode = "multiplicative") -``` - -```{r} -tmp <- my_prophet_model %>% predict(my_test) -head(tmp[, c("ds", "yhat", "yhat_lower", "yhat_upper")]) -#> # A tibble: 6 x 4 -#> ds yhat yhat_lower yhat_upper -#> -#> 1 1958-01-01 00:00:00 359. 350. 368. -#> 2 1958-02-01 00:00:00 350. 342. 360. -#> 3 1958-03-01 00:00:00 407. 398. 416. -#> 4 1958-04-01 00:00:00 398. 389. 407. -#> 5 1958-05-01 00:00:00 402. 393. 411. -#> 6 1958-06-01 00:00:00 459. 450. 469. -``` - -```{r} -y_ <- tmp$yhat -caret::RMSE(y_, y) -#> [1] 33.68719 -``` - -```{r} -# my_prophet_model %>% plot(tmp) # 予測結果のみでよい場合 - -my_prophet_model %>% plot(tmp) + - geom_line(data = my_train, aes(x = as.POSIXct(ds))) + - geom_line(data = my_test, aes(x = as.POSIXct(ds)), color = "red") -``` - - diff --git a/code/Rmd/ch13/13.01.Rmd b/code/Rmd/ch13/13.01.Rmd deleted file mode 100644 index 3a0c505..0000000 --- a/code/Rmd/ch13/13.01.Rmd +++ /dev/null @@ -1,105 +0,0 @@ -## 13.1 主成分分析 - -```{r} -library(tidyverse) - -my_data <- data.frame( - language = c( 0, 20, 20, 25, 22, 17), - english = c( 0, 20, 40, 20, 24, 18), - math = c(100, 20, 5, 30, 17, 25), - science = c( 0, 20, 5, 25, 16, 23), - society = c( 0, 20, 30, 0, 21, 17), - row.names = c("A", "B", "C", "D", "E", "F")) -my_result <- my_data %>% prcomp # 主成分分析の実行 -``` - -```{r} -my_result$x # 主成分スコア -#> PC1 PC2 ... -#> A -74.907282 -7.010808 ... -#> B 13.818842 2.753459 ... -#> C 33.714034 -18.417290 ... -#> D 1.730630 17.876372 ... -#> E 17.837474 -1.064998 ... -#> F 7.806303 5.863266 ... -``` - -```{r} -my_result %>% ggbiplot::ggbiplot( - labels = row.names(my_data), - scale = 0) -``` - -```{r} -my_result$rotation %>% t -#> language english math science society -#> PC1 0.2074983 0.3043604 -0.887261240 0.1301984 0.2452041 -#> PC2 0.2794627 -0.3250521 -0.097642669 0.7026667 -0.5594347 -#> PC3 -0.3061175 -0.6157986 -0.056345381 0.3384462 0.6398152 -#> PC4 0.7649426 -0.4716969 -0.007654992 -0.4180454 0.1324548 -#> PC5 0.4472136 0.4472136 0.447213595 0.4472136 0.4472136 -``` - -```{r} -summary(my_result) -#> Importance of components: -#> PC1 PC2 PC3 PC4 PC5 -#> Standard deviation 38.2644 12.25566 5.58845 1.52970 1.232e-15 -#> Proportion of Variance 0.8885 0.09115 0.01895 0.00142 0.000e+00 -#> Cumulative Proportion 0.8885 0.97963 0.99858 1.00000 1.000e+00 -``` - -### 13.1.1 標準化+主成分分析 - -```{r} -my_result <- prcomp( - x = my_data, - scale = TRUE) # 標準化 -# あるいは -my_result <- prcomp( - x = scale(my_data)) # 標準化データ - -my_result$x # 主成分スコア -#> PC1 PC2 ... -#> A -3.6737215 -0.5688501 ... -#> B 0.6528793 0.2469258 ... -#> C 1.5682936 -1.7425981 ... -#> D 0.2505043 1.6400394 ... -#> E 0.8861864 -0.1104931 ... -#> F 0.3158579 0.5349762 ... -``` - -### 13.1.2 補足:行列計算による再現 - -```{r} -Z <- my_data %>% scale(scale = FALSE) %>% as.matrix # 標準化しない場合 -#Z <- my_data %>% scale(scale = TRUE) %>% as.matrix # 標準化する場合 - -n <- nrow(my_data) -S <- var(Z) # 分散共分散行列 -#S <- t(Z) %*% Z / (n - 1) # (同じ結果) -tmp <- eigen(S) # 固有値と固有ベクトル -Z %*% tmp$vectors # 主成分スコア(結果は割愛) -cumsum(tmp$values) / sum(tmp$values) # 累積寄与率 -#> [1] 0.8884833 0.9796285 0.9985801 1.0000000 1.0000000 -``` - -```{r} -udv <- svd(Z) # 特異値分解 -U <- udv$u -d <- udv$d -V <- udv$v -W <- diag(d) - -c(all.equal(Z, U %*% W %*% t(V), check.attributes = FALSE), # 確認1 - all.equal(t(U) %*% U, diag(dim(U)[2])), # 確認2 - all.equal(t(V) %*% V, diag(dim(V)[2]))) # 確認3 -#> [1] TRUE TRUE TRUE - -U %*% W # 主成分スコア(結果は割愛) - -e <- d^2 / (n - 1) # 分散共分散行列の固有値 -cumsum(e) / sum(e) # 累積寄与率 -#> [1] 0.8884833 0.9796285 0.9985801 1.0000000 1.0000000 -``` - diff --git a/code/Rmd/ch13/13.02.Rmd b/code/Rmd/ch13/13.02.Rmd deleted file mode 100644 index ad46290..0000000 --- a/code/Rmd/ch13/13.02.Rmd +++ /dev/null @@ -1,114 +0,0 @@ -## 13.2 クラスタ分析 - -### 13.2.1 階層的クラスタ分析 - -```{r} -library(tidyverse) - -my_data <- data.frame( - x = c( 0, -16, 10, 10), - y = c( 0, 0, 10, -15), - row.names = c("A", "B", "C", "D")) - -my_result <- my_data %>% - dist("euclidian") %>% # distだけでも可 - hclust("complete") # hclustだけでも可 -``` - -```{r} -my_result %>% factoextra::fviz_dend( - k = 3, # クラスタ数 - rect = TRUE, rect_fill = TRUE) -``` - -```{r} -my_result %>% factoextra::fviz_dend( - k = 3, - rect = TRUE, rect_fill = TRUE, - type = "phylogenic") -``` - -```{r} -my_result %>% cutree(3) -#> A B C D -#> 1 2 1 3 -``` - -### 13.2.2 階層的クラスタ分析とヒートマップ - -```{r} -library(tidyverse) - -my_data <- data.frame( - language = c( 0, 20, 20, 25, 22, 17), - english = c( 0, 20, 40, 20, 24, 18), - math = c(100, 20, 5, 30, 17, 25), - science = c( 0, 20, 5, 25, 16, 23), - society = c( 0, 20, 30, 0, 21, 17), - row.names = c("A", "B", "C", "D", "E", "F")) - -try( # RMarkdownで発生するエラーを回避する. - my_data %>% scale %>% # 列ごとの標準化 - gplots::heatmap.2(cexRow = 1, cexCol = 1), # ラベルのサイズを指定して描画する. - silent = TRUE) -``` - -### 13.2.3 非階層的クラスタ分析 - -```{r} -library(tidyverse) - -my_data <- data.frame( - x = c( 0, -16, 10, 10), - y = c( 0, 0, 10, -15), - row.names = c("A", "B", "C", "D")) - -my_result <- my_data %>% kmeans(3) -``` - -```{r} -my_result$cluster -#> A B C D -#> 2 3 2 1 -``` - -### 13.2.4 クラスタ数の決定 - -```{r} -library(tidyverse) -library(factoextra) - -my_data <- iris[, -5] - -f <- 2:5 %>% map(function(k) { - my_data %>% kmeans(k) %>% - fviz_cluster(data = my_data, geom = "point") + - ggtitle(sprintf("k = %s", k)) -}) -gridExtra::grid.arrange(f[[1]], f[[2]], f[[3]], f[[4]], ncol = 2) -``` - -```{r} -fviz_nbclust(my_data, kmeans, method = "wss") -``` - -### 13.2.5 主成分分析とクラスタ分析 - -```{r} -library(tidyverse) -my_data <- iris[, -5] %>% scale - -my_result <- prcomp(my_data)$x %>% as.data.frame # 主成分分析 - -# 非階層的クラスタ分析の場合 -my_result$cluster <- (my_data %>% scale %>% kmeans(3))$cluster %>% as.factor - -# 階層的クラスタ分析の場合 -#my_result$cluster <- my_data %>% dist %>% hclust %>% cutree(3) %>% as.factor - -my_result %>% - ggplot(aes(x = PC1, y = PC2, color = cluster)) + # 色でクラスタを表現する. - geom_point(shape = iris$Species) + # 形で品種を表現する. - theme(legend.position = "none") -``` - diff --git a/code/Rmd/ch13/13.Rmd b/code/Rmd/ch13/13.Rmd deleted file mode 100644 index 74373de..0000000 --- a/code/Rmd/ch13/13.Rmd +++ /dev/null @@ -1,221 +0,0 @@ -## 13.1 主成分分析 - -```{r} -library(tidyverse) - -my_data <- data.frame( - language = c( 0, 20, 20, 25, 22, 17), - english = c( 0, 20, 40, 20, 24, 18), - math = c(100, 20, 5, 30, 17, 25), - science = c( 0, 20, 5, 25, 16, 23), - society = c( 0, 20, 30, 0, 21, 17), - row.names = c("A", "B", "C", "D", "E", "F")) -my_result <- my_data %>% prcomp # 主成分分析の実行 -``` - -```{r} -my_result$x # 主成分スコア -#> PC1 PC2 ... -#> A -74.907282 -7.010808 ... -#> B 13.818842 2.753459 ... -#> C 33.714034 -18.417290 ... -#> D 1.730630 17.876372 ... -#> E 17.837474 -1.064998 ... -#> F 7.806303 5.863266 ... -``` - -```{r} -my_result %>% ggbiplot::ggbiplot( - labels = row.names(my_data), - scale = 0) -``` - -```{r} -my_result$rotation %>% t -#> language english math science society -#> PC1 0.2074983 0.3043604 -0.887261240 0.1301984 0.2452041 -#> PC2 0.2794627 -0.3250521 -0.097642669 0.7026667 -0.5594347 -#> PC3 -0.3061175 -0.6157986 -0.056345381 0.3384462 0.6398152 -#> PC4 0.7649426 -0.4716969 -0.007654992 -0.4180454 0.1324548 -#> PC5 0.4472136 0.4472136 0.447213595 0.4472136 0.4472136 -``` - -```{r} -summary(my_result) -#> Importance of components: -#> PC1 PC2 PC3 PC4 PC5 -#> Standard deviation 38.2644 12.25566 5.58845 1.52970 1.232e-15 -#> Proportion of Variance 0.8885 0.09115 0.01895 0.00142 0.000e+00 -#> Cumulative Proportion 0.8885 0.97963 0.99858 1.00000 1.000e+00 -``` - -### 13.1.1 標準化+主成分分析 - -```{r} -my_result <- prcomp( - x = my_data, - scale = TRUE) # 標準化 -# あるいは -my_result <- prcomp( - x = scale(my_data)) # 標準化データ - -my_result$x # 主成分スコア -#> PC1 PC2 ... -#> A -3.6737215 -0.5688501 ... -#> B 0.6528793 0.2469258 ... -#> C 1.5682936 -1.7425981 ... -#> D 0.2505043 1.6400394 ... -#> E 0.8861864 -0.1104931 ... -#> F 0.3158579 0.5349762 ... -``` - -### 13.1.2 補足:行列計算による再現 - -```{r} -Z <- my_data %>% scale(scale = FALSE) %>% as.matrix # 標準化しない場合 -#Z <- my_data %>% scale(scale = TRUE) %>% as.matrix # 標準化する場合 - -n <- nrow(my_data) -S <- var(Z) # 分散共分散行列 -#S <- t(Z) %*% Z / (n - 1) # (同じ結果) -tmp <- eigen(S) # 固有値と固有ベクトル -Z %*% tmp$vectors # 主成分スコア(結果は割愛) -cumsum(tmp$values) / sum(tmp$values) # 累積寄与率 -#> [1] 0.8884833 0.9796285 0.9985801 1.0000000 1.0000000 -``` - -```{r} -udv <- svd(Z) # 特異値分解 -U <- udv$u -d <- udv$d -V <- udv$v -W <- diag(d) - -c(all.equal(Z, U %*% W %*% t(V), check.attributes = FALSE), # 確認1 - all.equal(t(U) %*% U, diag(dim(U)[2])), # 確認2 - all.equal(t(V) %*% V, diag(dim(V)[2]))) # 確認3 -#> [1] TRUE TRUE TRUE - -U %*% W # 主成分スコア(結果は割愛) - -e <- d^2 / (n - 1) # 分散共分散行列の固有値 -cumsum(e) / sum(e) # 累積寄与率 -#> [1] 0.8884833 0.9796285 0.9985801 1.0000000 1.0000000 -``` - - -## 13.2 クラスタ分析 - -### 13.2.1 階層的クラスタ分析 - -```{r} -library(tidyverse) - -my_data <- data.frame( - x = c( 0, -16, 10, 10), - y = c( 0, 0, 10, -15), - row.names = c("A", "B", "C", "D")) - -my_result <- my_data %>% - dist("euclidian") %>% # distだけでも可 - hclust("complete") # hclustだけでも可 -``` - -```{r} -my_result %>% factoextra::fviz_dend( - k = 3, # クラスタ数 - rect = TRUE, rect_fill = TRUE) -``` - -```{r} -my_result %>% factoextra::fviz_dend( - k = 3, - rect = TRUE, rect_fill = TRUE, - type = "phylogenic") -``` - -```{r} -my_result %>% cutree(3) -#> A B C D -#> 1 2 1 3 -``` - -### 13.2.2 階層的クラスタ分析とヒートマップ - -```{r} -library(tidyverse) - -my_data <- data.frame( - language = c( 0, 20, 20, 25, 22, 17), - english = c( 0, 20, 40, 20, 24, 18), - math = c(100, 20, 5, 30, 17, 25), - science = c( 0, 20, 5, 25, 16, 23), - society = c( 0, 20, 30, 0, 21, 17), - row.names = c("A", "B", "C", "D", "E", "F")) - -try( # RMarkdownで発生するエラーを回避する. - my_data %>% scale %>% # 列ごとの標準化 - gplots::heatmap.2(cexRow = 1, cexCol = 1), # ラベルのサイズを指定して描画する. - silent = TRUE) -``` - -### 13.2.3 非階層的クラスタ分析 - -```{r} -library(tidyverse) - -my_data <- data.frame( - x = c( 0, -16, 10, 10), - y = c( 0, 0, 10, -15), - row.names = c("A", "B", "C", "D")) - -my_result <- my_data %>% kmeans(3) -``` - -```{r} -my_result$cluster -#> A B C D -#> 2 3 2 1 -``` - -### 13.2.4 クラスタ数の決定 - -```{r} -library(tidyverse) -library(factoextra) - -my_data <- iris[, -5] - -f <- 2:5 %>% map(function(k) { - my_data %>% kmeans(k) %>% - fviz_cluster(data = my_data, geom = "point") + - ggtitle(sprintf("k = %s", k)) -}) -gridExtra::grid.arrange(f[[1]], f[[2]], f[[3]], f[[4]], ncol = 2) -``` - -```{r} -fviz_nbclust(my_data, kmeans, method = "wss") -``` - -### 13.2.5 主成分分析とクラスタ分析 - -```{r} -library(tidyverse) -my_data <- iris[, -5] %>% scale - -my_result <- prcomp(my_data)$x %>% as.data.frame # 主成分分析 - -# 非階層的クラスタ分析の場合 -my_result$cluster <- (my_data %>% scale %>% kmeans(3))$cluster %>% as.factor - -# 階層的クラスタ分析の場合 -#my_result$cluster <- my_data %>% dist %>% hclust %>% cutree(3) %>% as.factor - -my_result %>% - ggplot(aes(x = PC1, y = PC2, color = cluster)) + # 色でクラスタを表現する. - geom_point(shape = iris$Species) + # 形で品種を表現する. - theme(legend.position = "none") -``` - - diff --git a/code/py/ch03/03.01.py b/code/py/ch03/03.01.py deleted file mode 100644 index c9dc6e9..0000000 --- a/code/py/ch03/03.01.py +++ /dev/null @@ -1,96 +0,0 @@ -## 3.1 入門 - -### 3.1.1 数値 - -0x10 -#> 16 - -1.23e5 -#> 123000.0 - -2 * 3 -#> 6 - -10 / 3 -#> 3.3333333333333335 - -10 // 3 # 商 -#> 3 - -10 % 3 # 余り -#> 1 - -### 3.1.2 変数 - -x = 2 -y = 3 -x * y -#> 6 - -x, y = 20, 30 # まとめて名付け -x * y -#> 600 - -x = 1 + 1 -# この段階では結果は表示されない - -x # 変数名を評価する. -#> 2 - -### 3.1.3 文字列 - -my_s = 'abcde' - -len(my_s) -#> 5 - -'This is' ' a' ' pen.' -# あるいは -'This is ' + 'a' + ' pen.' -#> 'This is a pen.' - -my_s[1:4] -#> 'bcd' - -tmp = "{} is {}." -tmp.format('This', 'a pen') -#> 'This is a pen.' - -### 3.1.4 論理値 - -1 <= 2 -#> True - -1 < 0 -#> False - -0.1 + 0.1 + 0.1 == 0.3 -#> False - -import math -math.isclose(0.1 + 0.1 + 0.1, 0.3) -#> True - -True and False # 論理積(かつ) -#> False - -True or False # 論理和(または) -#> True - -not True # 否定(でない) -#> False - -#### 3.1.4.1 条件演算子 - -0 if 3 < 5 else 10 -#> 0 - -### 3.1.5 作業ディレクトリ - -import os -os.getcwd() -#> '/home/jovyan/work' - -os.chdir('..') -os.getcwd() -#> '/home/jovyan' diff --git a/code/py/ch03/03.02.py b/code/py/ch03/03.02.py deleted file mode 100644 index 51c9ea2..0000000 --- a/code/py/ch03/03.02.py +++ /dev/null @@ -1,45 +0,0 @@ -## 3.2 関数 - -### 3.2.1 関数の利用 - -import math -math.sqrt(4) -#> 2.0 - -math.log(100, 10) -#> 2.0 - -math.log(100) # 自然対数 -# あるいは -math.log(100, math.e) # 省略しない場合 - -#> 4.605170185988092 - -math.log10(100) # 常用対数 -#> 2.0 - -math.log2(1024) # 底が2の対数 -#> 10.0 - -#### 3.2.1.1 パイプ(Rのみ) - -### 3.2.2 関数の定義 - -def f(a, b): - return a - b - -f(3, 5) -#> -2 - -#### 3.2.2.1 デフォルト引数 - -def f(a, b=5): - return a - b - -f(3) # f(3, 5)と同じこと -#> -2 - -#### 3.2.2.2 無名関数 - -(lambda a, b: a - b)(3, 5) -#> -2 diff --git a/code/py/ch03/03.03.py b/code/py/ch03/03.03.py deleted file mode 100644 index 1298c5d..0000000 --- a/code/py/ch03/03.03.py +++ /dev/null @@ -1,149 +0,0 @@ -## 3.3 コレクション - -### 3.3.1 1次元データ - -x = ['foo', 'bar', 'baz'] - -len(x) -#> 3 - -x[1] -#> 'bar' - -x[1] = 'BAR' -x # 結果の確認 -#> ['foo', 'BAR', 'baz'] - -x[1] = 'bar' # 元に戻す. - -x[-2] -#> 'bar' - -x + ['qux'] -#> ['foo', 'bar', 'baz', 'qux'] - -x = x + ['qux'] -# あるいは -#x.append('qux') - -x # 結果の確認 -#> ['foo', 'bar', 'baz', 'qux'] - -#### 3.3.1.1 等間隔の数値からなる1次元データ - -list(range(5)) -#> [0, 1, 2, 3, 4] - -list(range(0, 11, 2)) -#> [0, 2, 4, 6, 8, 10] - -import numpy as np -np.arange(0, 1.1, 0.5) -#> array([0. , 0.5, 1. ]) - -np.linspace(0, 100, 5) -#> array([ 0., 25., 50., 75., 100.]) - -[10] * 5 -#> [10, 10, 10, 10, 10] - -#### 3.3.1.2 ファクタ(Rのみ) - -### 3.3.2 数値計算やデータ解析用の1次元データ - -import numpy as np -x = np.array([2, 3, 5, 7]) - -x + 10 # 加算 -#> array([12, 13, 15, 17]) - -x * 10 # 乗算 -#> array([20, 30, 50, 70]) - -x = [2, 3] -np.sin(x) -#> array([0.90929743, 0.14112001]) - -x = np.array([2, 3, 5, 7]) -y = np.array([1, 10, 100, 1000]) -x + y -#> array([ 3, 13, 105, 1007]) - -x * y -#> array([ 2, 30, 500, 7000]) - -np.dot(x, y) -# あるいは -x @ y - -#> 7532 - -x = np.array([True, False]) -y = np.array([True, True]) -x & y -#> array([ True, False]) - -#### 3.3.2.1 1次元データ同士の比較 - -u = np.array([1, 2, 3]) -v = np.array([1, 2, 3]) -w = np.array([1, 2, 4]) - -all(u == v) # 全体の比較 -#> True - -all(u == w) # 全体の比較 -#> False - -u == v # 要素ごとの比較 -#> array([ True, True, True]) - -u == w # 要素ごとの比較 -#> array([ True, True, False]) - -(u == w).sum() # 同じ要素の数 -#> 2 - -(u == w).mean() # 同じ要素の割合 -#> [1] 0.6666667 - -### 3.3.3 複数種類のデータをひとまとめにする - -x = [1, "two"] - -x[1] -#> 'two' - -### 3.3.4 文字列と値のペアのコレクション - -x = {'apple' : 'りんご', - 'orange': 'みかん'} - -x['grape'] = 'ぶどう' - -x['apple'] -# あるいは -tmp = 'apple' -x[tmp] - -#> 'りんご' - -### 3.3.5 補足:コピーと参照 - -x = ['foo', 'bar', 'baz'] -y = x -y[1] = 'BAR' # yを更新する. -y -#> ['foo', 'BAR', 'baz'] - -x # xも変わる. -#> ['foo', 'BAR', 'baz'] - -x = ['foo', 'bar', 'baz'] -y = x.copy() # 「y = x」とせずに,コピーする. -x == y, x is y -#> (True, False) # xとyは,等価(内容は同じ)だが同一ではない. - -y[1] = 'BAR' # yを更新しても, -x -#> ['foo', 'bar', 'baz'] # xは変化しない. diff --git a/code/py/ch03/03.04.py b/code/py/ch03/03.04.py deleted file mode 100644 index 0fd4e4a..0000000 --- a/code/py/ch03/03.04.py +++ /dev/null @@ -1,259 +0,0 @@ -## 3.4 データフレーム - -### 3.4.1 データフレームの作成 - -import pandas as pd - -#### 3.4.1.1 データを列ごとに記述する方法 - -my_df = pd.DataFrame({ - 'name': ['A', 'B', 'C', 'D'], - 'english': [ 60, 90, 70, 90], - 'math': [ 70, 80, 90, 100], - 'gender': ['f', 'm', 'm', 'f']}) - -#### 3.4.1.2 データを見た目のとおりに記述する方法 - -my_df = pd.DataFrame([ - ['A', 60, 70, 'f'], - ['B', 90, 80, 'm'], - ['C', 70, 90, 'm'], - ['D', 90, 100, 'f']], - columns=['name', 'english', - 'math', 'gender']) - -my_df.head() -# 結果は割愛 - -#### 3.4.1.3 データフレームのサイズ - -r, c = my_df.shape # 行数と列数 -r, c -#> (4, 4) - -r # 行数(len(my_df)も可) -#> 4 - -c # 列数 -#> 4 - -#### 3.4.1.4 組合せ - -from itertools import product -my_df2 = pd.DataFrame( - product([1, 2, 3], - [10, 100]), - columns=['X', 'Y']) -my_df2 -#> X Y -#> 0 1 10 -#> 1 1 100 -#> 2 2 10 -#> 3 2 100 -#> 4 3 10 -#> 5 3 100 - -#### 3.4.1.5 列と行の名前 - -my_df2.columns -#> Index(['X', 'Y'], dtype='object') - -my_df2.columns = ['P', 'Q'] -my_df2 -#> P Q -#> 0 1 10 -#> 1 1 100 -# 以下省略 - -list(my_df.index) -#> [0, 1, 2, 3] - -my_df2.index = [ - 'a', 'b', 'c', 'd', 'e', 'f'] -my_df2 -#> P Q -#> a 1 10 -#> b 1 100 -#> c 2 10 -# 以下省略 - -my_df3 = pd.DataFrame({ - 'english': [ 60, 90, 70, 90], - 'math': [ 70, 80, 90, 100], - 'gender': ['f', 'm', 'm', 'f']}, - index= ['A', 'B', 'C', 'D']) -my_df3 -#> english math gender -#> A 60 70 f -#> B 90 80 m -#> C 70 90 m -#> D 90 100 f - -### 3.4.2 データの追加 - -#### 3.4.2.1 行の追加(データフレームの結合) - -tmp = pd.DataFrame({ - 'name' : ['E'], - 'english': [80], - 'math' : [80], - 'gender' : ['m']}) -my_df2 = my_df.append(tmp) - -#### 3.4.2.2 列の追加 - -my_df2 = my_df.assign(id=[1, 2, 3, 4]) - -my_df3 = my_df.copy() # コピー -my_df3['id'] = [1, 2, 3, 4] # 更新 -my_df3 # 結果の確認(割愛) - -### 3.4.3 データの取り出し - -#### 3.4.3.1 観測値の取り出し - -my_df.iloc[0, 1] -#> 60 - -#### 3.4.3.2 1列の取り出し(結果は1次元データ) - -x = my_df.iloc[:, 1] -# あるいは -x = my_df['english'] -# あるいは -x = my_df.english -# あるいは -tmp = 'english' -x = my_df[tmp] - -x # 結果の確認(割愛) - -#### 3.4.3.3 複数列の取り出し(結果はデータフレーム) - -x = my_df[['name', 'math']] -# あるいは -x = my_df.loc[:, ['name', 'math']] - -x = my_df.take([0, 2], axis=1) -# あるいは -x = my_df.iloc[:, [0, 2]] - -x = my_df.drop( - columns=['english', 'gender']) -# あるいは -x = my_df.drop( - columns=my_df.columns[[1, 3]]) - -#### 3.4.3.4 複数行の取り出し(結果はデータフレーム) - -x = my_df.take([0, 2]) -# あるいは -x = my_df.iloc[[0, 2], :] - -x = my_df.drop([1, 3]) - -#### 3.4.3.5 検索 - -x = my_df[my_df['gender'] == 'm'] -# あるいは -x = my_df.query('gender == "m"') - -x = my_df[(my_df['english'] > 80) & (my_df['gender'] == "m")] -# あるいは -x = my_df.query('english > 80 and gender == "m"') - -x = my_df[my_df['english'] == my_df['english'].max()] -# あるいは -tmp = my_df['english'].max() -x = my_df.query('english == @tmp') - -my_df2 = my_df.copy() # コピー -my_df2.loc[my_df['gender'] == 'm', 'gender'] = 'M' - -my_df2 -#> name english math gender -#> 0 A 60 70 f -#> 1 B 90 80 M -#> 2 C 70 90 M -#> 3 D 90 100 f - -#### 3.4.3.6 並べ替え - -x = my_df.sort_values('english') - -x = my_df.sort_values('english', - ascending=False) - -### 3.4.4 補足:行列 - -#### 3.4.4.1 行列の生成 - -import numpy as np -x = [2, 3, 5, 7, 11, 13, 17, 19, 23, - 29, 31, 37] -A = np.array(x).reshape(3, 4) -A -#> array([[ 2, 3, 5, 7], -#> [11, 13, 17, 19], -#> [23, 29, 31, 37]]) - -#### 3.4.4.2 データフレームと行列 - -A = my_df.iloc[:, [1, 2]].values -A -#> array([[ 60, 70], -#> [ 90, 80], -#> [ 70, 90], -#> [ 90, 100]]) - -pd.DataFrame(A) -#> 0 1 -#> 0 60 70 -#> 1 90 80 -#> 2 70 90 -#> 3 90 100 - -#### 3.4.4.3 行列の変形 - -A.T -#> array([[ 60, 90, 70, 90], -#> [ 70, 80, 90, 100]]) - -#### 3.4.4.4 行列の積 - -A.T @ A -#> array([[24700, 26700], -#> [26700, 29400]]) - -### 3.4.5 縦型と横型 - -my_df = pd.DataFrame({ - 'day': [25, 26, 27], - 'min': [20, 21, 15], - 'max': [24, 27, 21]}) - -my_longer = my_df.melt(id_vars='day') -my_longer -#> day variable value -#> 0 25 min 20 -#> 1 26 min 21 -#> 2 27 min 15 -#> 3 25 max 24 -#> 4 26 max 27 -#> 5 27 max 21 - -my_wider = my_longer.pivot( - index='day', - columns='variable', - values='value') -my_wider -#> variable max min -#> day -#> 25 24 20 -#> 26 27 21 -#> 27 21 15 - -my_wider.plot( - style='o-', - xticks=my_wider.index, # x軸目盛り - ylabel='temperature') # y軸ラベル diff --git a/code/py/ch03/03.05.py b/code/py/ch03/03.05.py deleted file mode 100644 index 21da481..0000000 --- a/code/py/ch03/03.05.py +++ /dev/null @@ -1,85 +0,0 @@ -## 3.5 1次元データの(非)類似度 - -### 3.5.1 ユークリッド距離 - -import numpy as np -from scipy.spatial import distance -from scipy.stats import pearsonr - -A = np.array([3, 4, 5]) -B = np.array([3, 4, 29]) -C = np.array([9, -18, 8]) - -distance.euclidean(A, B) -#> 24.0 - -distance.euclidean(A, C) -#> 23.0 - -### 3.5.2 マンハッタン距離 - -distance.cityblock(A, B) -#> 24 - -distance.cityblock(A, C) -#> 31 - -### 3.5.3 コサイン類似度 - -1 - distance.cosine(A, B) -#> 0.8169678632647616 - -1 - distance.cosine(A, C) -#> -0.032651157422416865 - -### 3.5.4 相関係数 - -1 - distance.correlation(A, B) -# あるいは -pearsonr(A, B)[0] -#> 0.8824975032927698 - -1 - distance.correlation(A, C) -# あるいは -pearsonr(A, C)[0] -#> -0.032662766723200676 - -#### 3.5.4.1 データフレームを使う方法 - -# 小数点以下は3桁表示 -np.set_printoptions(precision=3) -import pandas as pd - -my_df = pd.DataFrame({ - 'x': [3, 3, 9], - 'y': [4, 4, -18], - 'z': [5, 29, 8]}, - index=['A', 'B', 'C']) - -# ユークリッド距離 -distance.cdist(my_df, my_df, - metric='euclidean') -#> array([[ 0., 24., 23.], -#> [24., 0., 31.], -#> [23., 31., 0.]]) - -# マンハッタン距離 -distance.cdist(my_df, my_df, - metric='cityblock') -#> array([[ 0., 24., 31.], -#> [24., 0., 49.], -#> [31., 49., 0.]]) - -# コサイン類似度 -1 - distance.cdist(my_df, my_df, - metric='cosine') -#> array([[ 1. , 0.817, -0.033], -#> [ 0.817, 1. , 0.293], -#> [-0.033, 0.293, 1. ]]) - -# 相関係数 -1 - distance.cdist(my_df, my_df, - metric='correlation') -#> array([[ 1. , 0.882, -0.033], -#> [ 0.882, 1. , 0.441], -#> [-0.033, 0.441, 1. ]]) diff --git a/code/py/ch03/03.06.py b/code/py/ch03/03.06.py deleted file mode 100644 index d84366e..0000000 --- a/code/py/ch03/03.06.py +++ /dev/null @@ -1,21 +0,0 @@ -## 3.6 Rのパッケージ,Pythonのモジュール - -### 3.6.1 Rのパッケージ - -### 3.6.2 Pythonのモジュール - -import math -import numpy as np -import pandas as pd - -import numpy -numpy.array([1, 2, 3, 4]) - -import numpy as np -np.array([1, 2, 3, 4]) - -from numpy import array -array([1, 2, 3, 4]) - -from numpy import * -array([1, 2, 3, 4]) diff --git a/code/py/ch03/03.07.py b/code/py/ch03/03.07.py deleted file mode 100644 index 9e88111..0000000 --- a/code/py/ch03/03.07.py +++ /dev/null @@ -1,110 +0,0 @@ -## 3.7 反復処理 - -import numpy as np -import pandas as pd - -### 3.7.1 指定した回数→1次元データ - -def f1(x): - tmp = np.random.random(x) - return np.mean(tmp) - -f1(10) # 動作確認 -#> 0.5427033207230424 # 結果の例 - -[f1(10) for i in range(3)] -#> [0.4864425069985622, -#> 0.4290935578857099, -#> 0.535206509631883] - -[f1(10)] * 3 -#> [0.43725641184595576, -#> 0.43725641184595576, -#> 0.43725641184595576] - -### 3.7.2 1次元データ→1次元データ - -v = [5, 10, 100] -[f1(x) for x in v] # 方法1 -#> [0.454, 0.419, 0.552] - -# あるいは - -v = pd.Series([5, 10, 100]) -v.apply(f1) # 方法2 -#> 0 0.394206 -#> 1 0.503949 -#> 2 0.532698 -#> dtype: float64 - -pd.Series([10] * 3).apply(f1) -# 結果は割愛 - -### 3.7.3 1次元データ→データフレーム - -def f2(n): - tmp = np.random.random(n) - return pd.Series([ - n, - tmp.mean(), - tmp.std(ddof=1)], - index=['x', 'p', 'q']) - -f2(10) # 動作確認 -#> x 10.000000 -#> p 0.405898 (平均の例) -#> q 0.317374 (標準偏差の例) -#> dtype: float64 - -v = pd.Series([5, 10, 100]) -v.apply(f2) -#> x p q -#> 0 5.0 0.507798 0.207970 -#> 1 10.0 0.687198 0.264427 -#> 2 100.0 0.487872 0.280743 - -### 3.7.4 データフレーム→データフレーム - -def f3(x, y): - tmp = np.random.random(x) * y - return pd.Series([ - x, - y, - tmp.mean(), - tmp.std(ddof=1)], - index=['x', 'y', 'p', 'q']) - -f3(10, 6) # 動作確認 -#> x 10.000000 -#> y 6.000000 -#> p 2.136413 (平均の例) -#> q 1.798755 (標準偏差の例) -#> dtype: float64 - -my_df = pd.DataFrame({ - 'x': [5, 10, 100, 5, 10, 100], - 'y': [6, 6, 6, 12, 12, 12]}) - -my_df.apply( - lambda row: f3(row['x'], row['y']), - axis=1) -# あるいは -my_df.apply(lambda row: - f3(*row), axis=1) - -#> x y p q -#> 0 5.00 6.00 3.37 1.96 -#> 1 10.00 6.00 1.92 0.95 -#> 2 100.00 6.00 2.90 1.73 -#> 3 5.00 12.00 6.82 3.00 -#> 4 10.00 12.00 7.05 2.42 -#> 5 100.00 12.00 5.90 3.54 - -### 3.7.5 補足:反復処理の並列化 - -from pandarallel import pandarallel -pandarallel.initialize() # 準備 - -v = pd.Series([5, 10, 100]) -v.parallel_apply(f1) -# 結果は割愛 diff --git a/code/py/ch03/03.08.py b/code/py/ch03/03.08.py deleted file mode 100644 index 97c9375..0000000 --- a/code/py/ch03/03.08.py +++ /dev/null @@ -1,31 +0,0 @@ -## 3.8 その他 - -### 3.8.1 よく遭遇するエラーとその対処方法 - -### 3.8.2 変数や関数についての調査 - -x = 123 -type(x) -#> int - -#> Variable Type Data/Info -#> ------------------------------ -#> x int 123 - -import math -?math.log -# あるいは -help(math.log) - -### 3.8.3 RのNA,Pythonのnan - -import numpy as np -v = [1, np.nan, 3] -v -#> [1, nan, 3] - -np.isnan(v[1]) -#> True - -v[1] == np.nan # 誤り -#> False diff --git a/code/py/ch04/04.01.py b/code/py/ch04/04.01.py deleted file mode 100644 index 71efa92..0000000 --- a/code/py/ch04/04.01.py +++ /dev/null @@ -1,154 +0,0 @@ -## 4.1 記述統計 - -### 4.1.1 平均・分散・標準偏差 - -import numpy as np -import pandas as pd - -x = [165, 170, 175, 180, 185] -np.mean(x) # リストの場合 -#> 175.0 - -x = np.array( # アレイ - [165, 170, 175, 180, 185]) -x.mean() # np.mean(x)も可 -#> 175.0 - -x = pd.Series( # シリーズ - [165, 170, 175, 180, 185]) -x.mean() # np.mean(x)も可 -#> 175.0 - -n = len(x) # サンプルサイズ -sum(x) / n -#> 175.0 - -y = [173, 174, 175, 176, 177] -np.mean(y) -#> 175.0 - -np.var(x, ddof=1) # xの分散 -#> 62.5 - -np.var(y, ddof=1) # yの分散 -#> 2.5 - -sum((x - np.mean(x))**2) / (n - 1) -#> 62.5 - -np.std(x, ddof=1) # xの標準偏差 -#> 7.905694150420948 - -np.std(y, ddof=1) # yの標準偏差 -#> 1.5811388300841898 - -np.var(x, ddof=1)**0.5 # xの標準偏差 -#> 7.905694150420948 - -s = pd.Series(x) -s.describe() -#> count 5.000000 (データ数) -#> mean 175.000000 (平均) -#> std 7.905694 (標準偏差) -#> min 165.000000 (最小値) -#> 25% 170.000000 (第1四分位数) -#> 50% 175.000000 (中央値) -#> 75% 180.000000 (第3四分位数) -#> max 185.000000 (最大値) -#> dtype: float64 - -# s.describe()で計算済み - -#### 4.1.1.1 不偏分散とその非負の平方根 - -x = [165, 170, 175, 180, 185] - -np.var(x, ddof=1) # 不偏分散 -#> 62.5 - -np.var(x, ddof=0) # 標本分散 -#> 50.0 - -np.std(x, ddof=1) # √不偏分散 -#> 7.905694150420949 - -np.std(x, ddof=0) # √標本分散 -#> 7.0710678118654755 - -np.std(x, ddof=1) / len(x)**0.5 -#> 3.5355339059327373 - -### 4.1.2 データフレームの統計処理 - -import numpy as np -import pandas as pd - -my_df = pd.DataFrame({ - 'name': ['A', 'B', 'C', 'D'], - 'english': [ 60, 90, 70, 90], - 'math': [ 70, 80, 90, 100], - 'gender': ['f', 'm', 'm', 'f']}) - -#### 4.1.2.1 列ごとの集計 - -my_df['english'].var(ddof=1) -# あるいは -np.var(my_df['english'], ddof=1) - -#> 225.0 - -my_df.var() -# あるいは -my_df.apply('var') -# あるいは -my_df.iloc[:, [1, 2]].apply( - lambda x: np.var(x, ddof=1)) - -#> english 225.000000 -#> math 166.666667 -#> dtype: float64 - -my_df.describe() -#> english math -#> count 4.0 4.000000 -#> mean 77.5 85.000000 -#> std 15.0 12.909944 -#> min 60.0 70.000000 -#> 25% 67.5 77.500000 -#> 50% 80.0 85.000000 -#> 75% 90.0 92.500000 -#> max 90.0 100.000000 - -#### 4.1.2.2 分割表とグループごとの集計 - -from collections import Counter -Counter(my_df.gender) -#> Counter({'f': 2, 'm': 2}) - -# あるいは - -my_df.groupby('gender').apply(len) -#> gender -#> f 2 -#> m 2 -#> dtype: int64 - -my_df2 = my_df.assign( - excel=my_df.math >= 80) -pd.crosstab(my_df2.gender, - my_df2.excel) -#> excel False True -#> gender -#> f 1 1 -#> m 0 2 - -my_df.groupby('gender').mean() -# あるいは -my_df.groupby('gender').agg('mean') -# あるいは -my_df.groupby('gender').agg(np.mean) - -#> english math -#> gender -#> f 75.0 85.0 -#> m 80.0 85.0 diff --git a/code/py/ch04/04.02.py b/code/py/ch04/04.02.py deleted file mode 100644 index 937c687..0000000 --- a/code/py/ch04/04.02.py +++ /dev/null @@ -1,102 +0,0 @@ -## 4.2 データの可視化 - -import numpy as np -import pandas as pd -import statsmodels.api as sm -iris = sm.datasets.get_rdataset('iris', 'datasets').data -iris.head() -#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species -#> 0 5.1 3.5 1.4 0.2 setosa -#> 1 4.9 3.0 1.4 0.2 setosa -#> 2 4.7 3.2 1.3 0.2 setosa -#> 3 4.6 3.1 1.5 0.2 setosa -#> 4 5.0 3.6 1.4 0.2 setosa - -### 4.2.1 ヒストグラム - -iris.hist('Sepal.Length') - -my_df = pd.DataFrame( - {'x': [10, 20, 30]}) -my_df.hist('x', bins=2) # 階級数は2 - -x = iris['Sepal.Length'] -tmp = np.linspace(min(x), max(x), 10) -iris.hist('Sepal.Length', - bins=tmp.round(2)) - -### 4.2.2 散布図 - -iris.plot('Sepal.Length', - 'Sepal.Width', - kind='scatter') - -### 4.2.3 箱ひげ図 - -iris.boxplot() - -### 4.2.4 棒グラフとエラーバー - -pd.options.display.float_format = ( - '{:.2f}'.format) -my_df = (iris.describe().transpose() - [['mean', 'std']]) -my_df['se'] = (my_df['std'] / - len(iris)**0.5) -my_df -#> mean std se -#> Sepal.Length 5.84 0.83 0.07 -#> Sepal.Width 3.06 0.44 0.04 -#> Petal.Length 3.76 1.77 0.14 -#> Petal.Width 1.20 0.76 0.06 - -my_df.plot(y='mean', kind='bar', yerr='se', capsize=10) - -my_group = iris.groupby('Species') # 品種ごとに, -my_df = my_group.agg('mean') # 各変数の,平均と -my_se = my_group.agg(lambda x: x.std() / len(x)**0.5) # 標準誤差を求める. -my_se -#> Sepal.Length Sepal.Width Petal.Length Petal.Width -#> Species -#> setosa 0.05 0.05 0.02 0.01 -#> versicolor 0.07 0.04 0.07 0.03 -#> virginica 0.09 0.05 0.08 0.04 - -my_group.agg('mean').plot(kind='bar', yerr=my_se, capsize=5) - -### 4.2.5 モザイクプロット - -from statsmodels.graphics.mosaicplot \ - import mosaic - -my_df = pd.DataFrame({ - 'Species': iris.Species, - 'w_Sepal': iris['Sepal.Width'] > 3}) - -my_table = pd.crosstab( # 分割表 - my_df['Species'], - my_df['w_Sepal']) -my_table -#> w_Sepal False True -#> Species -#> setosa 8 42 -#> versicolor 42 8 -#> virginica 33 17 - -mosaic(my_df, - index=['Species', 'w_Sepal']) - -my_table.columns = [str(x) for x in my_table.columns] -my_table.index = [str(x) for x in my_table.index] -mosaic(my_df, index=['Species', 'w_Sepal'], labelizer=lambda k: my_table.loc[k]) - -### 4.2.6 関数のグラフ - -import matplotlib.pyplot as plt -import numpy as np - -x = np.linspace(-2, 2, 100) -y = x**3 - x -plt.plot(x, y) - -### 4.2.7 ggplot2 (R) diff --git a/code/py/ch04/04.03.py b/code/py/ch04/04.03.py deleted file mode 100644 index d5a4dd7..0000000 --- a/code/py/ch04/04.03.py +++ /dev/null @@ -1,107 +0,0 @@ -## 4.3 乱数 - -import matplotlib.pyplot as plt -import numpy as np -rng = np.random.default_rng() - -### 4.3.1 一様乱数(離散) - -x = np.random.choice( - a=range(1, 7), # 1から6 - size=10000, # 乱数の数 - replace=True) # 重複あり -# あるいは -x = np.random.randint( -# あるいは -#x = rng.integers( - low=1, # 最小 - high=7, # 最大+1 - size=10000) # 乱数の数 - -plt.hist(x, bins=6) # ヒストグラム - -### 4.3.2 一様乱数(連続) - -x = np.random.random(size=1000) -# あるいは -x = rng.random(size=10000) -# あるいは -x = np.random.uniform( - low=0, # 最小 - high=1, # 最大 - size=1000) # 乱数の数 -plt.hist(x) - -tmp = np.random.uniform( - low=1, # 最小 - high=7, # 最大 + 1 - size=1000) # 乱数の数 -x = [int(k) for k in tmp] -plt.hist(x, bins=6) # 結果は割愛 - -### 4.3.3 二項乱数 - -n = 100 -p = 0.5 -r = 10000 -x = np.random.binomial( -# あるいは -#x = rng.binomial( - n=n, # 試行回数 - p=p, # 確率 - size=r) # 乱数の数 -plt.hist(x, bins=max(x) - min(x)) - -### 4.3.4 正規乱数 - -r = 10000 -x = np.random.normal( -# あるいは -#x = rng.normal( - loc=50, # 平均 - scale=5, # 標準偏差 - size=r) # 乱数の数 -plt.hist(x, bins=40) - -#### 4.3.4.1 補足:不偏性の具体例 - -import numpy as np -import pandas as pd - -def f(k): - n = 10000 - tmp = [g(np.random.normal(size=k, scale=3)) for _ in range(n)] - return pd.Series([k, - np.mean(tmp), # 平均 - np.std(tmp, ddof=1) / n**0.5], # 標準誤差 - index=['k', 'mean', 'se']) - -def g(x): - return np.var(x, ddof=1) -pd.Series([10, 20, 30]).apply(f) -#> k mean se -#> 0 10.0 9.025140 0.042690 -#> 1 20.0 9.022280 0.029525 -#> 2 30.0 8.983166 0.023584 - -def g(x): - return np.std(x, ddof=1) -pd.Series([10, 20, 30]).apply(f) -#> k mean se -#> 0 10.0 2.923114 0.006983 -#> 1 20.0 2.961450 0.004811 -#> 2 30.0 2.968328 0.003977 - -from math import gamma - -def g(x): - n = len(x) - return (np.std(x, ddof=1) * - (np.sqrt((n - 1) / 2) * - gamma((n - 1) / 2) / - gamma(n / 2))) -pd.Series([10, 20, 30]).apply(f) -#> k mean se -#> 0 10.0 3.005788 0.007121 -#> 1 20.0 3.001857 0.004894 -#> 2 30.0 2.995965 0.003925 diff --git a/code/py/ch04/04.04.py b/code/py/ch04/04.04.py deleted file mode 100644 index 770a5e4..0000000 --- a/code/py/ch04/04.04.py +++ /dev/null @@ -1,136 +0,0 @@ -## 4.4 統計的推測 - -### 4.4.1 検定 - -from statsmodels.stats.proportion import binom_test, proportion_confint - -binom_test(count=2, # 当たった回数 - nobs=15, # くじを引いた回数 - prop=4 / 10, # 当たる確率(仮説) - alternative='two-sided') # 両側検定(デフォルト) - # 左片側検定なら'smaller' - # 右片側検定なら'larger' -#> 0.03646166155263999 - -#### 4.4.1.1 補足:p値とは何か - -import numpy as np -import pandas as pd -from scipy import stats - -t = 4 / 10 # 当たる確率 -n = 15 # くじを引いた回数 -x = np.array(range(0, n + 1)) # 当たった回数 -my_pr = stats.binom.pmf(x, n, t) # x回当たる確率 -my_pr2 = stats.binom.pmf(2, n, t) # 2回当たる確率 - -my_data = pd.DataFrame({'x': x, 'y1': my_pr, 'y2': my_pr}) -my_data.loc[my_pr > my_pr2, 'y1'] = np.nan # 当たる確率が,2回当たる確率超過 -my_data.loc[my_pr <= my_pr2, 'y2'] = np.nan # 当たる確率が,2回当たる確率以下 -ax = my_data.plot(x='x', style='o', ylabel='probability', - legend=False) # 凡例を表示しない. -ax.hlines(y=my_pr2, xmin=0, xmax=15) # 水平線 -ax.vlines(x=x, ymin=0, ymax=my_pr) # 垂直線 - -### 4.4.2 推定 - -a = 0.05 -proportion_confint( - count=2, # 当たった回数 - nobs=15, # くじを引いた回数 - alpha=a, # 有意水準(省略可) - method='binom_test') -#> (0.024225732468536626, -#> 0.3967139842509865) - -a = 0.05 # 有意水準 -tmp = np.linspace(0, 1, 100) - -my_df = pd.DataFrame({ - 't': tmp, # 当たる確率 - 'q': a, # 水平線 - 'p': [binom_test(count=2, nobs=15, prop=t) for t in tmp]}) # p値 - -my_df.plot(x='t', legend=None, xlabel=r'$\theta$', ylabel=r'p-value') - -### 4.4.3 平均の差の検定と推定(t検定) - -from statsmodels.stats.weightstats import CompareMeans, DescrStatsW - -X = [32.1, 26.2, 27.5, 31.8, 32.1, 31.2, 30.1, 32.4, 32.3, 29.9, - 29.6, 26.6, 31.2, 30.9, 29.3] -Y = [35.4, 34.6, 31.1, 32.4, 33.3, 34.7, 35.3, 34.3, 32.1, 28.3, - 33.3, 30.5, 32.6, 33.3, 32.2] - -a = 0.05 # 有意水準(デフォルト) = 1 - 信頼係数 -alt = 'two-sided' # 両側検定(デフォルト) - # 左片側検定なら'smaller' - # 右片側検定なら'larger' - -d = DescrStatsW(np.array(X) - np.array(Y)) # 対標本の場合 -d.ttest_mean(alternative=alt)[1] # p値 -#> 0.0006415571512322235 - -d.tconfint_mean(alpha=a, alternative=alt) # 信頼区間 -#> (-3.9955246743198867, -1.3644753256801117) - -c = CompareMeans(DescrStatsW(X), DescrStatsW(Y)) # 対標本でない場合 - -ve = 'pooled' # 等分散を仮定する(デフォルト).仮定しないなら'unequal'. -c.ttest_ind(alternative=alt, usevar=ve)[1] # p値 -#> 0.000978530937238609 - -c.tconfint_diff(alpha=a, alternative=alt, usevar=ve) # 信頼区間 -#> (-4.170905570517185, -1.1890944294828283) - -### 4.4.4 独立性の検定(カイ2乗検定) - -import pandas as pd -my_url = ('https://raw.githubusercontent.com/taroyabuki' - '/fromzero/master/data/smoker.csv') -my_data = pd.read_csv(my_url) - -my_data.head() -#> alive smoker -#> 0 Yes No -#> 1 Yes No -#> 2 Yes No -#> 3 Yes No -#> 4 Yes No - -my_table = pd.crosstab( - my_data['alive'], - my_data['smoker']) -my_table -#> smoker No Yes -#> alive -#> No 117 54 -#> Yes 950 348 - -from scipy.stats import chi2_contingency -chi2_contingency(my_table, correction=False)[1] -#> 0.18860725715300422 - -### 4.4.5 ブートストラップ - -#### 4.4.5.1 15回引いて2回当たったくじ - -X = [0] * 13 + [1] * 2 # 手順1 -X -#> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1] - -tmp = np.random.choice(X, 15, replace=True) # 手順2 -tmp -#> array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0]) - -sum(tmp) # 手順3 -#> 2 - -n = 10**5 -result = [sum(np.random.choice(X, len(X), replace=True)) for _ in range(n)] # 手順4 - -import matplotlib.pyplot as plt -plt.hist(result, bins=range(0, 16)) - -np.quantile(result, [0.025, 0.975]) -#> array([0., 5.]) diff --git a/code/py/ch05/05.01.py b/code/py/ch05/05.01.py deleted file mode 100644 index d7bc504..0000000 --- a/code/py/ch05/05.01.py +++ /dev/null @@ -1,116 +0,0 @@ -## 5.1 データの読み込み - -### 5.1.1 CSV - - -#### 5.1.1.1 CSVの読み込み - -import pandas as pd -my_df = pd.read_csv('exam.csv') -my_df -#> name english math gender -#> 0 A 60 70 f -#> 1 B 90 80 m -#> 2 C 70 90 m -#> 3 D 90 100 f - -my_url = ('https://raw.githubusercontent.com/taroyabuki' - '/fromzero/master/data/exam.csv') -my_df = pd.read_csv(my_url) - -my_df2 = pd.read_csv('exam.csv', - index_col='name') -my_df2 -#> english math gender -#> name -#> A 60 70 f -#> B 90 80 m -#> C 70 90 m -#> D 90 100 f - -#### 5.1.1.2 CSVファイルへの書き出し - -my_df.to_csv('exam2.csv', index=False) - -my_df2.to_csv('exam3.csv') - -### 5.1.2 文字コード - -my_df = pd.read_csv('exam.csv', - encoding='UTF-8') - -my_df.to_csv('exam2.csv', index=False, encoding='UTF-8') - -### 5.1.3 ウェブ上の表 - -my_url = 'https://taroyabuki.github.io/fromzero/exam.html' -my_tables = pd.read_html(my_url) - -my_tables -#> [ Unnamed: 0 name english ... -#> 0 NaN A 60 ... -#> 1 NaN B 90 ... -#> 2 NaN C 70 ... -#> 3 NaN D 90 ...] - -my_tables[0] -#> Unnamed: 0 name english ... -#> 0 NaN A 60 ... -#> 1 NaN B 90 ... -#> 2 NaN C 70 ... -#> 3 NaN D 90 ... - -# 1列目以降を取り出す. -my_data = my_tables[0].iloc[:, 1:] -my_data -#> name english math gender -#> 0 A 60 70 f -#> 1 B 90 80 m -#> 2 C 70 90 m -#> 3 D 90 100 f - -### 5.1.4 JSONとXML - -#### 5.1.4.1 JSONデータの読み込み - -my_url = ('https://raw.githubusercontent.com/taroyabuki' - '/fromzero/master/data/exam.json') -my_data = pd.read_json(my_url) -#my_data = pd.read_json('exam.json') # (ファイルを使う場合) -my_data -#> name english math gender -#> 0 A 60 70 f -#> 1 B 90 80 m -#> 2 C 70 90 m -#> 3 D 90 100 f - -#### 5.1.4.2 XMLデータの読み込み - -import xml.etree.ElementTree as ET -from urllib.request import urlopen - -my_url = ('https://raw.githubusercontent.com/taroyabuki' - '/fromzero/master/data/exam.xml') -with urlopen(my_url) as f: - my_tree = ET.parse(f) # XMLデータの読み込み - -#my_tree = ET.parse('exam.xml') # (ファイルを使う場合) -my_ns = '{https://www.example.net/ns/1.0}' # 名前空間 - -my_records = my_tree.findall(f'.//{my_ns}record') - -def f(record): - my_dic1 = record.attrib # 属性を取り出す. - # 子要素の名前と内容のペアを辞書にする. - my_dic2 = {child.tag.replace(my_ns, ''): child.text for child in list(record)} - return {**my_dic1, **my_dic2} # 辞書を結合する. - -my_data = pd.DataFrame([f(record) for record in my_records]) -my_data['english'] = pd.to_numeric(my_data['english']) -my_data['math'] = pd.to_numeric(my_data['math']) -my_data -#> english math gender name -#> 0 60 70 f A -#> 1 90 80 m B -#> 2 70 90 m C -#> 3 90 100 f D diff --git a/code/py/ch05/05.02.py b/code/py/ch05/05.02.py deleted file mode 100644 index 80a9450..0000000 --- a/code/py/ch05/05.02.py +++ /dev/null @@ -1,84 +0,0 @@ -## 5.2 データの変換 - -### 5.2.1 標準化 - -import numpy as np -from scipy.stats import zscore - -x1 = [1, 2, 3] - -z1 = ((x1 - np.mean(x1)) / - np.std(x1, ddof=1)) -# あるいは -z1 = zscore(x1, ddof=1) - -z1 -#> array([-1., 0., 1.]) - -z1.mean(), np.std(z1, ddof=1) -#> (0.0, 1.0) - -z1 * np.std(x1, ddof=1) + np.mean(x1) -#> array([1., 2., 3.]) - -x2 = [1, 3, 5] -z2 = ((x2 - np.mean(x1)) / - np.std(x1, ddof=1)) -z2.mean(), np.std(z2, ddof=1) -#> (1.0, 2.0) - -### 5.2.2 ワンホットエンコーディング - -import pandas as pd -from sklearn.preprocessing import ( - OneHotEncoder) - -my_df = pd.DataFrame({ - 'id': [ 1 , 2 , 3 ], - 'class': ['A', 'B', 'C']}) - -my_enc = OneHotEncoder() -tmp = my_enc.fit_transform( - my_df[['class']]).toarray() -my_names = my_enc.get_feature_names() \ -if hasattr(my_enc, 'get_feature_names') \ -else my_enc.get_feature_names_out() -pd.DataFrame(tmp, columns=my_names) -#> x0_A x0_B x0_C -#> 0 1.0 0.0 0.0 -#> 1 0.0 1.0 0.0 -#> 2 0.0 0.0 1.0 - -my_df2 = pd.DataFrame({ - 'id': [ 4 , 5, 6 ], - 'class': ['B', 'C', 'B']}) -tmp = my_enc.transform( - my_df2[['class']]).toarray() -pd.DataFrame(tmp, columns=my_names) -#> x0_A x0_B x0_C -#> 0 0.0 1.0 0.0 -#> 1 0.0 0.0 1.0 -#> 2 0.0 1.0 0.0 - -#### 5.2.2.1 補足:冗長性の排除 - -my_enc = OneHotEncoder(drop='first') - -tmp = my_enc.fit_transform( - my_df[['class']]).toarray() -my_names = my_enc.get_feature_names() \ -if hasattr(my_enc, 'get_feature_names') \ -else my_enc.get_feature_names_out() -pd.DataFrame(tmp, columns=my_names) -#> x0_B x0_C -#> 0 0.0 0.0 -#> 1 1.0 0.0 -#> 2 0.0 1.0 - -tmp = my_enc.transform( - my_df2[['class']]).toarray() -pd.DataFrame(tmp, columns=my_names) -#> x0_B x0_C -#> 0 1.0 0.0 -#> 1 0.0 1.0 -#> 2 1.0 0.0 diff --git a/code/py/ch06/06.01.py b/code/py/ch06/06.01.py deleted file mode 100644 index cd21786..0000000 --- a/code/py/ch06/06.01.py +++ /dev/null @@ -1 +0,0 @@ -## 6.1 機械学習の目的(本書の場合) diff --git a/code/py/ch06/06.02.py b/code/py/ch06/06.02.py deleted file mode 100644 index 253b6e9..0000000 --- a/code/py/ch06/06.02.py +++ /dev/null @@ -1,39 +0,0 @@ -## 6.2 機械学習のためのデータ - -### 6.2.1 機械学習を学ぶのに使うデータセット - -#### 6.2.1.1 教師データあり - -#### 6.2.1.2 時系列データ(第\ref{時系列予測 - -#### 6.2.1.3 教師データなし(第\ref{教師なし学習 - -### 6.2.2 補足:アヤメのデータ - -#### 6.2.2.1 R - -#### 6.2.2.2 Python - -import statsmodels.api as sm -iris = sm.datasets.get_rdataset('iris', 'datasets').data -iris.head() -#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species -#> 0 5.1 3.5 1.4 0.2 setosa -# 以下省略 - -import seaborn as sns -iris = sns.load_dataset('iris') -iris.head() -#> sepal_length sepal_width petal_length petal_width species -#> 0 5.1 3.5 1.4 0.2 setosa -# 以下省略 - -import pandas as pd -from sklearn.datasets import load_iris -tmp = load_iris() -iris = pd.DataFrame(tmp.data, columns=tmp.feature_names) -iris['target'] = tmp.target_names[tmp.target] -iris.head() -#> sepal length (cm) sepal width (cm) ... petal width (cm) target -#> 0 5.1 3.5 ... 0.2 setosa -# 以下省略 diff --git a/code/py/ch06/06.03.py b/code/py/ch06/06.03.py deleted file mode 100644 index b322a14..0000000 --- a/code/py/ch06/06.03.py +++ /dev/null @@ -1,5 +0,0 @@ -## 6.3 機械学習のための手法 - -### 6.3.1 教師あり学習のためのフレームワーク - -### 6.3.2 本書で勧める手法とデータセットの組合せ diff --git a/code/py/ch07/07.01.py b/code/py/ch07/07.01.py deleted file mode 100644 index 615411e..0000000 --- a/code/py/ch07/07.01.py +++ /dev/null @@ -1 +0,0 @@ -## 7.1 自動車の停止距離 diff --git a/code/py/ch07/07.02.py b/code/py/ch07/07.02.py deleted file mode 100644 index 189a4a8..0000000 --- a/code/py/ch07/07.02.py +++ /dev/null @@ -1,28 +0,0 @@ -## 7.2 データの確認 - -import statsmodels.api as sm -my_data = sm.datasets.get_rdataset('cars', 'datasets').data - -my_data.shape -#> (50, 2) - -my_data.head() -#> speed dist -#> 0 4 2 -#> 1 4 10 -#> 2 7 4 -#> 3 7 22 -#> 4 8 16 - -my_data.describe() -#> speed dist -#> count 50.000000 50.000000 -#> mean 15.400000 42.980000 -#> std 5.287644 25.769377 -#> min 4.000000 2.000000 -#> 25% 12.000000 26.000000 -#> 50% 15.000000 36.000000 -#> 75% 19.000000 56.000000 -#> max 25.000000 120.000000 - -my_data.plot(x='speed', style='o') diff --git a/code/py/ch07/07.03.py b/code/py/ch07/07.03.py deleted file mode 100644 index 33d0887..0000000 --- a/code/py/ch07/07.03.py +++ /dev/null @@ -1,58 +0,0 @@ -## 7.3 回帰分析 - -### 7.3.1 回帰分析とは何か - -### 7.3.2 線形単回帰分析 - -import seaborn as sns -import statsmodels.api as sm - -my_data = sm.datasets.get_rdataset('cars', 'datasets').data -ax = sns.regplot(x='speed', y='dist', data=my_data) -ax.vlines(x=21.5, ymin=-5, ymax=67, linestyles='dotted') -ax.hlines(y=67, xmin=4, xmax=21.5, linestyles='dotted') -ax.set_xlim(4, 25) -ax.set_ylim(-5, 125) - -### 7.3.3 回帰分析の実践 - -#### 7.3.3.1 データの用意 - -import statsmodels.api as sm -my_data = sm.datasets.get_rdataset('cars', 'datasets').data -X, y = my_data[['speed']], my_data['dist'] - -#### 7.3.3.2 訓練 - -# モデルの指定 -from sklearn.linear_model import LinearRegression -my_model = LinearRegression() - -# 訓練(モデルをデータにフィットさせる.) -my_model.fit(X, y) - -# まとめて実行してもよい. -# my_model = LinearRegression().fit(X, y) - -my_model.intercept_, my_model.coef_ -#> (-17.579094890510973, -#> array([3.93240876])) - -#### 7.3.3.3 予測 - -tmp = [[21.5]] -my_model.predict(tmp) -#> array([66.96769343]) - -#### 7.3.3.4 モデルの可視化 - -import numpy as np -import pandas as pd - -tmp = pd.DataFrame({'speed': np.linspace(min(my_data.speed), - max(my_data.speed), - 100)}) -tmp['model'] = my_model.predict(tmp) - -pd.concat([my_data, tmp]).plot( - x='speed', style=['o', '-']) diff --git a/code/py/ch07/07.04.py b/code/py/ch07/07.04.py deleted file mode 100644 index c154006..0000000 --- a/code/py/ch07/07.04.py +++ /dev/null @@ -1,101 +0,0 @@ -## 7.4 当てはまりの良さの指標 - -### 7.4.1 RMSE - -import pandas as pd -import statsmodels.api as sm -from sklearn.linear_model import LinearRegression -from sklearn.metrics import mean_squared_error, r2_score - -my_data = sm.datasets.get_rdataset('cars', 'datasets').data -X, y = my_data[['speed']], my_data['dist'] - -my_model = LinearRegression() -my_model.fit(X, y) -y_ = my_model.predict(X) -my_data['y_'] = y_ - -pd.options.display.float_format = ( - '{:.2f}'.format) -my_data['residual'] = y - y_ -my_data.head() -#> speed dist y_ residual -#> 0 4 2 -1.85 3.85 -#> 1 4 10 -1.85 11.85 -#> 2 7 4 9.95 -5.95 -#> 3 7 22 9.95 12.05 -#> 4 8 16 13.88 2.12 - -ax = my_data.plot(x='speed', y='dist', style='o', legend=False) -my_data.plot(x='speed', y='y_', style='-', legend=False, ax=ax) -ax.vlines(x=X, ymin=y, ymax=y_, linestyles='dotted') - -mean_squared_error(y, y_)**0.5 -# あるいは -(my_data['residual']**2).mean()**0.5 - -#> 15.068855995791381 - -### 7.4.2 決定係数 - -my_model.score(X, y) -# あるいは -r2_score(y_true=y, y_pred=y_) -#> 0.6510793807582509 - -import numpy as np -np.corrcoef(y, y_)[0, 1]**2 -#> 0.6510793807582511 - -my_test = my_data[:3] -X = my_test[['speed']] -y = my_test['dist'] -y_ = my_model.predict(X) - -my_model.score(X, y) -# あるいは -r2_score(y_true=y, y_pred=y_) -#> -4.498191310376778 # 決定係数1 - -np.corrcoef(y, y_)[0, 1]**2 -#> 0.0769230769230769 # 決定係数6 - -### 7.4.3 当てはまりの良さの指標の問題点 - -import numpy as np -import pandas as pd -import statsmodels.api as sm -from sklearn.linear_model import LinearRegression -from sklearn.preprocessing import PolynomialFeatures - -my_data = sm.datasets.get_rdataset('cars', 'datasets').data - -my_idx = [1, 10, 26, 33, 38, 43] -my_sample = my_data.iloc[my_idx, ] -X, y = my_sample[['speed']], my_sample['dist'] - -d = 5 -X5 = PolynomialFeatures(d, include_bias=False).fit_transform(X) # Xの1乗から5乗の変数 - -my_model = LinearRegression() -my_model.fit(X5, y) -y_ = my_model.predict(X5) - -((y - y_)**2).mean()**0.5 -#> 7.725744805546204e-07 # RMSE - -my_model.score(X5, y) -#> 0.9999999999999989 # 決定係数1 - -np.corrcoef(y, y_)[0, 1]**2 -#> 0.9999999999999991 # 決定係数6 - -tmp = pd.DataFrame({'speed': np.linspace(min(my_data.speed), - max(my_data.speed), - 100)}) -X5 = PolynomialFeatures(d, include_bias=False).fit_transform(tmp) -tmp['model'] = my_model.predict(X5) - -my_sample = my_sample.assign(sample=y) -my_df = pd.concat([my_data, my_sample, tmp]) -my_df.plot(x='speed', style=['o', 'o', '-'], ylim=(0, 130)) diff --git a/code/py/ch07/07.05.py b/code/py/ch07/07.05.py deleted file mode 100644 index b8bd3c2..0000000 --- a/code/py/ch07/07.05.py +++ /dev/null @@ -1,38 +0,0 @@ -## 7.5 K最近傍法 - -### 7.5.1 K最近傍法とは何か - -### 7.5.2 K最近傍法の実践 - -# 準備 -import numpy as np -import pandas as pd -import statsmodels.api as sm -from sklearn.neighbors import KNeighborsRegressor - -my_data = sm.datasets.get_rdataset('cars', 'datasets').data -X, y = my_data[['speed']], my_data['dist'] - -# 訓練 -my_model = KNeighborsRegressor() -my_model.fit(X, y) - -# 可視化の準備 -tmp = pd.DataFrame({'speed': np.linspace(min(my_data.speed), - max(my_data.speed), - 100)}) -tmp['model'] = my_model.predict(tmp) - -pd.concat([my_data, tmp]).plot( - x='speed', style=['o', '-']) - -y_ = my_model.predict(X) - -((y - y_)**2).mean()**0.5 -#> 13.087184571174962 # RMSE - -my_model.score(X, y) -#> 0.7368165812204317 # 決定係数1 - -np.corrcoef(y, y_)[0, 1]**2 -#> 0.7380949412509705 # 決定係数6 diff --git a/code/py/ch07/07.06.py b/code/py/ch07/07.06.py deleted file mode 100644 index 48de71a..0000000 --- a/code/py/ch07/07.06.py +++ /dev/null @@ -1,142 +0,0 @@ -## 7.6 検証 - -### 7.6.1 訓練データ・検証データ・テストデータ - -### 7.6.2 検証とは何か - -### 7.6.3 検証の実践 - -import statsmodels.api as sm -from sklearn.linear_model import LinearRegression -from sklearn.model_selection import cross_val_score - -# データの準備 -my_data = sm.datasets.get_rdataset('cars', 'datasets').data -X, y = my_data[['speed']], my_data['dist'] - -# モデルの指定 -my_model = LinearRegression() - -# 検証(5分割交差検証) -my_scores = cross_val_score(my_model, X, y) - -# 5個の決定係数1を得る. -my_scores -#> array([-0.25789256, -0.21421069, -0.30902773, -0.27346232, 0.02312918]) - -# 平均を決定係数1(検証)とする. -my_scores.mean() -#> -0.20629282165364665 - -my_scores = cross_val_score(my_model, X, y, - scoring='neg_root_mean_squared_error') --my_scores.mean() -#> 15.58402474583013 # RMSE(検証) - -### 7.6.4 検証の並列化 - -### 7.6.5 指標のまとめ - -#### 7.6.5.1 準備 - -import numpy as np -import statsmodels.api as sm -from sklearn.linear_model import LinearRegression -from sklearn.metrics import mean_squared_error, r2_score -from sklearn.model_selection import cross_val_score, LeaveOneOut - -my_data = sm.datasets.get_rdataset('cars', 'datasets').data -X, y = my_data[['speed']], my_data['dist'] -my_model = LinearRegression().fit(X, y) -y_ = my_model.predict(X) - -#### 7.6.5.2 当てはまりの良さの指標 - -# RMSE(訓練) -mean_squared_error(y, y_)**0.5 -#> 15.068855995791381 - -# 決定係数1(訓練) -my_model.score(X, y) -# あるいは -r2_score(y_true=y, y_pred=y_) -#> 0.6510793807582509 - -# 決定係数6(訓練) -np.corrcoef(y, y_)[0, 1]**2 -#> 0.6510793807582511 - -#### 7.6.5.3 予測性能の指標(簡単に求められるもの) - -my_scores = cross_val_score(my_model, X, y, - scoring='neg_root_mean_squared_error') --my_scores.mean() -#> 15.301860331378464 # RMSE(検証) - -my_scores = cross_val_score(my_model, X, y, scoring='r2') # scoring='r2'は省略可 -my_scores.mean() -#> 0.49061365458235245 # 決定係数1(検証) - -#### 7.6.5.4 予測性能の指標(RとPythonで同じ結果を得る) - -# 方法1 -my_scores1 = cross_val_score(my_model, X, y, cv=LeaveOneOut(), - scoring='neg_mean_squared_error') -(-my_scores1.mean())**0.5 -#> 15.697306009399101 - -# 方法2 -my_scores2 = cross_val_score(my_model, X, y, cv=LeaveOneOut(), - scoring='neg_root_mean_squared_error') -(my_scores2**2).mean()**0.5 -#> 15.697306009399101 - --my_scores2.mean() -#> 12.059178648637483 - -### 7.6.6 補足:検証による手法の比較 - -import pandas as pd -import statsmodels.api as sm -from sklearn.linear_model import LinearRegression -from sklearn.metrics import mean_squared_error -from sklearn.model_selection import cross_val_score, LeaveOneOut -from sklearn.neighbors import KNeighborsRegressor - -my_data = sm.datasets.get_rdataset('cars', 'datasets').data -X, y = my_data[['speed']], my_data['dist'] - -my_lm_scores = cross_val_score( - LinearRegression(), - X, y, cv=LeaveOneOut(), scoring='neg_mean_squared_error') - -my_knn_socres = cross_val_score( - KNeighborsRegressor(n_neighbors=5), - X, y, cv=LeaveOneOut(), scoring='neg_mean_squared_error') - -(-my_lm_scores.mean())**0.5 -#> 15.697306009399101 # 線形回帰分析 - -(-my_knn_socres.mean())**0.5 -#> 16.07308308943869 # K最近傍法 - -my_df = pd.DataFrame({ - 'lm': -my_lm_scores, - 'knn': -my_knn_socres}) -my_df.head() -#> lm knn -#> 0 18.913720 108.16 -#> 1 179.215044 0.64 -#> 2 41.034336 64.00 -#> 3 168.490212 184.96 -#> 4 5.085308 0.00 - -my_df.boxplot().set_ylabel("$r^2$") - -from statsmodels.stats.weightstats import DescrStatsW -d = DescrStatsW(my_df.lm - my_df.knn) -d.ttest_mean()[1] # p値 -#> 0.6952755720536115 - -d.tconfint_mean(alpha=0.05, alternative='two-sided') # 信頼区間 -#> (-72.8275283312228, 48.95036023665703) diff --git a/code/py/ch07/07.07.py b/code/py/ch07/07.07.py deleted file mode 100644 index 7bbcdff..0000000 --- a/code/py/ch07/07.07.py +++ /dev/null @@ -1,73 +0,0 @@ -## 7.7 パラメータチューニング - -import pandas as pd -import statsmodels.api as sm -from sklearn.metrics import mean_squared_error -from sklearn.model_selection import GridSearchCV, LeaveOneOut -from sklearn.neighbors import KNeighborsRegressor - -my_data = sm.datasets.get_rdataset('cars', 'datasets').data -X, y = my_data[['speed']], my_data['dist'] - -my_params = {'n_neighbors': range(1, 16)} # 探索範囲(1以上16未満の整数) - -my_search = GridSearchCV(estimator=KNeighborsRegressor(), - param_grid=my_params, - cv=LeaveOneOut(), - scoring='neg_mean_squared_error') -my_search.fit(X, y) - -tmp = my_search.cv_results_ # チューニングの詳細 -my_scores = (-tmp['mean_test_score'])**0.5 # RMSE -my_results = pd.DataFrame(tmp['params']).assign(validation=my_scores) - -my_results.head() -#> n_neighbors validation -#> 0 1 20.089798 -#> 1 2 17.577685 -#> 2 3 16.348836 -#> 3 4 16.198804 -#> 4 5 16.073083 - -my_results.plot(x='n_neighbors', - style='o-', - ylabel='RMSE') - -my_search.best_params_ -#> {'n_neighbors': 5} - -(-my_search.best_score_)**0.5 -#> 16.07308308943869 - -my_model = my_search.best_estimator_ -y_ = my_model.predict(X) -mean_squared_error(y_, y)**0.5 -#> 13.087184571174962 - -### 7.7.1 補足:ハイパーパラメータとRMSE(訓練) - -import pandas as pd -import statsmodels.api as sm -from sklearn.metrics import mean_squared_error -from sklearn.model_selection import cross_val_score, LeaveOneOut -from sklearn.neighbors import KNeighborsRegressor - -my_data = sm.datasets.get_rdataset('cars', 'datasets').data -X, y = my_data[['speed']], my_data['dist'] - -def my_loocv(k): - my_model = KNeighborsRegressor(n_neighbors=k) - my_scores = cross_val_score(estimator=my_model, X=X, y=y, - cv=LeaveOneOut(), - scoring='neg_mean_squared_error') - y_ = my_model.fit(X, y).predict(X) - return pd.Series([k, - (-my_scores.mean())**0.5, # RMSE(検証) - mean_squared_error(y_, y)**0.5], # RMSE(訓練) - index=['n_neighbors', 'validation', 'training']) - -my_results = pd.Series(range(1, 16)).apply(my_loocv) - -my_results.plot(x='n_neighbors', - style='o-', - ylabel='RMSE') diff --git a/code/py/ch08/08.01.py b/code/py/ch08/08.01.py deleted file mode 100644 index 41c6822..0000000 --- a/code/py/ch08/08.01.py +++ /dev/null @@ -1,30 +0,0 @@ -## 8.1 ブドウの生育条件とワインの価格 - -import pandas as pd -my_url = 'http://www.liquidasset.com/winedata.html' -tmp = pd.read_table(my_url, skiprows=62, nrows=38, sep='\\s+', na_values='.') -tmp.describe() -#> OBS VINT LPRICE2 WRAIN DEGREES ... -#> count 38.000000 38.000000 27.000000 38.000000 37.000000 ... -#> mean 19.500000 1970.500000 -1.451765 605.000000 16.522973 ... -# 以下省略 - -my_data = tmp.iloc[:, 2:].dropna() -my_data.head() -#> LPRICE2 WRAIN DEGREES ... -#> 0 -0.99868 600 17.1167 ... -#> 1 -0.45440 690 16.7333 ... -#> 3 -0.80796 502 17.1500 ... -#> 5 -1.50926 420 16.1333 ... -#> 6 -1.71655 582 16.4167 ... - -my_data.shape -#> (27, 5) - -my_data.to_csv('wine.csv', - index=False) - -#my_data = pd.read_csv('wine.csv') # 作ったファイルを使う場合 -my_url = ('https://raw.githubusercontent.com/taroyabuki' - '/fromzero/master/data/wine.csv') -my_data = pd.read_csv(my_url) diff --git a/code/py/ch08/08.02.py b/code/py/ch08/08.02.py deleted file mode 100644 index e9f54fb..0000000 --- a/code/py/ch08/08.02.py +++ /dev/null @@ -1,60 +0,0 @@ -## 8.2 重回帰分析 - -import numpy as np -import pandas as pd -from sklearn.linear_model import LinearRegression -from sklearn.metrics import mean_squared_error -from sklearn.model_selection import cross_val_score, LeaveOneOut - -my_url = ('https://raw.githubusercontent.com/taroyabuki' - '/fromzero/master/data/wine.csv') -my_data = pd.read_csv(my_url) -X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2'] - -my_model = LinearRegression().fit(X, y) - -my_model.intercept_ -#> -12.145333576510417 - -pd.Series(my_model.coef_, - index=X.columns) -#> WRAIN 0.001167 -#> DEGREES 0.616392 -#> HRAIN -0.003861 -#> TIME_SV 0.023847 -#> dtype: float64 - -my_test = [[500, 17, 120, 2]] -my_model.predict(my_test) -#> array([-1.49884253]) - -y_ = my_model.predict(X) - -mean_squared_error(y_, y)**0.5 -#> 0.2586166620130621 # RMSE(訓練) - -my_model.score(X, y) -#> 0.8275277990052154 # 決定係数1 - -np.corrcoef(y, y_)[0, 1]**2 -#> 0.8275277990052158 # 決定係数6 - -my_scores = cross_val_score(my_model, X, y, - cv=LeaveOneOut(), - scoring='neg_mean_squared_error') -(-my_scores.mean())**0.5 -#> 0.32300426518411957 # RMSE(検証) - -### 8.2.1 補足:行列計算による再現 - -import numpy as np -M = np.matrix(X.assign(b0=1)) -b = np.linalg.pinv(M) @ y -pd.Series(b, - index=list(X.columns) + ['b0']) -#> WRAIN 0.001167 -#> DEGREES 0.616392 -#> HRAIN -0.003861 -#> TIME_SV 0.023847 -#> b0 -12.145334 -#> dtype: float64 diff --git a/code/py/ch08/08.03.py b/code/py/ch08/08.03.py deleted file mode 100644 index 3b5e70c..0000000 --- a/code/py/ch08/08.03.py +++ /dev/null @@ -1,36 +0,0 @@ -## 8.3 標準化 - -import pandas as pd -from sklearn.linear_model import LinearRegression -from sklearn.pipeline import Pipeline -from sklearn.preprocessing import StandardScaler -my_url = ('https://raw.githubusercontent.com/taroyabuki' - '/fromzero/master/data/wine.csv') -my_data = pd.read_csv(my_url) -X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2'] - -# StandardScalerで標準化した結果をデータフレームに戻してから描画する. -pd.DataFrame(StandardScaler().fit_transform(X), columns=X.columns - ).boxplot(showmeans=True) - -my_pipeline = Pipeline([ - ('sc', StandardScaler()), - ('lr', LinearRegression())]) -my_pipeline.fit(X, y) - -# 線形回帰の部分だけを取り出す. -my_lr = my_pipeline.named_steps.lr -my_lr.intercept_ -#> -1.4517651851851847 - -pd.Series(my_lr.coef_, - index=X.columns) -#> WRAIN 0.147741 -#> DEGREES 0.398724 -#> HRAIN -0.276802 -#> TIME_SV 0.192979 -#> dtype: float64 - -my_test = [[500, 17, 120, 2]] -my_pipeline.predict(my_test) -#> array([-1.49884253]) diff --git a/code/py/ch08/08.04.py b/code/py/ch08/08.04.py deleted file mode 100644 index d8502ce..0000000 --- a/code/py/ch08/08.04.py +++ /dev/null @@ -1,34 +0,0 @@ -## 8.4 入力変数の数とモデルの良さ - -import pandas as pd -from sklearn.linear_model import LinearRegression -from sklearn.metrics import mean_squared_error -from sklearn.model_selection import cross_val_score, LeaveOneOut - -my_url = ('https://raw.githubusercontent.com/taroyabuki' - '/fromzero/master/data/wine.csv') -my_data = pd.read_csv(my_url) - -n = len(my_data) -my_data2 = my_data.assign(v1=[i % 2 for i in range(n)], - v2=[i % 3 for i in range(n)]) -my_data2.head() -#> LPRICE2 WRAIN DEGREES HRAIN TIME_SV v1 v2 -#> 0 -0.99868 600 17.1167 160 31 0 0 -#> 1 -0.45440 690 16.7333 80 30 1 1 -#> 2 -0.80796 502 17.1500 130 28 0 2 -#> 3 -1.50926 420 16.1333 110 26 1 0 -#> 4 -1.71655 582 16.4167 187 25 0 1 - -X, y = my_data2.drop(columns=['LPRICE2']), my_data2['LPRICE2'] -my_model2 = LinearRegression().fit(X, y) - -y_ = my_model2.predict(X) -mean_squared_error(y_, y)**0.5 -#> 0.2562120047505748 # RMSE(訓練) - -my_scores = cross_val_score(my_model2, X, y, - cv=LeaveOneOut(), - scoring='neg_mean_squared_error') -(-my_scores.mean())**0.5 -#> 0.3569918035928941 # RMSE(検証) diff --git a/code/py/ch08/08.05.py b/code/py/ch08/08.05.py deleted file mode 100644 index 66129df..0000000 --- a/code/py/ch08/08.05.py +++ /dev/null @@ -1,36 +0,0 @@ -## 8.5 変数選択 - -import pandas as pd -from sklearn.feature_selection import SequentialFeatureSelector -from sklearn.linear_model import LinearRegression -from sklearn.model_selection import GridSearchCV, LeaveOneOut -from sklearn.pipeline import Pipeline - -my_url = ('https://raw.githubusercontent.com/taroyabuki' - '/fromzero/master/data/wine.csv') -my_data = pd.read_csv(my_url) - -n = len(my_data) -my_data2 = my_data.assign(v1=[i % 2 for i in range(n)], - v2=[i % 3 for i in range(n)]) -X, y = my_data2.drop(columns=['LPRICE2']), my_data2['LPRICE2'] - -my_sfs = SequentialFeatureSelector( - estimator=LinearRegression(), - direction='forward', # 変数増加法 - cv=LeaveOneOut(), - scoring='neg_mean_squared_error') - -my_pipeline = Pipeline([ # 変数選択の後で再訓練を行うようにする. - ('sfs', my_sfs), # 変数選択 - ('lr', LinearRegression())]) # 回帰分析 - -my_params = {'sfs__n_features_to_select': range(1, 6)} # 選択する変数の上限 -my_search = GridSearchCV(estimator=my_pipeline, - param_grid=my_params, - cv=LeaveOneOut(), - scoring='neg_mean_squared_error', - n_jobs=-1).fit(X, y) -my_model = my_search.best_estimator_ # 最良のパラメータで再訓練したモデル -my_search.best_estimator_.named_steps.sfs.get_support() -#> array([ True, True, True, True, False, False]) diff --git a/code/py/ch08/08.06.py b/code/py/ch08/08.06.py deleted file mode 100644 index 3b835d5..0000000 --- a/code/py/ch08/08.06.py +++ /dev/null @@ -1,98 +0,0 @@ -## 8.6 補足:正則化 - -import numpy as np -import pandas as pd -import warnings -from sklearn.exceptions import ConvergenceWarning -from sklearn.linear_model import ElasticNet, enet_path -from sklearn.model_selection import GridSearchCV, LeaveOneOut -from sklearn.pipeline import Pipeline -from sklearn.preprocessing import StandardScaler -from scipy.stats import zscore -warnings.simplefilter('ignore', ConvergenceWarning) # これ以降,警告を表示しない. - -my_url = ('https://raw.githubusercontent.com/taroyabuki' - '/fromzero/master/data/wine.csv') -my_data = pd.read_csv(my_url) -X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2'] - -### 8.6.1 正則化の実践 - -A = 2 -B = 0.1 - -my_pipeline = Pipeline([ - ('sc', StandardScaler()), - ('enet', ElasticNet( - alpha=A, - l1_ratio=B))]) -my_pipeline.fit(X, y) - -my_enet = my_pipeline.named_steps.enet -my_enet.intercept_ -#> -1.4517651851851852 - -pd.Series(my_enet.coef_, - index=X.columns) -#> WRAIN 0.000000 -#> DEGREES 0.074101 -#> HRAIN -0.041159 -#> TIME_SV 0.024027 -#> dtype: float64 - -my_test = pd.DataFrame( - [[500, 17, 120, 2]]) -my_pipeline.predict(my_test) -#> array([-1.41981616]) - -### 8.6.2 ペナルティの強さと係数の関係 - -As = np.e**np.arange(2, -5.5, -0.1) -B = 0.1 - -_, my_path, _ = enet_path( - zscore(X), zscore(y), - alphas=As, - l1_ratio=B) - -pd.DataFrame( - my_path.T, - columns=X.columns, - index=np.log(As) -).plot( - xlabel='log A ( = log alpha)', - ylabel='Coefficients') - -### 8.6.3 パラメータの決定 - -As = np.linspace(0, 0.1, 21) -Bs = np.linspace(0, 0.1, 6) - -my_pipeline = Pipeline([('sc', StandardScaler()), - ('enet', ElasticNet())]) -my_search = GridSearchCV( - estimator=my_pipeline, - param_grid={'enet__alpha': As, 'enet__l1_ratio': Bs}, - cv=LeaveOneOut(), - scoring='neg_mean_squared_error', - n_jobs=-1).fit(X, y) -my_model = my_search.best_estimator_ # 最良モデル - -my_search.best_params_ # 最良パラメータ -#> {'enet__alpha': 0.075, 'enet__l1_ratio': 0.0} - -tmp = my_search.cv_results_ # チューニングの詳細 -my_scores = (-tmp['mean_test_score'])**0.5 # RMSE - -my_results = pd.DataFrame(tmp['params']).assign(RMSE=my_scores).pivot( - index='enet__alpha', - columns='enet__l1_ratio', - values='RMSE') - -my_results.plot(style='o-', xlabel='A ( = alpha)', ylabel='RMSE').legend( - title='B ( = l1_ratio)') - -(-my_search.best_score_)**0.5 -#> 0.31945619679509646 - -### 8.6.4 補足:RとPythonで結果を同じにする方法 diff --git a/code/py/ch08/08.07.py b/code/py/ch08/08.07.py deleted file mode 100644 index 8622c0f..0000000 --- a/code/py/ch08/08.07.py +++ /dev/null @@ -1,58 +0,0 @@ -## 8.7 ニューラルネットワーク - -### 8.7.1 ニューラルネットワークとは何か - -import matplotlib.pyplot as plt -import numpy as np -x = np.linspace(-6, 6, 100) -y = 1 / (1 + np.exp(-x)) -plt.plot(x, y) - -### 8.7.2 ニューラルネットワークの訓練 - -import pandas as pd -import warnings -from sklearn.exceptions import ConvergenceWarning -from sklearn.neural_network import MLPRegressor -from sklearn.model_selection import cross_val_score, GridSearchCV, LeaveOneOut -from sklearn.pipeline import Pipeline -from sklearn.preprocessing import StandardScaler - -my_url = ('https://raw.githubusercontent.com/taroyabuki' - '/fromzero/master/data/wine.csv') -my_data = pd.read_csv(my_url) -X, y = my_data.drop(columns=['LPRICE2']), my_data['LPRICE2'] - -warnings.simplefilter("ignore", ConvergenceWarning) # これ以降,警告を表示しない. -my_pipeline = Pipeline([('sc', StandardScaler()), # 標準化 - ('mlp', MLPRegressor())]) # ニューラルネットワーク -my_pipeline.fit(X, y) # 訓練 - -my_scores = cross_val_score(my_pipeline, X, y, cv=LeaveOneOut(), - scoring='neg_mean_squared_error') -warnings.simplefilter("default", ConvergenceWarning) # これ以降,警告を表示する. - -(-my_scores.mean())**0.5 -#> 0.41735891601426384 - -### 8.7.3 ニューラルネットワークのチューニング - -my_pipeline = Pipeline([ - ('sc', StandardScaler()), - ('mlp', MLPRegressor(tol=1e-5, # 改善したと見なす基準 - max_iter=5000))]) # 改善しなくなるまでの反復数 -my_layers = (1, 3, 5, # 隠れ層1層の場合 - (1, 1), (3, 1), (5, 1), (1, 2), (3, 2), (5, 2)) # 隠れ層2層の場合 -my_params = {'mlp__hidden_layer_sizes': my_layers} -my_search = GridSearchCV(estimator=my_pipeline, - param_grid=my_params, - cv=LeaveOneOut(), - scoring='neg_mean_squared_error', - n_jobs=-1).fit(X, y) -my_model = my_search.best_estimator_ # 最良モデル - -my_search.best_params_ # 最良パラメータ -#> {'mlp__hidden_layer_sizes': 5} - -(-my_search.best_score_)**0.5 -#> 0.3759690731968538 diff --git a/code/py/ch09/09.01.py b/code/py/ch09/09.01.py deleted file mode 100644 index aa70ba1..0000000 --- a/code/py/ch09/09.01.py +++ /dev/null @@ -1,17 +0,0 @@ -## 9.1 アヤメのデータ - -import statsmodels.api as sm -my_data = sm.datasets.get_rdataset('iris', 'datasets').data -my_data.head() -#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species -#> 0 5.1 3.5 1.4 0.2 setosa -#> 1 4.9 3.0 1.4 0.2 setosa -#> 2 4.7 3.2 1.3 0.2 setosa -#> 3 4.6 3.1 1.5 0.2 setosa -#> 4 5.0 3.6 1.4 0.2 setosa - -my_data.describe() -#> Sepal.Length Sepal.Width Petal.Length Petal.Width -#> count 150.000000 150.000000 150.000000 150.000000 -#> mean 5.843333 3.057333 3.758000 1.199333 -# 以下省略 diff --git a/code/py/ch09/09.02.py b/code/py/ch09/09.02.py deleted file mode 100644 index b7353f8..0000000 --- a/code/py/ch09/09.02.py +++ /dev/null @@ -1,34 +0,0 @@ -## 9.2 木による分類 - -### 9.2.1 分類木の作成と利用 - -import graphviz -import pandas as pd -import statsmodels.api as sm -from sklearn import tree - -my_data = sm.datasets.get_rdataset('iris', 'datasets').data -X, y = my_data.iloc[:, 0:4], my_data.Species - -my_model = tree.DecisionTreeClassifier(max_depth=2, random_state=0) -my_model.fit(X, y) - -my_dot = tree.export_graphviz( - decision_tree=my_model, - out_file=None, # ファイルに出力しない. - feature_names=X.columns, # 変数名 - class_names=my_model.classes_, # カテゴリ名 - filled=True) # 色を塗る. -graphviz.Source(my_dot) - -my_test = pd.DataFrame([[5.0, 3.5, 1.5, 0.5], - [6.5, 3.0, 5.0, 2.0]]) -my_model.predict(my_test) -#> array(['setosa', 'virginica'], dtype=object) - -pd.DataFrame( - my_model.predict_proba(my_test), - columns=my_model.classes_) -#> setosa versicolor virginica -#> 0 1.0 0.000000 0.000000 -#> 1 0.0 0.021739 0.978261 diff --git a/code/py/ch09/09.03.py b/code/py/ch09/09.03.py deleted file mode 100644 index e666207..0000000 --- a/code/py/ch09/09.03.py +++ /dev/null @@ -1,82 +0,0 @@ -## 9.3 正解率 - -### 9.3.1 混同行列 - -import graphviz -import pandas as pd -import statsmodels.api as sm -from sklearn import tree -from sklearn.metrics import confusion_matrix -from sklearn.model_selection import cross_val_score, GridSearchCV, LeaveOneOut - -my_data = sm.datasets.get_rdataset('iris', 'datasets').data -X, y = my_data.iloc[:, 0:4], my_data.Species - -my_model = tree.DecisionTreeClassifier(max_depth=2, random_state=0).fit(X, y) -y_ = my_model.predict(X) -confusion_matrix(y_true=y, y_pred=y_) -#> array([[50, 0, 0], -#> [ 0, 49, 1], -#> [ 0, 5, 45]]) - -### 9.3.2 正解率(訓練) - -my_model.score(X, y) -# あるいは -y_ = my_model.predict(X) -(y_ == y).mean() - -#> 0.96 - -### 9.3.3 正解率(検証) - -cross_val_score(my_model, X, y, cv=LeaveOneOut()).mean() -#> 0.9533333333333334 - -### 9.3.4 パラメータチューニング - -my_search = GridSearchCV(estimator=tree.DecisionTreeClassifier(random_state=0), - param_grid={'max_depth': range(1, 11)}, - cv=LeaveOneOut(), - n_jobs=-1).fit(X, y) -my_search.best_params_, my_search.best_score_ -#> ({'max_depth': 2}, 0.9533333333333334) - -### 9.3.5 補足:木の複雑さの制限 - -my_params = { - 'max_depth': range(2, 6), - 'min_samples_split': [2, 20], - 'min_samples_leaf': range(1, 8)} - -my_search = GridSearchCV( - estimator=tree.DecisionTreeClassifier(min_impurity_decrease=0.01, - random_state=0), - param_grid=my_params, - cv=LeaveOneOut(), - n_jobs=-1).fit(X, y) -my_search.best_params_, my_search.best_score_ -#> ({'max_depth': 3, 'min_samples_leaf': 5, 'min_samples_split': 2}, -#> 0.9733333333333334) - -tmp = my_search.cv_results_ -my_results = pd.DataFrame(tmp['params']).assign( - Accuracy=tmp['mean_test_score']) -# 正解率(検証)の最大値 -my_results[my_results.Accuracy == my_results.Accuracy.max()] -#> max_depth min_samples_leaf min_samples_split Accuracy -#> 22 3 5 2 0.973333 -#> 23 3 5 20 0.973333 -#> 36 4 5 2 0.973333 -#> 37 4 5 20 0.973333 -#> 50 5 5 2 0.973333 -#> 51 5 5 20 0.973333 - -my_model = my_search.best_estimator_ -my_dot = tree.export_graphviz( - decision_tree=my_model, - out_file=None, - feature_names=X.columns, - class_names=my_model.classes_, - filled=True) -graphviz.Source(my_dot) diff --git a/code/py/ch09/09.04.py b/code/py/ch09/09.04.py deleted file mode 100644 index 5715309..0000000 --- a/code/py/ch09/09.04.py +++ /dev/null @@ -1,59 +0,0 @@ -## 9.4 複数の木を使う方法 - -### 9.4.1 ランダムフォレスト - -import pandas as pd -import statsmodels.api as sm -import warnings -import xgboost -from sklearn.ensemble import RandomForestClassifier -from sklearn.model_selection import GridSearchCV, LeaveOneOut -from sklearn.preprocessing import LabelEncoder - -my_data = sm.datasets.get_rdataset('iris', 'datasets').data -X, y = my_data.iloc[:, 0:4], my_data.Species -label_encoder = LabelEncoder(); y = label_encoder.fit_transform(y) - -my_search = GridSearchCV(RandomForestClassifier(), - param_grid={'max_features': [2, 3, 4]}, - cv=LeaveOneOut(), - n_jobs=-1).fit(X, y) -my_search.best_params_ -#> {'max_features': 2} - -my_search.cv_results_['mean_test_score'] -#> array([0.96 , 0.96 , 0.95333333]) - -### 9.4.2 ブースティング - -warnings.simplefilter('ignore') # これ以降,警告を表示しない. -my_search = GridSearchCV( - xgboost.XGBClassifier(eval_metric='mlogloss'), - param_grid={'n_estimators' : [50, 100, 150], - 'max_depth' : [1, 2, 3], - 'learning_rate' : [0.3, 0.4], - 'gamma' : [0], - 'colsample_bytree': [0.6, 0.8], - 'min_child_weight': [1], - 'subsample' : [0.5, 0.75, 1]}, - cv=5, # 5分割交差検証 - n_jobs=1).fit(X, y) # n_jobs=-1ではない. -warnings.simplefilter('default') # これ以降,警告を表示する. - -my_search.best_params_ -#> {'colsample_bytree': 0.6, -#> 'gamma': 0, -#> 'learning_rate': 0.3, -#> 'max_depth': 1, -#> 'min_child_weight': 1, -#> 'n_estimators': 50, -#> 'subsample': 0.75} - -my_search.best_score_ -#> 0.9666666666666668 - -### 9.4.3 入力変数の重要度 - -my_model = RandomForestClassifier().fit(X, y) -tmp = pd.Series(my_model.feature_importances_, index=X.columns) -tmp.sort_values().plot(kind='barh') diff --git a/code/py/ch09/09.05.py b/code/py/ch09/09.05.py deleted file mode 100644 index bab0168..0000000 --- a/code/py/ch09/09.05.py +++ /dev/null @@ -1,51 +0,0 @@ -## 9.5 欠損のあるデータでの学習 - -### 9.5.1 欠損のあるデータの準備 - -import numpy as np -import statsmodels.api as sm -import warnings -import xgboost -from sklearn import tree -from sklearn.impute import SimpleImputer -from sklearn.model_selection import cross_val_score, LeaveOneOut -from sklearn.pipeline import Pipeline - -my_data = sm.datasets.get_rdataset('iris', 'datasets').data - -n = len(my_data) -my_data['Petal.Length'] = [np.nan if i % 10 == 0 else - my_data['Petal.Length'][i] for i in range(n)] -my_data['Petal.Width'] = [np.nan if i % 10 == 1 else - my_data['Petal.Width'][i] for i in range(n)] - -my_data.describe() # countの値が135の変数に,150-135=15個の欠損がある. -#> Sepal.Length Sepal.Width Petal.Length Petal.Width -#> count 150.000000 150.000000 135.000000 135.000000 -#> mean 5.843333 3.057333 3.751852 1.197037 -# 以下省略 - -X, y = my_data.iloc[:, 0:4], my_data.Species - -### 9.5.2 方針1:欠損を埋めて学習する. - -my_pipeline = Pipeline([ - ('imputer', SimpleImputer(strategy='median')), # 欠損を中央値で埋める. - ('tree', tree.DecisionTreeClassifier(random_state=0))]) -my_scores = cross_val_score(my_pipeline, X, y, cv=LeaveOneOut(), n_jobs=-1) -my_scores.mean() -#> 0.9333333333333333 - -### 9.5.3 方針2:欠損があっても使える手法で学習する. - -from sklearn.preprocessing import LabelEncoder -label_encoder = LabelEncoder() -y = label_encoder.fit_transform(y) - -warnings.simplefilter('ignore') # これ以降,警告を表示しない. -my_scores = cross_val_score( - xgboost.XGBClassifier(eval_metric='mlogloss'), X, y, cv=5) -warnings.simplefilter('default') # これ以降,警告を表示する. - -my_scores.mean() -#> 0.9666666666666668 diff --git a/code/py/ch09/09.06.py b/code/py/ch09/09.06.py deleted file mode 100644 index cd814b3..0000000 --- a/code/py/ch09/09.06.py +++ /dev/null @@ -1,31 +0,0 @@ -## 9.6 他の分類手法 - -### 9.6.1 K最近傍法 - -import statsmodels.api as sm -from sklearn.model_selection import cross_val_score, LeaveOneOut -from sklearn.neighbors import KNeighborsClassifier - -my_data = sm.datasets.get_rdataset('iris', 'datasets').data -X, y = my_data.iloc[:, 0:4], my_data.Species - -my_scores = cross_val_score(KNeighborsClassifier(), X, y, cv=LeaveOneOut()) -my_scores.mean() -#> 0.9666666666666667 - -### 9.6.2 ニューラルネットワーク - -import statsmodels.api as sm -from sklearn.model_selection import cross_val_score, LeaveOneOut -from sklearn.neural_network import MLPClassifier -from sklearn.pipeline import Pipeline -from sklearn.preprocessing import StandardScaler - -my_data = sm.datasets.get_rdataset('iris', 'datasets').data -X, y = my_data.iloc[:, 0:4], my_data.Species - -my_pipeline = Pipeline([('sc', StandardScaler()), # 標準化 - ('mlp', MLPClassifier(max_iter=1000))]) # ニューラルネットワーク -my_scores = cross_val_score(my_pipeline, X, y, cv=LeaveOneOut(), n_jobs=-1) -my_scores.mean() -#> 0.9533333333333334 diff --git a/code/py/ch10/10.01.py b/code/py/ch10/10.01.py deleted file mode 100644 index ddce05e..0000000 --- a/code/py/ch10/10.01.py +++ /dev/null @@ -1,27 +0,0 @@ -## 10.1 2値分類の性能指標 - -### 10.1.1 陽性と陰性 - -import numpy as np -from sklearn.metrics import classification_report, confusion_matrix - -y = np.array([ 0, 1, 1, 0, 1, 0, 1, 0, 0, 1]) -y_score = np.array([0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5]) - -y_ = np.array([1 if 0.5 <= p else 0 for p in y_score]) -y_ -#> array([1, 1, 0, 0, 1, 1, 1, 0, 0, 1]) - -confusion_matrix(y_true=y, y_pred=y_) -#> array([[3, 2], -#> [1, 4]]) - -print(classification_report(y_true=y, y_pred=y_)) -#> precision recall f1-score support -#> -#> 0 0.75 0.60 0.67 5 -#> 1 0.67 0.80 0.73 5 -#> -#> accuracy 0.70 10 -#> macro avg 0.71 0.70 0.70 10 -#> weighted avg 0.71 0.70 0.70 10 diff --git a/code/py/ch10/10.02.py b/code/py/ch10/10.02.py deleted file mode 100644 index 75ee8a9..0000000 --- a/code/py/ch10/10.02.py +++ /dev/null @@ -1,37 +0,0 @@ -## 10.2 トレードオフ - -### 10.2.1 偽陽性率と真陽性率のトレードオフ(ROC曲線) - -import numpy as np -from sklearn.metrics import (roc_curve, RocCurveDisplay, - precision_recall_curve, PrecisionRecallDisplay, auc) - -y = np.array([ 0, 1, 1, 0, 1, 0, 1, 0, 0, 1]) -y_score = np.array([0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5]) -y_ = np.array([1 if 0.5 <= p else 0 for p in y_score]) - -[sum((y == 0) & (y_ == 1)) / sum(y == 0), # FPR - sum((y == 1) & (y_ == 1)) / sum(y == 1)] # TPR -#> [0.4, 0.8] - -my_fpr, my_tpr, _ = roc_curve(y_true=y, - y_score=y_score, - pos_label=1) # 1が陽性である. -RocCurveDisplay(fpr=my_fpr, tpr=my_tpr).plot() - -auc(x=my_fpr, y=my_tpr) -#> 0.8 - -### 10.2.2 再現率と精度のトレードオフ(PR曲線) - -[sum((y == 1) & (y_ == 1)) / sum(y == 1), # Recall == TPR - sum((y == 1) & (y_ == 1)) / sum(y_ == 1)] # Precision -#> [0.8, 0.6666666666666666] - -my_precision, my_recall, _ = precision_recall_curve(y_true=y, - probas_pred=y_score, - pos_label=1) -PrecisionRecallDisplay(precision=my_precision, recall=my_recall).plot() - -auc(x=my_recall, y=my_precision) -#> 0.8463095238095237 diff --git a/code/py/ch10/10.03.py b/code/py/ch10/10.03.py deleted file mode 100644 index 51b0f35..0000000 --- a/code/py/ch10/10.03.py +++ /dev/null @@ -1,72 +0,0 @@ -## 10.3 タイタニック - -import graphviz -import pandas as pd -from sklearn import tree -from sklearn.metrics import roc_curve, RocCurveDisplay, auc -from sklearn.model_selection import cross_val_score, LeaveOneOut -from sklearn.pipeline import Pipeline -from sklearn.preprocessing import OneHotEncoder - -my_url = ('https://raw.githubusercontent.com/taroyabuki' - '/fromzero/master/data/titanic.csv') -my_data = pd.read_csv(my_url) - -my_data.head() -#> Class Sex Age Survived -#> 0 1st Male Child Yes -#> 1 1st Male Child Yes -#> 2 1st Male Child Yes -#> 3 1st Male Child Yes -#> 4 1st Male Child Yes - -### 10.3.1 質的入力変数の扱い方 - -### 10.3.2 決定木の訓練 - -X, y = my_data.iloc[:, 0:3], my_data.Survived - -my_pipeline = Pipeline([ - ('ohe', OneHotEncoder(drop='first')), - ('tree', tree.DecisionTreeClassifier(max_depth=2, random_state=0, - min_impurity_decrease=0.01))]) -my_pipeline.fit(X, y) - -### 10.3.3 決定木の描画 - -my_enc = my_pipeline.named_steps['ohe'] # パイプラインからエンコーダを取り出す. -my_tree = my_pipeline.named_steps['tree'] # パイプラインから木を取り出す. - -my_dot = tree.export_graphviz( - decision_tree=my_tree, - out_file=None, - feature_names=my_enc.get_feature_names() \ - if hasattr(my_enc, 'get_feature_names') else my_enc.get_feature_names_out(), - class_names=my_pipeline.classes_, - filled=True) -graphviz.Source(my_dot) - -### 10.3.4 決定木の評価 - -my_scores = cross_val_score( - my_pipeline, X, y, - cv=LeaveOneOut(), - n_jobs=-1) -my_scores.mean() -#> 0.7832803271240345 - -tmp = pd.DataFrame( - my_pipeline.predict_proba(X), - columns=my_pipeline.classes_) -y_score = tmp.Yes - -my_fpr, my_tpr, _ = roc_curve(y_true=y, - y_score=y_score, - pos_label='Yes') -my_auc = auc(x=my_fpr, y=my_tpr) -my_auc -#> 0.7114886868858494 - -RocCurveDisplay(fpr=my_fpr, tpr=my_tpr, roc_auc=my_auc).plot() - -### 10.3.5 補足:質的入力変数の扱い diff --git a/code/py/ch10/10.04.py b/code/py/ch10/10.04.py deleted file mode 100644 index aee727a..0000000 --- a/code/py/ch10/10.04.py +++ /dev/null @@ -1,49 +0,0 @@ -## 10.4 ロジスティック回帰 - -import matplotlib.pyplot as plt -import numpy as np - -x = np.arange(-6, 6, 0.1) -y = 1 / (1 + np.exp(-x)) -plt.plot(x, y) - -import pandas as pd -from sklearn.linear_model import LogisticRegression -from sklearn.model_selection import cross_val_score, LeaveOneOut -from sklearn.pipeline import Pipeline -from sklearn.preprocessing import OneHotEncoder - -my_url = ('https://raw.githubusercontent.com/taroyabuki' - '/fromzero/master/data/titanic.csv') -my_data = pd.read_csv(my_url) - -X, y = my_data.iloc[:, 0:3], my_data.Survived - -my_pipeline = Pipeline([('ohe', OneHotEncoder(drop='first')), - ('lr', LogisticRegression(penalty='none'))]) -my_pipeline.fit(X, y) - -my_ohe = my_pipeline.named_steps.ohe -my_lr = my_pipeline.named_steps.lr - -my_lr.intercept_[0] -#> 2.043878162056783 - -tmp = my_ohe.get_feature_names() \ -if hasattr(my_ohe, 'get_feature_names') \ -else my_ohe.get_feature_names_out() -pd.Series(my_lr.coef_[0], - index=tmp) -#> x0_2nd -1.018069 -#> x0_3rd -1.777746 -#> x0_Crew -0.857708 -#> x1_Male -2.420090 -#> x2_Child 1.061531 -#> dtype: float64 - -my_scores = cross_val_score( - my_pipeline, X, y, - cv=LeaveOneOut(), - n_jobs=-1) -my_scores.mean() -#> 0.7782825988187188 diff --git a/code/py/ch11/11.01.py b/code/py/ch11/11.01.py deleted file mode 100644 index 6a69986..0000000 --- a/code/py/ch11/11.01.py +++ /dev/null @@ -1,70 +0,0 @@ -## 11.1 Kerasによる回帰 - -import matplotlib.pyplot as plt -import numpy as np -import pandas as pd -from keras import activations, callbacks, layers, models -from sklearn.preprocessing import StandardScaler -from sklearn.utils import shuffle - -my_url = ('https://raw.githubusercontent.com/taroyabuki' - '/fromzero/master/data/wine.csv') -tmp = pd.read_csv(my_url) - -my_data = shuffle(tmp) - -my_scaler = StandardScaler() -X = my_scaler.fit_transform( - my_data.drop(columns=['LPRICE2'])) -y = my_data['LPRICE2'] - -x = np.linspace(-3, 3, 100) -plt.plot(x, activations.relu(x)) -plt.xlabel('x') -plt.ylabel('ReLU(x)') - -my_model = models.Sequential() -my_model.add(layers.Dense(units=3, activation='relu', input_shape=[4])) -my_model.add(layers.Dense(units=1)) - -my_model.summary() # ネットワークの概要 -#> Model: "sequential" -#> _________________________________________________________________ -#> Layer (type) Output Shape Param # -#> ================================================================= -#> dense (Dense) (None, 3) 15 -#> _________________________________________________________________ -#> dense_1 (Dense) (None, 1) 4 -#> ================================================================= -#> Total params: 19 -#> Trainable params: 19 -#> Non-trainable params: 0 - -my_model.compile( - loss='mse', - optimizer='rmsprop') - -my_cb = callbacks.EarlyStopping( - patience=20, - restore_best_weights=True) - -my_history = my_model.fit( - x=X, - y=y, - validation_split=0.25, - batch_size=10, - epochs=500, - callbacks=[my_cb], - verbose=0) - -tmp = pd.DataFrame(my_history.history) -tmp.plot(xlabel='epoch') - -tmp.iloc[-1, ] -#> loss 0.192743 -#> val_loss 0.342249 -#> Name: 499, dtype: float64 - -y_ = my_model.predict(X) -((y_.ravel() - y)**2).mean() -#> 0.23050613964540986 diff --git a/code/py/ch11/11.02.py b/code/py/ch11/11.02.py deleted file mode 100644 index 8124cf3..0000000 --- a/code/py/ch11/11.02.py +++ /dev/null @@ -1,75 +0,0 @@ -## 11.2 Kerasによる分類 - -import numpy as np -import pandas as pd -import statsmodels.api as sm -from keras import callbacks, layers, losses, models -from sklearn.preprocessing import StandardScaler, LabelEncoder -from sklearn.utils import shuffle - -tmp = sm.datasets.get_rdataset('iris', 'datasets').data -my_data = shuffle(tmp) - -my_scaler = StandardScaler() -X = my_scaler.fit_transform( - my_data.drop(columns=['Species'])) -my_enc = LabelEncoder() -y = my_enc.fit_transform( - my_data['Species']) - -my_model = models.Sequential() -my_model.add(layers.Dense(units=3, activation='relu', input_shape=[4])) -my_model.add(layers.Dense(units=3, activation='softmax')) - -my_model.compile(loss='sparse_categorical_crossentropy', - optimizer='rmsprop', - metrics=['accuracy']) - -my_cb = callbacks.EarlyStopping( - patience=20, - restore_best_weights=True) - -my_history = my_model.fit( - x=X, - y=y, - validation_split=0.25, - batch_size=10, - epochs=500, - callbacks=[my_cb], - verbose=0) - -tmp = pd.DataFrame(my_history.history) -tmp.plot(xlabel='epoch') - -tmp.iloc[-1, ] -#> loss 0.067497 -#> accuracy 0.973214 -#> val_loss 0.143529 -#> val_accuracy 0.921053 - -tmp = my_model.predict(X) -y_ = np.argmax(tmp, axis=-1) -(y_ == y).mean() -#> 0.96 - -### 11.2.1 交差エントロピー - --np.log([0.8, 0.7, 0.3, 0.8]).mean() -#> 0.5017337127232719 - --np.log([0.7, 0.6, 0.2, 0.7]).mean() -#> 0.708403356019389 - -y = [2, 1, 0, 1] -y_1 = [[0.1, 0.1, 0.8], - [0.1, 0.7, 0.2], - [0.3, 0.4, 0.3], - [0.1, 0.8, 0.1]] -y_2 = [[0.1, 0.2, 0.7], - [0.2, 0.6, 0.2], - [0.2, 0.5, 0.3], - [0.2, 0.7, 0.1]] - -[losses.sparse_categorical_crossentropy(y_true=y, y_pred=y_1).numpy().mean(), - losses.sparse_categorical_crossentropy(y_true=y, y_pred=y_2).numpy().mean()] -#> [0.5017337, 0.70840335] diff --git a/code/py/ch11/11.03.py b/code/py/ch11/11.03.py deleted file mode 100644 index 974ab19..0000000 --- a/code/py/ch11/11.03.py +++ /dev/null @@ -1,225 +0,0 @@ -## 11.3 MNIST:手書き数字の分類 - -### 11.3.1 データの形式 - -import matplotlib.pyplot as plt -import numpy as np -import pandas as pd -import tensorflow as tf -from random import sample -from keras import callbacks, layers, models -from sklearn.metrics import confusion_matrix - -(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data() - -x_train.shape -#> (60000, 28, 28) - -np.set_printoptions(linewidth=170) -x_train[4, :, :] - -plt.matshow(x_train[4, :, :]) - -y_train -#> array([5, 0, 4, ..., 5, 6, 8], -#> dtype=uint8) - -x_train.min(), x_train.max() -#> (0, 255) - -x_train = x_train / 255 -x_test = x_test / 255 - -my_index = sample(range(60000), 6000) -x_train = x_train[my_index, :, :] -y_train = y_train[my_index] - -### 11.3.2 多層パーセプトロン - -my_model = models.Sequential() -my_model.add(layers.Flatten(input_shape=[28, 28])) -my_model.add(layers.Dense(units=256, activation="relu")) -my_model.add(layers.Dense(units=10, activation="softmax")) - -my_model.summary() -#> Model: "sequential" -#> _________________________________________________________________ -#> Layer (type) Output Shape Param # -#> ================================================================= -#> flatten (Flatten) (None, 784) 0 -#> _________________________________________________________________ -#> dense (Dense) (None, 256) 200960 -#> _________________________________________________________________ -#> dense_1 (Dense) (None, 10) 2570 -#> ================================================================= -#> Total params: 203,530 -#> Trainable params: 203,530 -#> Non-trainable params: 0 -#> _________________________________________________________________ - -my_model.compile(loss='sparse_categorical_crossentropy', - optimizer='rmsprop', - metrics=['accuracy']) - -my_cb = callbacks.EarlyStopping(patience=5, restore_best_weights=True) - -my_history = my_model.fit( - x=x_train, - y=y_train, - validation_split=0.2, - batch_size=128, - epochs=20, - callbacks=[my_cb], - verbose=0) - -tmp = pd.DataFrame(my_history.history) -tmp.plot(xlabel='epoch', style='o-') - -tmp = my_model.predict(x_test) -y_ = np.argmax(tmp, axis=-1) -confusion_matrix(y_true=y_test, - y_pred=y_) - -#> [[ 962 0 2 1 1 2 7 1 2 2] -#> [ 0 1123 4 0 0 1 3 0 4 0] -#> [ 11 4 954 11 6 2 7 9 26 2] -#> [ 3 0 20 930 2 12 2 11 21 9] -#> [ 1 1 7 0 927 1 11 1 5 28] -#> [ 10 1 3 16 4 812 11 7 24 4] -#> [ 9 3 4 0 9 10 919 0 4 0] -#> [ 3 6 17 4 11 0 0 965 2 20] -#> [ 8 4 6 12 6 9 9 7 901 12] -#> [ 9 8 0 8 31 4 1 14 7 927]] - -(y_ == y_test).mean() -#> 0.942 - -my_model.evaluate(x=x_test, y=y_test) -#> [0.20125965774059296, -#> 0.9419999718666077] - -### 11.3.3 畳み込みニューラルネットワーク(CNN) - -x_train2d = x_train.reshape(-1, 28, 28, 1) -x_test2d = x_test.reshape(-1, 28, 28, 1) - -#### 11.3.3.1 単純なCNN - -my_model = models.Sequential() -my_model.add(layers.Conv2D(filters=32, kernel_size=3, # 畳み込み層 - activation='relu', - input_shape=[28, 28, 1])) -my_model.add(layers.MaxPooling2D(pool_size=2)) # プーリング層 -my_model.add(layers.Flatten()) -my_model.add(layers.Dense(128, activation='relu')) -my_model.add(layers.Dense(10, activation='softmax')) - -my_model.summary() -#> Model: "sequential" -#> _________________________________________________________________ -#> Layer (type) Output Shape Param # -#> ================================================================= -#> conv2d (Conv2D) (None, 26, 26, 32) 320 -#> _________________________________________________________________ -#> max_pooling2d (MaxPooling2D) (None, 13, 13, 32) 0 -#> _________________________________________________________________ -#> flatten (Flatten) (None, 5408) 0 -#> _________________________________________________________________ -#> dense (Dense) (None, 128) 692352 -#> _________________________________________________________________ -#> dense_1 (Dense) (None, 10) 1290 -#> ================================================================= -#> Total params: 693,962 -#> Trainable params: 693,962 -#> Non-trainable params: 0 -#> _________________________________________________________________ - -my_model.compile(loss='sparse_categorical_crossentropy', - optimizer='rmsprop', - metrics=['accuracy']) - -from keras.callbacks import EarlyStopping -my_cb = EarlyStopping(patience=5, - restore_best_weights=True) - -my_history = my_model.fit( - x=x_train2d, - y=y_train, - validation_split=0.2, - batch_size=128, - epochs=20, - callbacks=my_cb, - verbose=0) - -tmp = pd.DataFrame(my_history.history) -tmp.plot(xlabel='epoch', style='o-') - -my_model.evaluate(x=x_test2d, y=y_test) -#> [0.1359061449766159, -#> 0.9581000208854675] - -#### 11.3.3.2 LeNet - -my_model = models.Sequential() -my_model.add(layers.Conv2D(filters=20, kernel_size=5, activation='relu', - input_shape=(28, 28, 1))) -my_model.add(layers.MaxPooling2D(pool_size=2, strides=2)) -my_model.add(layers.Conv2D(filters=20, kernel_size=5, activation='relu')) -my_model.add(layers.MaxPooling2D(pool_size=2, strides=2)) -my_model.add(layers.Dropout(rate=0.25)) -my_model.add(layers.Flatten()) -my_model.add(layers.Dense(500, activation='relu')) -my_model.add(layers.Dropout(rate=0.5)) -my_model.add(layers.Dense(10, activation='softmax')) - -my_model.compile(loss='sparse_categorical_crossentropy', - optimizer='rmsprop', - metrics=['accuracy']) - -my_cb = callbacks.EarlyStopping(patience=5, - restore_best_weights=True) - -my_history = my_model.fit( - x=x_train2d, - y=y_train, - validation_split=0.2, - batch_size=128, - epochs=20, - callbacks=my_cb, - verbose=0) - -tmp = pd.DataFrame(my_history.history) -tmp.plot(xlabel='epoch', style='o-') - -my_model.evaluate(x=x_test2d, y=y_test) -#> [0.06491111218929291, -#> 0.9797000288963318] - -#### 11.3.3.3 補足:LeNetが自信満々で間違う例 - -y_prob = my_model.predict(x_test2d) # カテゴリに属する確率 - -tmp = pd.DataFrame({ - 'y_prob': np.max(y_prob, axis=1), # 確率の最大値 - 'y_': np.argmax(y_prob, axis=1), # 予測カテゴリ - 'y': y_test, # 正解 - 'id': range(len(y_test))}) # 番号 - -tmp = tmp[tmp.y_ != tmp.y] # 予測がはずれたものを残す -my_result = tmp.sort_values('y_prob', ascending=False) # 確率の大きい順に並び替える - -my_result.head() -#> y_prob y_ y id -#> 2654 0.999997 1 6 2654 -#> 1232 0.999988 4 9 1232 -#> 3520 0.999926 4 6 3520 -#> 9729 0.999881 6 5 9729 -#> 2896 0.999765 0 8 2896 - -for i in range(5): - plt.subplot(1, 5, i + 1) - ans = my_result['y'].iloc[i] - id = my_result['id'].iloc[i] - plt.title(f'{ans} ({id})') - plt.imshow(x_test[id]) - plt.axis('off') diff --git a/code/py/ch11/11.04.py b/code/py/ch11/11.04.py deleted file mode 100644 index 37023ff..0000000 --- a/code/py/ch11/11.04.py +++ /dev/null @@ -1,89 +0,0 @@ -## 11.4 AutoML - -### 11.4.1 H2Oの起動と停止 - -import h2o -import pandas as pd -import tensorflow as tf -from h2o.automl import H2OAutoML -from random import sample - -h2o.init() -h2o.no_progress() -# h2o.cluster().shutdown() # 停止 - -### 11.4.2 H2Oのデータフレーム - -my_url = ('https://raw.githubusercontent.com/taroyabuki' - '/fromzero/master/data/wine.csv') -my_data = pd.read_csv(my_url) -my_frame = h2o.H2OFrame(my_data) # 通常のデータフレームをH2OFrameに変換する. -# あるいは -my_frame = h2o.import_file(my_url, header=1) # データを読み込む. - -my_frame.head(5) -#> LPRICE2 WRAIN DEGREES ... -#> --------- ------- --------- ... -#> -0.99868 600 17.1167 ... -#> -0.4544 690 16.7333 ... -#> -0.80796 502 17.15 ... -#> -1.50926 420 16.1333 ... -#> -1.71655 582 16.4167 ... - -# 通常のデータフレームに戻す. -h2o.as_list(my_frame).head() -# 結果は割愛(見た目は同じ) - -### 11.4.3 AutoMLによる回帰 - -my_model = H2OAutoML( - max_runtime_secs=60) -my_model.train( - y='LPRICE2', - training_frame=my_frame) - -my_model.leaderboard['rmse'].min() -#> 0.2704643402377778 - -tmp = h2o.as_list( - my_model.predict(my_frame)) - -pd.DataFrame({ - 'y': my_data['LPRICE2'], - 'y_': tmp['predict']} -).plot('y', 'y_', kind='scatter') - -### 11.4.4 AutoMLによる分類 - -(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data() -my_index = sample(range(60000), 6000) -x_train = x_train[my_index, :, :] -y_train = y_train[my_index] - -tmp = pd.DataFrame( - x_train.reshape(-1, 28 * 28)) -y = 'y' -tmp[y] = y_train -my_train = h2o.H2OFrame(tmp) -my_train[y] = my_train[y].asfactor() - -tmp = pd.DataFrame( - x_test.reshape(-1, 28 * 28)) -my_test = h2o.H2OFrame(tmp) - -my_model = H2OAutoML( - max_runtime_secs=120) -my_model.train( - y=y, - training_frame=my_train) - -my_model.leaderboard[ - 'mean_per_class_error'].min() -#> 0.06803754348177862 - -tmp = h2o.as_list( - my_model.predict(my_test)) -y_ = tmp.predict - -(y_ == y_test).mean() -#> 0.938 diff --git a/code/py/ch12/12.01.py b/code/py/ch12/12.01.py deleted file mode 100644 index 07af238..0000000 --- a/code/py/ch12/12.01.py +++ /dev/null @@ -1,32 +0,0 @@ -## 12.1 日時と日時の列 - -### 12.1.1 日時 - -import pandas as pd -pd.to_datetime('2020-01-01') -#> Timestamp('2020-01-01 00:00:00') - -### 12.1.2 等間隔の日時 - -pd.date_range(start='2021-01-01', end='2023-01-01', freq='1A') -#> DatetimeIndex(['2021-12-31', '2022-12-31'], -#> dtype='datetime64[ns]', freq='A-DEC') - -pd.date_range(start='2021-01-01', end='2023-01-01', freq='1AS') -#> DatetimeIndex(['2021-01-01', '2022-01-01', '2023-01-01'], -#> dtype='datetime64[ns]', freq='AS-JAN') - -pd.date_range(start='2021-01-01', end='2021-03-01', freq='2M') -#> DatetimeIndex(['2021-01-31'], dtype='datetime64[ns]', freq='2M') - -pd.date_range(start='2021-01-01', end='2021-03-01', freq='2MS') -#> DatetimeIndex(['2021-01-01', '2021-03-01'], -#> dtype='datetime64[ns]', freq='2MS') - -pd.date_range(start='2021-01-01', end='2021-01-03', freq='1D') -#> DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03'], -#> dtype='datetime64[ns]', freq='D') - -pd.date_range(start='2021-01-01 00:00:00', end='2021-01-01 03:00:00', freq='2H') -#> DatetimeIndex(['2021-01-01 00:00:00', '2021-01-01 02:00:00'], -#> dtype='datetime64[ns]', freq='2H') diff --git a/code/py/ch12/12.02.py b/code/py/ch12/12.02.py deleted file mode 100644 index 212894a..0000000 --- a/code/py/ch12/12.02.py +++ /dev/null @@ -1,123 +0,0 @@ -## 12.2 時系列データの予測 - -### 12.2.1 データの準備 - -import matplotlib.pyplot as plt -import pandas as pd -from pmdarima.datasets import airpassengers -from sklearn.metrics import mean_squared_error - -my_data = airpassengers.load_airpassengers() - -n = len(my_data) # データ数(144) -k = 108 # 訓練データ数 - -my_ds = pd.date_range( - start='1949/01/01', - end='1960/12/01', - freq='MS') -my_df = pd.DataFrame({ - 'ds': my_ds, - 'x': range(n), - 'y': my_data}, - index=my_ds) -my_df.head() -#> ds x y -#> 1949-01-01 1949-01-01 0 112.0 -#> 1949-02-01 1949-02-01 1 118.0 -#> 1949-03-01 1949-03-01 2 132.0 -#> 1949-04-01 1949-04-01 3 129.0 -#> 1949-05-01 1949-05-01 4 121.0 - -my_train = my_df[ :k] -my_test = my_df[-(n - k): ] -y = my_test.y - -plt.plot(my_train.y, label='train') -plt.plot(my_test.y, label='test') -plt.legend() - -### 12.2.2 線形回帰分析による時系列予測 - -from sklearn.linear_model import LinearRegression - -my_lm_model = LinearRegression() -my_lm_model.fit(my_train[['x']], my_train.y) - -X = my_test[['x']] -y_ = my_lm_model.predict(X) -mean_squared_error(y, y_)**0.5 # RMSE(テスト) -#> 70.63707081783771 - -y_ = my_lm_model.predict(my_df[['x']]) -tmp = pd.DataFrame(y_, - index=my_df.index) -plt.plot(my_train.y, label='train') -plt.plot(my_test.y, label='test') -plt.plot(tmp, label='model') -plt.legend() - -### 12.2.3 SARIMAによる時系列予測 - -#### 12.2.3.1 モデルの構築 - -import pmdarima as pm -my_arima_model = pm.auto_arima(my_train.y, m=12, trace=True) -#> (省略) -#> Best model: ARIMA(1,1,0)(0,1,0)[12] -#> Total fit time: 0.838 seconds - -#### 12.2.3.2 予測 - -y_, my_ci = my_arima_model.predict(len(my_test), # 期間はテストデータと同じ. - alpha=0.05, # 有意水準(デフォルト) - return_conf_int=True) # 信頼区間を求める. -tmp = pd.DataFrame({'y': y_, - 'Lo': my_ci[:, 0], - 'Hi': my_ci[:, 1]}, - index=my_test.index) -tmp.head() -#> y Lo Hi -#> 1958-01-01 345.964471 327.088699 364.840243 -#> 1958-02-01 331.731920 308.036230 355.427610 -#> 1958-03-01 386.787992 358.515741 415.060244 -#> 1958-04-01 378.774472 346.695454 410.853490 -#> 1958-05-01 385.777732 350.270765 421.284700 - -mean_squared_error(y, y_)**0.5 -#> 22.132236727738697 - -plt.plot(my_train.y, label='train') -plt.plot(my_test.y, label='test') -plt.plot(tmp.y, label='model') -plt.fill_between(tmp.index, - tmp.Lo, - tmp.Hi, - alpha=0.25) # 不透明度 -plt.legend(loc='upper left') - -### 12.2.4 Prophetによる時系列予測 - -try: from fbprophet import Prophet -except ImportError: from prophet import Prophet -my_prophet_model = Prophet(seasonality_mode='multiplicative') -my_prophet_model.fit(my_train) - -tmp = my_prophet_model.predict(my_test) -tmp[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].head() -#> ds yhat yhat_lower yhat_upper -#> 0 1958-01-01 359.239305 350.910898 368.464588 -#> 1 1958-02-01 350.690546 341.748862 359.964881 -#> 2 1958-03-01 407.188556 398.483316 415.463759 -#> 3 1958-04-01 398.481739 389.244105 406.742333 -#> 4 1958-05-01 402.595604 393.721421 411.331761 - -y_ = tmp.yhat -mean_squared_error(y, y_)**0.5 -#> 33.795549086036466 - -# my_prophet_model.plot(tmp) # 予測結果のみでよい場合 - -fig = my_prophet_model.plot(tmp) -fig.axes[0].plot(my_train.ds, my_train.y) -fig.axes[0].plot(my_test.ds, my_test.y, color='red') diff --git a/code/py/ch13/13.01.py b/code/py/ch13/13.01.py deleted file mode 100644 index f5095fa..0000000 --- a/code/py/ch13/13.01.py +++ /dev/null @@ -1,83 +0,0 @@ -## 13.1 主成分分析 - -import numpy as np -import pandas as pd -from pca import pca -from scipy.stats import zscore - -my_data = pd.DataFrame( - {'language': [ 0, 20, 20, 25, 22, 17], - 'english': [ 0, 20, 40, 20, 24, 18], - 'math': [100, 20, 5, 30, 17, 25], - 'science': [ 0, 20, 5, 25, 16, 23], - 'society': [ 0, 20, 30, 0, 21, 17]}, - index= ['A', 'B', 'C', 'D', 'E', 'F']) -my_model = pca(n_components=5) -my_result = my_model.fit_transform(my_data) # 主成分分析の実行 - -my_result['PC'] # 主成分スコア -#> PC1 PC2 ... -#> A 74.907282 7.010808 ... -#> B -13.818842 -2.753459 ... -#> C -33.714034 18.417290 ... -#> D -1.730630 -17.876372 ... -#> E -17.837474 1.064998 ... -#> F -7.806303 -5.863266 ... - -my_model.biplot(legend=False) - -my_result['loadings'] -#> language english math science society -#> PC1 -0.207498 -0.304360 0.887261 -0.130198 -0.245204 -#> PC2 -0.279463 0.325052 0.097643 -0.702667 0.559435 -#> PC3 0.306117 0.615799 0.056345 -0.338446 -0.639815 -#> PC4 0.764943 -0.471697 -0.007655 -0.418045 0.132455 -#> PC5 -0.447214 -0.447214 -0.447214 -0.447214 -0.447214 - -my_result['explained_var'] -#> array([0.88848331, 0.97962854, 0.99858005, 1. , 1. ]) - -### 13.1.1 標準化+主成分分析 - -tmp = zscore(my_data, ddof=1) # 標準化 -my_result = my_model.fit_transform( - tmp) -my_result['PC'] # 主成分スコア -#> PC1 PC2 ... -#> 1.0 3.673722 0.568850 ... -#> 1.0 -0.652879 -0.246926 ... -#> 1.0 -1.568294 1.742598 ... -#> 1.0 -0.250504 -1.640039 ... -#> 1.0 -0.886186 0.110493 ... -#> 1.0 -0.315858 -0.534976 ... - -### 13.1.2 補足:行列計算による再現 - -tmp = my_data - my_data.mean() -Z = np.matrix(tmp) # 標準化しない場合 -#Z = np.matrix(tmp / my_data.std(ddof=1)) # √不偏分散で標準化する場合 -#Z = np.matrix(tmp / my_data.std(ddof=0)) # pca(normalize=True)に合わせる場合 - -n = len(my_data) -S = np.cov(Z, rowvar=0, ddof=0) # 分散共分散行列 -#S = Z.T @ Z / n # (同じ結果) -vals, vecs = np.linalg.eig(S) # 固有値と固有ベクトル -idx = np.argsort(-vals) # 固有値の大きい順の番号 -vals, vecs = vals[idx], vecs[:, idx] # 固有値の大きい順での並べ替え -Z @ vecs # 主成分スコア(結果は割愛) -vals.cumsum() / vals.sum() # 累積寄与率 -#> array([0.88848331, 0.97962854, 0.99858005, 1. , 1. ]) - -U, d, V = np.linalg.svd(Z, full_matrices=False) # 特異値分解 -W = np.diag(d) - -[np.isclose(Z, U @ W @ V).all(), # 確認1 - np.isclose(U.T @ U, np.identity(U.shape[1])).all(), # 確認2 - np.isclose(V @ V.T, np.identity(V.shape[0])).all()] # 確認3 -#> [True, True, True] - -U @ W # 主成分スコア(結果は割愛) - -e = d ** 2 / n # 分散共分散行列の固有値 -e.cumsum() / e.sum() # 累積寄与率 -#> array([0.88848331, 0.97962854, 0.99858005, 1. , 1. ]) diff --git a/code/py/ch13/13.02.py b/code/py/ch13/13.02.py deleted file mode 100644 index 0c17a87..0000000 --- a/code/py/ch13/13.02.py +++ /dev/null @@ -1,114 +0,0 @@ -## 13.2 クラスタ分析 - -### 13.2.1 階層的クラスタ分析 - -import pandas as pd -from scipy.cluster import hierarchy - -my_data = pd.DataFrame( - {'x': [ 0, -16, 10, 10], - 'y': [ 0, 0, 10, -15]}, - index=['A', 'B', 'C', 'D']) - -my_result = hierarchy.linkage( - my_data, - metric='euclidean', # 省略可 - method='complete') - -hierarchy.dendrogram(my_result, - labels=my_data.index) - -hierarchy.cut_tree(my_result, 3) -#> array([[0], [1], [0], [2]]) - -# 補足(見やすくする) -my_data.assign(cluster= - hierarchy.cut_tree(my_result, 3)) -#> x y cluster -#> A 0 0 0 -#> B -16 0 1 -#> C 10 10 0 -#> D 10 -15 2 - -### 13.2.2 階層的クラスタ分析とヒートマップ - -import pandas as pd -import seaborn as sns - -my_data = pd.DataFrame( - {'language': [ 0, 20, 20, 25, 22, 17], - 'english': [ 0, 20, 40, 20, 24, 18], - 'math': [100, 20, 5, 30, 17, 25], - 'science': [ 0, 20, 5, 25, 16, 23], - 'society': [ 0, 20, 30, 0, 21, 17]}, - index= ['A', 'B', 'C', 'D', 'E', 'F']) - -sns.clustermap(my_data, z_score=1) # 列ごとの標準化 - -### 13.2.3 非階層的クラスタ分析 - -import pandas as pd -from sklearn.cluster import KMeans - -my_data = pd.DataFrame( - {'x': [ 0, -16, 10, 10], - 'y': [ 0, 0, 10, -15]}, - index=['A', 'B', 'C', 'D']) - -my_result = KMeans( - n_clusters=3).fit(my_data) - -my_result.labels_ -#> array([1, 0, 1, 2], dtype=int32) - -# 補足(見やすくする) -my_data.assign( - cluster=my_result.labels_) -#> x y cluster -#> A 0 0 1 -#> B -16 0 0 -#> C 10 10 1 -#> D 10 -15 2 - -### 13.2.4 クラスタ数の決定 - -import pandas as pd -import statsmodels.api as sm -from sklearn.cluster import KMeans - -iris = sm.datasets.get_rdataset('iris', 'datasets').data -my_data = iris.iloc[:, 0:4] - -k = range(1, 11) -my_df = pd.DataFrame({ - 'k': k, - 'inertia': [KMeans(k).fit(my_data).inertia_ for k in range(1, 11)]}) -my_df.plot(x='k', style='o-', legend=False) - -### 13.2.5 主成分分析とクラスタ分析 - -import seaborn as sns -import statsmodels.api as sm -from pca import pca -from scipy.cluster import hierarchy -from scipy.stats import zscore -from sklearn.cluster import KMeans - -iris = sm.datasets.get_rdataset('iris', 'datasets').data -my_data = zscore(iris.iloc[:, 0:4]) - -my_model = pca() # 主成分分析 -my_result = my_model.fit_transform(my_data)['PC'] -my_result['Species'] = list(iris.Species) - -# 非階層的クラスタ分析の場合 -my_result['cluster'] = KMeans(n_clusters=3).fit(my_data).labels_ - -# 階層的クラスタ分析の場合 -#my_result['cluster'] = hierarchy.cut_tree( -# hierarchy.linkage(my_data, method='complete'), 3)[:,0] - -sns.scatterplot(x='PC1', y='PC2', data=my_result, legend=False, - hue='cluster', # 色でクラスタを表現する. - style='Species', # 形で品種を表現する. - palette='bright') diff --git a/code/python-results.ipynb b/code/python-results.ipynb index ac98e83..db2c8bc 100644 --- a/code/python-results.ipynb +++ b/code/python-results.ipynb @@ -1,13 +1,13 @@ { "cells": [ { - "id": "16337230", + "id": "bff04a02", "cell_type": "markdown", "source": [ "[辻真吾・矢吹太朗『ゼロからはじめるデータサイエンス入門』(講談社, 2021)](https://github.com/taroyabuki/fromzero)" ], "metadata": { - "id": "16337230" + "id": "bff04a02" } }, { @@ -17,8 +17,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "5ee939a4-2e41-45e4-b129-68ae6e15bce9", - "outputId": "de8d82e5-d324-47a4-b7e9-da6558057c16" + "id": "94da1f7b-be50-4043-b5f3-5eb3c6ce6a18", + "outputId": "ba77a2a1-3e6d-47d6-edf5-1345bfad021b" }, "outputs": [ { @@ -33,9 +33,9 @@ "# Google Colaboratoryの環境設定\n", "import os\n", "if 'COLAB_GPU' in os.environ:\n", - " !python -m pip install h2o pandarallel pca pmdarima prophet | tail -n 1" + " !python -m pip install h2o pandarallel pca pmdarima | tail -n 1" ], - "id": "5ee939a4-2e41-45e4-b129-68ae6e15bce9" + "id": "94da1f7b-be50-4043-b5f3-5eb3c6ce6a18" }, { "cell_type": "code", @@ -44,8 +44,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "a048ab7b-5eb3-4d57-bfa4-2a604d84b103", - "outputId": "98dca4b1-250c-4453-b5a6-65f425d10b7e" + "id": "64d81db2-7706-4cf0-8874-2a41dd293672", + "outputId": "f4f2f116-31e9-4745-e35b-7470fbb660e4" }, "outputs": [ { @@ -63,10 +63,10 @@ "# これはPythonのコードの例です.\n", "1 + 1" ], - "id": "a048ab7b-5eb3-4d57-bfa4-2a604d84b103" + "id": "64d81db2-7706-4cf0-8874-2a41dd293672" }, { - "id": "c7a68b71", + "id": "fc75b4bb", "cell_type": "markdown", "source": [ "# 1 コンピュータとネットワーク\n", @@ -74,11 +74,11 @@ "\n" ], "metadata": { - "id": "c7a68b71" + "id": "fc75b4bb" } }, { - "id": "22f4f730", + "id": "9ed27a25", "cell_type": "markdown", "source": [ "## 1.1 コンピュータの基本操作\n", @@ -86,11 +86,11 @@ "\n" ], "metadata": { - "id": "22f4f730" + "id": "9ed27a25" } }, { - "id": "9a06d989", + "id": "b99a43da", "cell_type": "markdown", "source": [ "## 1.2 ネットワークの仕組み\n", @@ -98,11 +98,11 @@ "\n" ], "metadata": { - "id": "9a06d989" + "id": "b99a43da" } }, { - "id": "47fc0153", + "id": "0d38e074", "cell_type": "markdown", "source": [ "# 2 データサイエンスのための環境\n", @@ -110,11 +110,11 @@ "\n" ], "metadata": { - "id": "47fc0153" + "id": "0d38e074" } }, { - "id": "a8e20168", + "id": "90471f5c", "cell_type": "markdown", "source": [ "## 2.1 実行環境の選択\n", @@ -122,11 +122,11 @@ "\n" ], "metadata": { - "id": "a8e20168" + "id": "90471f5c" } }, { - "id": "56e32826", + "id": "e11f562e", "cell_type": "markdown", "source": [ "## 2.2 クラウド\n", @@ -134,11 +134,11 @@ "\n" ], "metadata": { - "id": "56e32826" + "id": "e11f562e" } }, { - "id": "79f7e7ee", + "id": "bab6b7a9", "cell_type": "markdown", "source": [ "## 2.3 Docker\n", @@ -146,11 +146,11 @@ "\n" ], "metadata": { - "id": "79f7e7ee" + "id": "bab6b7a9" } }, { - "id": "1473de81", + "id": "9e49d94d", "cell_type": "markdown", "source": [ "## 2.4 ターミナルの使い方\n", @@ -158,11 +158,11 @@ "\n" ], "metadata": { - "id": "1473de81" + "id": "9e49d94d" } }, { - "id": "cc705fc7", + "id": "f2eaae32", "cell_type": "markdown", "source": [ "## 2.5 RとPython\n", @@ -170,17 +170,17 @@ "\n" ], "metadata": { - "id": "cc705fc7" + "id": "f2eaae32" } }, { - "id": "4dbee399", + "id": "712848c2", "cell_type": "markdown", "source": [ "## 2.6 サンプルコードの利用" ], "metadata": { - "id": "4dbee399" + "id": "712848c2" } }, { @@ -190,8 +190,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "34675382-5212-453b-8985-4a26ed5f2141", - "outputId": "c30148a5-83ac-43de-8343-d5083ecfb5be" + "id": "9339201c-7fe4-4e52-81b3-7d5522c0bd71", + "outputId": "5028d67a-1437-4cf7-e1d5-31b099d03999" }, "outputs": [ { @@ -222,10 +222,10 @@ "1 + 3\n", "# 4 # 表示される." ], - "id": "34675382-5212-453b-8985-4a26ed5f2141" + "id": "9339201c-7fe4-4e52-81b3-7d5522c0bd71" }, { - "id": "579931a2", + "id": "7c983d53", "cell_type": "markdown", "source": [ "# 3 RとPython\n", @@ -233,17 +233,17 @@ "\n" ], "metadata": { - "id": "579931a2" + "id": "7c983d53" } }, { - "id": "f3f71fad", + "id": "6d87856d", "cell_type": "markdown", "source": [ "## 3.1 入門" ], "metadata": { - "id": "f3f71fad" + "id": "6d87856d" } }, { @@ -253,8 +253,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "0bf10589-16ae-49e8-8e5b-5842251c29b3", - "outputId": "c5ef64c8-6c01-4a00-a285-dfb64c2adbd8" + "id": "20bdbcb2-0132-4de7-8f3e-098b0c1739a2", + "outputId": "e6865bc0-7bd6-4715-9f4d-8e88c719f9e1" }, "outputs": [ { @@ -271,7 +271,7 @@ "source": [ "0x10" ], - "id": "0bf10589-16ae-49e8-8e5b-5842251c29b3" + "id": "20bdbcb2-0132-4de7-8f3e-098b0c1739a2" }, { "cell_type": "code", @@ -280,8 +280,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "13c637cf-f420-4bda-9332-23fef9d565ef", - "outputId": "b4c8237b-eb62-4823-dfae-ae6672a71490" + "id": "df5f6d34-6a71-4341-a5fc-3746e752c16a", + "outputId": "72a4e04e-662a-4e79-fba8-f0e828572b53" }, "outputs": [ { @@ -298,7 +298,7 @@ "source": [ "1.23e5" ], - "id": "13c637cf-f420-4bda-9332-23fef9d565ef" + "id": "df5f6d34-6a71-4341-a5fc-3746e752c16a" }, { "cell_type": "code", @@ -307,8 +307,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "c37df4bf-ceb7-40cd-8b9f-0ab7c65dd0a5", - "outputId": "c3123252-144f-4df4-9314-47737e280fdc" + "id": "c7995ee2-778f-4070-915a-35718d72f98a", + "outputId": "d1602aba-52e6-4b99-d279-f4defec84806" }, "outputs": [ { @@ -325,7 +325,7 @@ "source": [ "2 * 3" ], - "id": "c37df4bf-ceb7-40cd-8b9f-0ab7c65dd0a5" + "id": "c7995ee2-778f-4070-915a-35718d72f98a" }, { "cell_type": "code", @@ -334,8 +334,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "655c6302-b1dd-417d-96dd-251a3e085fc1", - "outputId": "fb93be0c-30a7-4373-bc6b-1bf44504285c" + "id": "2627cbfd-e672-4599-bde3-9cc8e661d17e", + "outputId": "547abd98-b1f2-4af5-9f82-2efade9577e8" }, "outputs": [ { @@ -352,7 +352,7 @@ "source": [ "10 / 3" ], - "id": "655c6302-b1dd-417d-96dd-251a3e085fc1" + "id": "2627cbfd-e672-4599-bde3-9cc8e661d17e" }, { "cell_type": "code", @@ -361,8 +361,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "8c9d52e8-5a27-4ea2-b8e8-12af3908a2a4", - "outputId": "8499dbcb-b91a-41e5-8b9b-813dc804dfe8" + "id": "b0652120-0280-4356-866a-57067904a3b3", + "outputId": "5eb8a10c-b396-480a-972a-f14f1aa067ca" }, "outputs": [ { @@ -381,7 +381,7 @@ "\n", "10 % 3 # 余り" ], - "id": "8c9d52e8-5a27-4ea2-b8e8-12af3908a2a4" + "id": "b0652120-0280-4356-866a-57067904a3b3" }, { "cell_type": "code", @@ -390,8 +390,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "a3cbf64b-a6a9-4e5e-828e-96fd669f318a", - "outputId": "1af0363e-acb3-48cb-895b-66436c55fec7" + "id": "b0c062b9-5f54-4498-84cc-bb27fdd0f326", + "outputId": "a3c4c9ff-1915-40c1-8b19-1799182d1b1a" }, "outputs": [ { @@ -413,7 +413,7 @@ "x, y = 20, 30 # まとめて名付け\n", "x * y" ], - "id": "a3cbf64b-a6a9-4e5e-828e-96fd669f318a" + "id": "b0c062b9-5f54-4498-84cc-bb27fdd0f326" }, { "cell_type": "code", @@ -422,8 +422,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "51f3a0a7-e419-4787-9a5a-9bdf0aea1ae7", - "outputId": "9ad84730-a9f2-4dac-86d8-fe959e5dc813" + "id": "1a9c83a7-9199-4724-a8c1-6c0bfb9b5251", + "outputId": "aadd8b86-0b47-4b44-c3d9-aa25cb510228" }, "outputs": [ { @@ -443,19 +443,19 @@ "\n", "x # 変数名を評価する." ], - "id": "51f3a0a7-e419-4787-9a5a-9bdf0aea1ae7" + "id": "1a9c83a7-9199-4724-a8c1-6c0bfb9b5251" }, { "cell_type": "code", "execution_count": 11, "metadata": { - "id": "79d34d7c-fa0c-4b7f-8b91-0571a7131778" + "id": "6db2af6b-e4a1-4447-b0ad-14548469a277" }, "outputs": [], "source": [ "my_s = 'abcde'" ], - "id": "79d34d7c-fa0c-4b7f-8b91-0571a7131778" + "id": "6db2af6b-e4a1-4447-b0ad-14548469a277" }, { "cell_type": "code", @@ -464,8 +464,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "24133c05-705e-470a-95d7-a2d42ead6cbd", - "outputId": "5ebd25c7-79da-4a78-a9ff-2a95b117f4b4" + "id": "0843fbc0-1b75-465f-b702-30f2bc25809f", + "outputId": "035d3cae-7e51-4860-e56a-1562ae8b5366" }, "outputs": [ { @@ -482,7 +482,7 @@ "source": [ "len(my_s)" ], - "id": "24133c05-705e-470a-95d7-a2d42ead6cbd" + "id": "0843fbc0-1b75-465f-b702-30f2bc25809f" }, { "cell_type": "code", @@ -490,10 +490,10 @@ "metadata": { "colab": { "base_uri": "https://localhost:8080/", - "height": 35 + "height": 36 }, - "id": "51c7a75f-15e1-4ccd-833a-4f690f525d10", - "outputId": "3822ec50-4ce4-4dea-b674-e1dc0c4616f2" + "id": "983deaa6-64c6-4b91-8b8f-6b7df019450e", + "outputId": "29adaf7c-494f-41e9-c8b1-967e1e93dcc0" }, "outputs": [ { @@ -515,7 +515,7 @@ "# あるいは\n", "'This is ' + 'a' + ' pen.'" ], - "id": "51c7a75f-15e1-4ccd-833a-4f690f525d10" + "id": "983deaa6-64c6-4b91-8b8f-6b7df019450e" }, { "cell_type": "code", @@ -523,10 +523,10 @@ "metadata": { "colab": { "base_uri": "https://localhost:8080/", - "height": 35 + "height": 36 }, - "id": "d8c7dd60-0f7b-46f9-9511-6e9ec82bd8ce", - "outputId": "0f46c718-2ae4-4c37-96ee-8b049aa2fbc8" + "id": "d7507791-18cf-45bd-8391-99205a7276d9", + "outputId": "f51f1b86-bef2-42d8-9099-de6be109451b" }, "outputs": [ { @@ -546,7 +546,7 @@ "source": [ "my_s[1:4]" ], - "id": "d8c7dd60-0f7b-46f9-9511-6e9ec82bd8ce" + "id": "d7507791-18cf-45bd-8391-99205a7276d9" }, { "cell_type": "code", @@ -554,10 +554,10 @@ "metadata": { "colab": { "base_uri": "https://localhost:8080/", - "height": 35 + "height": 36 }, - "id": "ae6356fa-ae00-4986-aa1f-4e0349c82439", - "outputId": "1d8df4b6-c371-4e38-d93a-3f6b2f16430c" + "id": "9161e0a8-7e26-4c22-88c1-53058fcb0e76", + "outputId": "4ff7c909-1051-4aad-dd93-826440ae3915" }, "outputs": [ { @@ -578,7 +578,7 @@ "tmp = \"{} is {}.\"\n", "tmp.format('This', 'a pen')" ], - "id": "ae6356fa-ae00-4986-aa1f-4e0349c82439" + "id": "9161e0a8-7e26-4c22-88c1-53058fcb0e76" }, { "cell_type": "code", @@ -587,8 +587,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "71aac99a-82bb-4f7d-8223-a46ba03ed9f3", - "outputId": "87713b50-43f9-464b-a2dc-9df42dbd4552" + "id": "d1832f14-18e8-4f22-ba0c-4cd31ce5e9da", + "outputId": "efa6f8a1-721b-4d87-ea30-5423e3a80f00" }, "outputs": [ { @@ -607,7 +607,7 @@ "\n", "1 < 0" ], - "id": "71aac99a-82bb-4f7d-8223-a46ba03ed9f3" + "id": "d1832f14-18e8-4f22-ba0c-4cd31ce5e9da" }, { "cell_type": "code", @@ -616,8 +616,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "df604bae-3001-4753-ae41-044a355efc28", - "outputId": "60537f80-9b19-4444-af9d-536d4f6dad5e" + "id": "68bcb1ce-b44f-45e3-8b28-d51d0dba4adb", + "outputId": "4aed38f8-9106-42c1-9fc0-5e19a35b7bc4" }, "outputs": [ { @@ -637,7 +637,7 @@ "import math\n", "math.isclose(0.1 + 0.1 + 0.1, 0.3)" ], - "id": "df604bae-3001-4753-ae41-044a355efc28" + "id": "68bcb1ce-b44f-45e3-8b28-d51d0dba4adb" }, { "cell_type": "code", @@ -646,8 +646,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "5e4e58e1-8e7a-465f-a31d-ef9458a4736a", - "outputId": "bcb6b316-c88f-4d3c-c471-8cf3e46e3025" + "id": "0ea56e0c-8da9-4956-9e2f-861e160d84df", + "outputId": "124e12e7-d898-40cf-e45a-8b2cb6bbcf0f" }, "outputs": [ { @@ -668,7 +668,7 @@ "\n", "not True # 否定(でない)" ], - "id": "5e4e58e1-8e7a-465f-a31d-ef9458a4736a" + "id": "0ea56e0c-8da9-4956-9e2f-861e160d84df" }, { "cell_type": "code", @@ -677,8 +677,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "cc5d4d8a-f594-4103-b813-cde55e49c8b5", - "outputId": "042d8a02-02f7-43dc-89eb-fb7db4762a09" + "id": "c2689fbc-f48f-4586-a35d-d27679f03463", + "outputId": "43c7324c-3586-4c78-d85c-e5a13f6532b9" }, "outputs": [ { @@ -695,7 +695,7 @@ "source": [ "0 if 3 < 5 else 10" ], - "id": "cc5d4d8a-f594-4103-b813-cde55e49c8b5" + "id": "c2689fbc-f48f-4586-a35d-d27679f03463" }, { "cell_type": "code", @@ -703,10 +703,10 @@ "metadata": { "colab": { "base_uri": "https://localhost:8080/", - "height": 35 + "height": 36 }, - "id": "da924452-44d2-4a6c-898a-2076e50fc3af", - "outputId": "feaf0835-bbd3-4961-c610-950c839ffcbe" + "id": "7b17eb0f-d929-40d8-bdcd-bd4068557164", + "outputId": "a408eff3-5abe-4c5a-a88f-3193c56f56ad" }, "outputs": [ { @@ -727,7 +727,7 @@ "import os\n", "os.getcwd()" ], - "id": "da924452-44d2-4a6c-898a-2076e50fc3af" + "id": "7b17eb0f-d929-40d8-bdcd-bd4068557164" }, { "cell_type": "code", @@ -735,10 +735,10 @@ "metadata": { "colab": { "base_uri": "https://localhost:8080/", - "height": 35 + "height": 36 }, - "id": "34fb5380-77f1-47c3-a707-58477a651f6b", - "outputId": "6073f03d-b966-4b7c-fe0f-8ce490e6fa18" + "id": "f6463f09-a96c-4c46-a80b-ac85bc7cec0d", + "outputId": "501bd909-95a3-41da-d7f4-15dd1615a18d" }, "outputs": [ { @@ -759,16 +759,16 @@ "os.chdir('..')\n", "os.getcwd()" ], - "id": "34fb5380-77f1-47c3-a707-58477a651f6b" + "id": "f6463f09-a96c-4c46-a80b-ac85bc7cec0d" }, { - "id": "ca79e5ae", + "id": "6024e0cc", "cell_type": "markdown", "source": [ "## 3.2 関数" ], "metadata": { - "id": "ca79e5ae" + "id": "6024e0cc" } }, { @@ -778,8 +778,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "1e2770aa-5cfd-465b-81a9-4fc5f4468090", - "outputId": "b720ef9d-0a1e-4728-c5d9-4432d074e86d" + "id": "7b972bd9-26a1-42a4-941a-73827bb58920", + "outputId": "3893c93f-7544-409e-b861-dcbf8930434f" }, "outputs": [ { @@ -797,7 +797,7 @@ "import math\n", "math.sqrt(4)" ], - "id": "1e2770aa-5cfd-465b-81a9-4fc5f4468090" + "id": "7b972bd9-26a1-42a4-941a-73827bb58920" }, { "cell_type": "code", @@ -806,8 +806,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "3b9a7a78-fca5-459e-b670-16eef4c70760", - "outputId": "ed9bcd04-72ec-426a-aedf-af94ac9803ea" + "id": "94af52ab-ea86-4bd1-bc9b-a68dbcd2e1d6", + "outputId": "c3e4e4bd-6b86-48c2-f45c-794a74686d8d" }, "outputs": [ { @@ -824,7 +824,7 @@ "source": [ "math.log(100, 10)" ], - "id": "3b9a7a78-fca5-459e-b670-16eef4c70760" + "id": "94af52ab-ea86-4bd1-bc9b-a68dbcd2e1d6" }, { "cell_type": "code", @@ -833,8 +833,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "e810530e-1cb8-4262-888b-eea33d6b46d0", - "outputId": "6b01fd98-8314-4eb1-a965-087a95488156" + "id": "8c15329a-1883-4136-aaf2-a4f35862612a", + "outputId": "80cb2cf8-ca53-4be8-97fb-e59b3d3475f5" }, "outputs": [ { @@ -853,7 +853,7 @@ "# あるいは\n", "math.log(100, math.e) # 省略しない場合\n" ], - "id": "e810530e-1cb8-4262-888b-eea33d6b46d0" + "id": "8c15329a-1883-4136-aaf2-a4f35862612a" }, { "cell_type": "code", @@ -862,8 +862,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "319d64b6-e55d-4e9a-8156-9eb1e5901c5d", - "outputId": "a99aed6b-05a0-4f71-959d-d3e0f2832fb7" + "id": "31ffa5ae-80bf-458e-9a1d-49418b9b75eb", + "outputId": "efa5877f-6502-4631-cf51-ea7359bc8e96" }, "outputs": [ { @@ -882,20 +882,20 @@ "\n", "math.log2(1024) # 底が2の対数" ], - "id": "319d64b6-e55d-4e9a-8156-9eb1e5901c5d" + "id": "31ffa5ae-80bf-458e-9a1d-49418b9b75eb" }, { "cell_type": "code", "execution_count": 26, "metadata": { - "id": "75a9db8a-647f-49b9-82a2-4d7e4eea0395" + "id": "43b3a66f-6393-496c-9d5b-8146c2368a94" }, "outputs": [], "source": [ "def f(a, b):\n", " return a - b" ], - "id": "75a9db8a-647f-49b9-82a2-4d7e4eea0395" + "id": "43b3a66f-6393-496c-9d5b-8146c2368a94" }, { "cell_type": "code", @@ -904,8 +904,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "8f8d1b96-b309-48f1-85a7-c28a5caa3871", - "outputId": "b7cf2aad-d547-45fc-ba2d-79a6263a105a" + "id": "2169483f-cbe6-410f-ae0c-3b2437bc50cf", + "outputId": "79db6341-0995-426b-a505-6228ada15ded" }, "outputs": [ { @@ -922,7 +922,7 @@ "source": [ "f(3, 5)" ], - "id": "8f8d1b96-b309-48f1-85a7-c28a5caa3871" + "id": "2169483f-cbe6-410f-ae0c-3b2437bc50cf" }, { "cell_type": "code", @@ -931,8 +931,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "888a9cbe-e482-477e-852c-ed0781d1126b", - "outputId": "c4851d0b-b729-4c05-cfac-7926b7cd6ec5" + "id": "196dbb08-be85-40da-a5ba-064b40cfa0f0", + "outputId": "ccef044f-06ba-4e57-f06f-8d02d2e241cf" }, "outputs": [ { @@ -952,7 +952,7 @@ "\n", "f(3) # f(3, 5)と同じこと" ], - "id": "888a9cbe-e482-477e-852c-ed0781d1126b" + "id": "196dbb08-be85-40da-a5ba-064b40cfa0f0" }, { "cell_type": "code", @@ -961,8 +961,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "8ee293ec-7125-4c52-979a-7fc2d5e035e5", - "outputId": "6914dc30-9b9f-4e96-fc0f-5c9ae6bdec9d" + "id": "23bdcab7-a734-4873-b1a2-668387f12848", + "outputId": "ed2c72dc-7c95-4f2a-ac43-4da1babb6d41" }, "outputs": [ { @@ -979,29 +979,29 @@ "source": [ "(lambda a, b: a - b)(3, 5)" ], - "id": "8ee293ec-7125-4c52-979a-7fc2d5e035e5" + "id": "23bdcab7-a734-4873-b1a2-668387f12848" }, { - "id": "a29ab86b", + "id": "0f82b54b", "cell_type": "markdown", "source": [ "## 3.3 コレクション" ], "metadata": { - "id": "a29ab86b" + "id": "0f82b54b" } }, { "cell_type": "code", "execution_count": 30, "metadata": { - "id": "9f863418-0c62-433b-a5c8-2676664379b5" + "id": "22d46799-8ea8-43d8-9fc9-b0f6779b212e" }, "outputs": [], "source": [ "x = ['foo', 'bar', 'baz']" ], - "id": "9f863418-0c62-433b-a5c8-2676664379b5" + "id": "22d46799-8ea8-43d8-9fc9-b0f6779b212e" }, { "cell_type": "code", @@ -1010,8 +1010,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "6d3a9f4c-3794-486e-8b35-0455ea1605c5", - "outputId": "4e54e8db-ae2e-4f33-ce6f-732d658978f2" + "id": "c323c1b9-6606-456a-bdfd-266ec133f31c", + "outputId": "4f869696-3e1d-4a37-a876-eb02d1ca0ac0" }, "outputs": [ { @@ -1028,7 +1028,7 @@ "source": [ "len(x)" ], - "id": "6d3a9f4c-3794-486e-8b35-0455ea1605c5" + "id": "c323c1b9-6606-456a-bdfd-266ec133f31c" }, { "cell_type": "code", @@ -1036,10 +1036,10 @@ "metadata": { "colab": { "base_uri": "https://localhost:8080/", - "height": 35 + "height": 36 }, - "id": "4462c4c4-86ea-4450-a6a0-ff4600c73969", - "outputId": "670a978e-dc57-4912-b3d8-617d54392a2b" + "id": "dd9033fa-bd34-472c-b6d2-ce54a4572bc8", + "outputId": "78430c8d-e80a-40c6-dabf-3722f809ec75" }, "outputs": [ { @@ -1059,13 +1059,13 @@ "source": [ "x[1]" ], - "id": "4462c4c4-86ea-4450-a6a0-ff4600c73969" + "id": "dd9033fa-bd34-472c-b6d2-ce54a4572bc8" }, { "cell_type": "code", "execution_count": 33, "metadata": { - "id": "374d0e15-6a97-4519-9a40-afed90abfeb5" + "id": "d752a037-486e-44ec-8133-8cf393025cd7" }, "outputs": [], "source": [ @@ -1074,7 +1074,7 @@ "\n", "x[1] = 'bar' # 元に戻す." ], - "id": "374d0e15-6a97-4519-9a40-afed90abfeb5" + "id": "d752a037-486e-44ec-8133-8cf393025cd7" }, { "cell_type": "code", @@ -1082,10 +1082,10 @@ "metadata": { "colab": { "base_uri": "https://localhost:8080/", - "height": 35 + "height": 36 }, - "id": "ecd4c244-9943-43a6-8815-68dcb7b1d5ab", - "outputId": "eaa27b78-e51b-469b-c0fb-312c0f6266fa" + "id": "6414e6b2-3519-40cf-988f-6047f4285af9", + "outputId": "15bb91c4-8db2-4637-be4c-41ca84344e92" }, "outputs": [ { @@ -1105,7 +1105,7 @@ "source": [ "x[-2]" ], - "id": "ecd4c244-9943-43a6-8815-68dcb7b1d5ab" + "id": "6414e6b2-3519-40cf-988f-6047f4285af9" }, { "cell_type": "code", @@ -1114,8 +1114,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "87563d35-cc13-4aa6-838d-7d272c9ef8b4", - "outputId": "ee7afaae-4185-440b-f2f9-a13f502dd271" + "id": "e07ecce3-71c1-43b2-aa82-cce015106e73", + "outputId": "4a94750c-5a64-4f06-9409-0d49ef9b4af4" }, "outputs": [ { @@ -1132,7 +1132,7 @@ "source": [ "x + ['qux']" ], - "id": "87563d35-cc13-4aa6-838d-7d272c9ef8b4" + "id": "e07ecce3-71c1-43b2-aa82-cce015106e73" }, { "cell_type": "code", @@ -1141,8 +1141,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "989556cc-565d-4222-a1a1-71e5bf1dfaa5", - "outputId": "39ebe196-a0e9-43b3-e346-9a1b79380060" + "id": "23c15f89-c034-441c-bdd6-6ba13ebf4f38", + "outputId": "17740d0c-34ad-48fc-eb81-d6926fcacbba" }, "outputs": [ { @@ -1163,7 +1163,7 @@ "\n", "x # 結果の確認" ], - "id": "989556cc-565d-4222-a1a1-71e5bf1dfaa5" + "id": "23c15f89-c034-441c-bdd6-6ba13ebf4f38" }, { "cell_type": "code", @@ -1172,8 +1172,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "3e9ec18b-8d0f-4ca3-8143-7c0029104b26", - "outputId": "478f4942-85d3-460c-c5ab-255a9940f8ba" + "id": "4eedf625-3bc6-41d8-a28d-f59ba1cd29af", + "outputId": "4a5591cc-ef70-4789-e21c-6d5bdcc70dac" }, "outputs": [ { @@ -1190,7 +1190,7 @@ "source": [ "list(range(5))" ], - "id": "3e9ec18b-8d0f-4ca3-8143-7c0029104b26" + "id": "4eedf625-3bc6-41d8-a28d-f59ba1cd29af" }, { "cell_type": "code", @@ -1199,8 +1199,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "ca01dd4d-6f1b-4e9f-bf1b-61c5ad25fe5e", - "outputId": "366b3d39-d901-44ae-aa8e-f12e677ef796" + "id": "28c3f4c6-1a5e-409b-820f-b7ef486c9f3d", + "outputId": "75f53a80-3789-454d-e2ff-0a4c35574e8e" }, "outputs": [ { @@ -1217,7 +1217,7 @@ "source": [ "list(range(0, 11, 2))" ], - "id": "ca01dd4d-6f1b-4e9f-bf1b-61c5ad25fe5e" + "id": "28c3f4c6-1a5e-409b-820f-b7ef486c9f3d" }, { "cell_type": "code", @@ -1226,8 +1226,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "4d8779e5-642f-45e5-a6b5-64e5493f7c24", - "outputId": "1fed10f7-a7ae-40c7-917f-0903630313f1" + "id": "f2fac332-de9c-4506-8b78-39ae98714efd", + "outputId": "9564aa58-8d51-4083-a58b-818cb67b483b" }, "outputs": [ { @@ -1245,7 +1245,7 @@ "import numpy as np\n", "np.arange(0, 1.1, 0.5)" ], - "id": "4d8779e5-642f-45e5-a6b5-64e5493f7c24" + "id": "f2fac332-de9c-4506-8b78-39ae98714efd" }, { "cell_type": "code", @@ -1254,8 +1254,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "d08114fa-1ece-4567-b165-2cf03a9e028e", - "outputId": "fb97178d-08c7-42f7-f7b3-eabbda6fd3d0" + "id": "6dabc93a-1569-4e94-a196-04da19f6c3ae", + "outputId": "28def329-9110-487e-8056-734bd779e8f0" }, "outputs": [ { @@ -1272,7 +1272,7 @@ "source": [ "np.linspace(0, 100, 5)" ], - "id": "d08114fa-1ece-4567-b165-2cf03a9e028e" + "id": "6dabc93a-1569-4e94-a196-04da19f6c3ae" }, { "cell_type": "code", @@ -1281,8 +1281,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "8fe4bcf9-287f-4866-8842-50596e1ea8fd", - "outputId": "53b873cb-3370-4249-e33e-281e3f25bce3" + "id": "5f28d840-5ab1-4880-b750-acb30c3bfd51", + "outputId": "8c4c8ec3-085e-4747-cd2f-22b318282379" }, "outputs": [ { @@ -1299,7 +1299,7 @@ "source": [ "[10] * 5" ], - "id": "8fe4bcf9-287f-4866-8842-50596e1ea8fd" + "id": "5f28d840-5ab1-4880-b750-acb30c3bfd51" }, { "cell_type": "code", @@ -1308,8 +1308,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "37d325d2-6b48-4474-83c2-c3fc526747d9", - "outputId": "35715636-3e89-4fda-f3ee-634a6f2fcd42" + "id": "916b3760-5e06-4275-995e-fb84ecce9378", + "outputId": "cda0093d-cdd3-4994-c3a3-30b4b8e8e693" }, "outputs": [ { @@ -1331,7 +1331,7 @@ "\n", "x * 10 # 乗算" ], - "id": "37d325d2-6b48-4474-83c2-c3fc526747d9" + "id": "916b3760-5e06-4275-995e-fb84ecce9378" }, { "cell_type": "code", @@ -1340,8 +1340,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "8fdf6032-1b25-4ffd-bc13-efb7be0320eb", - "outputId": "4658ed0c-f11c-4260-f754-12279b19adaa" + "id": "0aa041bf-40dd-4964-84bd-d0830bf64087", + "outputId": "830315fc-4c49-467e-d40b-1f4ba305bdd3" }, "outputs": [ { @@ -1359,7 +1359,7 @@ "x = [2, 3]\n", "np.sin(x)" ], - "id": "8fdf6032-1b25-4ffd-bc13-efb7be0320eb" + "id": "0aa041bf-40dd-4964-84bd-d0830bf64087" }, { "cell_type": "code", @@ -1368,8 +1368,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "67d55d6e-4ef7-4516-b131-e3bc2303e56a", - "outputId": "10f0cc7f-140c-4d8a-a59e-c281d0e6a8da" + "id": "d6a9080c-6cc7-4864-a40b-53ceb5919da4", + "outputId": "9ad98362-d155-4702-ffe9-0526fc74d9fd" }, "outputs": [ { @@ -1390,7 +1390,7 @@ "\n", "x * y" ], - "id": "67d55d6e-4ef7-4516-b131-e3bc2303e56a" + "id": "d6a9080c-6cc7-4864-a40b-53ceb5919da4" }, { "cell_type": "code", @@ -1399,8 +1399,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "5f708f16-4422-4bc0-a2f8-3436633b1f58", - "outputId": "a5a52e4d-e981-4d54-c125-2cb5499def1c" + "id": "c234eafc-4a6f-41c3-9ce9-662fa4745f6f", + "outputId": "420d0507-f747-4322-fc8e-341a467f2d8c" }, "outputs": [ { @@ -1419,7 +1419,7 @@ "# あるいは\n", "x @ y\n" ], - "id": "5f708f16-4422-4bc0-a2f8-3436633b1f58" + "id": "c234eafc-4a6f-41c3-9ce9-662fa4745f6f" }, { "cell_type": "code", @@ -1428,8 +1428,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "0cc3055c-746c-4eef-a32e-a5fe805fea1b", - "outputId": "b4c22149-0254-40c0-f5f2-8f88d8fbc1ee" + "id": "fc195af6-b6e8-4938-bf5d-66509747a340", + "outputId": "4ac2d675-e4a4-43bd-8308-d3bf49700cb4" }, "outputs": [ { @@ -1448,7 +1448,7 @@ "y = np.array([True, True])\n", "x & y" ], - "id": "0cc3055c-746c-4eef-a32e-a5fe805fea1b" + "id": "fc195af6-b6e8-4938-bf5d-66509747a340" }, { "cell_type": "code", @@ -1457,8 +1457,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "65f6193f-836e-4e55-979f-cf453e4e4dc6", - "outputId": "0e378aae-70c6-46d5-da63-93c24a53a00d" + "id": "ee670438-31c7-4fac-98d5-c0f739bf76c4", + "outputId": "40734719-7c0f-4fb4-9f40-9d34d5ab5c81" }, "outputs": [ { @@ -1485,7 +1485,7 @@ "\n", "u == w # 要素ごとの比較" ], - "id": "65f6193f-836e-4e55-979f-cf453e4e4dc6" + "id": "ee670438-31c7-4fac-98d5-c0f739bf76c4" }, { "cell_type": "code", @@ -1494,8 +1494,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "f8557951-c190-46b0-8cc7-fcc3f57c4ce5", - "outputId": "ea7470a6-db4a-4bc4-cf36-049853ece55e" + "id": "b5fe4882-f575-4ffc-82e6-32c0c81563e1", + "outputId": "70028115-21f8-46c7-e3a4-dbf449b418d2" }, "outputs": [ { @@ -1514,19 +1514,19 @@ "\n", "(u == w).mean() # 同じ要素の割合" ], - "id": "f8557951-c190-46b0-8cc7-fcc3f57c4ce5" + "id": "b5fe4882-f575-4ffc-82e6-32c0c81563e1" }, { "cell_type": "code", "execution_count": 49, "metadata": { - "id": "c22986ed-7c07-4e70-949f-90b371950488" + "id": "914dfa51-a580-442c-a709-91e7112584f5" }, "outputs": [], "source": [ "x = [1, \"two\"]" ], - "id": "c22986ed-7c07-4e70-949f-90b371950488" + "id": "914dfa51-a580-442c-a709-91e7112584f5" }, { "cell_type": "code", @@ -1534,10 +1534,10 @@ "metadata": { "colab": { "base_uri": "https://localhost:8080/", - "height": 35 + "height": 36 }, - "id": "2eedf34f-8d2c-4f11-9f43-595151f05165", - "outputId": "048acf6d-7800-4407-dd48-599780ab2b53" + "id": "8e4afd4c-fa45-4ec5-8304-b752377d864b", + "outputId": "fbf46103-2dde-4336-9e77-df66e3eda8eb" }, "outputs": [ { @@ -1557,32 +1557,32 @@ "source": [ "x[1]" ], - "id": "2eedf34f-8d2c-4f11-9f43-595151f05165" + "id": "8e4afd4c-fa45-4ec5-8304-b752377d864b" }, { "cell_type": "code", "execution_count": 51, "metadata": { - "id": "eea7bb26-6e6d-4e2b-a425-8389292faa65" + "id": "941ac635-3124-4134-9fc2-bafdf93a4670" }, "outputs": [], "source": [ "x = {'apple' : 'りんご',\n", " 'orange': 'みかん'}" ], - "id": "eea7bb26-6e6d-4e2b-a425-8389292faa65" + "id": "941ac635-3124-4134-9fc2-bafdf93a4670" }, { "cell_type": "code", "execution_count": 52, "metadata": { - "id": "b977665e-98f9-4a02-9a43-2458352dc042" + "id": "d46067c9-deb8-4889-8181-b4a343c40690" }, "outputs": [], "source": [ "x['grape'] = 'ぶどう'" ], - "id": "b977665e-98f9-4a02-9a43-2458352dc042" + "id": "d46067c9-deb8-4889-8181-b4a343c40690" }, { "cell_type": "code", @@ -1590,10 +1590,10 @@ "metadata": { "colab": { "base_uri": "https://localhost:8080/", - "height": 35 + "height": 36 }, - "id": "355d5ec5-5748-4047-99a2-443c21836184", - "outputId": "756cad72-f002-4fbf-d726-cfdec5063997" + "id": "78f21d21-0398-4748-a34e-65b25066ff27", + "outputId": "f5f6f851-57ee-4339-e4ac-7af5a5600711" }, "outputs": [ { @@ -1616,7 +1616,7 @@ "tmp = 'apple'\n", "x[tmp]\n" ], - "id": "355d5ec5-5748-4047-99a2-443c21836184" + "id": "78f21d21-0398-4748-a34e-65b25066ff27" }, { "cell_type": "code", @@ -1625,8 +1625,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "e1be4654-f71c-48a6-836a-3065cce545fe", - "outputId": "478ea981-a817-49f6-b156-8225a273b045" + "id": "b5b4e478-b2c2-4896-ae17-dfa7e43233e0", + "outputId": "880c0975-928f-446b-c80e-9f0866a93426" }, "outputs": [ { @@ -1648,7 +1648,7 @@ "\n", "x # xも変わる." ], - "id": "e1be4654-f71c-48a6-836a-3065cce545fe" + "id": "b5b4e478-b2c2-4896-ae17-dfa7e43233e0" }, { "cell_type": "code", @@ -1657,8 +1657,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "3da09475-bccb-41cd-b965-e184e74d9b53", - "outputId": "215f545a-77be-450e-9d43-3f21d41e5db2" + "id": "24c887b7-829b-4f24-9e54-8a113f1bb3f2", + "outputId": "45b4ca2a-b88a-48e6-b80c-df25fe976a14" }, "outputs": [ { @@ -1680,35 +1680,35 @@ "y[1] = 'BAR' # yを更新しても,\n", "x" ], - "id": "3da09475-bccb-41cd-b965-e184e74d9b53" + "id": "24c887b7-829b-4f24-9e54-8a113f1bb3f2" }, { - "id": "e8e29fab", + "id": "c5ca334a", "cell_type": "markdown", "source": [ "## 3.4 データフレーム" ], "metadata": { - "id": "e8e29fab" + "id": "c5ca334a" } }, { "cell_type": "code", "execution_count": 56, "metadata": { - "id": "629e8f00-6276-4c91-b354-e1173926ca9d" + "id": "27d5e2d5-0765-4cc7-b207-371de58cd3f6" }, "outputs": [], "source": [ "import pandas as pd" ], - "id": "629e8f00-6276-4c91-b354-e1173926ca9d" + "id": "27d5e2d5-0765-4cc7-b207-371de58cd3f6" }, { "cell_type": "code", "execution_count": 57, "metadata": { - "id": "023cf7bb-182a-448b-8d5d-527e559a2e05" + "id": "38cd8aa3-d976-4fbe-b7fb-d1921c99392a" }, "outputs": [], "source": [ @@ -1718,13 +1718,13 @@ " 'math': [ 70, 80, 90, 100],\n", " 'gender': ['f', 'm', 'm', 'f']})" ], - "id": "023cf7bb-182a-448b-8d5d-527e559a2e05" + "id": "38cd8aa3-d976-4fbe-b7fb-d1921c99392a" }, { "cell_type": "code", "execution_count": 58, "metadata": { - "id": "921ed4fc-6af3-4d08-940f-755bb95a6ce6" + "id": "569e1780-09fe-432a-89f3-2535e94ecb51" }, "outputs": [], "source": [ @@ -1736,7 +1736,7 @@ " columns=['name', 'english',\n", " 'math', 'gender'])" ], - "id": "921ed4fc-6af3-4d08-940f-755bb95a6ce6" + "id": "569e1780-09fe-432a-89f3-2535e94ecb51" }, { "cell_type": "code", @@ -1744,10 +1744,10 @@ "metadata": { "colab": { "base_uri": "https://localhost:8080/", - "height": 175 + "height": 174 }, - "id": "cd27c9cf-1b2f-4aa1-96b0-b7202826c09f", - "outputId": "7a709241-6576-45f0-9a2e-61bd18345bfd" + "id": "b6a6d99f-dd45-49e6-91ad-4f837e64bbe7", + "outputId": "59868ab9-bc12-488f-a358-d25587b514a4" }, "outputs": [ { @@ -1762,7 +1762,7 @@ ], "text/html": [ "\n", - "
\n", + "
\n", "
\n", "\n", - "
ndarray (28, 28) 
array([[  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",
+              "      
ndarray (28, 28) 
array([[  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,   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,   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,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0],\n",
@@ -26359,10 +26365,10 @@
               "      (() => {\n",
               "      const titles = ['show data', 'hide data'];\n",
               "      let index = 0\n",
-              "      document.querySelector('#id-9d1a5fde-b6b9-4a7b-af81-1e5d45794f52 button').onclick = (e) => {\n",
-              "        document.querySelector('#id-9d1a5fde-b6b9-4a7b-af81-1e5d45794f52').classList.toggle('show_array');\n",
+              "      document.querySelector('#id-03502ed6-4456-442b-abbf-fe23f1b950f0 button').onclick = (e) => {\n",
+              "        document.querySelector('#id-03502ed6-4456-442b-abbf-fe23f1b950f0').classList.toggle('show_array');\n",
               "        index = (++index) % 2;\n",
-              "        document.querySelector('#id-9d1a5fde-b6b9-4a7b-af81-1e5d45794f52 button').textContent = titles[index];\n",
+              "        document.querySelector('#id-03502ed6-4456-442b-abbf-fe23f1b950f0 button').textContent = titles[index];\n",
               "        e.preventDefault();\n",
               "        e.stopPropagation();\n",
               "      }\n",
@@ -26378,7 +26384,7 @@
         "np.set_printoptions(linewidth=170)\n",
         "x_train[4, :, :]"
       ],
-      "id": "8a29b2c1-592b-4b02-ad97-14f0d7337945"
+      "id": "b0860f34-2150-49fe-a8dc-9ca3dc2a15b5"
     },
     {
       "cell_type": "code",
@@ -26386,17 +26392,17 @@
       "metadata": {
         "colab": {
           "base_uri": "https://localhost:8080/",
-          "height": 454
+          "height": 455
         },
-        "id": "6f3d799b-5637-44e7-86c4-54ed7b9d0e33",
-        "outputId": "567488de-ff7b-4f04-f16e-1c07e28d5e8b"
+        "id": "39c8e7fc-f0b0-4b32-a355-a12fb03eb1bf",
+        "outputId": "afd069e8-d0d4-4cf3-f796-9814e0d963bf"
       },
       "outputs": [
         {
           "output_type": "execute_result",
           "data": {
             "text/plain": [
-              ""
+              ""
             ]
           },
           "metadata": {},
@@ -26416,7 +26422,7 @@
       "source": [
         "plt.matshow(x_train[4, :, :])"
       ],
-      "id": "6f3d799b-5637-44e7-86c4-54ed7b9d0e33"
+      "id": "39c8e7fc-f0b0-4b32-a355-a12fb03eb1bf"
     },
     {
       "cell_type": "code",
@@ -26425,8 +26431,8 @@
         "colab": {
           "base_uri": "https://localhost:8080/"
         },
-        "id": "bc9ec7ae-7b76-4457-a037-55ed4ec2b78e",
-        "outputId": "99473afc-51f8-4aaa-a49d-6189436e919e"
+        "id": "682e4935-34c2-466a-aa4a-2e63159601f6",
+        "outputId": "c7e33b51-4f6b-46d0-bab8-5fbd7bcd685e"
       },
       "outputs": [
         {
@@ -26443,7 +26449,7 @@
       "source": [
         "y_train"
       ],
-      "id": "bc9ec7ae-7b76-4457-a037-55ed4ec2b78e"
+      "id": "682e4935-34c2-466a-aa4a-2e63159601f6"
     },
     {
       "cell_type": "code",
@@ -26452,8 +26458,8 @@
         "colab": {
           "base_uri": "https://localhost:8080/"
         },
-        "id": "d2c904d8-25e8-4a26-a899-84a5a59d6f5f",
-        "outputId": "a61bf3f8-2972-4539-c9cf-bced91eb50b7"
+        "id": "4d5dcaed-6ea0-423f-905f-b1ef7f096cce",
+        "outputId": "b5280356-1385-4a49-f2bb-6384776b5001"
       },
       "outputs": [
         {
@@ -26470,26 +26476,26 @@
       "source": [
         "x_train.min(), x_train.max()"
       ],
-      "id": "d2c904d8-25e8-4a26-a899-84a5a59d6f5f"
+      "id": "4d5dcaed-6ea0-423f-905f-b1ef7f096cce"
     },
     {
       "cell_type": "code",
       "execution_count": 347,
       "metadata": {
-        "id": "41a53c88-5953-40b0-9e3a-55dbaed387c9"
+        "id": "95974e0b-643b-4067-a381-76a9e188b0e2"
       },
       "outputs": [],
       "source": [
         "x_train = x_train / 255\n",
         "x_test  = x_test  / 255"
       ],
-      "id": "41a53c88-5953-40b0-9e3a-55dbaed387c9"
+      "id": "95974e0b-643b-4067-a381-76a9e188b0e2"
     },
     {
       "cell_type": "code",
       "execution_count": 348,
       "metadata": {
-        "id": "b9c76595-f0a2-413a-8c48-d7b88093d383"
+        "id": "7009590b-6bb1-47b3-acf1-bca2d175c0f5"
       },
       "outputs": [],
       "source": [
@@ -26497,7 +26503,7 @@
         "x_train = x_train[my_index, :, :]\n",
         "y_train = y_train[my_index]"
       ],
-      "id": "b9c76595-f0a2-413a-8c48-d7b88093d383"
+      "id": "7009590b-6bb1-47b3-acf1-bca2d175c0f5"
     },
     {
       "cell_type": "code",
@@ -26506,8 +26512,8 @@
         "colab": {
           "base_uri": "https://localhost:8080/"
         },
-        "id": "9ac3a33e-5256-4dd5-b7fc-a1e9e4d02c96",
-        "outputId": "86dcd937-654b-4e51-a9f7-9f6969daa031"
+        "id": "e9adad5d-de51-4529-aae7-f13105cc75ea",
+        "outputId": "65ad0495-38a2-4add-fd47-d061a706786f"
       },
       "outputs": [
         {
@@ -26546,7 +26552,7 @@
         "\n",
         "my_cb = callbacks.EarlyStopping(patience=5, restore_best_weights=True)"
       ],
-      "id": "9ac3a33e-5256-4dd5-b7fc-a1e9e4d02c96"
+      "id": "e9adad5d-de51-4529-aae7-f13105cc75ea"
     },
     {
       "cell_type": "code",
@@ -26554,10 +26560,10 @@
       "metadata": {
         "colab": {
           "base_uri": "https://localhost:8080/",
-          "height": 466
+          "height": 467
         },
-        "id": "03741cfa-3026-4053-9bb6-32a3a7648366",
-        "outputId": "670fe21d-f516-4f0f-840f-6eb7cb52f2b5"
+        "id": "a904fda7-b9a5-4979-bdf4-190dd7957838",
+        "outputId": "cd49c4af-2948-4439-be10-12bd0124b2f6"
       },
       "outputs": [
         {
@@ -26576,7 +26582,7 @@
             "text/plain": [
               "
" ], - "image/png": "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idn17733Hj766CN8/vnnOHToELy9vTF69GiUlZVZzNPev/vGUtexajQaJCYm4vXXX0diYiJ++OEHnD17FnfeeafVfO35W2gs1s4rAIwZM8ak3GvWrKkzz6Z6XgHrx1vzODMyMrBs2TIIgoB77723znyb4rl1GrEZi4+PF6dPn258r9PpxMjISHHBggVm00+YMEG8/fbbTZYlJCSITzzxhFPL6QzZ2dkiAPG3336zmGb58uWiv79/4xXKQebNmyf27NnT5vTN6bw+//zzYlxcnKjX682ud9dzKoqiCEDcsGGD8b1erxfDw8PF999/37isoKBAlMvl4po1ayzmY+/fvSvceKzmHD58WAQgpqWlWUxj79+CK5g71qlTp4rjx4+3Kx93OK+iaNu5HT9+vDhixIg607jDuXWkZlszotVqcfToUYwaNcq4TCKRYNSoUThw4IDZbQ4cOGCSHgBGjx5tMX1TplarAQBBQUF1pisuLkabNm0QHR2N8ePH4+TJk41RvAZLTk5GZGQk2rZti8mTJyM9Pd1i2uZyXrVaLVatWoVp06bVecNIdz2nN0pNTUVmZqbJufP390dCQoLFc1efv/umSq1WQxAEBAQE1JnOnr+FpmTPnj0ICwtDx44d8dRTTyEvL89i2uZ0XrOysrB582Y8+uijVtO667mtj2YbjOTm5kKn00GlUpksV6lUyMzMNLtNZmamXembKr1ejxkzZmDw4MHo1q2bxXQdO3bEsmXL8OOPP2LVqlXQ6/UYNGgQLl++3IiltV9CQgJWrFiBrVu34rPPPkNqaipuuukmFBUVmU3fXM7rxo0bUVBQgIcffthiGnc9p+ZUnx97zl19/u6borKyMsyaNQuTJk2q8yZq9v4tNBVjxozBypUrsWvXLrz77rv47bffcNttt0Gn05lN31zOKwD897//ha+vL+65554607nrua0vt7hrL9ln+vTpOHHihNX2xYEDB2LgwIHG94MGDULnzp3xxRdf4K233nJ2MevttttuM77u0aMHEhIS0KZNG6xbt86mXxvu6uuvv8Ztt92GyMhIi2nc9ZzSdRUVFZgwYQJEUcRnn31WZ1p3/Vu4//77ja+7d++OHj16IC4uDnv27MHIkSNdWDLnW7ZsGSZPnmy1Y7m7ntv6arY1IyEhIZBKpcjKyjJZnpWVhfDwcLPbhIeH25W+KXrmmWfw888/Y/fu3WjVqpVd28pkMvTu3Rvnz593UumcIyAgAB06dLBY7uZwXtPS0rBz50489thjdm3nrucUgPH82HPu6vN335RUByJpaWnYsWOH3beWt/a30FS1bdsWISEhFsvt7ue12t69e3H27Fm7/44B9z23tmq2wYinpyf69u2LXbt2GZfp9Xrs2rXL5JdjTQMHDjRJDwA7duywmL4pEUURzzzzDDZs2IBff/0VsbGxdueh0+lw/PhxREREOKGEzlNcXIyUlBSL5Xbn81pt+fLlCAsLw+23327Xdu56TgEgNjYW4eHhJueusLAQhw4dsnju6vN331RUByLJycnYuXMngoOD7c7D2t9CU3X58mXk5eVZLLc7n9eavv76a/Tt2xc9e/a0e1t3Pbc2c3UPWmf69ttvRblcLq5YsUI8deqU+M9//lMMCAgQMzMzRVEUxYceekicPXu2Mf2+fftEDw8P8YMPPhBPnz4tzps3T5TJZOLx48dddQg2e+qpp0R/f39xz549YkZGhvGh0WiMaW483jfeeEPctm2bmJKSIh49elS8//77RYVCIZ48edIVh2CzF198UdyzZ4+Ympoq7tu3Txw1apQYEhIiZmdni6LYvM6rKBpGDbRu3VqcNWtWrXXufk6LiorEY8eOiceOHRMBiIsXLxaPHTtmHEGycOFCMSAgQPzxxx/Fv//+Wxw/frwYGxsrlpaWGvMYMWKE+PHHHxvfW/u7d5W6jlWr1Yp33nmn2KpVKzEpKcnkb7i8vNyYx43Hau1vwVXqOtaioiLxpZdeEg8cOCCmpqaKO3fuFPv06SO2b99eLCsrM+bhLudVFK1/j0VRFNVqtahUKsXPPvvMbB7ucm6dpVkHI6Ioih9//LHYunVr0dPTU4yPjxcPHjxoXDd06FBx6tSpJunXrVsndujQQfT09BS7du0qbt68uZFLXD8AzD6WL19uTHPj8c6YMcP42ahUKnHs2LFiYmJi4xfeThMnThQjIiJET09PMSoqSpw4caJ4/vx54/rmdF5FURS3bdsmAhDPnj1ba527n9Pdu3eb/d5WH5Nerxdff/11UaVSiXK5XBw5cmStz6FNmzbivHnzTJbV9XfvKnUda2pqqsW/4d27dxvzuPFYrf0tuEpdx6rRaMRbb71VDA0NFWUymdimTRvx8ccfrxVUuMt5FUXr32NRFMUvvvhC9PLyEgsKCszm4S7n1lkEURRFp1a9EBEREdWh2fYZISIiIvfAYISIiIhcisEIERERuRSDESIiInIpBiNERETkUgxGiIiIyKUYjBAREZFLMRghIiIil2IwQkRuZ8+ePRAEAQUFBa4uChE5AIMRIiIicikGI0RERORSDEaIyG56vR4LFixAbGwsvLy80LNnT3z33XcArjehbN68GT169IBCocCAAQNw4sQJkzy+//57dO3aFXK5HDExMVi0aJHJ+vLycsyaNQvR0dGQy+Vo164dvv76a5M0R48eRb9+/aBUKjFo0CCcPXvWuQdORE7BYISI7LZgwQKsXLkSn3/+OU6ePIkXXngBDz74IH777TdjmpdffhmLFi3CkSNHEBoainHjxqGiogKAIYiYMGEC7r//fhw/fhzz58/H66+/jhUrVhi3nzJlCtasWYOPPvoIp0+fxhdffAEfHx+Tcrz66qtYtGgR/vzzT3h4eGDatGmNcvxE5GCuvm0wEbmXsrIyUalUivv37zdZ/uijj4qTJk0y3k7922+/Na7Ly8sTvby8xLVr14qiKIoPPPCAeMstt5hs//LLL4tdunQRRVEUz549KwIQd+zYYbYM1fvYuXOncdnmzZtFAGJpaalDjpOIGg9rRojILufPn4dGo8Ett9wCHx8f42PlypVISUkxphs4cKDxdVBQEDp27IjTp08DAE6fPo3Bgweb5Dt48GAkJydDp9MhKSkJUqkUQ4cOrbMsPXr0ML6OiIgAAGRnZzf4GImocXm4ugBE5F6Ki4sBAJs3b0ZUVJTJOrlcbhKQ1JeXl5dN6WQymfG1IAgADP1ZiMi9sGaEiOzSpUsXyOVypKeno127diaP6OhoY7qDBw8aX1+7dg3nzp1D586dAQCdO3fGvn37TPLdt28fOnToAKlUiu7du0Ov15v0QSGi5os1I0RkF19fX7z00kt44YUXoNfrMWTIEKjVauzbtw9+fn5o06YNAODNN99EcHAwVCoVXn31VYSEhOCuu+4CALz44ovo378/3nrrLUycOBEHDhzA0qVL8emnnwIAYmJiMHXqVEybNg0fffQRevbsibS0NGRnZ2PChAmuOnQichIGI0Rkt7feeguhoaFYsGABLly4gICAAPTp0wevvPKKsZlk4cKFeP7555GcnIxevXrhp59+gqenJwCgT58+WLduHebOnYu33noLERERePPNN/Hwww8b9/HZZ5/hlVdewdNPP428vDy0bt0ar7zyiisOl4icTBBFUXR1IYio+dizZw+GDx+Oa9euISAgwNXFISI3wD4jRERE5FIMRoiIiMil2ExDRERELsWaESIiInIpBiNERETkUgxGiIiIyKUYjBAREZFLMRghIiIil2IwQkRERC7FYISIiIhcisEIERERudT/A2zc2X0e5NCpAAAAAElFTkSuQmCC\n" + "image/png": "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fHmuTVdzOl+ea9PVHM63vhqRauzASkRERDbFYISIiIhsqlkHI1KpFIsXL242KwQ3p/PluTZdzel8ea5NV3M7X33sogMrERERNV3NumaEiIiIbI/BCBEREdkUgxEiIiKyKQYjREREZFNNPhj59NNPERoaCplMhr59+yI2Nrbe9N9//z3uueceyGQydOnSBbt27bJSSRtm+fLl6NOnD9zc3ODv74+xY8ciISGh3n02btwIkUikc5PJZFYqsemWLFlyV7nvueeeevex1/c1NDT0rnMViUSYMWNGrent7T3966+/MHr0aAQFBUEkEmHHjh06zwuCgEWLFiEwMBDOzs6IiorC5cuX9eZr7OfeGuo714qKCsydOxddunSBi4sLgoKCMGnSJNy8ebPePE35LFiDvvf1mWeeuavcDzzwgN58G+P7Cug/39o+wyKRCO+//36deTbW99ZSmnQwsn37dsyePRuLFy9GXFwcunXrhhEjRiAzM7PW9IcPH8aECRPw7LPP4tSpUxg7dizGjh2Ls2fPWrnkxvvzzz8xY8YMHD16FHv37kVFRQWGDx+O4uLievdzd3dHWlqa9nb9+nUrlbhhOnXqpFPugwcP1pnWnt/X48eP65zn3r17AQCPP/54nfvY03taXFyMbt264dNPP631+ffeew8fffQR1q1bh2PHjsHFxQUjRoxAaWlpnXka+7m3lvrOValUIi4uDgsXLkRcXBx++uknJCQk4OGHH9abrzGfBWvR974CwAMPPKBT7q1bt9abZ2N9XwH951vzPNPS0rBhwwaIRCI89thj9ebbGN9bixGasIiICGHGjBnav1UqlRAUFCQsX7681vRPPPGE8NBDD+ls69u3r/D8889btJyWkJmZKQAQ/vzzzzrTfPXVV4KHh4f1CmUmixcvFrp162Zw+qb0vr766qtCWFiYoFara33eXt9TQRAEAMLPP/+s/VutVgsBAQHC+++/r92Wl5cnSKVSYevWrXXmY+zn3hbuPNfaxMbGCgCE69ev15nG2M+CLdR2rpMnTxbGjBljVD728L4KgmHv7ZgxY4QhQ4bUm8Ye3ltzarI1I+Xl5Th58iSioqK028RiMaKionDkyJFa9zly5IhOegAYMWJEnekbs/z8fACAt7d3vemKiorQqlUrhISEYMyYMTh37pw1itdgly9fRlBQENq0aYOJEyciOTm5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\n" }, "metadata": {} } @@ -26594,7 +26600,7 @@ "tmp = pd.DataFrame(my_history.history)\n", "tmp.plot(xlabel='epoch', style='o-')" ], - "id": "03741cfa-3026-4053-9bb6-32a3a7648366" + "id": "a904fda7-b9a5-4979-bdf4-190dd7957838" }, { "cell_type": "code", @@ -26603,8 +26609,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "fd9f1377-8716-4e20-a65b-e5a304daa20a", - "outputId": "de07fe64-bd52-48a8-ee24-6ff52b162191" + "id": "13b4dbba-81f9-480a-9ac1-652f548a6578", + "outputId": "f5c3e3e1-80b9-4969-c6a6-08a8703eaa9d" }, "outputs": [ { @@ -26626,16 +26632,16 @@ "output_type": "execute_result", "data": { "text/plain": [ - "array([[ 958, 0, 3, 3, 1, 3, 9, 2, 1, 0],\n", - " [ 0, 1117, 3, 2, 1, 1, 7, 1, 3, 0],\n", - " [ 5, 3, 975, 7, 8, 2, 11, 9, 11, 1],\n", - " [ 0, 1, 14, 953, 2, 17, 2, 9, 11, 1],\n", - " [ 1, 0, 3, 4, 937, 1, 17, 0, 2, 17],\n", - " [ 10, 0, 0, 25, 5, 821, 11, 4, 11, 5],\n", - " [ 10, 3, 6, 1, 17, 7, 909, 3, 2, 0],\n", - " [ 3, 11, 19, 8, 8, 1, 0, 966, 2, 10],\n", - " [ 5, 2, 5, 12, 10, 7, 8, 6, 917, 2],\n", - " [ 9, 7, 2, 13, 34, 6, 1, 25, 6, 906]])" + "array([[ 964, 0, 1, 3, 0, 3, 6, 1, 2, 0],\n", + " [ 0, 1118, 3, 2, 0, 0, 3, 2, 7, 0],\n", + " [ 6, 1, 957, 15, 11, 1, 14, 7, 18, 2],\n", + " [ 2, 2, 10, 959, 0, 7, 3, 9, 13, 5],\n", + " [ 4, 1, 5, 0, 909, 1, 14, 2, 5, 41],\n", + " [ 12, 3, 2, 38, 4, 789, 12, 3, 24, 5],\n", + " [ 11, 3, 1, 1, 10, 13, 912, 2, 5, 0],\n", + " [ 3, 7, 27, 6, 7, 1, 2, 959, 3, 13],\n", + " [ 5, 3, 9, 24, 10, 8, 9, 9, 892, 5],\n", + " [ 13, 6, 1, 11, 18, 5, 0, 13, 6, 936]])" ] }, "metadata": {}, @@ -26648,7 +26654,7 @@ "confusion_matrix(y_true=y_test,\n", " y_pred=y_)" ], - "id": "fd9f1377-8716-4e20-a65b-e5a304daa20a" + "id": "13b4dbba-81f9-480a-9ac1-652f548a6578" }, { "cell_type": "code", @@ -26657,8 +26663,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "450ad061-66c7-4150-a386-8bdd76f6fd38", - "outputId": "93717184-f91a-4127-aa02-51c6556370a4" + "id": "15ba914e-35d2-46b1-b671-9906e9a4c6d0", + "outputId": "764fa770-adf5-4571-8a93-3bdb9d94ea7e" }, "outputs": [ { @@ -26671,7 +26677,7 @@ } ], "source": [], - "id": "450ad061-66c7-4150-a386-8bdd76f6fd38" + "id": "15ba914e-35d2-46b1-b671-9906e9a4c6d0" }, { "cell_type": "code", @@ -26680,15 +26686,15 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "09851a5b-7254-4fdf-b813-23947fe80ee6", - "outputId": "64f02990-2a01-44cf-bf90-ece9666027f1" + "id": "47a54946-f9be-4af0-a53c-56c028101e4f", + "outputId": "47774c68-7c1a-4c01-f6b4-304ac4543d32" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ - "0.9459" + "0.9395" ] }, "metadata": {}, @@ -26698,7 +26704,7 @@ "source": [ "(y_ == y_test).mean()" ], - "id": "09851a5b-7254-4fdf-b813-23947fe80ee6" + "id": "47a54946-f9be-4af0-a53c-56c028101e4f" }, { "cell_type": "code", @@ -26707,22 +26713,22 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "c224b67f-6794-4cf4-96c9-eff83b6b72fb", - "outputId": "75523e2b-7583-4aba-8f41-b3bf5bc73d4e" + "id": "3a9b64e0-9787-4ff5-b161-79204f67bf99", + "outputId": "26fdb4d9-6b2c-4c19-bdb4-b56e784c4661" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ - "313/313 [==============================] - 1s 2ms/step - loss: 0.2031 - accuracy: 0.9459\n" + "313/313 [==============================] - 1s 2ms/step - loss: 0.2198 - accuracy: 0.9395\n" ] }, { "output_type": "execute_result", "data": { "text/plain": [ - "[0.20314112305641174, 0.945900022983551]" + "[0.21984204649925232, 0.9394999742507935]" ] }, "metadata": {}, @@ -26732,20 +26738,20 @@ "source": [ "my_model.evaluate(x=x_test, y=y_test)" ], - "id": "c224b67f-6794-4cf4-96c9-eff83b6b72fb" + "id": "3a9b64e0-9787-4ff5-b161-79204f67bf99" }, { "cell_type": "code", "execution_count": 354, "metadata": { - "id": "5ed03e84-18f2-49aa-ab2d-5d9e5189e09a" + "id": "080e5ece-a69f-415a-97df-763875b8247a" }, "outputs": [], "source": [ "x_train2d = x_train.reshape(-1, 28, 28, 1)\n", "x_test2d = x_test.reshape(-1, 28, 28, 1)" ], - "id": "5ed03e84-18f2-49aa-ab2d-5d9e5189e09a" + "id": "080e5ece-a69f-415a-97df-763875b8247a" }, { "cell_type": "code", @@ -26754,8 +26760,8 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "1b027a5d-d9e6-4907-b6df-e477bd10c2ea", - "outputId": "91e22c26-c532-4d63-b140-c2c7d429345e" + "id": "351aa245-5b79-49f4-81ba-8268cd5250c4", + "outputId": "b1fea5c6-c957-4a26-e500-49b280878b1b" }, "outputs": [ { @@ -26805,7 +26811,7 @@ "my_cb = EarlyStopping(patience=5,\n", " restore_best_weights=True)" ], - "id": "1b027a5d-d9e6-4907-b6df-e477bd10c2ea" + "id": "351aa245-5b79-49f4-81ba-8268cd5250c4" }, { "cell_type": "code", @@ -26813,10 +26819,10 @@ "metadata": { "colab": { "base_uri": "https://localhost:8080/", - "height": 466 + "height": 467 }, - "id": "6037ed8f-bcfb-4c58-a7e5-bd2424e7a0d9", - "outputId": "94008605-f732-4554-9aac-80e7b5b57063" + "id": "bea240d5-aa81-4c45-94db-7f427000714a", + "outputId": "ae39330d-1518-4a64-f753-df4d3a5a7419" }, "outputs": [ { @@ -26835,7 +26841,7 @@ "text/plain": [ "
" ], - "image/png": "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A1i+fDkbNmzgvffeIy4ujiuuuIKsrKwK0zeWz3XNmjWkp6czderUStM01M+0IqWfjzOfXXW+9/VRfn4+s2fPZsKECVUuoubsd6G+GDVqFCtXrmTz5s0sXLiQX375heuuuw6TyVRh+sbyuQKsWLECX19fbrnllirTNdTPtroaxKq9wjkzZsxg3759dtsXBw4cyMCBA63PBw0aROfOnXn//fd58cUX3V3Marvuuuusj3v06MGAAQNo2bIlX375pUO/NhqqDz/8kOuuu45mzZpVmqahfqaiTFFREbfffjuqqvLee+9VmbahfhfGjx9vfdy9e3d69OhB27Zt2bJlC8OGDavDkrnfsmXLmDRpkt2O5Q31s62uRlszEhISglarJTEx0WZ7YmIiERERFR4TERHhVPr66MEHH+T777/n559/pnnz5k4dq9fr6d27N8eOHXNT6dwjICCADh06VFruxvC5njp1ik2bNjF9+nSnjmuonylg/Xyc+eyq872vT0oDkVOnTvHjjz86vbS8ve9CfdWmTRtCQkIqLXdD/1xL/fbbbxw+fNjp7zE03M/WUY02GPHw8KBv375s3rzZus1sNrN582abX44XGzhwoE16gB9//LHS9PWJqqo8+OCDrF69mp9++onWrVs7nYfJZOLvv/8mMjLSDSV0n+zsbI4fP15puRvy51rqo48+IiwsjOuvv96p4xrqZwrQunVrIiIibD67zMxMduzYUelnV53vfX1RGogcPXqUTZs2ERwc7HQe9r4L9dXZs2dJSUmptNwN+XO92Icffkjfvn3p2bOn08c21M/WYXXdg9advvjiC9VgMKjLly9XDxw4oP7jH/9QAwIC1ISEBFVVVfXOO+9Un3rqKWv6rVu3qjqdTn3ttdfUgwcPqvPmzVP1er36999/19UpOOz+++9X/f391S1btqjx8fHWW25urjXNpef7wgsvqD/88IN6/Phxdffu3er48eNVo9Go7t+/vy5OwWGPPfaYumXLFjUuLk7dunWrOnz4cDUkJERNSkpSVbVxfa6qahk10KJFC3X27Nnl9jX0zzQrK0v966+/1L/++ksF1EWLFql//fWXdQTJggUL1ICAAPXbb79V9+7dq44dO1Zt3bq1mpeXZ81j6NCh6ltvvWV9bu97X1eqOtfCwkL1xhtvVJs3b67GxsbafIcLCgqseVx6rva+C3WlqnPNyspSH3/8cXX79u1qXFycumnTJrVPnz5q+/bt1fz8fGseDeVzVVX7f8eqqqoZGRmql5eX+t5771WYR0P5bN2lUQcjqqqqb731ltqiRQvVw8ND7d+/v/rHH39Y91111VXqlClTbNJ/+eWXaocOHVQPDw+1a9eu6rp162q5xNUDVHj76KOPrGkuPd+ZM2da35vw8HB19OjRakxMTO0X3knjxo1TIyMjVQ8PDzUqKkodN26ceuzYMev+xvS5qqqq/vDDDyqgHj58uNy+hv6Z/vzzzxX+3Zaek9lsVp977jk1PDxcNRgM6rBhw8q9Dy1btlTnzZtns62q731dqepc4+LiKv0O//zzz9Y8Lj1Xe9+FulLVuebm5qojRoxQQ0NDVb1er7Zs2VK95557ygUVDeVzVVX7f8eqqqrvv/++6unpqaanp1eYR0P5bN1FUVVVdWvVixBCCCFEFRptnxEhhBBCNAwSjAghhBCiTkkwIoQQQog6JcGIEEIIIeqUBCNCCCGEqFMSjAghhBCiTkkwIoQQQog6JcGIEEIIIeqUBCNCiAZny5YtKIpCenp6XRdFCOECEowIIYQQok5JMCKEEEKIOiXBiBDCaWazmfnz59O6dWs8PT3p2bMnX331FVDWhLJu3Tp69OiB0Wjk8ssvZ9++fTZ5fP3113Tt2hWDwUCrVq14/fXXbfYXFBQwe/ZsoqOjMRgMtGvXjg8//NAmze7du7nsssvw8vJi0KBBHD582L0nLoRwCwlGhBBOmz9/PitXrmTJkiXs37+fRx99lDvuuINffvnFmuaJJ57g9ddfZ9euXYSGhjJmzBiKiooASxBx++23M378eP7++2+ef/55nnvuOZYvX249fvLkyXz++ee8+eabHDx4kPfffx8fHx+bcjzzzDO8/vrr/Pnnn+h0OqZNm1Yr5y+EcLG6XjZYCNGw5Ofnq15eXuq2bdtstt99993qhAkTrMupf/HFF9Z9KSkpqqenp7pq1SpVVVV14sSJ6rXXXmtz/BNPPKF26dJFVVVVPXz4sAqoP/74Y4VlKH2NTZs2WbetW7dOBdS8vDyXnKcQovZIzYgQwinHjh0jNzeXa6+9Fh8fH+tt5cqVHD9+3Jpu4MCB1sdBQUF07NiRgwcPAnDw4EEGDx5sk+/gwYM5evQoJpOJ2NhYtFotV111VZVl6dGjh/VxZGQkAElJSTU+RyFE7dLVdQGEEA1LdnY2AOvWrSMqKspmn8FgsAlIqsvT09OhdHq93vpYURTA0p9FCNGwSM2IEMIpXbp0wWAwcPr0adq1a2dzi46Otqb7448/rI/T0tI4cuQInTt3BqBz585s3brVJt+tW7fSoUMHtFot3bt3x2w22/RBEUI0XlIzIoRwiq+vL48//jiPPvooZrOZIUOGkJGRwdatW/Hz86Nly5YA/POf/yQ4OJjw8HCeeeYZQkJCuOmmmwB47LHH6NevHy+++CLjxo1j+/btvP3227z77rsAtGrViilTpjBt2jTefPNNevbsyalTp0hKSuL222+vq1MXQriJBCNCCKe9+OKLhIaGMn/+fE6cOEFAQAB9+vTh6aeftjaTLFiwgEceeYSjR4/Sq1cvvvvuOzw8PADo06cPX375JXPnzuXFF18kMjKSf/7zn0ydOtX6Gu+99x5PP/00DzzwACkpKbRo0YKnn366Lk5XCOFmiqqqal0XQgjReGzZsoVrrrmGtLQ0AgIC6ro4QogGQPqMCCGEEKJOSTAihBBCiDolzTRCCCGEqFNSMyKEEEKIOiXBiBBCCCHqlAQjQgghhKhTEowIIYQQok5JMCKEEEKIOiXBiBBCCCHqlAQjQgghhKhTEowIIYQQok79PzeSf9tBm18eAAAAAElFTkSuQmCC\n" + "image/png": "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\n" }, "metadata": {} } @@ -26853,7 +26859,7 @@ "tmp = pd.DataFrame(my_history.history)\n", "tmp.plot(xlabel='epoch', style='o-')" ], - "id": "6037ed8f-bcfb-4c58-a7e5-bd2424e7a0d9" + "id": "bea240d5-aa81-4c45-94db-7f427000714a" }, { "cell_type": "code", @@ -26862,10 +26868,17 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "22726e92-a797-44c8-adb2-f44296e9b0be", - "outputId": "058314e4-fa1a-4054-e657-3bfa2f6f1106" + "id": "6f8ece04-ae5b-447c-9789-93e3f2f1e7f6", + "outputId": "3181899c-6ce1-41c4-ee72-33f0aba8e067" }, "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\r 1/313 [..............................] - ETA: 7s - loss: 0.0300 - accuracy: 1.0000" + ] + }, { "output_type": "stream", "name": "stderr", @@ -26878,14 +26891,14 @@ "output_type": "stream", "name": "stdout", "text": [ - "313/313 [==============================] - 2s 7ms/step - loss: 0.1357 - accuracy: 0.9647\n" + "313/313 [==============================] - 2s 6ms/step - loss: 0.1325 - accuracy: 0.9600\n" ] }, { "output_type": "execute_result", "data": { "text/plain": [ - "[0.1356654167175293, 0.9646999835968018]" + "[0.13254806399345398, 0.9599999785423279]" ] }, "metadata": {}, @@ -26895,13 +26908,13 @@ "source": [ "my_model.evaluate(x=x_test2d, y=y_test)" ], - "id": "22726e92-a797-44c8-adb2-f44296e9b0be" + "id": "6f8ece04-ae5b-447c-9789-93e3f2f1e7f6" }, { "cell_type": "code", "execution_count": 358, "metadata": { - "id": "7abaa3cf-26cd-4a60-a7e2-4e06e2a9f118" + "id": "82ec40ca-907c-4de7-837b-8ae067116d45" }, "outputs": [], "source": [ @@ -26924,7 +26937,7 @@ "my_cb = callbacks.EarlyStopping(patience=5,\n", " restore_best_weights=True)" ], - "id": "7abaa3cf-26cd-4a60-a7e2-4e06e2a9f118" + "id": "82ec40ca-907c-4de7-837b-8ae067116d45" }, { "cell_type": "code", @@ -26932,10 +26945,10 @@ "metadata": { "colab": { "base_uri": "https://localhost:8080/", - "height": 466 + "height": 468 }, - "id": "f2d7a1c4-66c3-482e-93a9-aa8a7b0058e9", - "outputId": "7ee4c281-e9a3-4286-ed67-9751d5114433" + "id": "87c5f0d5-2f6c-42d1-ad22-ddfe3cd577eb", + "outputId": "0f5d733d-66a8-43e3-8e0b-ced1922f9054" }, "outputs": [ { @@ -26954,7 +26967,7 @@ "text/plain": [ "
" ], - "image/png": "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/MGIESMICwvDaDQyYMAAfv/99waLrSmoUzPNG2+8wcsvv0xGRgZ9+vTh9ddfZ/Dgmjt+nj59mscff5wvv/ySkydP0qZNG+bNm8dll11W58DrbPdS+OxWOPsPxVLo2H79Qo+baxRFIS7cwOGcQtJzi2jd0vWy0kII0VQUWYsY8smQBjteZmEmwxa7ronedNMmggPc+//pddddx/3338+aNWu4+OKLATh58iQrVqxg+fLl5Ofnc9lll/H888+j1+tZuHAhY8eOZd++fbRu3bpe76egoIBRo0YxdOhQtmzZQlZWFnfddReTJ09mwYIFWK1Wxo0bx913382nn35KaWkpmzdvRimbRmLChAn069ePt956C61WS3JyMgEBzWtpEY+TkSVLljBlyhTefvtthgwZwrx58xg1ahT79u0jJiamSvnS0lIuueQSYmJi+OKLL0hISCA1NZWIiIiGiN8zdhusmEqVRKSiFdOg6+Wg0Xp0aJPRkYzIXCNCCOF7LVq0YMyYMXzyySfOZOSLL74gKiqKESNGoNFo6NOnj7P8s88+y1dffcXSpUuZPHlyvc79ySefUFxczMKFCwkJCQFg/vz5jB07lhdffJGAgAByc3O54oor6NChAwDdunVz7p+WlsY///lPunbtCkCnTp3qFU9T5HEyMnfuXO6++25uv/12AN5++22WLVvGBx98wLRp06qU/+CDDzh58iTr1693Znpt27at9RwlJSWUlJxp7jCbzZ6GWb3U9WA+XksBFczHHOXaXejRoeNkeK8Q4hwVpAti002b3Cq7NXMr962+z2W5Ny9+kwGmAS7P64kJEyZw99138+abb6LX6/n444+58cYb0Wg05Ofn89RTT7Fs2TLS09OxWq0UFRWRlpbm0Tmqs2fPHvr06eNMRADOP/987HY7+/bt429/+xu33XYbo0aN4pJLLiEpKYnrr7+euLg4AKZMmcJdd93Ff//7X5KSkrjuuuucSUtz4VGfkdLSUrZu3UpS0pme0BqNhqSkJDZs2FDtPkuXLmXo0KFMmjQJk8lEz549mTVrFjZbzR09Z8+eTXh4uPOWmJjoSZg1y890XcaTchWYZHivEOIcpSgKwQHBbt2GxQ/DFGxCofqZrBUUYoNjGRY/zOWxFA9nwx47diyqqrJs2TKOHDnCr7/+yoQJEwB49NFH+eqrr5g1axa//vorycnJ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4ALS09PZu3evRzEUFhby4osv8p///IeWLVsSExPDoUOHmDhxIq+//jqqqjJnzhwuu+wy9u/fT1hYGHa7nTFjxpCXl8eiRYvo0KEDu3fvRqvVEhISwo033siHH37I//3f/znPU/7cm7PSSjLSwEzSTCOEED7XokULxowZwyeffOJMRr744guioqIYMWIEGo2GPn3OrBr27LPP8tVXX7F06dIa11qrzUMPPeR83LZtW5577jn+8Y9/OJORl156iYEDBzqfA/To0QOAvLw8Xn31VebPn8/EiRMB6NChAxdccIFHMVgsFt58881K72vkyJGVyrz77rtERETw888/c8UVV7Bq1So2b97Mnj176Ny5MwDt27d3lr/rrrsYNmwY6enpxMXFkZWVxfLly+tVi+QOSUYaWHnNSEZukZ8jEUKIhqEEBdFl21a3yhb+/jtH/l79ircVJb77DsEDB7o8rycmTJjA3XffzZtvvoler+fjjz/mxhtvRKPRkJ+fz1NPPcWyZctIT0/HarVSVFREWlqaR+cot2rVKmbPns3evXsxm81YrVaKi4spLCwkODiY5ORkrrvuumr33bNnDyUlJc6kqa4CAwPp3bt3pW2ZmZk88cQTrF27lqysLGw2G4WFhc73mZycTKtWrZyJyNkGDx5Mjx49+Oijj5g2bRqLFi2iTZs2/O1vf6tXrK5In5EGZipPRswlfo5ECCEahqIoaIKD3bqFnH8+uthYUJSaDoYuNpaQ8893eSylpmPUYOzYsaiqyrJlyzhy5Ai//vorEyZMAODRRx/lq6++YtasWfz6668kJyfTq1cvSktLPf48Dh8+zBVXXEHv3r353//+x9atW3njjTcAnMcLqiWRqu01cDQBAZX6zFgslmqPc/ZnNHHiRJKTk3n11VdZv349ycnJtGzZ0q24yt11110sWLAAcDTR3H777R5/F56SZKSBSc2IEKI5U7RaTI9NL3ty1gWs7LnpsekoWm2Dn9tgMHDNNdfw8ccf8+mnn9KlSxf69+8PODqT3nbbbVx99dX06tWL2NhYZ2dQT23duhW73c6cOXM477zz6Ny5M8ePH69Upnfv3qxevbra/Tt16kRQUFCNr0dHRwOQnp7u3JacnOxWbOvWreOBBx7gsssuo0ePHuj1erKzsyvFdfToUf76668aj3HzzTeTmprKa6+9xu7du51NSd4k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YebMmWzbto0+ffowatQosrKyqi2/fv16xo8fz5133sn27dsZN24c48aNY+fOnT6O3HM///wzkyZNYuPGjaxcuRKLxcKll15KQUFBrfsZjUbS09Odt9TUVB9FXD89evSoFPdvv/1WY9mm/L1u2bKl0vtcuXIlANddd12N+zSl77SgoIA+ffrwxhtvVPv6Sy+9xGuvvcbbb7/Npk2bCAkJYdSoURQXF9d4TE//7n2ltvdaWFjItm3bePLJJ9m2bRtffvkl+/bt48orr3R5XE/+FnzF1fcKMHr06Epxf/rpp7Ues7F+r+D6/VZ8n+np6XzwwQcoisK1115b63Eb43frNZ4ulNeUDB48WJ00aZLzuc1mU+Pj49XZs2dXW/76669XL7/88krbhgwZot5zzz1ejdMbsrKyVED9+eefayzz4YcfquHh4b4LqoHMnDlT7dOnj9vlz6Xv9cEHH1Q7dOig2u32al9vqt+pqqoqoH711VfO53a7XY2NjVVffvll57bTp0+rer1e/fTTT2s8jqd/9/5w9nutzubNm1VATU1NrbGMp38L/lDde504caJ61VVXeXScpvC9qqp73+1VV12ljhw5stYyTeG7bUjnbM1IaWkpW7duJSkpyblNo9GQlJTEhg0bqt1nw4YNlcoDjBo1qsbyjVlubi4AkZGRtZbLz8+nTZs2JCYmctVVV7Fr1y5fhFdv+/fvJz4+nvbt2zNhwgTS0tJqLHuufK+lpaUsWrSIO+64o9YFI5vqd3q2lJQUMjIyKn134eHhDBkypMbvri5/941Vbm4uiqIQERFRazlP/hYak7Vr1xITE0OXLl249957ycnJqbHsufS9ZmZmsmzZMu68806XZZvqd1sX52wykp2djc1mc64mXM5kMpGRkVHtPhkZGR6Vb6zsdjsPPfQQ559/fq2rI3fp0oUPPviAb775hkWLFmG32xk2bBhHjx71YbSeGzJkCAsWLGDFihW89dZbpKSkcOGFF5KXl1dt+XPle/366685ffo0t912W41lmup3Wp3y78eT764uf/eNUXFxMVOnTmX8+PG1LqLm6d9CYzF69GgWLlzI6tWrefHFF/n5558ZM2YMNput2vLnyvcK8NFHHxEWFsY111xTa7mm+t3Wlc7fAYiGN2nSJHbu3OmyfXHo0KEMHTrU+XzYsGF069aNd955h2effdbbYdbZ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\n" + "image/png": "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jet7VVXHqIFWrVqp06dPv+C9hv6d5ubmqr/++qv666+/qoA6f/589ddff3WOIJk7d64aGRmpfv311+rvv/+ujhkzRm3btq1aWFjozGPYsGHqv//9b+drdz/3daW6ay0pKVGvv/56tWXLlmpycnKln+Hi4mJnHudfq7ufhbpS3bXm5uaqjzzyiLpx40Y1JSVFXbVqldq3b1+1Y8eOalFRkTOPhvK9qqr7/8eqqqo5OTlqSEiI+vrrr7vMo6F8t/7SqIMRVVXVf//732qrVq3UoKAgdeDAgeqmTZuc71122WXqhAkTKqX/9NNP1U6dOqlBQUFqt27d1GXLlgW4xDUDuNwWLVrkTHP+9U6dOtX52ZjNZvWaa65Rd+zYEfjCe+mWW25R4+Pj1aCgILVFixbqLbfcoh48eND5fmP6XlVVVb///nsVUPfv33/Bew39O12zZo3L/7fl12S329UnnnhCNZvNqsFgUIcPH37B59C6dWt19uzZlfZV93NfV6q71pSUlCp/htesWePM4/xrdfezUFequ9aCggL1qquuUps3b67q9Xq1devW6n333XdBUNFQvldVdf//WFVV9T//+Y8aHBysZmdnu8yjoXy3/qKoqqr6tepFCCGEEKIajbbPiBBCCCEaBglGhBBCCFGnJBgRQgghRJ2SYEQIIYQQdUqCESGEEELUKQlGhBBCCFGnJBgRQgghRJ2SYEQIIYQQdUqCESFEg7N27VoURSE7O7uuiyKE8AEJRoQQQghRpyQYEUIIIUSdkmBECOE1u93OnDlzaNu2LcHBwfTq1YvPP/8cONeEsmzZMnr27InRaOTiiy9m165dlfL43//+R7du3TAYDLRp04Z58+ZVer+4uJjp06eTmJiIwWCgQ4cOvP3225XSbN++nf79+xMSEsLgwYPZv3+/fy9cCOEXEowIIbw2Z84clixZwhtvvMHu3bt56KGHuP322/npp5+caR599FHmzZvH1q1bad68OaNHj6a0tBRwBBE333wzt956Kzt37uTJJ5/kiSeeYPHixc7j77zzTj766CNeeeUV9u7dy3/+8x/CwsIqleMf//gH8+bNY9u2beh0OiZOnBiQ6xdC+FhdLxsshGhYioqK1JCQEHXDhg2V9t9zzz3quHHjnMupf/zxx873Tp8+rQYHB6uffPKJqqqqetttt6lXXnllpeMfffRRtWvXrqqqqur+/ftVQP3hhx9clqH8HKtWrXLuW7ZsmQqohYWFPrlOIUTgSM2IEMIrBw8epKCggCuvvJKwsDDntmTJEg4dOuRMN2jQIOfzZs2a0blzZ/bu3QvA3r17GTJkSKV8hwwZwoEDB7DZbCQnJ6PVarnsssuqLUvPnj2dz+Pj4wHIysqq9TUKIQJLV9cFEEI0LHl5eQAsW7aMFi1aVHrPYDBUCkhqKjg42KN0er3e+VxRFMDRn0UI0bBIzYgQwitdu3bFYDCQlpZGhw4dKm2JiYnOdJs2bXI+P3v2LH/88QddunQBoEuXLqxfv75SvuvXr6dTp05otVp69OiB3W6v1AdFCNF4Sc2IEMIr4eHhPPLIIzz00EPY7XYuueQScnJyWL9+PSaTidatWwPw9NNPEx0djdls5h//+AcxMTGMHTsWgIcffpgBAwbwzDPPcMstt7Bx40YWLlzIa6+9BkCbNm2YMGECEydO5JVXXqFXr16kpqaSlZXFzTffXFeXLoTwEwlGhBBee+aZZ2jevDlz5szh8OHDREZG0rdvXx577DFnM8ncuXOZMmUKBw4coHfv3nzzzTcEBQUB0LdvXz799FNmzZrFM888Q3x8PE8//TR33XWX8xyvv/46jz32GH/96185ffo0rVq14rHHHquLyxVC+Jmiqqpa14UQQjQea9eu5YorruDs2bNERkbWdXGEEA2A9BkRQgghRJ2SYEQIIYQQdUqaaYQQQghRp6RmRAghhBB1SoIRIYQQQtQpCUaEEEIIUackGBFCCCFEnZJgRAghhBB1SoIRIYQQQtQpCUaEEEIIUackGBFCCCFEnfp/IX3bIxbxqyEAAAAASUVORK5CYII=\n" }, "metadata": {} } @@ -26972,7 +26985,7 @@ "tmp = pd.DataFrame(my_history.history)\n", "tmp.plot(xlabel='epoch', style='o-')" ], - "id": "f2d7a1c4-66c3-482e-93a9-aa8a7b0058e9" + "id": "87c5f0d5-2f6c-42d1-ad22-ddfe3cd577eb" }, { "cell_type": "code", @@ -26981,15 +26994,15 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "edaaad87-73c8-4732-b0bc-cfa82646d6ba", - "outputId": "dc6e7d12-0109-4503-a886-0493acdb1f35" + "id": "56d6bb62-aa29-46c6-b1d0-f1bf547d97ba", + "outputId": "74255816-17e6-436f-cb9b-dbc556129c59" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ - "\r 1/313 [..............................] - ETA: 12s - loss: 0.0050 - accuracy: 1.0000" + " 9/313 [..............................] - ETA: 2s - loss: 0.0349 - accuracy: 0.9896 " ] }, { @@ -27004,14 +27017,14 @@ "output_type": "stream", "name": "stdout", "text": [ - "313/313 [==============================] - 3s 9ms/step - loss: 0.0596 - accuracy: 0.9805\n" + "313/313 [==============================] - 2s 7ms/step - loss: 0.0609 - accuracy: 0.9795\n" ] }, { "output_type": "execute_result", "data": { "text/plain": [ - "[0.05964328721165657, 0.9804999828338623]" + "[0.06093818321824074, 0.9794999957084656]" ] }, "metadata": {}, @@ -27021,7 +27034,7 @@ "source": [ "my_model.evaluate(x=x_test2d, y=y_test)" ], - "id": "edaaad87-73c8-4732-b0bc-cfa82646d6ba" + "id": "56d6bb62-aa29-46c6-b1d0-f1bf547d97ba" }, { "cell_type": "code", @@ -27030,15 +27043,15 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "642002f7-1fff-4b31-9957-9c127a66c297", - "outputId": "8792cd94-e0f0-4c8a-e8fd-887a37f46f34" + "id": "4ecd8d3b-3a79-4dee-8d01-65d857b55857", + "outputId": "7a8f6aef-a980-4fc1-929b-0c9514165ec9" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ - "313/313 [==============================] - 2s 6ms/step\n" + "313/313 [==============================] - 2s 7ms/step\n" ] } ], @@ -27054,7 +27067,7 @@ "tmp = tmp[tmp.y_ != tmp.y] # 予測がはずれたものを残す\n", "my_result = tmp.sort_values('y_prob', ascending=False) # 確率の大きい順に並び替える" ], - "id": "642002f7-1fff-4b31-9957-9c127a66c297" + "id": "4ecd8d3b-3a79-4dee-8d01-65d857b55857" }, { "cell_type": "code", @@ -27062,10 +27075,10 @@ "metadata": { "colab": { "base_uri": "https://localhost:8080/", - "height": 261 + "height": 262 }, - "id": "0760d31b-979f-491c-90f8-0449810cb96c", - "outputId": "07b7719d-5824-4dd0-ceda-8e0935018841" + "id": "4a0b47d8-0c33-437a-a217-ad2c1649d0bf", + "outputId": "b4de1810-ebb7-4d70-a5bb-1dd55a2f6bf0" }, "outputs": [ { @@ -27081,15 +27094,15 @@ "data": { "text/plain": [ " y_prob y_ y id\n", - "3767 1.00 2 7 3767\n", "3520 1.00 4 6 3520\n", - "3780 1.00 6 4 3780\n", - "321 1.00 7 2 321\n", - "2035 1.00 3 5 2035" + "9009 1.00 2 7 9009\n", + "6505 1.00 0 9 6505\n", + "1901 1.00 4 9 1901\n", + "3767 1.00 2 7 3767" ], "text/html": [ "\n", - "
\n", + "
\n", "
\n", " \n", "
\n", " \n", - " \n", + " \n", " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", " \n", - "\n", - "\n", - "\n", - "\n", + "\n", "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "
GLM Model: summaryStatus of Neuron Layers: predicting LPRICE2, regression, gaussian distribution, Quadratic loss, 541 weights/biases, 10.5 KB, 231 training samples, mini-batch size 1
familylinkregularizationlambda_searchnumber_of_predictors_totalnumber_of_active_predictorsnumber_of_iterationstraining_frame
layerunitstypedropoutl1l2mean_raterate_rmsmomentummean_weightweight_rmsmean_biasbias_rms
gaussianidentityRidge ( lambda = 0.01453 )nlambda = 30, lambda.max = 40.791, lambda.min = 0.01453, lambda.1se = 0.184414Input0.0
220RectifierDropout10.00.00.00.00926360.00494880.0-0.00943070.30434190.49168450.0222527
320RectifierDropout10.00.00.00.02074720.03739040.0-0.02519100.21841710.98637540.0217107
426AutoML_1_20240323_154436_training_wine.hex
1Linear0.00.00.00271770.00146950.00.01684520.3608547-0.00419810.0000000
\n", "
\n", "
\n", - "
ModelMetricsRegressionGLM: glm\n",
+              "
ModelMetricsRegression: deeplearning\n",
               "** Reported on train data. **\n",
               "\n",
-              "MSE: 0.06694572584805399\n",
-              "RMSE: 0.25873872119969593\n",
-              "MAE: 0.2235444233397049\n",
+              "MSE: 0.06512864718246027\n",
+              "RMSE: 0.2552031488490302\n",
+              "MAE: 0.212997766961256\n",
               "RMSLE: NaN\n",
-              "Mean Residual Deviance: 0.06694572584805399\n",
-              "R^2: 0.8273649567047465\n",
-              "Null degrees of freedom: 26\n",
-              "Residual degrees of freedom: 22\n",
-              "Null deviance: 10.47026468899523\n",
-              "Residual deviance: 1.8075345978974575\n",
-              "AIC: 15.61810844742614
\n", - "
ModelMetricsRegressionGLM: glm\n",
+              "Mean Residual Deviance: 0.06512864718246027
\n", + "
ModelMetricsRegression: deeplearning\n",
               "** Reported on cross-validation data. **\n",
               "\n",
-              "MSE: 0.09272963353958945\n",
-              "RMSE: 0.3045154077211684\n",
-              "MAE: 0.2704554570357195\n",
+              "MSE: 0.07882734293860551\n",
+              "RMSE: 0.28076207532109015\n",
+              "MAE: 0.23254450392017365\n",
               "RMSLE: NaN\n",
-              "Mean Residual Deviance: 0.09272963353958945\n",
-              "R^2: 0.7608751851134741\n",
-              "Null degrees of freedom: 26\n",
-              "Residual degrees of freedom: 22\n",
-              "Null deviance: 11.91964575278737\n",
-              "Residual deviance: 2.503700105568915\n",
-              "AIC: 24.414866768740747
\n", + "Mean Residual Deviance: 0.07882734293860551
\n", "
\n", " \n", "
\n", " \n", - " \n", - " \n", - "\n", - " \n", - "\n", + " \n", + " \n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "
Model Summary:
number_of_trees
66.0
Model Summary for Stacked Ensemble:
keyvalue
Stacking strategyblending
Number of base models (used / total)3/3
# GBM base models (used / total)1/1
# XGBoost base models (used / total)1/1
# GLM base models (used / total)1/1
Metalearner algorithmGLM
Metalearner fold assignment schemeAUTO
Metalearner nfolds0
Metalearner fold_columnNone
Custom metalearner hyperparametersNone
\n", "
\n", "
\n", - "
ModelMetricsMultinomial: xgboost\n",
+              "
ModelMetricsMultinomialGLM: stackedensemble\n",
               "** Reported on train data. **\n",
               "\n",
-              "MSE: 0.00749412479631111\n",
-              "RMSE: 0.08656861322853168\n",
-              "LogLoss: 0.04740095339921249\n",
-              "Mean Per-Class Error: 0.001897944385561524\n",
+              "MSE: 0.015936942504265094\n",
+              "RMSE: 0.12624160369808796\n",
+              "LogLoss: 0.06479567656825114\n",
+              "Null degrees of freedom: 4220\n",
+              "Residual degrees of freedom: 4131\n",
+              "Null deviance: 19460.13631038754\n",
+              "Residual deviance: 547.0051015891761\n",
               "AUC table was not computed: it is either disabled (model parameter 'auc_type' was set to AUTO or NONE) or the domain size exceeds the limit (maximum is 50 domains).\n",
               "AUCPR table was not computed: it is either disabled (model parameter 'auc_type' was set to AUTO or NONE) or the domain size exceeds the limit (maximum is 50 domains).
\n", "
\n", @@ -29252,21 +28971,7 @@ "9\n", "Error\n", "Rate\n", - " 455.0\n", - "0.0\n", - "0.0\n", - "0.0\n", - "0.0\n", - "0.0\n", - "0.0\n", - "0.0\n", - "0.0\n", - "0.0\n", - "0.0\n", - "0 / 455\n", - "0.0\n", - "475.0\n", - "0.0\n", + " 414.0\n", "0.0\n", "0.0\n", "0.0\n", @@ -29274,116 +28979,130 @@ "1.0\n", "0.0\n", "0.0\n", - "0.0021008\n", - "1 / 476\n", - "1.0\n", - "0.0\n", - "369.0\n", - "0.0\n", - "0.0\n", - "0.0\n", - "0.0\n", "1.0\n", "0.0\n", - "0.0\n", - "0.0053908\n", - "2 / 371\n", + "0.0048077\n", + "2 / 416\n", "0.0\n", - "0.0\n", + "477.0\n", "1.0\n", - "436.0\n", - "0.0\n", + "2.0\n", "0.0\n", + "2.0\n", "0.0\n", "0.0\n", "0.0\n", "0.0\n", - "0.0022883\n", - "1 / 437\n", + "0.0103734\n", + "5 / 482\n", "0.0\n", "0.0\n", + "388.0\n", "0.0\n", "0.0\n", - "409.0\n", "0.0\n", "0.0\n", "0.0\n", "0.0\n", "0.0\n", "0.0\n", - "0 / 409\n", + "0 / 388\n", "0.0\n", "0.0\n", + "2.0\n", + "432.0\n", "0.0\n", + "1.0\n", + "1.0\n", + "1.0\n", "0.0\n", "0.0\n", - "360.0\n", - "0.0\n", + "0.0114416\n", + "5 / 437\n", + "1.0\n", "0.0\n", "0.0\n", "0.0\n", + "431.0\n", "0.0\n", - "0 / 360\n", + "1.0\n", + "1.0\n", + "1.0\n", + "2.0\n", + "0.0137300\n", + "6 / 437\n", "0.0\n", "0.0\n", + "1.0\n", "0.0\n", "0.0\n", - "0.0\n", - "0.0\n", - "418.0\n", - "0.0\n", - "0.0\n", - "0.0\n", - "0.0\n", - "0 / 418\n", - "1.0\n", + "380.0\n", "1.0\n", "0.0\n", "0.0\n", "0.0\n", + "0.0052356\n", + "2 / 382\n", + "0.0\n", "0.0\n", + "1.0\n", "0.0\n", - "441.0\n", "0.0\n", + "2.0\n", + "437.0\n", "0.0\n", - "0.0045147\n", - "2 / 443\n", - "0.0\n", "0.0\n", "0.0\n", + "0.0068182\n", + "3 / 440\n", + "1.0\n", + "1.0\n", + "1.0\n", "0.0\n", + "1.0\n", "0.0\n", "0.0\n", - "1.0\n", + "414.0\n", "0.0\n", - "420.0\n", + "3.0\n", + "0.0166271\n", + "7 / 421\n", + "0.0\n", "0.0\n", - "0.0023753\n", - "1 / 421\n", - "1.0\n", + "2.0\n", + "2.0\n", "0.0\n", + "2.0\n", "0.0\n", "0.0\n", + "385.0\n", + "2.0\n", + "0.0203562\n", + "8 / 393\n", + "0.0\n", "0.0\n", "0.0\n", + "5.0\n", "0.0\n", + "1.0\n", "0.0\n", + "1.0\n", "0.0\n", + "418.0\n", + "0.0164706\n", + "7 / 425\n", + "416.0\n", + "478.0\n", + "396.0\n", + "441.0\n", "432.0\n", - "0.0023095\n", - "1 / 433\n", - "458.0\n", - "476.0\n", - "370.0\n", - "436.0\n", - "409.0\n", - "360.0\n", - "419.0\n", - "443.0\n", - "420.0\n", - "432.0\n", - "0.0018944\n", - "8 / 4,223\n", + "389.0\n", + "440.0\n", + "417.0\n", + "387.0\n", + "425.0\n", + "0.0106610\n", + "45 / 4,221\n", " \n", "
\n", "
\n", @@ -29431,13 +29150,13 @@ " k\n", "hit_ratio\n", " 1\n", - "0.9981056\n", + "0.989339\n", "2\n", - "0.9995264\n", + "0.9971570\n", "3\n", - "0.9997632\n", + "0.9988154\n", "4\n", - "1.0\n", + "0.9997631\n", "5\n", "1.0\n", "6\n", @@ -29453,13 +29172,16 @@ " \n", "
\n", "
\n", - "
ModelMetricsMultinomial: xgboost\n",
+              "
ModelMetricsMultinomialGLM: stackedensemble\n",
               "** Reported on validation data. **\n",
               "\n",
-              "MSE: 0.06692148817697058\n",
-              "RMSE: 0.25869187883845635\n",
-              "LogLoss: 0.2308354326101069\n",
-              "Mean Per-Class Error: 0.06715225960420251\n",
+              "MSE: 0.08387483810234274\n",
+              "RMSE: 0.2896115296433185\n",
+              "LogLoss: 0.2910408607030443\n",
+              "Null degrees of freedom: 575\n",
+              "Residual degrees of freedom: 486\n",
+              "Null deviance: 2659.2635051935285\n",
+              "Residual deviance: 335.2790715299072\n",
               "AUC table was not computed: it is either disabled (model parameter 'auc_type' was set to AUTO or NONE) or the domain size exceeds the limit (maximum is 50 domains).\n",
               "AUCPR table was not computed: it is either disabled (model parameter 'auc_type' was set to AUTO or NONE) or the domain size exceeds the limit (maximum is 50 domains).
\n", "
\n", @@ -29517,136 +29239,136 @@ "Rate\n", " 53.0\n", "0.0\n", - "0.0\n", "1.0\n", "0.0\n", "0.0\n", + "3.0\n", "0.0\n", - "1.0\n", "0.0\n", "0.0\n", - "0.0363636\n", - "2 / 55\n", - "0.0\n", - "66.0\n", "0.0\n", + "0.0701754\n", + "4 / 57\n", + "0.0\n", + "57.0\n", "0.0\n", "1.0\n", "0.0\n", "0.0\n", - "1.0\n", "0.0\n", "0.0\n", - "0.0294118\n", - "2 / 68\n", - "0.0\n", "1.0\n", - "57.0\n", - "2.0\n", - "0.0\n", - "0.0\n", - "0.0\n", "0.0\n", + "0.0338983\n", + "2 / 59\n", + "1.0\n", + "1.0\n", + "50.0\n", + "1.0\n", + "1.0\n", "0.0\n", "1.0\n", - "0.0655738\n", - "4 / 61\n", - "0.0\n", "1.0\n", "2.0\n", - "60.0\n", "0.0\n", - "2.0\n", + "0.1379310\n", + "8 / 58\n", + "0.0\n", "0.0\n", + "2.0\n", + "58.0\n", "0.0\n", "1.0\n", - "0.0\n", - "0.0909091\n", - "6 / 66\n", + "1.0\n", + "1.0\n", + "2.0\n", + "1.0\n", + "0.1212121\n", + "8 / 66\n", "0.0\n", "0.0\n", "0.0\n", "0.0\n", - "57.0\n", - "0.0\n", - "0.0\n", - "0.0\n", + "47.0\n", "0.0\n", + "1.0\n", "2.0\n", - "0.0338983\n", - "2 / 59\n", - "1.0\n", + "0.0\n", "2.0\n", + "0.0961538\n", + "5 / 52\n", + "0.0\n", + "1.0\n", "0.0\n", + "2.0\n", "1.0\n", + "49.0\n", "0.0\n", - "43.0\n", "0.0\n", "0.0\n", "0.0\n", + "0.0754717\n", + "4 / 53\n", + "2.0\n", + "1.0\n", "1.0\n", - "0.1041667\n", - "5 / 48\n", - "0.0\n", - "0.0\n", - "2.0\n", "0.0\n", "0.0\n", "1.0\n", - "48.0\n", + "52.0\n", "0.0\n", "0.0\n", "0.0\n", - "0.0588235\n", - "3 / 51\n", - "1.0\n", - "2.0\n", + "0.0877193\n", + "5 / 57\n", + "0.0\n", + "0.0\n", + "1.0\n", + "1.0\n", + "1.0\n", "0.0\n", "0.0\n", + "65.0\n", + "1.0\n", + "2.0\n", + "0.0845070\n", + "6 / 71\n", + "0.0\n", + "1.0\n", "0.0\n", + "4.0\n", + "2.0\n", "0.0\n", "0.0\n", - "50.0\n", "0.0\n", + "51.0\n", "0.0\n", - "0.0566038\n", - "3 / 53\n", + "0.1206897\n", + "7 / 58\n", "0.0\n", - "2.0\n", - "1.0\n", - "1.0\n", "0.0\n", - "1.0\n", "0.0\n", "0.0\n", - "45.0\n", - "1.0\n", - "0.1176471\n", - "6 / 51\n", - "0.0\n", "0.0\n", "0.0\n", - "1.0\n", - "2.0\n", - "1.0\n", "0.0\n", - "1.0\n", + "3.0\n", "0.0\n", - "59.0\n", - "0.078125\n", - "5 / 64\n", - "55.0\n", - "74.0\n", - "62.0\n", - "66.0\n", - "60.0\n", - "48.0\n", - "48.0\n", - "53.0\n", - "46.0\n", - "64.0\n", - "0.0659722\n", - "38 / 576\n", + "42.0\n", + "0.0666667\n", + "3 / 45\n", + "56.0\n", + "61.0\n", + "55.0\n", + "67.0\n", + "52.0\n", + "54.0\n", + "55.0\n", + "72.0\n", + "57.0\n", + "47.0\n", + "0.0902778\n", + "52 / 576\n", " \n", "
\n", "
\n", @@ -29694,19 +29416,19 @@ " k\n", "hit_ratio\n", " 1\n", - "0.9340278\n", + "0.9097222\n", "2\n", - "0.9774306\n", + "0.9652778\n", "3\n", - "0.9913195\n", + "0.9861111\n", "4\n", "0.9947917\n", "5\n", - "0.9965278\n", + "0.9947917\n", "6\n", - "0.9982639\n", + "0.9965278\n", "7\n", - "0.9982639\n", + "0.9965278\n", "8\n", "0.9982639\n", "9\n", @@ -29715,407 +29437,7 @@ "1.0\n", " \n", "
\n", - "
\n", - "
\n", - " \n", - "
\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
Scoring History:
timestampdurationnumber_of_treestraining_rmsetraining_loglosstraining_classification_errortraining_auctraining_pr_aucvalidation_rmsevalidation_loglossvalidation_classification_errorvalidation_aucvalidation_pr_auc
2024-03-23 15:45:53 0.014 sec0.00.90000002.30258510.8950983nannan0.90000002.30258510.9079861nannan
2024-03-23 15:45:58 5.379 sec5.00.50053950.72092120.0887994nannan0.54020640.83080710.1493056nannan
2024-03-23 15:46:0410.809 sec10.00.33434480.36994530.0468861nannan0.39598680.49117950.1059028nannan
2024-03-23 15:46:0613.614 sec15.00.25530310.23207740.0312574nannan0.33941550.36963060.0972222nannan
2024-03-23 15:46:0916.326 sec20.00.20792820.16475850.0198911nannan0.31105100.31564300.0833333nannan
2024-03-23 15:46:1118.389 sec25.00.17496750.12573000.0139711nannan0.29106330.28048390.0746528nannan
2024-03-23 15:46:1320.343 sec30.00.15380890.10287020.0087615nannan0.28086870.26374620.0746528nannan
2024-03-23 15:46:1824.758 sec35.00.13745750.08751740.0068672nannan0.27512530.25438810.078125nannan
2024-03-23 15:46:1926.386 sec40.00.12461510.07636600.0044992nannan0.27174200.24918980.0677083nannan
2024-03-23 15:46:2128.242 sec45.00.11466630.06800830.0042624nannan0.26614360.24121970.0694444nannan
2024-03-23 15:46:2329.862 sec50.00.10622470.06147080.0035520nannan0.26351450.23785130.0659722nannan
2024-03-23 15:46:2431.326 sec55.00.09860080.05582910.0026048nannan0.26162950.23479890.0694444nannan
2024-03-23 15:46:2632.881 sec60.00.09236720.05152110.0023680nannan0.26053380.23346260.0694444nannan
2024-03-23 15:46:2734.268 sec65.00.08761100.04801870.0021312nannan0.25939940.23194800.0694444nannan
2024-03-23 15:46:2834.960 sec66.00.08656860.04740100.0018944nannan0.25869190.23083540.0659722nannan
\n", - "
\n", - "
\n", - "
\n", - " \n", - "
\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
Variable Importances:
variablerelative_importancescaled_importancepercentage
435787.51556401.00.0333121
657540.98120120.68694670.0228837
100435.30862430.55276190.0184137
437427.55596920.54291750.0180857
329414.86257930.52679920.0175488
549378.34957890.48043440.0160043
155352.66342160.44781770.0149178
407350.54653930.44512970.0148282
323340.05850220.43181180.0143846
349330.80297850.42005900.0139931
------------
4971.02393390.00130020.0000433
1480.80688480.00102460.0000341
980.55225750.00070130.0000234
1280.51810310.00065790.0000219
2300.41181180.00052290.0000174
2870.29172710.00037040.0000123
5090.25655360.00032580.0000109
1290.25244140.00032060.0000107
2010.23077770.00029300.0000098
2860.17935180.00022770.0000076
\n", - "
\n", - "
[368 rows x 4 columns]
\n",
+              "
\n",
               "\n",
               "[tips]\n",
               "Use `model.explain()` to inspect the model.\n",
@@ -30134,7 +29456,7 @@
         "    y=y,\n",
         "    training_frame=my_train)"
       ],
-      "id": "4be7c133-3523-48f9-bf28-93b11d2ec6fa"
+      "id": "4bc5d1db-f75b-49bb-8d98-41e70d139d7d"
     },
     {
       "cell_type": "code",
@@ -30143,15 +29465,15 @@
         "colab": {
           "base_uri": "https://localhost:8080/"
         },
-        "id": "af750bfd-c358-4ff9-8b36-53b5566f8c12",
-        "outputId": "5c2b703a-9f92-4b17-c7c7-978ebf1b512e"
+        "id": "307fc438-8537-4fa0-92ef-c681697b0be7",
+        "outputId": "897017e8-1782-43fb-d0f1-dfd646525963"
       },
       "outputs": [
         {
           "output_type": "execute_result",
           "data": {
             "text/plain": [
-              "0.06715225960420251"
+              "0.08944251059813861"
             ]
           },
           "metadata": {},
@@ -30162,7 +29484,7 @@
         "my_model.leaderboard[\n",
         "    'mean_per_class_error'].min()"
       ],
-      "id": "af750bfd-c358-4ff9-8b36-53b5566f8c12"
+      "id": "307fc438-8537-4fa0-92ef-c681697b0be7"
     },
     {
       "cell_type": "code",
@@ -30171,8 +29493,8 @@
         "colab": {
           "base_uri": "https://localhost:8080/"
         },
-        "id": "b9bec57b-30b7-4ff9-abb2-14bdda339e00",
-        "outputId": "a73aef77-ad81-4b96-8da8-064271a1464c"
+        "id": "f5b256cc-20d1-4417-8557-8cff1814a850",
+        "outputId": "56ea2f31-7650-455f-edef-d7df5be6eac2"
       },
       "outputs": [
         {
@@ -30191,7 +29513,7 @@
           "output_type": "execute_result",
           "data": {
             "text/plain": [
-              "0.9211"
+              "0.9301"
             ]
           },
           "metadata": {},
@@ -30205,10 +29527,10 @@
         "\n",
         "(y_ == y_test).mean()"
       ],
-      "id": "b9bec57b-30b7-4ff9-abb2-14bdda339e00"
+      "id": "f5b256cc-20d1-4417-8557-8cff1814a850"
     },
     {
-      "id": "38a5e562",
+      "id": "dda702ba",
       "cell_type": "markdown",
       "source": [
         "# 12 時系列予測\n",
@@ -30216,17 +29538,17 @@
         "\n"
       ],
       "metadata": {
-        "id": "38a5e562"
+        "id": "dda702ba"
       }
     },
     {
-      "id": "ad38b231",
+      "id": "a2cd393b",
       "cell_type": "markdown",
       "source": [
         "## 12.1 日時と日時の列"
       ],
       "metadata": {
-        "id": "ad38b231"
+        "id": "a2cd393b"
       }
     },
     {
@@ -30236,8 +29558,8 @@
         "colab": {
           "base_uri": "https://localhost:8080/"
         },
-        "id": "b880fbb6-d20a-4382-9f8e-867a63001e76",
-        "outputId": "3b56ea5f-95f5-44e4-a589-8e2958e9eb44"
+        "id": "68867b51-7ad7-41ff-be74-e2a229222c47",
+        "outputId": "3e16cb72-4fb6-412c-e049-b4282664a2c8"
       },
       "outputs": [
         {
@@ -30263,7 +29585,7 @@
         "import pandas as pd\n",
         "pd.to_datetime('2020-01-01')"
       ],
-      "id": "b880fbb6-d20a-4382-9f8e-867a63001e76"
+      "id": "68867b51-7ad7-41ff-be74-e2a229222c47"
     },
     {
       "cell_type": "code",
@@ -30272,8 +29594,8 @@
         "colab": {
           "base_uri": "https://localhost:8080/"
         },
-        "id": "7e8e991c-7460-4707-a220-af919fe723ea",
-        "outputId": "479c3760-d1bb-4ac6-e06a-01685a5bd89f"
+        "id": "9f2160f0-fffe-47e2-9a78-f0c2a0239dc8",
+        "outputId": "96e4a8ef-3e6d-4f5d-e6d9-4c7dfb66f5aa"
       },
       "outputs": [
         {
@@ -30300,16 +29622,16 @@
         "\n",
         "pd.date_range(start='2021-01-01 00:00:00', end='2021-01-01 03:00:00', freq='2H')"
       ],
-      "id": "7e8e991c-7460-4707-a220-af919fe723ea"
+      "id": "9f2160f0-fffe-47e2-9a78-f0c2a0239dc8"
     },
     {
-      "id": "e88aa058",
+      "id": "03f7ace5",
       "cell_type": "markdown",
       "source": [
         "## 12.2 時系列データの予測"
       ],
       "metadata": {
-        "id": "e88aa058"
+        "id": "03f7ace5"
       }
     },
     {
@@ -30319,8 +29641,8 @@
         "colab": {
           "base_uri": "https://localhost:8080/"
         },
-        "id": "4372a37d-c2c8-48d5-b4cd-0d60c2327d9a",
-        "outputId": "bccd22bb-d87f-4924-851b-d8c6d78ece94"
+        "id": "dc6d4587-a2f9-4566-8bcd-999905172c1b",
+        "outputId": "eb64a359-5e56-433d-a410-7236d59692ac"
       },
       "outputs": [
         {
@@ -30345,20 +29667,20 @@
         "\n",
         "my_data = airpassengers.load_airpassengers()"
       ],
-      "id": "4372a37d-c2c8-48d5-b4cd-0d60c2327d9a"
+      "id": "dc6d4587-a2f9-4566-8bcd-999905172c1b"
     },
     {
       "cell_type": "code",
       "execution_count": 378,
       "metadata": {
-        "id": "e4fb478e-d19c-444f-a0da-12af31038781"
+        "id": "f4662430-3e54-47e9-b4ae-9b3a4e10953a"
       },
       "outputs": [],
       "source": [
         "n = len(my_data) # データ数(144)\n",
         "k = 108          # 訓練データ数"
       ],
-      "id": "e4fb478e-d19c-444f-a0da-12af31038781"
+      "id": "f4662430-3e54-47e9-b4ae-9b3a4e10953a"
     },
     {
       "cell_type": "code",
@@ -30368,8 +29690,8 @@
           "base_uri": "https://localhost:8080/",
           "height": 206
         },
-        "id": "e887eba8-7e4e-4e66-a7a0-f6a19bec3a6e",
-        "outputId": "c5a763f1-8e79-4121-a597-aacbc355d11c"
+        "id": "a32aeee7-427b-4b5c-86a2-3ba1fb1a306e",
+        "outputId": "2bd9a049-0620-494b-999c-b10028993424"
       },
       "outputs": [
         {
@@ -30385,7 +29707,7 @@
             ],
             "text/html": [
               "\n",
-              "  
\n", + "
\n", "
\n", "\n", - "
  1. 0.48236708897166
  2. 0.494719698210247
  3. 0.584646507585421
\n" + "
  1. 0.507733941520564
  2. 0.479989877832122
  3. 0.610116322198883
\n" ], - "text/markdown": "1. 0.48236708897166\n2. 0.494719698210247\n3. 0.584646507585421\n\n\n", - "text/latex": "\\begin{enumerate*}\n\\item 0.48236708897166\n\\item 0.494719698210247\n\\item 0.584646507585421\n\\end{enumerate*}\n", + "text/markdown": "1. 0.507733941520564\n2. 0.479989877832122\n3. 0.610116322198883\n\n\n", + "text/latex": "\\begin{enumerate*}\n\\item 0.507733941520564\n\\item 0.479989877832122\n\\item 0.610116322198883\n\\end{enumerate*}\n", "text/plain": [ - "[1] 0.4823671 0.4947197 0.5846465" + "[1] 0.5077339 0.4799899 0.6101163" ] }, "metadata": {} @@ -3956,18 +3993,18 @@ "source": [ "replicate(n = 3, expr = f1(10))" ], - "id": "16f68279-51a6-42b7-ae5a-554b75484766" + "id": "c10d5333-85de-4b8e-8b0f-9d53432b405f" }, { "cell_type": "code", - "execution_count": 141, + "execution_count": 104, "metadata": { - "id": "f255a05c-21f3-43e6-8f96-fa7cfdffafc8", - "outputId": "5455c9ff-3f05-4f5e-b0f2-ad47b4b218b5", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "486cd9a8-27e6-4bd1-b1ec-cdaf0cc0cd8b", + "outputId": "1d9e411c-6adc-432d-9d07-81aae9bd3fd5" }, "outputs": [ { @@ -3979,12 +4016,12 @@ ".list-inline>li {display: inline-block}\n", ".list-inline>li:not(:last-child)::after {content: \"\\00b7\"; padding: 0 .5ex}\n", "\n", - "
  1. 0.443401985242963
  2. 0.443401985242963
  3. 0.443401985242963
\n" + "
  1. 0.413155443849973
  2. 0.413155443849973
  3. 0.413155443849973
\n" ], - "text/markdown": "1. 0.443401985242963\n2. 0.443401985242963\n3. 0.443401985242963\n\n\n", - "text/latex": "\\begin{enumerate*}\n\\item 0.443401985242963\n\\item 0.443401985242963\n\\item 0.443401985242963\n\\end{enumerate*}\n", + "text/markdown": "1. 0.413155443849973\n2. 0.413155443849973\n3. 0.413155443849973\n\n\n", + "text/latex": "\\begin{enumerate*}\n\\item 0.413155443849973\n\\item 0.413155443849973\n\\item 0.413155443849973\n\\end{enumerate*}\n", "text/plain": [ - "[1] 0.443402 0.443402 0.443402" + "[1] 0.4131554 0.4131554 0.4131554" ] }, "metadata": {} @@ -3993,18 +4030,18 @@ "source": [ "rep(x = f1(10), times = 3)" ], - "id": "f255a05c-21f3-43e6-8f96-fa7cfdffafc8" + "id": "486cd9a8-27e6-4bd1-b1ec-cdaf0cc0cd8b" }, { "cell_type": "code", - "execution_count": 142, + "execution_count": 105, "metadata": { - "id": "cd95a8d9-dc4e-4d6a-a245-60ac245a984f", - "outputId": "424bfa00-182b-4f7c-efb7-a824c38ed70f", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "5b023da1-f82e-4b7a-a151-5f0bb2764e65", + "outputId": "1779d964-88b5-4e84-a35f-8a8b5609cd92" }, "outputs": [ { @@ -4016,12 +4053,12 @@ ".list-inline>li {display: inline-block}\n", ".list-inline>li:not(:last-child)::after {content: \"\\00b7\"; padding: 0 .5ex}\n", "\n", - "
  1. 0.479906096216291
  2. 0.344323980319314
  3. 0.528733301388565
\n" + "
  1. 0.440390569297597
  2. 0.392302758106962
  3. 0.511298703690991
\n" ], - "text/markdown": "1. 0.479906096216291\n2. 0.344323980319314\n3. 0.528733301388565\n\n\n", - "text/latex": "\\begin{enumerate*}\n\\item 0.479906096216291\n\\item 0.344323980319314\n\\item 0.528733301388565\n\\end{enumerate*}\n", + "text/markdown": "1. 0.440390569297597\n2. 0.392302758106962\n3. 0.511298703690991\n\n\n", + "text/latex": "\\begin{enumerate*}\n\\item 0.440390569297597\n\\item 0.392302758106962\n\\item 0.511298703690991\n\\end{enumerate*}\n", "text/plain": [ - "[1] 0.4799061 0.3443240 0.5287333" + "[1] 0.4403906 0.3923028 0.5112987" ] }, "metadata": {} @@ -4031,18 +4068,18 @@ "v <- c(5, 10, 100)\n", "v %>% map_dbl(f1)" ], - "id": "cd95a8d9-dc4e-4d6a-a245-60ac245a984f" + "id": "5b023da1-f82e-4b7a-a151-5f0bb2764e65" }, { "cell_type": "code", - "execution_count": 143, + "execution_count": 106, "metadata": { - "id": "e179c3a8-467f-4ee4-9d81-9ade45753e89", - "outputId": "24118314-bef5-4779-b09a-5b30031937c5", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "82b69452-b8b7-401a-bfde-a4aae4c32478", + "outputId": "a572f724-c702-41c9-cd12-41118e7ad6a0" }, "outputs": [ { @@ -4054,12 +4091,12 @@ ".list-inline>li {display: inline-block}\n", ".list-inline>li:not(:last-child)::after {content: \"\\00b7\"; padding: 0 .5ex}\n", "\n", - "
  1. 0.480115511850454
  2. 0.479903662973084
  3. 0.248961041914299
\n" + "
  1. 0.386965759377927
  2. 0.425318954745308
  3. 0.472503300127573
\n" ], - "text/markdown": "1. 0.480115511850454\n2. 0.479903662973084\n3. 0.248961041914299\n\n\n", - "text/latex": "\\begin{enumerate*}\n\\item 0.480115511850454\n\\item 0.479903662973084\n\\item 0.248961041914299\n\\end{enumerate*}\n", + "text/markdown": "1. 0.386965759377927\n2. 0.425318954745308\n3. 0.472503300127573\n\n\n", + "text/latex": "\\begin{enumerate*}\n\\item 0.386965759377927\n\\item 0.425318954745308\n\\item 0.472503300127573\n\\end{enumerate*}\n", "text/plain": [ - "[1] 0.4801155 0.4799037 0.2489610" + "[1] 0.3869658 0.4253190 0.4725033" ] }, "metadata": {} @@ -4069,18 +4106,18 @@ "rep(x = 10, times = 3) %>% map_dbl(f1)\n", "# 結果は割愛" ], - "id": "e179c3a8-467f-4ee4-9d81-9ade45753e89" + "id": "82b69452-b8b7-401a-bfde-a4aae4c32478" }, { "cell_type": "code", - "execution_count": 144, + "execution_count": 107, "metadata": { - "id": "336ef165-ec76-4b99-aeb7-8d98aeb1c5b4", - "outputId": "b025c562-eeae-4924-831a-0b939be76003", "colab": { "base_uri": "https://localhost:8080/", "height": 149 - } + }, + "id": "a9d591f2-22c9-4830-8fb2-447b1ab3d3fb", + "outputId": "489e6395-88e9-4abc-be24-7074a3befda6" }, "outputs": [ { @@ -4091,22 +4128,22 @@ "\t
$x
\n", "\t\t
10
\n", "\t
$p
\n", - "\t\t
0.530081658647396
\n", + "\t\t
0.435875510820188
\n", "\t
$q
\n", - "\t\t
0.400712637988222
\n", + "\t\t
0.246495322346235
\n", "\n" ], - "text/markdown": "$x\n: 10\n$p\n: 0.530081658647396\n$q\n: 0.400712637988222\n\n\n", - "text/latex": "\\begin{description}\n\\item[\\$x] 10\n\\item[\\$p] 0.530081658647396\n\\item[\\$q] 0.400712637988222\n\\end{description}\n", + "text/markdown": "$x\n: 10\n$p\n: 0.435875510820188\n$q\n: 0.246495322346235\n\n\n", + "text/latex": "\\begin{description}\n\\item[\\$x] 10\n\\item[\\$p] 0.435875510820188\n\\item[\\$q] 0.246495322346235\n\\end{description}\n", "text/plain": [ "$x\n", "[1] 10\n", "\n", "$p\n", - "[1] 0.5300817\n", + "[1] 0.4358755\n", "\n", "$q\n", - "[1] 0.4007126\n" + "[1] 0.2464953\n" ] }, "metadata": {} @@ -4122,18 +4159,18 @@ "\n", "f2(10) # 動作確認" ], - "id": "336ef165-ec76-4b99-aeb7-8d98aeb1c5b4" + "id": "a9d591f2-22c9-4830-8fb2-447b1ab3d3fb" }, { "cell_type": "code", - "execution_count": 145, + "execution_count": 108, "metadata": { - "id": "f652bd90-61b4-488f-9bdb-6f812a08c87b", - "outputId": "72468c17-7ba8-48f1-cb9a-669eccaab6c4", "colab": { "base_uri": "https://localhost:8080/", "height": 192 - } + }, + "id": "399a4c09-4878-497c-b91d-f7da11e7241b", + "outputId": "178b02df-16e2-4415-febd-e92d17819756" }, "outputs": [ { @@ -4147,19 +4184,19 @@ "\t<dbl><dbl><dbl>\n", "\n", "\n", - "\t 50.55522720.2502222\n", - "\t 100.45691050.2804306\n", - "\t1000.49619420.2954105\n", + "\t 50.38459420.3126241\n", + "\t 100.45520560.2930233\n", + "\t1000.48920270.2614759\n", "\n", "\n" ], - "text/markdown": "\nA tibble: 3 × 3\n\n| x <dbl> | p <dbl> | q <dbl> |\n|---|---|---|\n| 5 | 0.5552272 | 0.2502222 |\n| 10 | 0.4569105 | 0.2804306 |\n| 100 | 0.4961942 | 0.2954105 |\n\n", - "text/latex": "A tibble: 3 × 3\n\\begin{tabular}{lll}\n x & p & q\\\\\n & & \\\\\n\\hline\n\t 5 & 0.5552272 & 0.2502222\\\\\n\t 10 & 0.4569105 & 0.2804306\\\\\n\t 100 & 0.4961942 & 0.2954105\\\\\n\\end{tabular}\n", + "text/markdown": "\nA tibble: 3 × 3\n\n| x <dbl> | p <dbl> | q <dbl> |\n|---|---|---|\n| 5 | 0.3845942 | 0.3126241 |\n| 10 | 0.4552056 | 0.2930233 |\n| 100 | 0.4892027 | 0.2614759 |\n\n", + "text/latex": "A tibble: 3 × 3\n\\begin{tabular}{lll}\n x & p & q\\\\\n & & \\\\\n\\hline\n\t 5 & 0.3845942 & 0.3126241\\\\\n\t 10 & 0.4552056 & 0.2930233\\\\\n\t 100 & 0.4892027 & 0.2614759\\\\\n\\end{tabular}\n", "text/plain": [ " x p q \n", - "1 5 0.5552272 0.2502222\n", - "2 10 0.4569105 0.2804306\n", - "3 100 0.4961942 0.2954105" + "1 5 0.3845942 0.3126241\n", + "2 10 0.4552056 0.2930233\n", + "3 100 0.4892027 0.2614759" ] }, "metadata": {} @@ -4169,18 +4206,18 @@ "v <- c(5, 10, 100)\n", "v %>% map_dfr(f2)" ], - "id": "f652bd90-61b4-488f-9bdb-6f812a08c87b" + "id": "399a4c09-4878-497c-b91d-f7da11e7241b" }, { "cell_type": "code", - "execution_count": 146, + "execution_count": 109, "metadata": { - "id": "0caa7fe1-15de-4539-b94c-5be8cdda9945", - "outputId": "86e8d982-6f5a-4cef-e075-ef9236d42f1e", "colab": { "base_uri": "https://localhost:8080/", "height": 184 - } + }, + "id": "7dd59b18-0086-4afc-adf6-f51d44f4221c", + "outputId": "922fcf48-8075-48fd-cc54-133b048f2872" }, "outputs": [ { @@ -4193,13 +4230,13 @@ "\t
$y
\n", "\t\t
6
\n", "\t
$p
\n", - "\t\t
3.2
\n", + "\t\t
3.9
\n", "\t
$q
\n", - "\t\t
1.47572957474524
\n", + "\t\t
1.79195734076208
\n", "\n" ], - "text/markdown": "$x\n: 10\n$y\n: 6\n$p\n: 3.2\n$q\n: 1.47572957474524\n\n\n", - "text/latex": "\\begin{description}\n\\item[\\$x] 10\n\\item[\\$y] 6\n\\item[\\$p] 3.2\n\\item[\\$q] 1.47572957474524\n\\end{description}\n", + "text/markdown": "$x\n: 10\n$y\n: 6\n$p\n: 3.9\n$q\n: 1.79195734076208\n\n\n", + "text/latex": "\\begin{description}\n\\item[\\$x] 10\n\\item[\\$y] 6\n\\item[\\$p] 3.9\n\\item[\\$q] 1.79195734076208\n\\end{description}\n", "text/plain": [ "$x\n", "[1] 10\n", @@ -4208,10 +4245,10 @@ "[1] 6\n", "\n", "$p\n", - "[1] 3.2\n", + "[1] 3.9\n", "\n", "$q\n", - "[1] 1.47573\n" + "[1] 1.791957\n" ] }, "metadata": {} @@ -4230,18 +4267,18 @@ "\n", "f3(x = 10, y = 6) # 動作確認" ], - "id": "0caa7fe1-15de-4539-b94c-5be8cdda9945" + "id": "7dd59b18-0086-4afc-adf6-f51d44f4221c" }, { "cell_type": "code", - "execution_count": 147, + "execution_count": 110, "metadata": { - "id": "952c48bf-fe20-4899-9ca5-e923f4f27d36", - "outputId": "b0340ea7-1ab6-4d53-c6ff-089ab59c0348", "colab": { "base_uri": "https://localhost:8080/", "height": 286 - } + }, + "id": "0cdb88f6-ce49-4565-b415-9c91f64f5984", + "outputId": "59ee4012-8594-4c62-e15f-e2b8eb48de9d" }, "outputs": [ { @@ -4255,25 +4292,25 @@ "\t<dbl><dbl><dbl><dbl>\n", "\n", "\n", - "\t 5 64.02.121320\n", - "\t 10 62.61.646545\n", - "\t100 63.41.740777\n", - "\t 5127.44.669047\n", - "\t 10127.42.796824\n", - "\t100127.13.554766\n", + "\t 5 63.601.949359\n", + "\t 10 63.201.619328\n", + "\t100 63.721.694197\n", + "\t 5127.401.673320\n", + "\t 10126.602.270585\n", + "\t100126.763.481901\n", "\n", "\n" ], - "text/markdown": "\nA tibble: 6 × 4\n\n| x <dbl> | y <dbl> | p <dbl> | q <dbl> |\n|---|---|---|---|\n| 5 | 6 | 4.0 | 2.121320 |\n| 10 | 6 | 2.6 | 1.646545 |\n| 100 | 6 | 3.4 | 1.740777 |\n| 5 | 12 | 7.4 | 4.669047 |\n| 10 | 12 | 7.4 | 2.796824 |\n| 100 | 12 | 7.1 | 3.554766 |\n\n", - "text/latex": "A tibble: 6 × 4\n\\begin{tabular}{llll}\n x & y & p & q\\\\\n & & & \\\\\n\\hline\n\t 5 & 6 & 4.0 & 2.121320\\\\\n\t 10 & 6 & 2.6 & 1.646545\\\\\n\t 100 & 6 & 3.4 & 1.740777\\\\\n\t 5 & 12 & 7.4 & 4.669047\\\\\n\t 10 & 12 & 7.4 & 2.796824\\\\\n\t 100 & 12 & 7.1 & 3.554766\\\\\n\\end{tabular}\n", + "text/markdown": "\nA tibble: 6 × 4\n\n| x <dbl> | y <dbl> | p <dbl> | q <dbl> |\n|---|---|---|---|\n| 5 | 6 | 3.60 | 1.949359 |\n| 10 | 6 | 3.20 | 1.619328 |\n| 100 | 6 | 3.72 | 1.694197 |\n| 5 | 12 | 7.40 | 1.673320 |\n| 10 | 12 | 6.60 | 2.270585 |\n| 100 | 12 | 6.76 | 3.481901 |\n\n", + "text/latex": "A tibble: 6 × 4\n\\begin{tabular}{llll}\n x & y & p & q\\\\\n & & & \\\\\n\\hline\n\t 5 & 6 & 3.60 & 1.949359\\\\\n\t 10 & 6 & 3.20 & 1.619328\\\\\n\t 100 & 6 & 3.72 & 1.694197\\\\\n\t 5 & 12 & 7.40 & 1.673320\\\\\n\t 10 & 12 & 6.60 & 2.270585\\\\\n\t 100 & 12 & 6.76 & 3.481901\\\\\n\\end{tabular}\n", "text/plain": [ - " x y p q \n", - "1 5 6 4.0 2.121320\n", - "2 10 6 2.6 1.646545\n", - "3 100 6 3.4 1.740777\n", - "4 5 12 7.4 4.669047\n", - "5 10 12 7.4 2.796824\n", - "6 100 12 7.1 3.554766" + " x y p q \n", + "1 5 6 3.60 1.949359\n", + "2 10 6 3.20 1.619328\n", + "3 100 6 3.72 1.694197\n", + "4 5 12 7.40 1.673320\n", + "5 10 12 6.60 2.270585\n", + "6 100 12 6.76 3.481901" ] }, "metadata": {} @@ -4286,18 +4323,18 @@ "\n", "my_df %>% pmap_dfr(f3)" ], - "id": "952c48bf-fe20-4899-9ca5-e923f4f27d36" + "id": "0cdb88f6-ce49-4565-b415-9c91f64f5984" }, { "cell_type": "code", - "execution_count": 148, + "execution_count": 111, "metadata": { - "id": "f8e48f74-e0ff-4882-9f21-e65ae0fb66eb", - "outputId": "06da7764-83b0-4790-9086-e32189fa4e43", "colab": { "base_uri": "https://localhost:8080/", - "height": 225 - } + "height": 70 + }, + "id": "2a4505c7-2240-43ac-9bca-b44ed1a7c388", + "outputId": "bcc5a044-3b27-4596-b430-bc05476f5781" }, "outputs": [ { @@ -4305,15 +4342,6 @@ "name": "stderr", "text": [ "Loading required package: future\n", - "\n", - "\n", - "Attaching package: ‘future’\n", - "\n", - "\n", - "The following object is masked from ‘package:caret’:\n", - "\n", - " cluster\n", - "\n", "\n" ] }, @@ -4326,12 +4354,12 @@ ".list-inline>li {display: inline-block}\n", ".list-inline>li:not(:last-child)::after {content: \"\\00b7\"; padding: 0 .5ex}\n", "\n", - "
  1. 0.264389970803893
  2. 0.604479306408133
  3. 0.477258430004528
\n" + "
  1. 0.867937745696644
  2. 0.556042997133206
  3. 0.530369206151645
\n" ], - "text/markdown": "1. 0.264389970803893\n2. 0.604479306408133\n3. 0.477258430004528\n\n\n", - "text/latex": "\\begin{enumerate*}\n\\item 0.264389970803893\n\\item 0.604479306408133\n\\item 0.477258430004528\n\\end{enumerate*}\n", + "text/markdown": "1. 0.867937745696644\n2. 0.556042997133206\n3. 0.530369206151645\n\n\n", + "text/latex": "\\begin{enumerate*}\n\\item 0.867937745696644\n\\item 0.556042997133206\n\\item 0.530369206151645\n\\end{enumerate*}\n", "text/plain": [ - "[1] 0.2643900 0.6044793 0.4772584" + "[1] 0.8679377 0.5560430 0.5303692" ] }, "metadata": {} @@ -4346,28 +4374,28 @@ " furrr_options(seed = TRUE))\n", "# 結果は割愛" ], - "id": "f8e48f74-e0ff-4882-9f21-e65ae0fb66eb" + "id": "2a4505c7-2240-43ac-9bca-b44ed1a7c388" }, { - "id": "cc8e45e9", + "id": "6e7f8d23", "cell_type": "markdown", "source": [ "## 3.8 その他" ], "metadata": { - "id": "cc8e45e9" + "id": "6e7f8d23" } }, { "cell_type": "code", - "execution_count": 149, + "execution_count": 112, "metadata": { - "id": "03bd5111-e033-4fc1-b3a8-347189857580", - "outputId": "11ed90a8-a130-4cd4-8218-ff62aa98b13b", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "289deda5-01b7-4089-af87-6ed456cabaf0", + "outputId": "9b069d0e-e087-41c8-d0c1-85d84c1c0a38" }, "outputs": [ { @@ -4389,13 +4417,13 @@ "x <- 123\n", "typeof(x)" ], - "id": "03bd5111-e033-4fc1-b3a8-347189857580" + "id": "289deda5-01b7-4089-af87-6ed456cabaf0" }, { "cell_type": "code", - "execution_count": 150, + "execution_count": 113, "metadata": { - "id": "0cabd75c-c761-4ad0-abc8-61815c18182e" + "id": "e460c864-27b1-497a-979d-02665c1c3091" }, "outputs": [], "source": [ @@ -4403,18 +4431,18 @@ "# あるいは\n", "help(log)" ], - "id": "0cabd75c-c761-4ad0-abc8-61815c18182e" + "id": "e460c864-27b1-497a-979d-02665c1c3091" }, { "cell_type": "code", - "execution_count": 151, + "execution_count": 114, "metadata": { - "id": "d3c5ffb9-e72c-4bcb-8ad1-0e6c880bcf6f", - "outputId": "f4ce3632-47d8-4c44-a9fe-1763aeca2f96", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "a0a17dd2-b882-4270-bc40-4b89811a716a", + "outputId": "abd0e1f8-f49d-4824-dd43-85bebbaae996" }, "outputs": [ { @@ -4441,18 +4469,18 @@ "v <- c(1, NA, 3)\n", "v" ], - "id": "d3c5ffb9-e72c-4bcb-8ad1-0e6c880bcf6f" + "id": "a0a17dd2-b882-4270-bc40-4b89811a716a" }, { "cell_type": "code", - "execution_count": 152, + "execution_count": 115, "metadata": { - "id": "d3949fe8-58d8-4d34-87f8-279ac7d7e36d", - "outputId": "1399e0a5-3400-4e5b-ca03-b3664cb88107", "colab": { "base_uri": "https://localhost:8080/", "height": 52 - } + }, + "id": "51fc9d82-04b6-439e-89dd-e4325a8df2e6", + "outputId": "e0a5d60c-b7c2-4b18-ef70-a7d28adda5dd" }, "outputs": [ { @@ -4489,56 +4517,73 @@ "\n", "v[2] == NA # 誤り" ], - "id": "d3949fe8-58d8-4d34-87f8-279ac7d7e36d" + "id": "51fc9d82-04b6-439e-89dd-e4325a8df2e6" }, { - "id": "88e0e27f", + "id": "ab1aca33", "cell_type": "markdown", "source": [ "# 4 統計入門" ], "metadata": { - "id": "88e0e27f" + "id": "ab1aca33" } }, { "cell_type": "code", - "execution_count": 153, + "execution_count": 116, "metadata": { - "id": "d7c411be-e5d8-4b75-aa1a-99aae304cc7a" + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "4ac9b825-a5bc-4616-8f30-59736884d415", + "outputId": "6db91b9c-5016-4423-ece9-5e96b3a2395b" }, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "Installing packages into ‘/usr/local/lib/R/site-library’\n", + "(as ‘lib’ is unspecified)\n", + "\n", + "also installing the dependencies ‘later’, ‘plyr’, ‘htmlwidgets’, ‘lazyeval’, ‘crosstalk’, ‘promises’, ‘zoo’, ‘ssanv’, ‘productplots’, ‘plotly’, ‘ggrepel’, ‘mnormt’, ‘lmtest’\n", + "\n", + "\n" + ] + } + ], "source": [ "# Google Colaboratoryの環境設定\n", "if (file.exists(\"/content\")) {\n", " options(Ncpus = parallel::detectCores())\n", - " packages_to_install <- c(\"exactci\", \"ggmosaic\", \"pastecs\", \"psych\", \"vcd\")\n", " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"exactci\", \"ggmosaic\", \"pastecs\", \"psych\", \"vcd\")\n", " install.packages(setdiff(packages_to_install, installed_packages))\n", "}" ], - "id": "d7c411be-e5d8-4b75-aa1a-99aae304cc7a" + "id": "4ac9b825-a5bc-4616-8f30-59736884d415" }, { - "id": "50294b38", + "id": "ed7d6561", "cell_type": "markdown", "source": [ "## 4.1 記述統計" ], "metadata": { - "id": "50294b38" + "id": "ed7d6561" } }, { "cell_type": "code", - "execution_count": 154, + "execution_count": 117, "metadata": { - "id": "75934537-cb9d-4df2-aa43-bbdc4ac744e8", - "outputId": "73cea224-3534-48ca-adf9-e7c2b0f1394d", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "beeefb4c-a1ae-4502-8b35-2f7b09800ba4", + "outputId": "f55829e8-3ccf-4248-97b4-929754e59db8" }, "outputs": [ { @@ -4560,18 +4605,18 @@ "x <- c(165, 170, 175, 180, 185)\n", "mean(x) # 平均" ], - "id": "75934537-cb9d-4df2-aa43-bbdc4ac744e8" + "id": "beeefb4c-a1ae-4502-8b35-2f7b09800ba4" }, { "cell_type": "code", - "execution_count": 155, + "execution_count": 118, "metadata": { - "id": "6307da8d-1de3-447c-b11a-bc7ced583eb3", - "outputId": "13c6d5af-e7a9-41d1-b75b-4dc674a0b13e", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "1836f64f-2711-45b9-93ef-b5e5433806c3", + "outputId": "85c9e3d6-4e28-4883-9313-eb28b6d1fd57" }, "outputs": [ { @@ -4593,18 +4638,18 @@ "n <- length(x) # サンプルサイズ\n", "sum(x) / n" ], - "id": "6307da8d-1de3-447c-b11a-bc7ced583eb3" + "id": "1836f64f-2711-45b9-93ef-b5e5433806c3" }, { "cell_type": "code", - "execution_count": 156, + "execution_count": 119, "metadata": { - "id": "b0b65929-e82e-4156-823f-65f69317230f", - "outputId": "85ad844f-4ffa-426f-8283-9037ed8a93ec", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "dff73f28-9653-4227-9f6f-e0863b02758f", + "outputId": "04613d67-0650-4d45-98a1-685bd066978e" }, "outputs": [ { @@ -4626,18 +4671,18 @@ "y <- c(173, 174, 175, 176, 177)\n", "mean(y)" ], - "id": "b0b65929-e82e-4156-823f-65f69317230f" + "id": "dff73f28-9653-4227-9f6f-e0863b02758f" }, { "cell_type": "code", - "execution_count": 157, + "execution_count": 120, "metadata": { - "id": "71527c4d-cdbb-4249-8b9a-09026d92f9c0", - "outputId": "16a00191-5d4e-4d05-ed16-09f38b9406be", "colab": { "base_uri": "https://localhost:8080/", "height": 52 - } + }, + "id": "eb3d74ad-61f9-45ca-a5c1-750b05a77800", + "outputId": "20b77433-8df3-4254-dc0b-13f4aa40633c" }, "outputs": [ { @@ -4674,18 +4719,18 @@ "\n", "var(y) # yの分散" ], - "id": "71527c4d-cdbb-4249-8b9a-09026d92f9c0" + "id": "eb3d74ad-61f9-45ca-a5c1-750b05a77800" }, { "cell_type": "code", - "execution_count": 158, + "execution_count": 121, "metadata": { - "id": "621648af-6517-49ee-8966-03dd49cffb41", - "outputId": "951aba78-620f-46ac-b05a-f40158783b39", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "596533f1-4b40-4c90-b115-a1952c400827", + "outputId": "363e5479-28d4-49e9-abc2-b4f753c36592" }, "outputs": [ { @@ -4706,18 +4751,18 @@ "source": [ "sum((x - mean(x))^2) / (n - 1)" ], - "id": "621648af-6517-49ee-8966-03dd49cffb41" + "id": "596533f1-4b40-4c90-b115-a1952c400827" }, { "cell_type": "code", - "execution_count": 159, + "execution_count": 122, "metadata": { - "id": "537e40c5-5e61-4ac5-8ec6-9439a1a9762f", - "outputId": "bbb24ff8-71f8-45e7-c8ac-83a6b70870ea", "colab": { "base_uri": "https://localhost:8080/", "height": 52 - } + }, + "id": "63ad097e-dc62-4fae-b29a-5a2b61b3a75a", + "outputId": "4bfbdd41-7e85-4b43-da08-ede455788caf" }, "outputs": [ { @@ -4754,18 +4799,18 @@ "\n", "sd(y) # yの標準偏差" ], - "id": "537e40c5-5e61-4ac5-8ec6-9439a1a9762f" + "id": "63ad097e-dc62-4fae-b29a-5a2b61b3a75a" }, { "cell_type": "code", - "execution_count": 160, + "execution_count": 123, "metadata": { - "id": "16ab0ed2-4e93-41bf-9326-2aec9abaa8b0", - "outputId": "f0a34cb8-2160-409e-eeff-641eceedba8b", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "c06e57ee-6531-44a3-955e-dba26f9073c0", + "outputId": "2a8f6673-0b67-4ef9-d6c9-c7ece0facd76" }, "outputs": [ { @@ -4786,18 +4831,18 @@ "source": [ "var(x)**0.5 # xの標準偏差" ], - "id": "16ab0ed2-4e93-41bf-9326-2aec9abaa8b0" + "id": "c06e57ee-6531-44a3-955e-dba26f9073c0" }, { "cell_type": "code", - "execution_count": 161, + "execution_count": 124, "metadata": { - "id": "2b75fffa-83d3-4ce2-9b8c-54df291cc4f4", - "outputId": "8c58fe64-e715-4655-e1a1-c1e6259844f1", "colab": { "base_uri": "https://localhost:8080/", - "height": 164 - } + "height": 181 + }, + "id": "894e6554-a14e-431e-9f99-997a5d73c447", + "outputId": "eede276c-918f-4d8b-ac04-f72e7215569a" }, "outputs": [ { @@ -4858,18 +4903,18 @@ "\n", "pastecs::stat.desc(x)" ], - "id": "2b75fffa-83d3-4ce2-9b8c-54df291cc4f4" + "id": "894e6554-a14e-431e-9f99-997a5d73c447" }, { "cell_type": "code", - "execution_count": 162, + "execution_count": 125, "metadata": { - "id": "47edfb1e-99f3-40c8-bfbe-505370248e95", - "outputId": "0348a8de-1bdd-40d9-d9a1-165138971a8e", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "0c752c7f-e6d8-4e22-bce2-7cd432047aa8", + "outputId": "1bf8383d-7855-4317-e01d-a2565cc59c8a" }, "outputs": [ { @@ -4896,18 +4941,18 @@ "source": [ "quantile(x)" ], - "id": "47edfb1e-99f3-40c8-bfbe-505370248e95" + "id": "0c752c7f-e6d8-4e22-bce2-7cd432047aa8" }, { "cell_type": "code", - "execution_count": 163, + "execution_count": 126, "metadata": { - "id": "4bc4314c-3a9d-4e20-89d2-2a87345caba1", - "outputId": "f4a7cd1a-9d6f-48b2-e3a4-c38a855e678b", "colab": { "base_uri": "https://localhost:8080/", "height": 69 - } + }, + "id": "2af816e8-c0f7-4b9d-b4f5-a575e7b8803b", + "outputId": "7afa65ce-d0ed-42b1-8405-eb3905553327" }, "outputs": [ { @@ -4963,18 +5008,18 @@ "n <- length(x)\n", "var(x) * (n - 1) / n # 標本分散" ], - "id": "4bc4314c-3a9d-4e20-89d2-2a87345caba1" + "id": "2af816e8-c0f7-4b9d-b4f5-a575e7b8803b" }, { "cell_type": "code", - "execution_count": 164, + "execution_count": 127, "metadata": { - "id": "0cbe3fd9-6df4-4283-9ae6-ef3dd6f96d95", - "outputId": "523b1bcb-d990-4abf-ec76-9b5825b3e454", "colab": { "base_uri": "https://localhost:8080/", "height": 69 - } + }, + "id": "93784f0c-2fe3-46dd-89d2-9227a029d3fc", + "outputId": "cecebaf3-88f0-4020-8b70-9629483a090a" }, "outputs": [ { @@ -5027,18 +5072,18 @@ "# あるいは\n", "sd(x) * sqrt((n - 1) / n) # √標本分散" ], - "id": "0cbe3fd9-6df4-4283-9ae6-ef3dd6f96d95" + "id": "93784f0c-2fe3-46dd-89d2-9227a029d3fc" }, { "cell_type": "code", - "execution_count": 165, + "execution_count": 128, "metadata": { - "id": "ef1db35f-6acb-4889-8115-28d28b29ce17", - "outputId": "0989ebde-4511-43df-8711-784b857d9273", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "36ee9470-868d-46ae-9703-2620bcf8ca3c", + "outputId": "edc09a27-4a22-4e23-f6b4-c091a7590239" }, "outputs": [ { @@ -5059,13 +5104,13 @@ "source": [ "sd(x) / length(x)**0.5" ], - "id": "ef1db35f-6acb-4889-8115-28d28b29ce17" + "id": "36ee9470-868d-46ae-9703-2620bcf8ca3c" }, { "cell_type": "code", - "execution_count": 166, + "execution_count": 129, "metadata": { - "id": "332fe843-0778-4b12-9fff-2b43596c830c" + "id": "f0bb78e4-37b3-4481-b1cb-3b59ffbb59f6" }, "outputs": [], "source": [ @@ -5077,18 +5122,18 @@ " math = c( 70, 80, 90, 100),\n", " gender = c(\"f\", \"m\", \"m\", \"f\"))" ], - "id": "332fe843-0778-4b12-9fff-2b43596c830c" + "id": "f0bb78e4-37b3-4481-b1cb-3b59ffbb59f6" }, { "cell_type": "code", - "execution_count": 167, + "execution_count": 130, "metadata": { - "id": "caf3ce7f-cb7b-41a2-80a2-da41ad2c9538", - "outputId": "3a542890-bd76-4655-daff-d1105a4f0a38", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "d463b807-3c18-4d43-9eef-f4c27126046b", + "outputId": "55fb8ff9-e920-4be1-bbe5-2604426ab465" }, "outputs": [ { @@ -5109,18 +5154,18 @@ "source": [ "var(my_df$english)" ], - "id": "caf3ce7f-cb7b-41a2-80a2-da41ad2c9538" + "id": "d463b807-3c18-4d43-9eef-f4c27126046b" }, { "cell_type": "code", - "execution_count": 168, + "execution_count": 131, "metadata": { - "id": "21a4dab3-6811-43b7-9f45-82c62f0bf859", - "outputId": "af9c3340-5fc0-4fc6-e688-67ba3c65a434", "colab": { "base_uri": "https://localhost:8080/", - "height": 469 - } + "height": 468 + }, + "id": "e2b4d8f5-b14b-4d8a-a335-3a8066c5a0a0", + "outputId": "77100031-fd89-4bfb-cb44-dae41ed92f6b" }, "outputs": [ { @@ -5262,18 +5307,18 @@ " where(is.numeric), # 数値の列の\n", " function(x) { var(x) })) # 不偏分散\n" ], - "id": "21a4dab3-6811-43b7-9f45-82c62f0bf859" + "id": "e2b4d8f5-b14b-4d8a-a335-3a8066c5a0a0" }, { "cell_type": "code", - "execution_count": 169, + "execution_count": 132, "metadata": { - "id": "49cbde6f-18d7-4b21-95a0-16cee9aa2313", - "outputId": "4b0a8010-18f6-4b04-8202-a217ba793c8d", "colab": { "base_uri": "https://localhost:8080/", - "height": 744 - } + "height": 763 + }, + "id": "a07e482d-2f59-4557-af74-a54aa2d2f4fd", + "outputId": "396d5e90-26f2-4a91-bf28-972cd8482dbb" }, "outputs": [ { @@ -5370,18 +5415,18 @@ "pastecs::stat.desc(my_df)\n", "# 以下省略" ], - "id": "49cbde6f-18d7-4b21-95a0-16cee9aa2313" + "id": "a07e482d-2f59-4557-af74-a54aa2d2f4fd" }, { "cell_type": "code", - "execution_count": 170, + "execution_count": 133, "metadata": { - "id": "414c96a1-e2d2-4cb9-b18c-2776f218b12b", - "outputId": "1931ff61-6c20-43af-cf6b-23363b8f187d", "colab": { "base_uri": "https://localhost:8080/", - "height": 69 - } + "height": 71 + }, + "id": "3e0811e3-8ae0-49c6-b611-7b7c81322ecb", + "outputId": "74f67fce-42d9-4eac-e2fd-a27ae013a119" }, "outputs": [ { @@ -5399,18 +5444,18 @@ "source": [ "table(my_df$gender)\n" ], - "id": "414c96a1-e2d2-4cb9-b18c-2776f218b12b" + "id": "3e0811e3-8ae0-49c6-b611-7b7c81322ecb" }, { "cell_type": "code", - "execution_count": 171, + "execution_count": 134, "metadata": { - "id": "0b457dfe-a1cf-410c-9ded-072ec5ca288f", - "outputId": "9c6901a3-72e5-493b-c3a1-322d36fdaf17", "colab": { "base_uri": "https://localhost:8080/", - "height": 86 - } + "height": 89 + }, + "id": "3f39bc67-babf-4305-93e6-44d6b9bb7c19", + "outputId": "76ecdce4-40bd-4c85-b52f-ade1dfb487a9" }, "outputs": [ { @@ -5432,18 +5477,18 @@ " excel = my_df$math >= 80)\n", "table(my_df2)\n" ], - "id": "0b457dfe-a1cf-410c-9ded-072ec5ca288f" + "id": "3f39bc67-babf-4305-93e6-44d6b9bb7c19" }, { "cell_type": "code", - "execution_count": 172, + "execution_count": 135, "metadata": { - "id": "0bf20769-f5af-44de-9f93-5ff3e4d3d300", - "outputId": "4e1011b6-0593-49da-863d-38fdfd9336e2", "colab": { "base_uri": "https://localhost:8080/", - "height": 161 - } + "height": 160 + }, + "id": "aa37b858-8a84-40d6-8702-9c787fd2b09d", + "outputId": "28aa6f17-2523-46df-f10b-f7889fe8027d" }, "outputs": [ { @@ -5479,28 +5524,28 @@ " where(is.numeric), mean),\n", " .groups = \"drop\") # グループ化解除\n" ], - "id": "0bf20769-f5af-44de-9f93-5ff3e4d3d300" + "id": "aa37b858-8a84-40d6-8702-9c787fd2b09d" }, { - "id": "309ee210", + "id": "859a3929", "cell_type": "markdown", "source": [ "## 4.2 データの可視化" ], "metadata": { - "id": "309ee210" + "id": "859a3929" } }, { "cell_type": "code", - "execution_count": 173, + "execution_count": 136, "metadata": { - "id": "9f3a41d0-5c3a-4983-bd8a-a0dbf17ea6c7", - "outputId": "b90348c0-e82f-4f48-cec9-d0f2541b598e", "colab": { "base_uri": "https://localhost:8080/", "height": 286 - } + }, + "id": "b00eb78e-fc56-4791-9c71-6c8df967ce9d", + "outputId": "34d63a74-e572-4cdf-f2ce-2fc80329be64" }, "outputs": [ { @@ -5541,18 +5586,18 @@ "source": [ "head(iris)" ], - "id": "9f3a41d0-5c3a-4983-bd8a-a0dbf17ea6c7" + "id": "b00eb78e-fc56-4791-9c71-6c8df967ce9d" }, { "cell_type": "code", - "execution_count": 174, + "execution_count": 137, "metadata": { - "id": "53278c58-cadd-406c-ba0a-9f6572d7089c", - "outputId": "39910b19-604a-47f4-83bc-e89cccb3052e", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "b9e45600-719b-4911-bb55-eb457b657024", + "outputId": "6999a1e2-b927-40d6-e071-a05091bc9d7e" }, "outputs": [ { @@ -5574,18 +5619,18 @@ "source": [ "hist(iris$Sepal.Length)" ], - "id": "53278c58-cadd-406c-ba0a-9f6572d7089c" + "id": "b9e45600-719b-4911-bb55-eb457b657024" }, { "cell_type": "code", - "execution_count": 175, + "execution_count": 138, "metadata": { - "id": "257fa4cd-4a7f-4402-afb3-cf074f5d1b19", - "outputId": "347b4a35-6997-4cb9-a0a7-481dec78b118", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "793efce0-3bf8-4c28-bfe6-1fb90e155e71", + "outputId": "7850075e-f138-4b39-b0f8-e1848e5be342" }, "outputs": [ { @@ -5608,18 +5653,18 @@ "x <- c(10, 20, 30)\n", "hist(x, breaks = 2) # 階級数は2" ], - "id": "257fa4cd-4a7f-4402-afb3-cf074f5d1b19" + "id": "793efce0-3bf8-4c28-bfe6-1fb90e155e71" }, { "cell_type": "code", - "execution_count": 176, + "execution_count": 139, "metadata": { - "id": "b0f629ca-594c-48f6-9404-5fbc83191f97", - "outputId": "7eed8813-9018-4eca-f6b2-1a90627bc4b0", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "9f36b11e-1001-4870-a529-9c0dc460d564", + "outputId": "0daf46f1-55fe-4eb8-e599-03e0c939ecf6" }, "outputs": [ { @@ -5644,18 +5689,18 @@ " length.out = 10)\n", "hist(x, breaks = tmp, right = FALSE)" ], - "id": "b0f629ca-594c-48f6-9404-5fbc83191f97" + "id": "9f36b11e-1001-4870-a529-9c0dc460d564" }, { "cell_type": "code", - "execution_count": 177, + "execution_count": 140, "metadata": { - "id": "708973b1-0669-4889-af5b-0dad5245b203", - "outputId": "36357504-0029-47ba-fb92-7162e30b2220", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "f814d3be-428d-44a6-b369-2a9db1a89170", + "outputId": "2882edaa-b4ce-4b59-c005-9e3e4077f5a2" }, "outputs": [ { @@ -5678,18 +5723,18 @@ "plot(iris$Sepal.Length,\n", " iris$Sepal.Width)" ], - "id": "708973b1-0669-4889-af5b-0dad5245b203" + "id": "f814d3be-428d-44a6-b369-2a9db1a89170" }, { "cell_type": "code", - "execution_count": 178, + "execution_count": 141, "metadata": { - "id": "b9c0aec3-fb29-4d78-8641-37ccc6f9b520", - "outputId": "eaa1e1ad-540a-49bb-ddb0-4b214edbac79", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "fc8d9f3f-d183-46d2-8539-364d83b56df2", + "outputId": "05b4f774-b77b-45e6-fc9a-6dd367dee98b" }, "outputs": [ { @@ -5711,18 +5756,18 @@ "source": [ "boxplot(iris[, -5])" ], - "id": "b9c0aec3-fb29-4d78-8641-37ccc6f9b520" + "id": "fc8d9f3f-d183-46d2-8539-364d83b56df2" }, { "cell_type": "code", - "execution_count": 179, + "execution_count": 142, "metadata": { - "id": "19eeb55e-4a4f-4386-9546-4b4d1469eaa5", - "outputId": "88122725-36f5-401e-f7c8-59c329c5545d", "colab": { "base_uri": "https://localhost:8080/", - "height": 224 - } + "height": 223 + }, + "id": "d72d959c-1049-4aab-8024-44a18dd37367", + "outputId": "e9e17836-39e2-4f65-d79e-04f5f2fc236f" }, "outputs": [ { @@ -5761,18 +5806,18 @@ "my_df <- psych::describe(iris[, -5])\n", "my_df %>% select(mean, sd, se)" ], - "id": "19eeb55e-4a4f-4386-9546-4b4d1469eaa5" + "id": "d72d959c-1049-4aab-8024-44a18dd37367" }, { "cell_type": "code", - "execution_count": 180, + "execution_count": 143, "metadata": { - "id": "805f6cda-3360-49a5-a8ac-f376d4cd92b5", - "outputId": "321bbb92-b49b-4ed2-8241-770670a44509", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "9adf6667-9b48-4cc9-8410-5d3792bc5605", + "outputId": "29a48650-6db3-4e12-998a-4d4e30d8f781" }, "outputs": [ { @@ -5798,18 +5843,18 @@ " geom_errorbar(aes(ymin = mean - se, ymax = mean + se)) +\n", " xlab(NULL)" ], - "id": "805f6cda-3360-49a5-a8ac-f376d4cd92b5" + "id": "9adf6667-9b48-4cc9-8410-5d3792bc5605" }, { "cell_type": "code", - "execution_count": 181, + "execution_count": 144, "metadata": { - "id": "80e9dd66-5c40-4be6-86e3-989411b146b8", - "outputId": "8d400b4c-22df-48a4-e13e-881edc83faa2", "colab": { "base_uri": "https://localhost:8080/", "height": 286 - } + }, + "id": "05ee6831-0f45-42b8-ad96-87dab5aea830", + "outputId": "622d7ec6-fe96-4f3d-874f-de86eed5548d" }, "outputs": [ { @@ -5861,18 +5906,18 @@ "my_df$se <- tmp$value\n", "head(my_df)" ], - "id": "80e9dd66-5c40-4be6-86e3-989411b146b8" + "id": "05ee6831-0f45-42b8-ad96-87dab5aea830" }, { "cell_type": "code", - "execution_count": 182, + "execution_count": 145, "metadata": { - "id": "1d4e9cf1-2d2e-4664-9686-5e5b4a595a92", - "outputId": "bca7b1d7-1ba8-4250-ddd3-c7acce905086", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "204f9e39-9584-4428-a8de-76869b9c6cc6", + "outputId": "8e687c32-ee3b-49a5-e5a5-0464cc1c1bd1" }, "outputs": [ { @@ -5897,18 +5942,18 @@ " geom_col(position = \"dodge\") +\n", " geom_errorbar(aes(ymin = value - se, ymax = value + se), position = \"dodge\")" ], - "id": "1d4e9cf1-2d2e-4664-9686-5e5b4a595a92" + "id": "204f9e39-9584-4428-a8de-76869b9c6cc6" }, { "cell_type": "code", - "execution_count": 183, + "execution_count": 146, "metadata": { - "id": "d3fc1522-a946-43fd-adbb-811b11385c86", - "outputId": "16ddd992-d42d-4109-b12c-06bdec63847a", "colab": { "base_uri": "https://localhost:8080/", "height": 857 - } + }, + "id": "6b0f72a0-828d-4d6a-b55d-89bb72033bb2", + "outputId": "18e05e8c-1671-4502-94a0-26475c046284" }, "outputs": [ { @@ -5956,18 +6001,18 @@ " geom_bar(stat = \"summary\", fun = mean, position = \"dodge\") +\n", " stat_summary(geom = \"errorbar\", fun.data = mean_se, position = \"dodge\")" ], - "id": "d3fc1522-a946-43fd-adbb-811b11385c86" + "id": "6b0f72a0-828d-4d6a-b55d-89bb72033bb2" }, { "cell_type": "code", - "execution_count": 184, + "execution_count": 147, "metadata": { - "id": "7b615afc-fd3b-4656-98a6-0c5cd35fb32b", - "outputId": "fa804c56-e7e9-4e15-d9b1-ac6cb196ce05", "colab": { "base_uri": "https://localhost:8080/", - "height": 524 - } + "height": 527 + }, + "id": "fa070828-980c-40f1-b950-2e323cde2bf5", + "outputId": "3e8a9b0c-d001-440a-e090-3d5b601fafc6" }, "outputs": [ { @@ -6009,18 +6054,18 @@ " formula = ~ Species + w_Sepal,\n", " data = my_df)" ], - "id": "7b615afc-fd3b-4656-98a6-0c5cd35fb32b" + "id": "fa070828-980c-40f1-b950-2e323cde2bf5" }, { "cell_type": "code", - "execution_count": 185, + "execution_count": 148, "metadata": { - "id": "9af60bc2-684d-4ce3-a8ed-7b507f8a7c07", - "outputId": "4bfd3735-bded-472f-bc4f-025a84f3a49c", "colab": { "base_uri": "https://localhost:8080/", - "height": 472 - } + "height": 473 + }, + "id": "0152dbda-c942-41cf-bb29-f1ed777302ab", + "outputId": "361e329a-fef3-4c4a-acee-eaa64f3d0ef2" }, "outputs": [ { @@ -6052,18 +6097,18 @@ "vcd::mosaic(formula = ~w_Sepal + Species, data = my_df,\n", " labeling = labeling_values)" ], - "id": "9af60bc2-684d-4ce3-a8ed-7b507f8a7c07" + "id": "0152dbda-c942-41cf-bb29-f1ed777302ab" }, { "cell_type": "code", - "execution_count": 186, + "execution_count": 149, "metadata": { - "id": "c2248ce2-0ee2-4d76-8b38-524036babf4c", - "outputId": "73d68aa4-0b8a-424f-c2da-ab6be58e12d7", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "fbae3bbd-123a-46bc-84f0-5561eb41b47a", + "outputId": "878a704a-54bd-41d3-ea3c-6e1adb9eea4d" }, "outputs": [ { @@ -6085,18 +6130,18 @@ "source": [ "curve(x^3 - x, -2, 2)" ], - "id": "c2248ce2-0ee2-4d76-8b38-524036babf4c" + "id": "fbae3bbd-123a-46bc-84f0-5561eb41b47a" }, { "cell_type": "code", - "execution_count": 187, + "execution_count": 150, "metadata": { - "id": "80a0d968-6a25-406a-b672-d8fab9d51f94", - "outputId": "6244cd5c-1224-4ead-bcf9-7e72e6aa70cc", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "83ea5cc6-a0de-46ad-aa23-04f1cee61994", + "outputId": "0ab8950b-0816-46e9-e71f-3f771885476a" }, "outputs": [ { @@ -6124,18 +6169,18 @@ " geom_histogram(breaks = tmp,\n", " closed = \"left\")" ], - "id": "80a0d968-6a25-406a-b672-d8fab9d51f94" + "id": "83ea5cc6-a0de-46ad-aa23-04f1cee61994" }, { "cell_type": "code", - "execution_count": 188, + "execution_count": 151, "metadata": { - "id": "cfb7d48f-ce30-4df6-8a60-2a0ed1aa2368", - "outputId": "a42e9970-6506-4cf7-e7d6-7bf7fb60ad03", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "0a25b6eb-2b6f-4d57-bd99-b9ce3a302a57", + "outputId": "fe0d3859-5a84-45f6-f926-3d4354552cb3" }, "outputs": [ { @@ -6160,18 +6205,18 @@ " y = Sepal.Width)) +\n", " geom_point()" ], - "id": "cfb7d48f-ce30-4df6-8a60-2a0ed1aa2368" + "id": "0a25b6eb-2b6f-4d57-bd99-b9ce3a302a57" }, { "cell_type": "code", - "execution_count": 189, + "execution_count": 152, "metadata": { - "id": "40c812bc-722f-451a-a013-2827c60e2cf7", - "outputId": "6b63ac4c-9a22-4709-fd43-0245074b158d", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "ea270979-ca1c-4838-8204-f85711ac50f0", + "outputId": "9024555b-a914-47f6-89db-2dee371d66c9" }, "outputs": [ { @@ -6200,18 +6245,18 @@ " geom_boxplot() +\n", " xlab(NULL)" ], - "id": "40c812bc-722f-451a-a013-2827c60e2cf7" + "id": "ea270979-ca1c-4838-8204-f85711ac50f0" }, { "cell_type": "code", - "execution_count": 190, + "execution_count": 153, "metadata": { - "id": "9d1fcb62-1467-4fa8-b19e-82c0d57eaedf", - "outputId": "f3b93654-cd8d-48f4-b5ae-5ff14b69fa51", "colab": { "base_uri": "https://localhost:8080/", - "height": 784 - } + "height": 797 + }, + "id": "6293859e-8b19-4e2e-83ee-78e711160c28", + "outputId": "a3a17da0-1fe0-407e-9af3-b3299f256991" }, "outputs": [ { @@ -6266,18 +6311,18 @@ " geom_mosaic(\n", " aes(x = product(w_Sepal, Species)))" ], - "id": "9d1fcb62-1467-4fa8-b19e-82c0d57eaedf" + "id": "6293859e-8b19-4e2e-83ee-78e711160c28" }, { "cell_type": "code", - "execution_count": 191, + "execution_count": 154, "metadata": { - "id": "9e9a8187-1a8e-49e4-adcb-ae1e9b1aea07", - "outputId": "967f5df2-6981-4930-d233-3bf58864a7b1", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "0b321c17-ba71-4795-b1c4-dfac12424438", + "outputId": "2b4883e8-4406-46df-e1e7-dca36630e803" }, "outputs": [ { @@ -6302,28 +6347,28 @@ " ggplot(aes(x = x)) +\n", " stat_function(fun = f)" ], - "id": "9e9a8187-1a8e-49e4-adcb-ae1e9b1aea07" + "id": "0b321c17-ba71-4795-b1c4-dfac12424438" }, { - "id": "7645502c", + "id": "dcd7da02", "cell_type": "markdown", "source": [ "## 4.3 乱数" ], "metadata": { - "id": "7645502c" + "id": "dcd7da02" } }, { "cell_type": "code", - "execution_count": 192, + "execution_count": 155, "metadata": { - "id": "ae55c5ce-f9ee-4c43-b73c-9e18592b1595", - "outputId": "38c4d884-2aab-4859-fb70-b2f65a19a29e", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "e5f38459-2c0a-4d1a-a002-b0d6caaac449", + "outputId": "fc093cea-8660-4825-808d-85d33662b78e" }, "outputs": [ { @@ -6332,7 +6377,7 @@ "text/plain": [ "Plot with title “Histogram of x”" ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAAC/VBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUW\nFhYXFxcYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMkJCQlJSUmJiYnJyco\nKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6\nOjo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tM\nTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1e\nXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1ubm5vb29w\ncHBxcXFzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+fn5/f3+AgICBgYGCgoKD\ng4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OUlJSV\nlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGioqKjo6OkpKSlpaWmpqan\np6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O0tLS1tbW2tra3t7e4uLi5\nubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTFxcXGxsbHx8fIyMjJycnKysrL\ny8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc3Nzd\n3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u7u7v\n7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7+/v8/Pz9/f3+/v7///9B8z1b\nAAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO3dD5zVdZ3v8e8wDMOAiKigooB/s9ve\nBMHSVvFSmH9SAnNXRWtBMDXRpbBLJop/Vk1Y/7RG/umau7m5ZUpbds0rq9jaWqnkvam0idgN\n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\nrkJggg==" + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAAC/VBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUW\nFhYXFxcYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMkJCQlJSUmJiYnJyco\nKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6\nOjo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tM\nTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1e\nXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1ubm5vb29w\ncHBxcXFzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+fn5/f3+AgICBgYGCgoKD\ng4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OUlJSV\nlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGioqKjo6OkpKSlpaWmpqan\np6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O0tLS1tbW2tra3t7e4uLi5\nubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTFxcXGxsbHx8fIyMjJycnKysrL\ny8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc3Nzd\n3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u7u7v\n7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7+/v8/Pz9/f3+/v7///9B8z1b\nAAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO3dC3hV9Znv8X8SNiHhJiqI3L1Q5zin\ngqijjtJDC/VSpWCdUdF2QLBewJYWO9SK4mWUFkZsx1IvPepMnTotVTqtHvXIIM7Ysa1CPacq\nnRq1p6jUa6gFETBkPWftvXPhsrOSN+//v/bKu7+f55lkAytrhczv29yWxEUA1Fy5XwHAAkIC\nPCAkwANCAjwgJMADQgI8ICTAA0ICPCAkwANCAjwgJMADQgI8ICTAA0ICPCAkwANCAjwgJMAD\nQgI8ICTAA0ICPCAkwANCAjwgJMADQgI8ICTAA0ICPCAkwANCAjwgJMADQgI8ICTAA0ICPCAk\nwANCAjwgJMADQgI8ICTAA0ICPCAkwANCKpsfOVdbtouvnNCn7tBtZbu8PYSUlu865zYXH052\n7tTyhvQLl7elXJc3iJDSsk9IDbfccus+R71R436TwitziXMDb/nezhSuVCkIKS37hFTSP7hU\nQjrduUtSuEwFIaS0dC2kk9IJKX4NFqRwmQpCSGnp8HOkD++YPLjX4GNvejuKzih86uLmx7/7\n3o3HD8oNOeXupuKL3H1M/f5nPPNK/IcfRNFdzn3swy8eOCSKmv/llMG9+v/FP+SPin93YvSj\n8XWjr9oZbZi6X99PPr/75Xc/3yXFy7R+jrS6yrnH4+eNBxUvjW4gpLR0FNLOSS2zPvSl3UL6\nP8NbfvfEd/Iv8eXC49oV8ZP4V/c5d9TNztVE0QUtR53ZHEU/cO6/r6zK/2reKwfmnw3+Y/vV\n9zjfXiHlz3543Oec+AQfpPo2MYSQ0tJRSLc592f/8tSjZzv3P6IXfhIf9P0nX4ka490fctu/\nLuzl3BnxMU/Hvz3+u/f+Zb9CPfmXHDMyN/6I6EHnqr/z3F3xUSsLv3vwiE9fPjA+7enD5h8f\nv8gtbRff83wvPXmsc+c9+eSulj/d/lHnrozWVrna/5vyG8UOQkrLd93u2kOa5dzN8bOdMy7/\n+q7oD674OdJ1zg14PX5+b/zrdVF0sXP7xe9Jto1uC8mNfTV+8O0zzsh/LPZp5/6m+Lt/HUUP\nxM/6vBztOMK5qW0X3+t8e3+O9Ota1+uXH3FueVpvDHsIKS0dhfRF50Z9742Wg1pDGufcrPyv\nmwY5d30UHenc5/K/vLo9pPt2O/UXnDul+LtPx0XWOjcj/s0r4ndibUfsdb59vtiw3Ll656Y0\nh/rL20dIacmHNHJ0QZ/dQ3q2Ph/WYXMeyH8ZoCWk5l7Fd1NRdGKhiviQm/K/ur89pGJ6q6cd\nWlsIc3Lxd/P3Koxwbkn8LP4k6rDWa+99vn1Cap4Sv/D+rwd/I9hFSGnp8Kt2a/+8+E5qzFNt\n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\n0O+CXyr6xfTBNftN+Wn4CxWk9MWGp07fr9ewv0nl9obm28f1Gfgpb1/V4D+jADwgJMADQgI8\nICTAA0ICPCAkwANCAjwgJMADQgI8ICTAA0ICPCAkwANCAjwgJMADQgI8ICTAA0ICPCAkwANC\nAjwgJMADQgI8ICTAA0ICPCAkwANCAjwgJMADQgI8ICTAA0ICPCAkwANCAjwgJMADQgI8ICTA\nA0ICPCAkwANCAjwgpJ5pddWM/LPTq58s92uCAkLqoS51q6Pofvflcr8eKCKkHmrLmLHbt478\nyLZyvx4oIqSe6vGqxVdUP1Xu1wItCKnHmlub+0q5Xwe0IqQea71zz5X7dUArQuqpdp140AET\nm8v9WqAFIfVUy9wP7nHfLPdrgRaE1EP9tu5TUfTx+hfL/XqgiJB6pl0n9v1/cU21J+0q92uC\nAkLqmf7eLc8/u97dXO7XBAWEBHhASIAHhAR4QEiAB4QEeEBIgAeEBHhASIAHhAR4QEiAB4QE\neEBIgAeEBHhASIAHhAR4QEiAB4QEeEBIgAeEBHhASIAHhAR4QEiAB4QEeEBIgAeEBHhASIAH\nhAR4QEiAB4QEeEBIgAeEBHjw/wE3vNGz8UMXdQAAAABJRU5ErkJggg==" }, "metadata": { "image/png": { @@ -6348,18 +6393,18 @@ " replace = TRUE) # 重複あり\n", "hist(x, breaks = 0:6) # ヒストグラム" ], - "id": "ae55c5ce-f9ee-4c43-b73c-9e18592b1595" + "id": "e5f38459-2c0a-4d1a-a002-b0d6caaac449" }, { "cell_type": "code", - "execution_count": 193, + "execution_count": 156, "metadata": { - "id": "51c20e34-5558-46a1-b87a-bfec7392d50f", - "outputId": "2dc7aae4-1ed1-4188-e32f-c8b485d6b1af", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "a9da263d-a3df-4ac0-90b7-0bf57c296c55", + "outputId": "6a9d9583-0141-436d-8fb0-9eb14e850491" }, "outputs": [ { @@ -6368,7 +6413,7 @@ "text/plain": [ "Plot with title “Histogram of x”" ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAAC/VBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUW\nFhYXFxcYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMkJCQlJSUmJiYnJyco\nKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6\nOjo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tM\nTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1e\nXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1ubm5vb29w\ncHBxcXFycnJzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+fn5/f3+AgICBgYGC\ngoKDg4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OU\nlJSVlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGioqKjo6OkpKSlpaWm\npqanp6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O1tbW2tra3t7e4uLi5\nubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTFxcXGxsbHx8fIyMjJycnKysrL\ny8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc3Nzd\n3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u7u7v\n7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7+/v8/Pz9/f3+/v7///9P/i37\nAAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO2dDXgV5Zmw3ySchEQDBQURJQGVuquf\nJaJWrNKiUPxBxG+tImpLSqxVQGM/7LLdIiAWtbDiupZ1i58/1d2upUq3a63bLMVdrbWVtJ+i\n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\nkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6f\nkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6f\nkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6f\nkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6f\nkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6f\nkIQGia/bJyShQeLr9glJaJD4un1CEhokvm7fmZBaN9etWbN2ywH2IiR8N31HQmqcN9RkqFiy\nM2g/QsJ303cjpK2jzOjqRcuWLZgx3IxpDNiRkPDd9N0IqSa1um2rZWVBbcCOhITvpu9GSMNm\ndW5PHxGwIyHhu+m7EVJqaef24uL9/vLVIYM6KDfNvdxFTWpAThTi4+dAqibsxd8DoUOqvKRz\ne9rI/f5y77q6Dn7xz73dxda63PjRj/Dxc2Br2Iu/B0KHVFuwvCm7tWOhmS91OAD5SeiQto01\n5ROr586ZOaHMjN8ueUgA+Uf47yPtXlFVlP42UmrcqhbBAwLIR3J6idCuTfX1Db09JwegiOhf\nawegAEICEICQAAQgJAABCAlAAEICEICQAAQgJAABCAlAAEICEICQAAQgJAABCAlAAEICEICQ\nAAQgJAABCAlAAJshjTMAFhkneDHbDOmyqeutMpX1da9/meDFbDOkasmfdMn6rG9zfUJifdYX\ngJBYn/UFICTWZ30BCIn1WV8AQmJ91heAkFif9QUgJNZnfQEIifVZXwBCYn3WF8BmSFddZXFx\n1md9yfVthtTYaHFx1md9yfX5ZxQAAhASgACEBCAAIQEIQEgAAhASgACEBCAAIQEIQEgAAhAS\ngACEBCAAIQEIQEgAAhASgACEBCAAIQEIEHtI22orU4fXbA14R8zrN86rKB457dfW1k/zDVNj\nb/3HP3/wwDPXWVv/5SuG9Tv0wt/Etb7X/DeFJwUeUDjiDmn3WHPR0lmpUY29viPm9T8Yaabc\neHm//i9YWj/Nc0WxhdR9/fvM0QtuGFL8K0vrv1g+eOGDNw/rtzae9b2NY8u7hCR1/cUd0grz\nXf/tj8y8Xt8R8/pzzF3+20fNeZbW99lTNSa2kLqt/87BJ+7wvIaDZ1ta/zLzS//t82ZCPOt/\nVHpyQ8m+IUldf3GHVFXelL45Zmhrb++Ief3rJzb7b1tLK2NZvsfTva3g57GF1G395eaJ9E08\n0+9h/VNNev7egJHxrP/BvGavS0hS11/MIe0qmpi5rTabe3lHzOu30ZQ6PY7le1z/ldJrtsUV\nUvf1zy5t9po+imf1ntafaTb4b98rPDeuQ/C6hCR2/cUc0iaT/Vlii0xdL++Ief027sx8gmdn\n/YmHfxhbSN3Xrzzud6cXmKPvt7X+xkFjnnrrdxPLno3nANLsG5LY9RdzSPVmTuZ2uVnTyzti\nXj/Lk8Vn7Ilj+Z7Wv9884sUWUvf1yysPn/fInRXmXyyt7/3hOGNMxTOxLJ9l35DErr/YQ5qb\nuV1mftLLO2JeP8MPS8Z+EMfqPa3/zuDzvThD2n/9EvMD/+3Wg4e12Fl/46gRtz927/EDY/mE\nJEvXkISuv5hDajAzM7cLzH/28o6Y1/dpXWjO+XMci/e4/qUHvxZjSN3XP6To4/TNxSaW5/+7\nrz+u7A3/7cdHHNEcx/oZ9g1J7PqLOaTd/bJPc84wr/XyjpjX9zuaZa6N5f/GPa7/uLnx9ddf\nf8nMeD2WL/i7n/9JRZkreLaJ5RtJ3dbfXnBm5vYr5sU41s+wb0hi11/cT3+fWpb+H+De4SN6\nfUfM63u15pZ4lu5x/XmmnflW1vfmmsyX+ZPNFivrv2tOy9xeYtbHsn6aLk9/S11/cYe0yiz2\n395tbvK8Xb9/pes7rKz/qKmNZ+We19/4WJqHzeTHXrayvre+4Kwmz3uu8DOxLN99/VGpP/pv\ntw0e0BTPAXgdIclef3GH1DLeTLvp0oIT/P8NbDATu77DyvpHm2vnZ4jnNUrd1s8Q29dIPax/\nvam66Wulxessrb+m8JBv37d0lFkZz/pP+o900TD/zfvC11/sL1rdfkNl6og56SfJ2h7IzndY\nWb/jU6s/2Vk/Q3whdV+/9Z/G9B943m+trf/MhUP6DZr0s5iWv7X94W4Qvv74ZxQAAhASgACE\nBCAAIQEIQEgAAhASgACEBCAAIQEIQEgAAhASgACEBCAAIQEIQEgAAhASgACEBCAAIQEIQEgA\nAhASgACEBCAAIQEIQEgAAhASgACEBCAAIQEIQEgAAhASgACEBCAAIQEIQEgAAhASgACEBCAA\nIQEIQEgAAhASgACEBCAAIQEIQEgAAhBSflJXMCN9c27hU7aPBDIQUp5ytanzvEfMN2wfB2Qh\npDxl+8jRTTtGfHqn7eOALISUr/yyYNENhc/YPgpog5DyltklqW/aPgZoh5DylnpjNtg+BmiH\nkPKVvacddsj4VttHAW0QUr6y3Dx8v/l720cBbRBSnvLH0vM878yyTbaPA7IQUn6y97SD/r9f\nU8npe20fCWQgpPzk78yK9M0Sc7vtI4EMhAQgACEBCEBIAAIQEoAAhAQgACEBCEBIAAIQEoAA\nhAQgACEBCEBIAAIQEoAAhAQgACEBCEBIAAIQEoAAhAQgACEBCEBIAAIQEoAAhAQgACEBCEBI\nAAIQEoAAhAQgACEBCEBIAAIQEoAAhAQgACEBCEBIAAL8D7IloIFZP2VaAAAAAElFTkSuQmCC\n" + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAAC/VBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUW\nFhYXFxcYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMkJCQlJSUmJiYnJyco\nKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6\nOjo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tM\nTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1e\nXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1ubm5vb29w\ncHBxcXFycnJzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+fn5/f3+AgICBgYGC\ngoKDg4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OU\nlJSVlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGioqKjo6OkpKSlpaWm\npqanp6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O1tbW2tra3t7e4uLi5\nubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTFxcXGxsbHx8fIyMjJycnKysrL\ny8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc3Nzd\n3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u7u7v\n7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7+/v8/Pz9/f3+/v7///9P/i37\nAAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO2dC3hU5ZmA/yFMQqKBgnIRIQGVurXb\nJqJWXKWiUC8g4q5VxNqSEmsV0NhFl+0WAbFoCyuua1lXumqru12LSre11m2W4q6X2kra9YYt\n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\n0/PPKX3Y1MkjhITvpB/9v0cqH9k3effmhobG3jJ5qajbv20iJHwn/chC+ijNh89f89kP+uy3\nPvtEb68RemZjJ3cREr6TfvTfI/3t5X0wn5jnv7l3uP8Zp+q/A/cjJHwn/ehD+mUfvrTbUHxw\nm3e/OfiCuZ/rVxL0anFCwnfTjz6kn5cdWJw0rNHzxlZu8zefKp0esCMh4bvpRxbS9gxvb6ju\nw+/+HniN571vbk1vf+VjATsSEr6bfgy/RejeA4sHXed5zYkH09vXDwjYkZDw3fSj+4d9Gc67\noi//1PzkcR963l9ck9psrqoK2JGQ8N303Xhlw0Nm/H9+1HDY9z9seep0c0fAjoSE76bvRkje\ndw8ypcdUmqIik/jrtoD9CAnfTT+ykKo+c2J3DqS+ufLMyvKSQ467qiFwN0LCd9OPLKThpcaY\nhP+/0qIUQisQEr6bfmQhNZ0y7ze7vQ/++6/O6PtLhA4MIeG76UcW0pc7HvisSwVXICR8N/3I\nQhp6Z/vG3w8TXIGQ8N30IwuppOPXMPxNieAKhITvph9ZSMeOzPwR2ccPDfoB658KIeG76UcW\n0o+LzNgp06ccYRIPCK5ASPhu+hH+NYozBxhjik+vF1yAkPAd9aN8ZcPe1za/2vM3MISCkPDd\n9PlDY0KDxNft84fGhAaJr9vnD40JDRJft+/MHxrrG4SE76bvyB8a6yuEhO+m78YfGuszhITv\npu/GHxrrM4SE76bvxh8a6zOEhO+m78YfGuszhITvpu/GHxrrM4SE76bvxh8a6zOEhO+mH92r\nv58XfOBOCAnfTT+ykAZ8S/CBOyEkfDf9yEKacvZewUfugJDw3fQjC+nNWWf9YGNjGsEVCAnf\nTT+GX6Kf++9f7Qkh4bvpRxbSzC/OqW1HcAVCwnfTd+R3f/cVQsJ3048mpNseS9/89jXBB09D\nSPhu+tGEZOoyN/MEHzwNIeG76ROS0CDxdfuEJDRIfN0+IQkNEl+3T0hCg8TX7ROS0CDxdfuE\nJDRIfN1+RCGduCSFOSF9I7gCIeG76UcU0j4IrkBI+G760YR07z4IrkBI+G76vNZOaJD4un1C\nEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1C\nEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1C\nEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1C\nEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1C\nEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1nQmrbUr9u3fqtB9iLkPDd9B0JqWnBMJOmYtmu\noP0ICd9N342Qto0142qWrFixaNZIU9UUsCMh4bvpuxFSbXJt+1br6kRdwI6EhO+m70ZII+Z0\nbc8cHbAjIeG76bsRUnJ51/bS4oAdCQnfTd+NkCov7NqeMSZgR0LCd9N3I6S6xMrmzNbOxWZh\nwI6EhO+m70ZI28eb8sk18+fNnlRmJu4I2JGQ8N303QjJ27Oquij1Y6TkhDWtQfsREr6bviMh\n+eze3NDQ2Fsm71x8QSenm+YsOiHh2/TdCSnNBwtf7HHf+3WXdTKDz0j4TvqOhfSqeSjw43xp\nh++m70ZItR3MMmfU1gbsSEj4bvpuhGT2IWBHQsJ303cjpK8VVT+yPcUL5r7t2wN2JCR8N303\nQvKerk5c8b7H90j4+eo7EpL30bdKRz5ASPj56rsSkue9NNlM30pI+PnpuxOS59095OAlhISf\nl75LIXlvXWQICT8vfadC8ryHF2wK/Dgh4bvpOxbSgSAkfDd9QhIaJL5un5CEBomv2yckoUHi\n6/YJSWiQ+Lp9QhIaJL5un5CEBomv2yckoUHi6/YJSWiQ+Lp9QhIaJL5un5CEBomv2yckoUHi\n6/YJSWiQ+Lp9QhIaJL5un5CEBomv2yckoUHi6/YJSWiQ+Lp9QhIaJL5un5CEBomv2yckoUHi\n6/YJSWiQ+Lp9QhIaJL5un5CEBomv2yckoUHi6/YJSWiQ+Lp9QhIaJL5un5CEBomv2yckoUHi\n6/YJSWiQ+Lp9QhIaJL5un5CEBomv2yckoUHi6/YJSWiQ+Lp9QhIaJL5un5CEBomv2yckoUHi\n6/YJSWiQ+Lp9QhIaJL5un5CEBomv2yckoUHi6/YJSWiQ+Lp9QhIaJL5un5CEBomv2yckoUHi\n6/YJSWiQ+Lp9QhIaJL5un5CEBomv2yckoUHi6/YJSWiQ+Lp9QhIaJL5un5CEBomv2yckoUHi\n6/YJSWiQ+Lp9QhIaJL5un5CEBomv2yckoUHi6/YJSWiQ+Lp9QhIaJL5un5CEBomv2yckoUHi\n6/YJSWiQ+Lp9QhIaJL5un5CEBomv2yckoUHi6/YJSWiQ+Lp9QhIaJL5un5CEBomv2yckoUHi\n6/YJSWiQ+Lp9QhIaJL5un5CEBomv2yckoUHi6/YJSWiQ+Lp9QhIaJL5u35mQ2rbUr1u3fusB\n9iIkfDd9R0JqWjDMpKlYtitoP0LCd9N3I6RtY824miUrViyaNdJUNQXsSEj4bvpuhFSbXNu+\n1bo6URewIyHhu+m7EdKIOV3bM0cH7EhI+G76boSUXN61vbQ4YEdCwnfTdyOkygu7tmeMCdiR\nkPDd9N0IqS6xsjmztXOxWRiwIyHhu+m7EdL28aZ8cs38ebMnlZmJOwJ2JCR8N303QvL2rKou\nSv0YKTlhTWvQfoSE76bvSEg+uzc3NDT2lknrT9Z2cgMh4TvpuxNSB02v7HfHK8MHd1JumrNo\nhIRv03ckpGemVp6yOvNF3cKgR+FLO3w3fTdCerzElCXNqekXBxESfh76boQ0LfmjtuZVyRN2\neoSEn5e+GyGNviT1dn3x1FZCws9L342QkovTN/eYqwgJPy99N0IadW7m9utmBSHh56PvRkhX\nJW5rSd22zTZXX0lI+PnnuxHSuxVmSnqj7SpjCAk//3w3QvLemXt1+9aDRxISfv75joTUVwgJ\n302fkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhok\nvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhok\nvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhok\nvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhok\nvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhok\nvm6fkIQGia/bJyShQRX9wWEAAAg5SURBVOLr9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr\n9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr\n9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr9glJaJD4un1CEhokvm6fkIQGia/bJyShQeLr\n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" }, "metadata": { "image/png": { @@ -6384,18 +6429,18 @@ " n = 1000) # 乱数の数\n", "hist(x)" ], - "id": "51c20e34-5558-46a1-b87a-bfec7392d50f" + "id": "a9da263d-a3df-4ac0-90b7-0bf57c296c55" }, { "cell_type": "code", - "execution_count": 194, + "execution_count": 157, "metadata": { - "id": "111061ee-df8b-4abd-9e27-fb3e13c5003b", - "outputId": "1ecde770-841d-452e-a1ac-814a827cfaaa", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "c320de46-69bd-495c-8bd6-9f6f1fb0a6dd", + "outputId": "dcd685f8-aea9-4cda-f613-a6adecf086b5" }, "outputs": [ { @@ -6404,7 +6449,7 @@ "text/plain": [ "Plot with title “Histogram of x”" ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAAC/VBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUW\nFhYXFxcYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMkJCQlJSUmJiYnJyco\nKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6\nOjo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tM\nTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1e\nXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1ubm5vb29w\ncHBxcXFzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+fn5/f3+AgICBgYGCgoKD\ng4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OUlJSV\nlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGioqKjo6OkpKSlpaWmpqan\np6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O0tLS1tbW2tra3t7e4uLi5\nubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTFxcXGxsbHx8fIyMjJycnKysrL\ny8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc3Nzd\n3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u7u7v\n7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7+/v8/Pz9/f3+/v7///9B8z1b\nAAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO3dC5zVdZ3/8e8wHIbhIqKCinLxlv7b\nTRB1tVX6U5iXlMDcVLQWBPOGLYX9yUTxsl6CvJSZl/7mpptrpLSlf3NlEXdtrVRyN5U2UfuH\n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\niRTSVgyvQEixEJJOnJDu2orhFQgpFkLS4bl2ci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiE\npENIci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6\nhCTncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENI\nci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6hCTn\ncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENIci6H\nQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiE\npENIci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6\nhCTncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENI\nci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6hCTn\ncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENIci6HQEg6hCTncgiEpENIci6H\nQEg6hCTncgiEpENIci6HQEg6hCTncgiEpJObkJpfXLxo0ZKVXRxFSLEQkk5OQlo9e2goGXH5\n+nLHEVIshKSTj5BW7RX2mzZv/vy5U4aF0avLHEhIsRCSTj5CmlFY2Hqv6aa6WWUOJKRYCEkn\nHyHtNr3j/inDyxxISLEQkk4+Qipc2XH/0j5lDiSkWAhJJx8hjTy54/6kUWUOJKRYCEknHyHN\nqluwoeXeukvCnDIHElIshKSTj5DWjA0DJ0w7f+bU8f3CuLVlDiSkWAhJJx8hJRuvG1Nf/DZS\n4fDbmsodR0ixEJJOTkJKvff8smUrtpfJ+uuuaXcuIUVCSDr5CSm18YlHXvrg7756xMHt9g8b\nOnksIekQkk4+QrrikeLLWwanH9wd/HS5A/nQLhZC0slHSKWv1D0QGk48+4gw6IUyBxJSLISk\nk6OQ9hu0PH15X90ZZQ4kpFgISSc/Ib0Rvla6P3mPMgcSUiyEpJOfkFaGu0r35xbKHEhIsRCS\n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\ngf8BEg0NN4X7O2YAAAAASUVORK5CYII=" + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAAC/VBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUW\nFhYXFxcYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMkJCQlJSUmJiYnJyco\nKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6\nOjo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tM\nTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1e\nXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1ubm5vb29w\ncHBxcXFzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+fn5/f3+AgICBgYGCgoKD\ng4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OUlJSV\nlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGioqKjo6OkpKSlpaWmpqan\np6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O0tLS1tbW2tra3t7e4uLi5\nubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTFxcXGxsbHx8fIyMjJycnKysrL\ny8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc3Nzd\n3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u7u7v\n7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7+/v8/Pz9/f3+/v7///9B8z1b\nAAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO3dC5zVdZ3/8e8wDMMMlxEVRO5eyP7t\nJgi22ir9KcxLSmBuKloLgnlDo7AlE8XLKgWr1ip56W+2urlFSlv6t1YWcdfWSiV3U2kTsQ2V\n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\nZyAhtSEknb0upG7dattUE1IbQtLZ60Ka06f9S3V8aNeOkHT2upC2HnHk1tbbhNSOkHT2upCS\nlXWXtt4kpHaEpLP3hZS8/VbrrUfnlziMkGIhJJ28hLSHCCkWQtIhJDmXQyAkHUKSczkEQtIh\nJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKS\nczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmX\nQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkE\nQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAk\nHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIh\nJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKS\nczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmX\nQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkE\nQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAk\nHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIh\nJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKS\nczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmX\nQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkE\nQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAk\nHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIhJDmXQyAkHUKSczkEQtIh\n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\nHEhIsRCSTj5CuuumebOmTh6/LEkWDX6g1IGEFAsh6eQjpHYbtpX8ZUKKhZB08hbSbhBSLISk\nQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqE\nJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hy\nLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdy\nCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodA\nSDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISk\nQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqE\nJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hy\nLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdy\nCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodA\nSDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISk\nQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqE\nJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hy\nLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdy\nCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodA\nSDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISk\nQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqEJOdyCISkQ0hyLodASDqE\n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\nAAAASUVORK5CYII=" }, "metadata": { "image/png": { @@ -6421,18 +6466,18 @@ " n = 1000)) # 乱数の数\n", "hist(x, breaks = 0:6) # 結果は割愛" ], - "id": "111061ee-df8b-4abd-9e27-fb3e13c5003b" + "id": "c320de46-69bd-495c-8bd6-9f6f1fb0a6dd" }, { "cell_type": "code", - "execution_count": 195, + "execution_count": 158, "metadata": { - "id": "9c5a282d-00cd-4e18-b47b-02b945a6edd9", - "outputId": "a5a297c5-4d74-49b1-85cf-f11b9528dc26", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "7f948073-d8be-4480-a67d-adc5f6f8fdc9", + "outputId": "64fbf3ec-d708-429b-84f2-6684a2aafb72" }, "outputs": [ { @@ -6441,7 +6486,7 @@ "text/plain": [ "Plot with title “Histogram of x”" ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAADAFBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUW\nFhYXFxcYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMkJCQlJSUmJiYnJyco\nKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6\nOjo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tM\nTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1e\nXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1ubm5vb29w\ncHBxcXFycnJzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+fn5/f3+AgICBgYGC\ngoKDg4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OU\nlJSVlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGioqKjo6OkpKSlpaWm\npqanp6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O0tLS1tbW2tra3t7e4\nuLi5ubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTFxcXGxsbHx8fIyMjJycnK\nysrLy8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc\n3Nzd3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u\n7u7v7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7+/v8/Pz9/f3+/v7////i\nsF19AAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO3dC5xUZf348WfZHZZdbgICisCi\nppaVu6ImphgKgaaG5ZXS2KBMAUX/2J/MC94vkJgZGZhpVv4UFfPy87YhlnlJIUu8pIj9QiXN\ngviB3Fz2/M7MLLvP2VnmcuY7c57nOZ/36+XOOew5c56dPR9nZ+fZGeUBKJqKegCACwgJEEBI\ngABCAgQQEiCAkAABhAQIICRAACEBAggJEEBIgABCAgQQEiCAkAABhAQIICRAACEBAggJEEBI\ngABCAgQQEiCAkAABhAQIICRAACEBAggJEEBIgABCAgQQEiCAkAABhAQIICRAACEBAggJEEBI\ngABCAgQQEiCAkAABhAQIIKTI3KNUdWQHXzi8W80eGyM7vHsIqVxuUUqtTS+OVmpctCE9r5LW\nR3V4BxFSuWSEtOKGG27K2Or9SvV6GQbzHaV633DH1jIcKS4IqVwyQurUj1RZQjpaqe+U4TAx\nQkjlkl9Ih5YnJH8EM8pwmBghpHLZ4WOkj+eP7l/V/8CrP/S8Y1IPXdR0/1/XXXVwn8SAsT9v\nTu/y8wNq+x7z4tv+Jzd53q1KHf7xOTsP8LyW/xrbv6rn536U3Mr/15HePQ01dRdu9V47bqfu\nX3xFP7x+fd9JH2b7Y6SmCqWe9C/XDEwfGiEQUrnsKKSto1pP6z3e0kL6826t/3rIv5J7nJda\nrp7nf/DX7lRqv+uVqvS8r7dudWyL592l1GcWViTXpr69c/Ki/3/ajx64vg4hJa/9E36fk/0r\n2FTW28QhhFQuOwrpZqU++V/PPnaCUl/wXn3A3+jXT7/trfHP+91v/s3MKqWO8bd5wf/nhlt+\n+fkeqXqSew4bkmjYx3tIqS4/WX6rv9XC1L/uOvjL03r7V3v0oOkH+7vc0Hbw4PW99fSBSp36\n9NPbWj+7+bNKXeAtqVDVfynzjeIOQiqXW5SuPaRGpa73L7ZOmHbtNu8fKv0Y6TKler3nX/7S\nX1/qeWcotZN/T7Kxri0ktdc7/sKPjzkm+bPYl5X6RvpfT/K8+/yLbiu9LfsodVzbwTtcX8fH\nSC9Xq6o/7q3U3LLdGs4hpHLZUUjnKDX0jvdbN9oeUr1Sjcn15j5KXe55+yp1enL14vaQ7tSu\n+mylxqb/9QW/yGqlJvj/eL5/J9a2RYfry/hlw1ylapUa01KqL959hFQuyZCG1KV000N6qTYZ\n1p6T70v+GqA1pJaq9N2U5x2SqsLf5Ork2r3tIaXTaxq/R3UqzNHpf03OVRis1DX+hf8gas/t\nx+54fRkhtYzxd+77XslvBHcRUrns8Ld2Sz6dvpMa9mxbSBv8i/mpTf0T/FivxV+9Mbn2WFtI\n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\noILfTXE1AAAAAElFTkSuQmCC" + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAAC/VBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUW\nFhYXFxcYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMkJCQlJSUmJiYnJyco\nKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6\nOjo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tM\nTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1e\nXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1ubm5vb29w\ncHBxcXFycnJzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+fn5/f3+AgICBgYGC\ngoKDg4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OU\nlJSVlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGioqKjo6OkpKSlpaWm\npqanp6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O1tbW2tra3t7e4uLi5\nubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTFxcXGxsbHx8fIyMjJycnKysrL\ny8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc3Nzd\n3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u7u7v\n7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7+/v8/Pz9/f3+/v7///9P/i37\nAAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO3dC5yUVf348TO7LAvLTVBAVmBBRdT+\nuYCaWmIYhlekElR+ZaxgpmCSoX+yTJQ0FRJ/ZuY9y9tPUTHzloj40zRLqH/i5ReI/UUh1Fo0\n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" }, "metadata": { "image/png": { @@ -6460,18 +6505,18 @@ " n = r) # 乱数の数\n", "hist(x, breaks = max(x) - min(x))" ], - "id": "9c5a282d-00cd-4e18-b47b-02b945a6edd9" + "id": "7f948073-d8be-4480-a67d-adc5f6f8fdc9" }, { "cell_type": "code", - "execution_count": 196, + "execution_count": 159, "metadata": { - "id": "92fa34b4-1005-4363-9f29-f08b319c915d", - "outputId": "d44f7a6d-4368-49c5-afdd-11271d37b8fc", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "aca21a30-01b8-4793-b68b-632fe25abf1b", + "outputId": "344d6c6d-05be-46ac-9a22-8134fae8a3cd" }, "outputs": [ { @@ -6480,7 +6525,7 @@ "text/plain": [ "Plot with title “Histogram of x”" ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAAC/VBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUW\nFhYXFxcYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMkJCQlJSUmJiYnJyco\nKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6\nOjo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tM\nTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1e\nXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1ubm5vb29w\ncHBxcXFycnJzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+fn5/f3+AgICBgYGC\ngoKDg4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OU\nlJSVlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGioqKjo6OkpKSlpaWm\npqanp6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O1tbW2tra3t7e4uLi5\nubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTFxcXGxsbHx8fIyMjJycnKysrL\ny8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc3Nzd\n3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u7u7v\n7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7+/v8/Pz9/f3+/v7///9P/i37\nAAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO3dC5gU1Znw8TMMw3BHUVARZkBFN2bN\nIEZFIgaDoqJIsl4xF0YwRsGIWUzYJCpoNDGw4rqGGPUzJppklSi5uOqGRbLxEhMh2XjdiJgN\n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\nQrIYIckhJIsRkhxCshghySEkixGSHEKyGCHJISSLEZIcQrIYIckhJIsRkhxCshghySEkixGS\nHEKyGCHJISSLEZIcQrIYIckhJIsRkhxCshghySEkixGSHEKyGCHJISSLEZIcQrIYIckhJIsR\nkhxCshghySEkixGSHEKyGCHJISSLEZIcQrIYIckhJIsRkhxCshghySEkixGSHEKyGCHJISSL\nEZIcQrIYIckhJIsRkhxCshghySEkixGSHEKyGCHJISSLEZIcQrIYIckhJIsRkhxCshghySEk\nixGSHEKyGCHJISSLEZIcQrIYIckhJIsRkhxCshghySEkixGSHEKyGCHJISSLEZIcQrIYIckh\nJIsRkhxCshghySEkixGSHEKyGCHJISSLeUMa9513ErgFQtJlJqQEeUPqqfpM/8Uu6VsgJF1m\nQkqQN6S/3j6pVo346lrZWyAkXWZCSlDF10hv3XZiD3X8//s/wVsgJF3mY0ae47c8678xg+z+\nzYYNNzepvpf8UewWCEmbufFsn0YeoeTsFtLWH5/VRzXU1S1sE7oFQtJ15qmeoIqQnrhooOrz\nyVXO+rPUAqFbICRdZ0IS5A1p/fWjlTryW5sK220nDRW6BULSdSYkQd6QeqhBl6zuGL5VI3QL\nhKTrTEiCvCFN+N7W8rBW6ls65ob0raP89tEsFEJKkf9rpOffLvzyO9FbMDek5qYFPoM1C4WQ\nUuQNaedMtcq9uFU1twregsEhaRYGIWXIG9JN6vRX3Yv/OU/9i+AtEJKuMyEJ8oZ0xBntG1MO\nEbwFQtJ1JiRB3pD63NS+sahO8BYISdeZkAR5Q9rv8+0bs/cTvAVC0nUmJEHekGb2/ffCxc47\nen5a8BYISdeZkAR5Q9pwgGo4+YzjB6sD/ix4C4Sk60xIgnw/R9p4yT5KqSGffV3yFghJ15mQ\nBFWctNr2xitbhG+BkHSdCUkQL34SHyGhkzektmVnjPlgieAtEJKuMyEJ8oa0WKm+g0oEb4GQ\ndJ0JSZA3pOGnrEvgFghJ15mQBHlDqns6iVsgJF1nQhLke0T6dfeu27ZuxfLlK9d3sRch6ToT\nkiBvSF+c3Z1rtswbqooartsath8h6ToTkiBvSJtPueDRF9cWdX3FDaPU6OYFixZdNX2YamoJ\n2ZGQdJ0JSZA3JFXW9RVn1S1r32pdWjM3ZEdC0nUmJEHeZKbPmNWh6yvuP7O8fd6IkB0JSdeZ\n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" + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAADAFBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUW\nFhYXFxcYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMkJCQlJSUmJiYnJyco\nKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6\nOjo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tM\nTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1e\nXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1ubm5vb29w\ncHBxcXFycnJzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+fn5/f3+AgICBgYGC\ngoKDg4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OU\nlJSVlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGioqKjo6OkpKSlpaWm\npqanp6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O0tLS1tbW2tra3t7e4\nuLi5ubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTFxcXGxsbHx8fIyMjJycnK\nysrLy8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc\n3Nzd3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u\n7u7v7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7+/v8/Pz9/f3+/v7////i\nsF19AAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO3dCXxU1aH48TMkk5CwCQooAgFc\nqL6HUKyKVigK7mtrXai2UHAHpf7RYp8oiLUVeGJ9uOJW1yogbq9ueYjWSrVC+1dcWhFrUali\n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\nR4vJSgglpC5CnJX5v88KMTH74RyxOIxRpdwjFlnZkDSY7Egx4Jf3/ayzuE2HyXaq2W3Kohv7\nigd1mKyEUEK6/NxD2h26OnMNTsp+OFs8FsaoMj7rdry1I6TYT3bJoszDd+vtym5bNZhspbg3\n8+/ajrvWazBZCWE9RlraYb/tq8TY7PY08T8hjdpmZ3T8e2NIGky20XfFHzWY7M5lX9knp4o3\nNZishNBWNvxAvLO1fGR2c4z4e1ijttHT4sqPPvrobTHmoy/jP9kdzhMvaDDZ/cu22ScXilc0\nmKyEwEP6eL8fZk+/J163Dqq2/6+0vVefoAeVNUXsMDX+k91wy0PZ00PF6vhP1pokXrVPjhRr\nNJishODvkXpX2NfgXzt23GzNFzMym7eKqwMfVNI7T9keFkc+9W78J7t9947vZk4eF9+04j9Z\na3nq8C2W9Xq7/XSYrITgQ3qsLH3GFeM6iJssq364OOnqM1KDvgp80JJkHyNpMNknUh0mXPnd\nVOcVOkzW+okYcvU5VRVLtZhs24XwGOnVk7uX7TQ6+35DGy6tSe8+8X+DH7MkuZA0mOyyY3Yq\n7/Wj7PKG+E+24bbB7bsc+0d7M/6TbTv+jAJQgJAABQgJUICQAAUICVCAkAAFCAlQgJAABQgJ\nUICQAAUICVCAkAAFCAlQgJAABQgJUICQAAUICVCAkAAFCAlQgJAABQgJUICQAAUICVCAkAAF\nCAlQgJAABQgJUICQAAUICVCAkAAFCAlQgJAABQgJUICQAAUICVCAkAAFCAlQgJD0VJsaY58c\n0+7lqGeCLELS1Pmi1rIWiUuingdyCElTG/rttWVjn703RT0P5BCSrl5ITb+03bKoZ4FGhKSt\nCyvTl0U9B+xASNpaIcTKqOeAHQhJV9sP7rnz8IaoZ4FGhKSrOeLhe8Svop4FGhGSpv5adaxl\nHVb9XtTzQA4h6Wn7wR0+zNRU+e3tUc8EWYSkp/8Uc+2TmeL6qGeCLEICFCAkQAFCAhQgJEAB\nQgIUICRAAUICFCAkQAFCAhQgJEABQgIUICRAAUICFCAkQAFCAhQgJEABQgIUICRAAUICFCAk\nQAFCAhQgJEABQgIUICRAAUICFCAkQAFCAhQgJEABQgIUICRAAUICFPg/Kc1oUgLICk8AAAAA\nSUVORK5CYII=" }, "metadata": { "image/png": { @@ -6497,13 +6542,13 @@ " n = r) # 乱数の数\n", "hist(x, breaks = 40)" ], - "id": "92fa34b4-1005-4363-9f29-f08b319c915d" + "id": "aca21a30-01b8-4793-b68b-632fe25abf1b" }, { "cell_type": "code", - "execution_count": 197, + "execution_count": 160, "metadata": { - "id": "88fae50b-8cdd-4871-a62a-2d816be99f61" + "id": "a5c0cee9-f1ad-40c0-9a9b-9fdbfcbb1a37" }, "outputs": [], "source": [ @@ -6517,18 +6562,18 @@ " se = sd(tmp) / sqrt(n)) # 標準誤差\n", "}" ], - "id": "88fae50b-8cdd-4871-a62a-2d816be99f61" + "id": "a5c0cee9-f1ad-40c0-9a9b-9fdbfcbb1a37" }, { "cell_type": "code", - "execution_count": 198, + "execution_count": 161, "metadata": { - "id": "f4b0653c-12a9-4823-83aa-8d390a9772eb", - "outputId": "ac8dc805-4360-4f35-b6dd-522b26b6fcd7", "colab": { "base_uri": "https://localhost:8080/", "height": 192 - } + }, + "id": "9fe1e63e-87d6-40c2-8342-420a23b5ad4a", + "outputId": "d24f53c8-dfb6-4adc-da9d-b2b90a12cbf3" }, "outputs": [ { @@ -6542,19 +6587,19 @@ "\t<dbl><dbl><dbl>\n", "\n", "\n", - "\t109.0163020.04274751\n", - "\t209.0556480.02949131\n", - "\t308.9862440.02376209\n", + "\t108.9797340.04212187\n", + "\t209.0183820.02933529\n", + "\t308.9801370.02348067\n", "\n", "\n" ], - "text/markdown": "\nA tibble: 3 × 3\n\n| k <dbl> | mean <dbl> | se <dbl> |\n|---|---|---|\n| 10 | 9.016302 | 0.04274751 |\n| 20 | 9.055648 | 0.02949131 |\n| 30 | 8.986244 | 0.02376209 |\n\n", - "text/latex": "A tibble: 3 × 3\n\\begin{tabular}{lll}\n k & mean & se\\\\\n & & \\\\\n\\hline\n\t 10 & 9.016302 & 0.04274751\\\\\n\t 20 & 9.055648 & 0.02949131\\\\\n\t 30 & 8.986244 & 0.02376209\\\\\n\\end{tabular}\n", + "text/markdown": "\nA tibble: 3 × 3\n\n| k <dbl> | mean <dbl> | se <dbl> |\n|---|---|---|\n| 10 | 8.979734 | 0.04212187 |\n| 20 | 9.018382 | 0.02933529 |\n| 30 | 8.980137 | 0.02348067 |\n\n", + "text/latex": "A tibble: 3 × 3\n\\begin{tabular}{lll}\n k & mean & se\\\\\n & & \\\\\n\\hline\n\t 10 & 8.979734 & 0.04212187\\\\\n\t 20 & 9.018382 & 0.02933529\\\\\n\t 30 & 8.980137 & 0.02348067\\\\\n\\end{tabular}\n", "text/plain": [ " k mean se \n", - "1 10 9.016302 0.04274751\n", - "2 20 9.055648 0.02949131\n", - "3 30 8.986244 0.02376209" + "1 10 8.979734 0.04212187\n", + "2 20 9.018382 0.02933529\n", + "3 30 8.980137 0.02348067" ] }, "metadata": {} @@ -6564,18 +6609,18 @@ "g <- var\n", "c(10, 20, 30) %>% map_dfr(f)" ], - "id": "f4b0653c-12a9-4823-83aa-8d390a9772eb" + "id": "9fe1e63e-87d6-40c2-8342-420a23b5ad4a" }, { "cell_type": "code", - "execution_count": 199, + "execution_count": 162, "metadata": { - "id": "d2d263b3-055c-4563-83d6-2165e7bbd19e", - "outputId": "929a34aa-64a4-45ad-be54-021596c7f5bb", "colab": { "base_uri": "https://localhost:8080/", - "height": 224 - } + "height": 223 + }, + "id": "d59ab24a-e3eb-42f3-b3c8-a1a61f36179a", + "outputId": "7a91c92a-9af7-4cf2-c96f-6e7b919d7753" }, "outputs": [ { @@ -6589,21 +6634,21 @@ "\t<dbl><dbl><dbl>\n", "\n", "\n", - "\t 52.8152350.010235961\n", - "\t102.9206850.006981528\n", - "\t152.9418610.005529631\n", - "\t202.9549500.004876614\n", + "\t 52.8040530.010217735\n", + "\t102.9051790.006929028\n", + "\t152.9390280.005614585\n", + "\t202.9650980.004883380\n", "\n", "\n" ], - "text/markdown": "\nA tibble: 4 × 3\n\n| k <dbl> | mean <dbl> | se <dbl> |\n|---|---|---|\n| 5 | 2.815235 | 0.010235961 |\n| 10 | 2.920685 | 0.006981528 |\n| 15 | 2.941861 | 0.005529631 |\n| 20 | 2.954950 | 0.004876614 |\n\n", - "text/latex": "A tibble: 4 × 3\n\\begin{tabular}{lll}\n k & mean & se\\\\\n & & \\\\\n\\hline\n\t 5 & 2.815235 & 0.010235961\\\\\n\t 10 & 2.920685 & 0.006981528\\\\\n\t 15 & 2.941861 & 0.005529631\\\\\n\t 20 & 2.954950 & 0.004876614\\\\\n\\end{tabular}\n", + "text/markdown": "\nA tibble: 4 × 3\n\n| k <dbl> | mean <dbl> | se <dbl> |\n|---|---|---|\n| 5 | 2.804053 | 0.010217735 |\n| 10 | 2.905179 | 0.006929028 |\n| 15 | 2.939028 | 0.005614585 |\n| 20 | 2.965098 | 0.004883380 |\n\n", + "text/latex": "A tibble: 4 × 3\n\\begin{tabular}{lll}\n k & mean & se\\\\\n & & \\\\\n\\hline\n\t 5 & 2.804053 & 0.010217735\\\\\n\t 10 & 2.905179 & 0.006929028\\\\\n\t 15 & 2.939028 & 0.005614585\\\\\n\t 20 & 2.965098 & 0.004883380\\\\\n\\end{tabular}\n", "text/plain": [ " k mean se \n", - "1 5 2.815235 0.010235961\n", - "2 10 2.920685 0.006981528\n", - "3 15 2.941861 0.005529631\n", - "4 20 2.954950 0.004876614" + "1 5 2.804053 0.010217735\n", + "2 10 2.905179 0.006929028\n", + "3 15 2.939028 0.005614585\n", + "4 20 2.965098 0.004883380" ] }, "metadata": {} @@ -6613,18 +6658,18 @@ "g <- sd\n", "c(5, 10, 15, 20) %>% map_dfr(f)" ], - "id": "d2d263b3-055c-4563-83d6-2165e7bbd19e" + "id": "d59ab24a-e3eb-42f3-b3c8-a1a61f36179a" }, { "cell_type": "code", - "execution_count": 200, + "execution_count": 163, "metadata": { - "id": "7dcebb48-c052-406d-85ff-59bb9a5f0000", - "outputId": "f36868fa-d38a-4e88-bd83-659aba5199e9", "colab": { "base_uri": "https://localhost:8080/", "height": 192 - } + }, + "id": "3373f31b-4da2-474e-a8f4-7ad97728b950", + "outputId": "0408752e-4ee1-42d2-f4f0-2877e1a06fb3" }, "outputs": [ { @@ -6638,19 +6683,19 @@ "\t<dbl><dbl><dbl>\n", "\n", "\n", - "\t103.0084140.007145555\n", - "\t202.9887590.004848848\n", - "\t303.0042490.003956752\n", + "\t102.9900410.007089437\n", + "\t202.9940270.004918216\n", + "\t302.9956510.003939130\n", "\n", "\n" ], - "text/markdown": "\nA tibble: 3 × 3\n\n| k <dbl> | mean <dbl> | se <dbl> |\n|---|---|---|\n| 10 | 3.008414 | 0.007145555 |\n| 20 | 2.988759 | 0.004848848 |\n| 30 | 3.004249 | 0.003956752 |\n\n", - "text/latex": "A tibble: 3 × 3\n\\begin{tabular}{lll}\n k & mean & se\\\\\n & & \\\\\n\\hline\n\t 10 & 3.008414 & 0.007145555\\\\\n\t 20 & 2.988759 & 0.004848848\\\\\n\t 30 & 3.004249 & 0.003956752\\\\\n\\end{tabular}\n", + "text/markdown": "\nA tibble: 3 × 3\n\n| k <dbl> | mean <dbl> | se <dbl> |\n|---|---|---|\n| 10 | 2.990041 | 0.007089437 |\n| 20 | 2.994027 | 0.004918216 |\n| 30 | 2.995651 | 0.003939130 |\n\n", + "text/latex": "A tibble: 3 × 3\n\\begin{tabular}{lll}\n k & mean & se\\\\\n & & \\\\\n\\hline\n\t 10 & 2.990041 & 0.007089437\\\\\n\t 20 & 2.994027 & 0.004918216\\\\\n\t 30 & 2.995651 & 0.003939130\\\\\n\\end{tabular}\n", "text/plain": [ " k mean se \n", - "1 10 3.008414 0.007145555\n", - "2 20 2.988759 0.004848848\n", - "3 30 3.004249 0.003956752" + "1 10 2.990041 0.007089437\n", + "2 20 2.994027 0.004918216\n", + "3 30 2.995651 0.003939130" ] }, "metadata": {} @@ -6666,28 +6711,28 @@ "}\n", "c(10, 20, 30) %>% map_dfr(f)" ], - "id": "7dcebb48-c052-406d-85ff-59bb9a5f0000" + "id": "3373f31b-4da2-474e-a8f4-7ad97728b950" }, { - "id": "71f02235", + "id": "323f127e", "cell_type": "markdown", "source": [ "## 4.4 統計的推測" ], "metadata": { - "id": "71f02235" + "id": "323f127e" } }, { "cell_type": "code", - "execution_count": 201, + "execution_count": 164, "metadata": { - "id": "e96f07cb-9d1c-4605-955a-b8b22aa6bf21", - "outputId": "e2f64b4e-f921-46f3-9178-e39f9b4425ce", "colab": { "base_uri": "https://localhost:8080/", "height": 1000 - } + }, + "id": "25175000-222f-45e2-bde2-7fc958342b0c", + "outputId": "bf163b31-866e-4ad0-b878-bf9695003feb" }, "outputs": [ { @@ -6702,11 +6747,6 @@ "Attaching package: ‘testthat’\n", "\n", "\n", - "The following objects are masked from ‘package:rlang’:\n", - "\n", - " is_false, is_null, is_true\n", - "\n", - "\n", "The following object is masked from ‘package:dplyr’:\n", "\n", " matches\n", @@ -6779,18 +6819,18 @@ " # 左片側検定なら'less'\n", " # 右片側検定なら'greater'\n" ], - "id": "e96f07cb-9d1c-4605-955a-b8b22aa6bf21" + "id": "25175000-222f-45e2-bde2-7fc958342b0c" }, { "cell_type": "code", - "execution_count": 202, + "execution_count": 165, "metadata": { - "id": "92fc38d1-7196-43f3-809a-0ec46f08f1c4", - "outputId": "48d4bdde-57db-4d84-a644-79d0fad8e7b7", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "bfdd1524-f612-4602-a9d9-1209a96eabea", + "outputId": "3f5dbc24-d458-417f-a0e7-c7739754bd9b" }, "outputs": [ { @@ -6826,42 +6866,42 @@ " geom_hline(yintercept = my_pr2) + # 水平線\n", " theme(legend.position = \"none\") # 凡例を表示しない." ], - "id": "92fc38d1-7196-43f3-809a-0ec46f08f1c4" + "id": "bfdd1524-f612-4602-a9d9-1209a96eabea" }, { "cell_type": "code", - "execution_count": 203, + "execution_count": 166, "metadata": { - "id": "57c02f6b-ce08-4395-9af1-0a644e87ffbe" + "id": "97659370-3601-4dfc-8a34-86c5eedbbc57" }, "outputs": [], "source": [ "# 前項の結果(再掲)" ], - "id": "57c02f6b-ce08-4395-9af1-0a644e87ffbe" + "id": "97659370-3601-4dfc-8a34-86c5eedbbc57" }, { "cell_type": "code", - "execution_count": 204, + "execution_count": 167, "metadata": { - "id": "b5dcbd6a-b0c8-4d01-bfec-f9b3c61f44d8" + "id": "537b86a0-3d1e-44ef-91be-1ead7c0a6d79" }, "outputs": [], "source": [ "# 前項冒頭のコード" ], - "id": "b5dcbd6a-b0c8-4d01-bfec-f9b3c61f44d8" + "id": "537b86a0-3d1e-44ef-91be-1ead7c0a6d79" }, { "cell_type": "code", - "execution_count": 205, + "execution_count": 168, "metadata": { - "id": "c95ad909-4a9c-4e14-a0ef-63eb11fd8ab3", - "outputId": "50679756-f068-4325-af70-0e9564ec3d66", "colab": { "base_uri": "https://localhost:8080/", - "height": 208 - } + "height": 215 + }, + "id": "05cd01cd-cfd1-4117-8f60-11befbda1a63", + "outputId": "75dae136-085d-4344-9be9-8ea1ec1421f2" }, "outputs": [ { @@ -6897,18 +6937,18 @@ " # 左片側検定なら'less'\n", " # 右片側検定なら'greater'\n" ], - "id": "c95ad909-4a9c-4e14-a0ef-63eb11fd8ab3" + "id": "05cd01cd-cfd1-4117-8f60-11befbda1a63" }, { "cell_type": "code", - "execution_count": 206, + "execution_count": 169, "metadata": { - "id": "fd1c5ede-ab8e-476c-b217-ff546df70527", - "outputId": "d3ffcd69-cf7d-4a2f-d403-5bb612195287", "colab": { "base_uri": "https://localhost:8080/", - "height": 208 - } + "height": 215 + }, + "id": "ee1ff75e-aba0-49f0-b6e9-0914dd14ed11", + "outputId": "8c281018-ed97-4277-f1f5-3ab99380bfeb" }, "outputs": [ { @@ -6938,17 +6978,17 @@ " alternative = \"two.sided\",\n", " conf.level = 0.95)\n" ], - "id": "fd1c5ede-ab8e-476c-b217-ff546df70527" + "id": "ee1ff75e-aba0-49f0-b6e9-0914dd14ed11" }, { "cell_type": "code", - "execution_count": 207, + "execution_count": 170, "metadata": { - "id": "d025ed6e-486c-4204-86f0-01a40e882ae8", - "outputId": "ff4b7cb2-d042-4c71-8a95-f2a037bc997e", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "0a6678b8-c01e-4b17-84a0-1a84832698b5", + "outputId": "4374669f-e15c-4403-eac5-5581815ef6b3" }, "outputs": [ { @@ -6970,18 +7010,18 @@ " \"/fromzero/master/data/smoker.csv\")\n", "my_data <- read_csv(my_url)" ], - "id": "d025ed6e-486c-4204-86f0-01a40e882ae8" + "id": "0a6678b8-c01e-4b17-84a0-1a84832698b5" }, { "cell_type": "code", - "execution_count": 208, + "execution_count": 171, "metadata": { - "id": "669b9a1e-2fc7-4a6d-a8a0-7823053f9cbd", - "outputId": "c9a0bef0-d0d8-4ed2-eea4-97266a55df2c", "colab": { "base_uri": "https://localhost:8080/", "height": 286 - } + }, + "id": "cec257c1-7602-4f7d-b01f-f354a5ca9f07", + "outputId": "bc316db2-cc0c-4e4d-b8ff-725b326037ac" }, "outputs": [ { @@ -7022,18 +7062,18 @@ "source": [ "head(my_data)" ], - "id": "669b9a1e-2fc7-4a6d-a8a0-7823053f9cbd" + "id": "cec257c1-7602-4f7d-b01f-f354a5ca9f07" }, { "cell_type": "code", - "execution_count": 209, + "execution_count": 172, "metadata": { - "id": "c0cc62ba-b42e-4772-bfec-0a3bc09ce69b", - "outputId": "5828dd84-6caf-4df4-d154-5093ac32f93d", "colab": { "base_uri": "https://localhost:8080/", - "height": 86 - } + "height": 89 + }, + "id": "b9f036f2-a08f-418c-95a8-14b19971fd9f", + "outputId": "dfa51fc5-2cea-4bbc-d5b3-bed00f8381e9" }, "outputs": [ { @@ -7053,18 +7093,18 @@ "my_table <- table(my_data)\n", "my_table" ], - "id": "c0cc62ba-b42e-4772-bfec-0a3bc09ce69b" + "id": "b9f036f2-a08f-418c-95a8-14b19971fd9f" }, { "cell_type": "code", - "execution_count": 210, + "execution_count": 173, "metadata": { - "id": "e39ca4b5-a89f-4960-a317-386d9fda74c3", - "outputId": "907c5739-53f4-45eb-e7cf-e6428789b902", "colab": { "base_uri": "https://localhost:8080/", - "height": 104 - } + "height": 107 + }, + "id": "affc0222-847a-45e6-bc60-5c44be99cc8a", + "outputId": "d429513f-bce0-4a0b-e41b-ed76335a2311" }, "outputs": [ { @@ -7084,18 +7124,18 @@ "source": [ "chisq.test(my_table, correct = FALSE)\n" ], - "id": "e39ca4b5-a89f-4960-a317-386d9fda74c3" + "id": "affc0222-847a-45e6-bc60-5c44be99cc8a" }, { "cell_type": "code", - "execution_count": 211, + "execution_count": 174, "metadata": { - "id": "59aebb99-9dee-4d12-b40b-b7614dabd99d", - "outputId": "0488f1d9-d785-4f32-f60b-d496387cab99", "colab": { "base_uri": "https://localhost:8080/", "height": 69 - } + }, + "id": "bcc37adc-e598-467b-b371-f0506c4f73be", + "outputId": "7fc72947-ae18-4903-f75b-0a9843e60660" }, "outputs": [ { @@ -7126,12 +7166,12 @@ ".list-inline>li {display: inline-block}\n", ".list-inline>li:not(:last-child)::after {content: \"\\00b7\"; padding: 0 .5ex}\n", "\n", - "
  1. 0
  2. 1
  3. 0
  4. 1
  5. 0
  6. 0
  7. 0
  8. 0
  9. 0
  10. 0
  11. 0
  12. 1
  13. 0
  14. 0
  15. 0
\n" + "
  1. 0
  2. 0
  3. 0
  4. 0
  5. 0
  6. 0
  7. 0
  8. 1
  9. 0
  10. 0
  11. 1
  12. 0
  13. 0
  14. 0
  15. 0
\n" ], - "text/markdown": "1. 0\n2. 1\n3. 0\n4. 1\n5. 0\n6. 0\n7. 0\n8. 0\n9. 0\n10. 0\n11. 0\n12. 1\n13. 0\n14. 0\n15. 0\n\n\n", - "text/latex": "\\begin{enumerate*}\n\\item 0\n\\item 1\n\\item 0\n\\item 1\n\\item 0\n\\item 0\n\\item 0\n\\item 0\n\\item 0\n\\item 0\n\\item 0\n\\item 1\n\\item 0\n\\item 0\n\\item 0\n\\end{enumerate*}\n", + "text/markdown": "1. 0\n2. 0\n3. 0\n4. 0\n5. 0\n6. 0\n7. 0\n8. 1\n9. 0\n10. 0\n11. 1\n12. 0\n13. 0\n14. 0\n15. 0\n\n\n", + "text/latex": "\\begin{enumerate*}\n\\item 0\n\\item 0\n\\item 0\n\\item 0\n\\item 0\n\\item 0\n\\item 0\n\\item 1\n\\item 0\n\\item 0\n\\item 1\n\\item 0\n\\item 0\n\\item 0\n\\item 0\n\\end{enumerate*}\n", "text/plain": [ - " [1] 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0" + " [1] 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0" ] }, "metadata": {} @@ -7140,12 +7180,12 @@ "output_type": "display_data", "data": { "text/html": [ - "3" + "2" ], - "text/markdown": "3", - "text/latex": "3", + "text/markdown": "2", + "text/latex": "2", "text/plain": [ - "[1] 3" + "[1] 2" ] }, "metadata": {} @@ -7163,18 +7203,18 @@ "n <- 10^5\n", "result <- replicate(n, sum(sample(X, size = length(X), replace = TRUE))) # 手順4" ], - "id": "59aebb99-9dee-4d12-b40b-b7614dabd99d" + "id": "bcc37adc-e598-467b-b371-f0506c4f73be" }, { "cell_type": "code", - "execution_count": 212, + "execution_count": 175, "metadata": { - "id": "a593484a-23f2-4d4f-9085-acc571f78521", - "outputId": "e514cff7-25df-4d89-dd9d-4744b8f84577", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "c00342bf-fc4d-4cc1-aca8-14ba99933899", + "outputId": "13af4d24-1e7e-4215-d78d-c0182291f21b" }, "outputs": [ { @@ -7183,7 +7223,7 @@ "text/plain": [ "Plot with title “Histogram of result”" ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAAC/VBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUW\nFhYXFxcYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMkJCQlJSUmJiYnJyco\nKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6\nOjo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tM\nTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1e\nXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1ubm5vb29w\ncHBxcXFzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+fn5/f3+AgICBgYGCgoKD\ng4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OUlJSV\nlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGioqKjo6OkpKSlpaWmpqan\np6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O0tLS1tbW2tra3t7e4uLi5\nubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTFxcXGxsbHx8fIyMjJycnKysrL\ny8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc3Nzd\n3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u7u7v\n7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7+/v8/Pz9/f3+/v7///9B8z1b\nAAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO3dDXhU5Znw8XsIQ0gwRCwiBggfQt23\nrQVBK13F8haqVUSwbqVYLZG4ooLExW6KUkAsUMMr2Fr8oGvt6trdosS1utWVRu3i1halvl0V\n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\nkBrm9JG48kUHTOsICRbwHdL2wTKsYkFNzbypZTK8wbCQkGAB3yFVRlcnj5pWRqoMCwkJFvAd\nUt/p6eMpAwwLCQkW8B1SdHH6eGE3w0JCggV8hzTwivTxpEGGhYQEC/gOqSqy7FDiaN98qTYs\nJCRYwHdIe0ZKybiKWTOnjS2WMXsNCwkJFvD/faTDy0cUxL6NFB29qsm0jpBggaxGhA5u2rCh\nvr1MWhASLMCIkPL+hGQnRoSU9yckOzEipLw/IdmJESHl/QnJTowIKe9PSHZiREh5f0KyEyNC\nyvsTkp0YEVLen5DsxIiQ8v6EZCdGhJT3JyQ75WZEaM+s61ImERLCLzcjQh9c/fWULxMSwo8R\nIeX9CclOjAgp709IdmJESHl/QrITI0LK+xOSnRgRUt6fkOzEiJDy/oRkJ0aElPcnJDsxIqS8\nPyHZiREh5f0JyU78FCHl/QnJTtn+xr7D65/fYl5BSLCA75DueD728v5e7gd3o14zLSQkWMB3\nSPGv1D0thZfNOFdK3zYsJCRYILuQhpVudF+uiVxjWEhIsEBWIe2SW+PHk/sZFhISLJBVSFvl\nkfjxvKhhISHBAlmF1FS6NH48/STDQkKCBfyHNPWV+t1zh+53D9/qMdGwkJBgAf8hJTzuOI/2\n6LLesJCQYAHfIT20YkHVtMlj6xxnZb+nTAsJCRbIdrLBtfeI8c2EBAsohNQBQoIFCEl5f0Ky\nEyEp709IdiIk5f0JyU6EpLw/IdmJkJT3JyQ7EZLy/oRkJ0JS3p+Q7ERIyvsTkp0ISXl/QrIT\nISnvT0h2IiTl/QnJToSkvD8h2YmQlPcnJDsRkvL+hGQnQlLe/7bIEM/uzPn/fBwvhKS9f7e7\nvDq7Iuf/83G8EFJw+08ipPAgpOD2J6QQIaTg9iekECGk4PYnpBAhpOD2J6QQIaTg9iekECGk\n4PYnpBAhpOD2J6QQIaTg9iekECGk4PYnpBAhpOD2J6QQIaTg9iekECGk4PYnpBAhpOD2J6QQ\nIaTg9iekECGk4PYnpBAhpOD2J6QQIaTg9iekECGk4PYnpBAhpOD2J6QQIaTg9iekECGk4PYn\npBAhpOD2J6QQIaTg9iekECGk4PYnpBAhpOD2J6QQIaTg9iekECGk4PYnpBAhpOD2J6QQIaTg\n9iekECGk4PYnpBAhpOD2J6QQIaTg9iekECGk4PYnpBAhpOD2J6QQIaTg9iekECGk4PYnpBAh\n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\nAQr+FzKlFwCt1JN6AAAAAElFTkSuQmCC" + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAAC/VBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUW\nFhYXFxcYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMkJCQlJSUmJiYnJyco\nKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6\nOjo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tM\nTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1e\nXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1ubm5vb29w\ncHBxcXFzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+fn5/f3+AgICBgYGCgoKD\ng4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OUlJSV\nlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGioqKjo6OkpKSlpaWmpqan\np6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O0tLS1tbW2tra3t7e4uLi5\nubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTFxcXGxsbHx8fIyMjJycnKysrL\ny8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc3Nzd\n3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u7u7v\n7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7+/v8/Pz9/f3+/v7///9B8z1b\nAAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO3dDXhU5Znw8TuESUgwxFhADBBAYe3b\n1hJBK61ieRdWq4hg3ZVitURwRQWNi92IUqC4SBtWsGvxg77Wrq7dFjWu1VbXNOoutlokdbta\nbIngLiqCaKgN34ac6z3zkZlJIE8OZ+7hZM7z/12XmUPynHkOzvyvfN0k4gDImAR9AUAYEBKg\ngJAABYQEKCAkQAEhAQoICVBASIACQgIUEBKggJAABYQEKCAkQAEhAQoICVBASIACQgIUEBKg\ngJAABYQEKCAkQAEhAQoICVBASIACQgIUEBKggJAABYQEKCAkQAEhAQoICVBASIACQgIUEBKg\ngJAABYQEKCAkQAEhAQoICVBASFn2qEhhYJuvHdOn6OS9vk8P9NpzDCHp+oGI7IofThQ5P9gn\n4ysS1eL7fELyjpB0HRZS06pVdx+2anu+vHkMLmaOSOmqhw76Pr89pGN0uTmNkHQdFtIR/ZMc\nk2fmBSJzMjm/PaRjdLk5jZB0eQvp7GPzzHSvYH4m57eHdIwuN6cRkq4uP0f65P6JA3oPOOOO\nnY4zOfapi1S7r/142VllkYHn/bA1fsoPxxafMPnVLe4b9znOAyLnfnJj/4GO0/av5w3oXfKF\nf4qucl873nm0smjYbQedjVOO7/tXb6Rvn35/c+LbJD9HSt2f84c5IwtLzvjeJ50uzLlN5Kzo\n654QyXfarz3tctElQtLVVUgHJySe1ie/lfbM/K/Bidd+8cPoGX8XOy5c7b5w//Rjkc/fGXtG\nfz2x6qI2x/mJyOfW5kX/NHdL/+jNgD+ldu9wf51DSt3f433ib/nLfR0vjJD8IyRdXYV0r8in\n//XXz14q8mXn90+6ix5Zt8Vpdp/3I+79t5reIpPdNevdV1f+4OEvHZd8Gg8fGqk81XlKpNc9\nrz/grlobe+1JQy6eV+re7QXl1We5p6xKbt7x/t5ad4bI19atO5R4a/L+thSJfPOPr35ZZEHH\nCztySMnLhQEh6fqBpEuFVCVyp3tzcMa87xxy3pf4Jx3fFun3nnv7sPvnDY5zjcjx7nuSvcOS\nT2MZ9Y578P3Jk6PvDi4W+Ub8tX/jvlNxb/psdg6cKjIluXmn++v0OVLy/uaJTHBvdh4nJfs6\nXtgRQ0peLgwISVdXId0oUvHQ9sSi9mfmaJGq6J9by0SWOs5nRK6M/vFbqZB+nHbXN4icF3/t\neveJXygyw33lze47seSKTvd3hJBi93eKyG37XOeK/LLjhRGSb4SkKxrS0GExfdJDeq04GtYp\nsx+Pfhkg8cxs6x1/b+A4X4xV4S65I/qnx1IhxZ/h9VNPLoyFOTH+2uiswhCR5e6N+0nPKe17\nd76/I4QUvb+2XqnSv9fxwgjJN0LS1eVX7V74bPypO/zXyWfmbvfm/tjSSSIXOW2xJ7br2eTT\nOD/2+c097hv6/p/R/dtDit2f+27lXvfm7rSQOt3fEUKK3d/utHeZizteGCH5Rki6uh4Ravv1\n0q+URr/Ktjv9PdKK2NvOEvm64xTG38nEnvFO6swW933G5e47oeu7C6nz/R0eUuzMtnyRu9Iu\nOe3Cbkt8oHg/IR0tQtJlnrVrfdL97OUXyWdmZfz57hwsEfmu44xMfI60sGNI/+mufi1+f+aQ\nOt9fFyE5f3H417ITF7ZcZGCbE/vKOSEdHULS1UVIe++oujj2Ydp5Ik84291F69w/LHU/ZIt+\nGW2NSN4fHecKkdKd7nugoR1Dqo9/eeH37qc255pD6nR/XYV0g0j5Hjeey6+65d2OFxb9ct9T\njvNmcYcraL9cGBCSrq7eI7nvLC79xYb//HZECnc4rRGR8Wv/3dk1RGTk6se/6X5Md7W7psE9\n9/M/euDMvh1Des8taMrrPxt8qki/l3eYQup0f12FtLlI5Oyf//tXRT7b2vHCNue5Kc65+YQv\ndbiC9suFASHp6iqk14ckPr3v9YATmyaNfc80OYnw1X3RM2bGjou/2zGk6HsQV/nb5dGvDphC\n6nx/XYTkPBr/GqAMfrPzhV0bOxz1kvsurS11RvvlomuEpKvLz5G2337GiZHiT1/zu+gf3p12\nfJ8Ry9yDj//hzNLISZf8LH7GoRWnFg786//+RfyU5BP/4Hc/UzT46vec+lN7D/mJMaRO99dV\nSM7GWSMKiz93W/NhF9a6fFTB4Gt2vOv+LfakzkheLrpESD3PP7vvfoK+BhwlQuo5Ni6//mvR\ngeyLRaYFfS04SoTUczS5n+pPe/Glm9yPq54L+lpwlAipB1nSPnDwraCvBEeLkHqShr8eEikc\nNv3FoK8DR42QAAWEBCggJEABIQEKCAlQQEiAAkICFBASoICQAAWEBCggJEABIQEKMgmpbXN9\nXV3DVrVrAXKW/5Ca5w+Mz/xXLPX/W0qBcPAd0rYRMqpqcW3twhnlMrpZ85KA3OM7pNmRtYmj\n1tV5/O4cWM53SINmpY6nD9W4FCB3+Q4pkvbjmZYUaFwKkLt8hzTsstTx1OEalwLkLt8hVeet\n2B8/2r1IarQuB8hNvkPaNUZKJlbNmztzQrGMb+l+PRBm/r+PdGBlZX7020iRcWtaFS8IyEUZ\njQjt29TY2HRA61KA3MWIEKCAESFAASNCgAJGhAAFjAgBChgRAhQwIgQoYEQIUMCIEKCAESFA\nASNCgAJGhAAFjAgBChgRAhQwIgQoyM6I0N6V30m6/Wq/WwA5IzsjQu+dPTbp08LX9RB62R8R\n+hUhIfyyPyJESLBA9keECAkWyP6IECHBAtkfESIkWCD7I0KEBAtkf0SIkGCB7I8IERIskP0R\nIUKCBbL/U4QICRbI/k8RIiRYgBEhQAEjQoACRoQABYwIAQoYEQIUZBRSVOvGV/cZFxASLOA/\npF/9zehpjU7T50RKVhvXHduQPmmo92zbsbwwhJrvkF6JSET6bT6779e/epz8zLDwGIf0bF4/\nryKzj+WFIdR8h3RRpK713dOuyF/nOH/sO8mw8BiH9HTR615NrTqWF4ZQ8x3Sp65wXzTIudHj\nqjLDQkKCBfyPCC12X+yWa6PHt/Y2LCQkWMB3SCO+EX1Zekv05fQTDQsJCRbw/88oCte1H74c\nudSwkJBgAd8hNZXlLYgfXRHpvd6wkJBgAf/fR9o4aWH84LShT5rWERIskPFkg+O8Z34zIcEC\nCiF1g5BgAUICFBASoICQAAWEBCggJEABIQEKCAlQQEiAAkICFBASoICQAAWEBCggJEABIQEK\nCAlQQEiAAkICFBASoICQAAWEBCggJEABIQEKCAlQQEiAAkICFBASoICQAAWEBCggJEABIQEK\nCAlQkCMhbd7g1V2EhADkSEhl4hkhIQA5ElLf1V7ruJ6QEABCAhQQEqCAkAAFhAQoICRAASEB\nCggJUEBIgIJMQmrbXF9X17C1m1WEBAv4D6l5/sD4TE7F0r2mdYQEC/gOadsIGVW1uLZ24Yxy\nGd1sWEhIsIDvkGZH1iaOWlfnVRsWEhIs4DukQbNSx9OHGhYSEizgO6TIstTxkgLDQkKCBXyH\nNOyy1PHU4YaFhAQL+A6pOm/F/vjR7kVSY1hISLCA75B2jZGSiVXz5s6cUCzjWwwLCQkW8P99\npAMrK/Oj30aKjFvTalpHSLBARiNC+zY1NjZ1lwkhwQKMCAEKGBECFDAiBChgRAhQwIgQoIAR\nIUABI0KAAkaEAAWMCAEKGBECFDAiBChgRAhQwIgQoIARIUABI0KAAkaEAAXZGRHaPnlS0pmy\n3+8eKYSEni07I0It36pJuoL3SAg/RoQABYwIAQoYEQIUMCIEKMj0N/YdWP/8FvMKQoIFfId0\n+/PRl/eVuR/cjX3NtJCQYAHfIcW+Uve0FF4y52wpfcuwkJBggcxCGlW60X35eN5VhoWEBAtk\nFNIHcmvseNpgw0JCggUyCmmrPBw7XhgxLCQkWCCjkFpLl8eOZ51gWEhIsID/kGa82rRzwcg9\n7uGbfacYFhISLOA/pLjHHOeRvr3WGxYSEizgO6QHVy2unjltQoPjrB78lGkhIcECmU42uFoO\nGd9MSLCAQkiO0/y24Y2EBAv4D+l3Fw47Z3V87rvGdC+EBAv4DumlQimOyJdjPz+IkGA73yFN\njjzRtn9l5MzdDiEBvkMaekX0ZUPBha2EBPj/KUKLYjcPyY2EBPgOacjF8dsFUktIsJ7vkG7M\nu/tg9LZtptx0AyHBcr5D+rBCJsUO2m4UISRYzv/3kXZef1Pi6PFTCAmWU5lsMCIkWICQAAWE\nBCggJEABIQEKCAlQQEiAAkICFBASoICQAAWEBCggJEABIQEKCAlQQEiAAkICFBASoICQAAWE\nBCggJEABIQEKCAlQQEiAAkICFBASoICQAAWEBCggJEABIQEKCAlQQEiAAkICFBASoICQAAWE\nBCggJEABIQEKCAlQQEiAAkICFBASoICQAAWEBCggJEABIQEKMgmpbXN9XV3D1m5WERIs4D+k\n5vkDJaZi6V7TOkKCBXyHtG2EjKpaXFu7cEa5jG42LCQkWMB3SLMjaxNHravzqg0LCQkW8B3S\noFmp4+lDDQsJCRbwHVJkWep4SYFhISHBAr5DGnZZ6njqcMNCQoIFfIdUnbdif/xo9yKpMSwk\nJFjAd0i7xkjJxKp5c2dOKJbxLYaFhAQL+P8+0oGVlfnRbyNFxq1pNa0jJFggoxGhfZsaG5u6\ny4SQYAFGhAAFjAgBChgRAhQwIgQoYEQIUMCIEKCAESFAASNCgAJGhAAFjAgBChgRAhQwIgQo\nYEQIUMCIEKCAESFAASNCgILsjAht6V+WVEJICL/sjAgdeqE+6S5CQvgxIgQoYEQIUMCIEKCA\nESFAASNCgAJGhAAFjAgBChgRAhQwIgQo4KcIAQr4KUKAAkaEAAU2jwidWlDm1ac2ZP53QJjZ\nPCJU8aUfeFX4dOZ/B4SZzSNCFVM9Ly0iJBhlFFK75rcNbyQkWMB/SL+7cNg5q+Mf1NWY7oWQ\nYAHfIb1UKMUR+XJsOIiQYDvfIU2OPNG2f2XkzN0OIQG+Qxp6RfRlQ8GFrYQE+B8RWhS7eUhu\nJCTAd0hDLo7fLpBaQoL1fId0Y97dB6O3bTPlphsICZbzHdKHFTIpdtB2owghwXL+v4+08/qb\nEkePn0JIsJzKZIMRIcEChERIUEBIhAQFhERIUEBIhAQFhERIUEBIhAQFhERIUEBIhAQFhERI\nUEBIhAQFhERIUEBIhAQFhERIUEBIhAQFhERIUEBIhAQFhERIUEBIhAQFhERIUEBIhAQFhERI\nUEBIhAQFhERIUEBIhAQFhERIUEBIhAQFhERIUEBIhAQFhERIUEBIhAQFhERIUEBIhAQFhERI\nUEBIhAQF6SGNu+9PWdiBkGCB9JB6S9GM5w5p70BIsEB6SB/ePzFfht7WpLsDIcECnT5H+uDe\n/9tLzvl/f1bcgZBggcO/2LBt1WgpvvaPajsQEixwWEh7H720SCoikSVtSjsQEizQKaSXru4n\nRV9/wdl6qSxW2oGQYIH0kLb+wyiR07+/K3rcNmmg0g6EBAukh9RLSq/d0P6H7+cp7UBIsEB6\nSON/tDf1h6Y6pR0ICRbo+DnSGzujL37r8dy2zfV1dQ1bu1lFSLBAekgHZ8kL7s3dUtXq4czm\n+QMlpmLpXtM6QoIF0kO6UyZvcW/+MF3u6v7EbSNkVNXi2tqFM8pldLNhISHBAukhnXZR4uDC\nkd2fODuyNnHUujqv2rCQkGCB9JCK7kwc1Ea6P3HQrNTx9KGGhYQEC6SHdOINiYPrT+z+xMiy\n1PGSAsNCQoIF0kOaVfzz6M3BNb2v7P7EYZeljqcONywkJFggPaRtJ0nFX110zgly0v92f2J1\n3or98aPdi6TGsJCQYIEO30fafu2nRGTA377r4cRdY6RkYtW8uTMnFMv4FsNCQoIFOg2ttr33\n1m6PZx5YWZkf/TZSZNwa47edCAkWyOiHn+zb1NjY1F0mhAQLpIfUtvaiys/GeTqXESEgIT2k\nFSLFpXEezmRECEhKD2nI+Zu9n8iIEJCSHlLklaM4kREhIKXDe6SXj+JERoSAlPSQvnn9UZzI\niBCQkh5Sy/mXP7uxKab7ExkRAlLSQ5KU7k9kRAhISU9mxszZ7bo/kREhIMX/ZAMjQkBSp5D+\n/MauoziZESEgrkNIL44VecZxpvzS27mMCAEJ6SH9pqDkfDekDwYVbOhyfQojQkBSekiTK955\nP/oeaUfF1O5PZEQISEkP6VPLnVhIzh1l3Z/IiBCQ0uFXX/5LIqQHM/4pQr/bkPRDQkL4dZi1\nuy0R0lXDuj/ROCL0Vn7aN3cJCeGXHtI1ZY3RkJpvFQ9Dd+YRoT3NSc8SEsIvPaT3h/YeI5WV\nhVKxvfsTGRECUjp8H2nHddGfItT/uh0eTmRECEjp/FOEtjd5eG8Uw4gQkMRPESIkKEgPaWLS\neM/nH1j//BbzCkKCBY7475FKyrs/8fbnoy/vK3OXj33NtJCQYIH0kD6J2fPGzed+7OHE6Ffq\nnpbCS+acLaVvGRYSEixwxM+RbrnWw4nRkEaVbnRfPp53lWEhIcECRwzpZQ8f2kVD+kBujR1P\nG2xYSEiwwBFDeq7Yw4luSFvl4djxQtNsHiHBAukh7Yr74IVKDz/7OxpSa+ny2PGsEwwLCQkW\nOPJPEXrYw4kzXm3auWDkHvfwzb5TDAsJCRbo8A/74qZd5+WfmieSe8xxHunba71hISHBAr4n\nGx5ctbh65rQJDY6zevBTpoWEBAtkNCIU13LI+GZCggXSQxr9hbPSeb+TD00/4piQYIH0kE4s\ncj/pyXP/K8qP8n4nNab3a4QEC6Qn0HzO3N/ucz7+j6+e52FEKB0hwXbpCVxVlTj4ytVHdyeE\nBNulJzDggcTBPw7s/sSxaQYREiyXnkBh+w8G+vvC7k/s1aswKZ+QYLn0BE4vj/8S2Zf6j+7+\nxJqS1Jfq+NAOtktP4Ml8GTFpyqSTJe+x7k88ePoZB9uPCQm26/jbKM7vIyIFf1nv5cyNRTe3\nHxISbNcpgUPvbnrH+DOB0nz8UfvRi8sNywgJFsjoF415QkiwQCa/aMwbQoIF/P+iMa8ICRbw\n/YvGPCMkWMD3LxrzjJBgAd+/aMwzQoIFfP+iMc8ICRbw/YvGPCMkWMD3LxrzjJBgAd+/aMwz\nQoIF/P+iMa8ICRboMP39RjZ2ICRYID2kPt/Jxg6EBAukhzTpAvNPqPOHkGCB9JC2z/jKjzc0\nxSjuQEiwwJF/iL7Cz19NIiRYID2Z6VfOmp2guAMhwQKa73uOjJBggWRId6+L3bz2rvYOhAQL\nJEOS6vjNXO0dCAkWICRCggJCIiQoICRCggJCIiQoICRCggJCIiQoSIV01uIoOTN2o7gDIcEC\nqZA6UNyBkGCBZDIPd6C4AyHBAszaERIUEBIhQQEhERIUEBIhQQEhERIUEBIhQQEhERIUBBnS\nK9/xrICQ0KMFGVLVgHFeCSGhRws0JO9PZEJCz0ZInhASzAjJE0KCGSF5QkgwIyRPCAlmhOQJ\nIcGMkDwhJJhlElLb5vq6uoat3awiJFjAf0jN8wfG/1l6xdK9pnWEBAv4DmnbCBlVtbi2duGM\nchndbFhISLCA75BmR9YmjlpX51UbFhISLOA7pEGzUsfThxoWEhIs4DukyLLU8ZICw0JCggV8\nhzTsstTx1OGGhYQEC/gOqTpvxf740e5FUmNYSEiwgO+Qdo2RkolV8+bOnFAs41sMCwkJFvD/\nfaQDKyvzo99Gioxb02paR0iwQEYjQvs2NTY2dfcTGQgJFmBEyBNCghkjQp4QEswYEfKEkGDG\niJAnhAQzRoQ8ISSYMSLkCSHBjBEhTwgJZowIeUJIMGNEyBNCghkjQp4QEswYEfKEkGDGiJAn\nhAQzRoQ8ISSYMSLkCSHBjBEhTwgJZtkZEdq7MvVbK68jJIRfdkaE3vvS2KRTZX8Xd0FICA1G\nhDwhJJgxIuQJIcGMESFPCAlmjAh5QkgwY0TIE0KCGSNCnhASzBgR8oSQYMaIkCeEBDNGhDwh\nJJjxU4Q8ISSY8VOEPCEkmDEi5AkhwYwRIU8ICWaMCHlCSDBjRMgTQoIZI0KeEBLMMgqp3YdN\nhjcSEiygElKN6V5CEVKfuzZ49bbG/1HkGkLyJE88K9P4P4pcQ0je9l/xK4/+sVjj/yhyje+Q\nxqYZFP6QPO9/DyFZyXdIvXoVJuUTUhIh2cl3SDUlqS/VWfChHSHByHdIB08/42D7MSGlEJKd\n/H+xYWPRze2HhJRCSHbK4Kt2H3/UfvTicsMyQoIFVL78bURIsAAhKe9PSHYiJOX9CclOhKS8\nPyHZiZCU9yckOxGS8v6EZCdCUt6fkOxESMr7E5KdCEl5f0KyEyEp709IdiIk5f0JyU6EpLw/\nIdmJkJT3JyQ7EZLy/oRkJ0JS3p+Q7ERIyvsTkp0ISXl/QrITISnvT0h2IiTl/QnJToSkvD8h\n2YmQlPcnJDsRkvL+hGQnQlLen5DsREjK+xOSnQhJeX9CshMhKe9PSHYiJOX9CclOhKS8PyHZ\niZCU9yckOxGS8v6EZCdCUt6fkOxESMr7E5KdCEl5f0KyEyEp709IdiIk5f0JyU6EpLw/IdmJ\nkJT3JyQ7EZLy/oRkJ0JS3p+Q7ERIyvsTkp0ISXl/QrITISnvT0h2IiTl/QnJToSkvD8h2YmQ\nlPcnJDsRkvL+hGQnQlLen5DsREjK+xOSnQhJeX9CshMhKe9PSHbKJKS2zfV1dQ1bu1lFSLCA\n/5Ca5w+UmIqle03rCAkW8B3SthEyqmpxbe3CGeUyutmwkJBgAd8hzY6sTRy1rs6rNiwkJFjA\nd0iDZqWOpw81LCQkWMB3SJFlqeMlBYaFhAQL+A5p2GWp46nDDQsJCRbwHVJ13or98aPdi6TG\nsJCQYAHfIe0aIyUTq+bNnTmhWMa3GBYSEizg//tIB1ZW5ke/jRQZt6bVtI6QYIGMRoT2bWps\nbOoqk3aEBAswIqS8PyHZiREh5f0JyU6MCCnvT0h2YkRIeX9CshMjQsr7E5KdGBFS3p+Q7MSI\nkPL+hGQnRoSU9yckOzEipLw/IdmJESHl/QnJTtkZEdpx0aSkM2V/F6cTEkIjOyNCf15Yk3QF\n75EQfowIKe9PSHZiREh5f0KyEyNCyvsTkp0YEVLen5DsxIiQ8v6EZCdGhJT3JyQ7MSKkvD8h\n2YkRIeX9CclOjAgp709IduKnCCnvT0h2yvQ39h1Y//wW8wpCggV8h3T789GX95W5H9yNfc20\nkJBgAd8hxb5S97QUXjLnbCl9y7CQkGCBzEIaVbrRffl43lWGhYQEC2QU0gdya+x42mDDQkKC\nBTIKaas8HDteGDEsJCRYIKOQWkuXx45nnWBYSEiwgP+QZrzatHPByD3u4Zt9pxgWEhIs4D+k\nuMcc55G+vdYbFhISLOA7pAdXLa6eOW1Cg+OsHvyUaSEhwQKZTja4Wg4Z30xIsIBCSN0gJFiA\nkJT3JyQ7EZLy/oRkJ0JS3p+Q7ERIyvsTkp0ISXl/QrITISnvT0h2IiTl/QnJToSkvD8h2YmQ\nlPcnJDsRkvL+hGQnQlLen5DsREjK+xOSnQhJeX9CshMhKe9PSHYiJOX9CclOhKS8/10F93v2\nh6z/z8exQkjK+8/NG+JVX9PP1URuIaTg9p9alfX/+ThWCCm4/QkpRAgpuP0JKUQIKbj9CSlE\nCCm4/QkpRAgpuP0JKUQIKbj9CSlECCm4/QkpRAgpuP0JKUQIKbj9CSlECCm4/QkpRAgpuP0J\nKUQIKbj9CSlECCm4/QkpRAgpuP0JKUQIKbj9CSlECCm4/QkpRAgpuP0JKUQIKbj9CSlECCm4\n/QkpRAgpuP0JKUQIKbj9CSlECCm4/QkpRAgpuP0JKUQIKbj9CSlECCm4/QkpRAgpuP0JKUQI\nKbj9CSlECCm4/QkpRAgpuP0JKUQIKbj9CSlECCm4/QkpRAgpuP0JKUQIKbj9CSlECCm4/Qkp\n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\nSIACQgIU/H95fgZKb8nNAgAAAABJRU5ErkJggg==" }, "metadata": { "image/png": { @@ -7197,18 +7237,18 @@ "hist(x = result, breaks = 0:15,\n", " right = FALSE)" ], - "id": "a593484a-23f2-4d4f-9085-acc571f78521" + "id": "c00342bf-fc4d-4cc1-aca8-14ba99933899" }, { "cell_type": "code", - "execution_count": 213, + "execution_count": 176, "metadata": { - "id": "0d8cebfb-32d2-497a-baa3-59fc47b90dfc", - "outputId": "636a56ea-4978-4cd4-e755-2e00781736fe", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "461a0129-9f7a-444f-8f77-de43e3144f5b", + "outputId": "abcf23b6-8dce-4f6e-a5f6-80331cc06ec8" }, "outputs": [ { @@ -7235,51 +7275,68 @@ "source": [ "quantile(result, c(0.025, 0.975))" ], - "id": "0d8cebfb-32d2-497a-baa3-59fc47b90dfc" + "id": "461a0129-9f7a-444f-8f77-de43e3144f5b" }, { - "id": "a0125811", + "id": "8bc5f5fd", "cell_type": "markdown", "source": [ "# 5 前処理" ], "metadata": { - "id": "a0125811" + "id": "8bc5f5fd" } }, { "cell_type": "code", - "execution_count": 214, + "execution_count": 177, "metadata": { - "id": "37582708-5531-4fad-9dfb-35800014751e" + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "2d9d8fc1-3420-4c0e-a166-12d131d39f3b", + "outputId": "d7118ab5-3946-4599-bd8a-ccfd3cb5d413" }, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "Installing package into ‘/usr/local/lib/R/site-library’\n", + "(as ‘lib’ is unspecified)\n", + "\n", + "also installing the dependencies ‘shape’, ‘future.apply’, ‘numDeriv’, ‘progressr’, ‘SQUAREM’, ‘diagram’, ‘lava’, ‘prodlim’, ‘iterators’, ‘clock’, ‘gower’, ‘hardhat’, ‘ipred’, ‘timeDate’, ‘e1071’, ‘foreach’, ‘ModelMetrics’, ‘pROC’, ‘recipes’, ‘reshape2’\n", + "\n", + "\n" + ] + } + ], "source": [ "# Google Colaboratoryの環境設定\n", "if (file.exists(\"/content\")) {\n", " options(Ncpus = parallel::detectCores())\n", - " packages_to_install <- c(\"caret\")\n", " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"caret\")\n", " install.packages(setdiff(packages_to_install, installed_packages))\n", "}" ], - "id": "37582708-5531-4fad-9dfb-35800014751e" + "id": "2d9d8fc1-3420-4c0e-a166-12d131d39f3b" }, { - "id": "b4864dfa", + "id": "87525fa5", "cell_type": "markdown", "source": [ "## 5.1 データの読み込み" ], "metadata": { - "id": "b4864dfa" + "id": "87525fa5" } }, { "cell_type": "code", - "execution_count": 215, + "execution_count": 178, "metadata": { - "id": "24ea4f4a-4a7a-4003-8c17-1b738d67bbeb" + "id": "b5c28b09-0c0f-4d8a-bfd7-06fa91405dbe" }, "outputs": [], "source": [ @@ -7287,18 +7344,18 @@ "system(str_c(\"wget https://raw.githubusercontent.com/taroyabuki\",\n", " \"/fromzero/master/data/exam.csv\"))" ], - "id": "24ea4f4a-4a7a-4003-8c17-1b738d67bbeb" + "id": "b5c28b09-0c0f-4d8a-bfd7-06fa91405dbe" }, { "cell_type": "code", - "execution_count": 216, + "execution_count": 179, "metadata": { - "id": "e0acf885-6c1c-462c-83f8-efda9b59e6fe", - "outputId": "9d7e4f7e-3294-4fec-9fed-e1ecb0d11f63", "colab": { "base_uri": "https://localhost:8080/", - "height": 362 - } + "height": 367 + }, + "id": "5dca006b-07ad-4bc7-947f-3e09f1f12b51", + "outputId": "255f5b3a-f59b-46d4-9c95-c2729e5a1872" }, "outputs": [ { @@ -7354,17 +7411,17 @@ "\n", "my_df" ], - "id": "e0acf885-6c1c-462c-83f8-efda9b59e6fe" + "id": "5dca006b-07ad-4bc7-947f-3e09f1f12b51" }, { "cell_type": "code", - "execution_count": 217, + "execution_count": 180, "metadata": { - "id": "4cbf4f39-5599-4444-a487-a2ecc4a98b21", - "outputId": "8600e018-dbf1-4e95-b2e5-63d26ed6ab26", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "e87681e4-6f3a-4df7-9bd0-755833199134", + "outputId": "46d544b6-e6f8-4d1a-e24d-c6cc08e671ed" }, "outputs": [ { @@ -7389,18 +7446,18 @@ "# あるいは\n", "my_df <- read.csv(my_url, stringsAsFactors = FALSE)" ], - "id": "4cbf4f39-5599-4444-a487-a2ecc4a98b21" + "id": "e87681e4-6f3a-4df7-9bd0-755833199134" }, { "cell_type": "code", - "execution_count": 218, + "execution_count": 181, "metadata": { - "id": "65b58340-f4c7-4735-be8d-d95acfe249df", - "outputId": "d5df902b-5f7b-4479-f289-1555a698c9d2", "colab": { "base_uri": "https://localhost:8080/", - "height": 224 - } + "height": 223 + }, + "id": "0a15b130-6d1e-439a-977e-36cd6ec5f4c5", + "outputId": "cd4edee6-5903-4229-a155-610721dc38c3" }, "outputs": [ { @@ -7441,13 +7498,13 @@ " row.names = 1)\n", "my_df2" ], - "id": "65b58340-f4c7-4735-be8d-d95acfe249df" + "id": "0a15b130-6d1e-439a-977e-36cd6ec5f4c5" }, { "cell_type": "code", - "execution_count": 219, + "execution_count": 182, "metadata": { - "id": "d6bc8599-f784-40cd-b451-65b9f0ac9ad3" + "id": "b76d61e7-8687-4159-9d68-5095dc48021a" }, "outputs": [], "source": [ @@ -7457,29 +7514,29 @@ " file = \"exam2.csv\",\n", " row.names = FALSE)" ], - "id": "d6bc8599-f784-40cd-b451-65b9f0ac9ad3" + "id": "b76d61e7-8687-4159-9d68-5095dc48021a" }, { "cell_type": "code", - "execution_count": 220, + "execution_count": 183, "metadata": { - "id": "85bff779-82dc-49b6-b7ba-dbd836ae9636" + "id": "d562c9be-80d9-4ccf-930f-6b76abc6c740" }, "outputs": [], "source": [ "my_df2 %>% write.csv(\"exam3.csv\")" ], - "id": "85bff779-82dc-49b6-b7ba-dbd836ae9636" + "id": "d562c9be-80d9-4ccf-930f-6b76abc6c740" }, { "cell_type": "code", - "execution_count": 221, + "execution_count": 184, "metadata": { - "id": "40714e2f-100a-4c8c-9595-15baf8a9c694", - "outputId": "02a88822-833b-43d1-b5ee-2de96d985885", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "fb1b9e69-e8d1-4414-b437-e1bd63abc97d", + "outputId": "b897bab3-391a-4b48-a641-fd246d289eda" }, "outputs": [ { @@ -7505,13 +7562,13 @@ " stringsAsFactors = FALSE,\n", " fileEncoding = \"UTF-8\")" ], - "id": "40714e2f-100a-4c8c-9595-15baf8a9c694" + "id": "fb1b9e69-e8d1-4414-b437-e1bd63abc97d" }, { "cell_type": "code", - "execution_count": 222, + "execution_count": 185, "metadata": { - "id": "500a76ff-1863-45a1-9c97-cb1d5a6e4215" + "id": "eb2d9798-d854-493f-8b89-fc4c7f15caa7" }, "outputs": [], "source": [ @@ -7520,31 +7577,31 @@ "my_df %>% write.csv(file = \"exam2.csv\", row.names = FALSE,\n", " fileEncoding = \"UTF-8\")" ], - "id": "500a76ff-1863-45a1-9c97-cb1d5a6e4215" + "id": "eb2d9798-d854-493f-8b89-fc4c7f15caa7" }, { "cell_type": "code", - "execution_count": 223, + "execution_count": 186, "metadata": { - "id": "293dd877-7300-412f-8edd-28e7b0b37c9c" + "id": "76a014f6-1f8f-4405-9c9f-67130e56ec92" }, "outputs": [], "source": [ "my_url <- \"https://taroyabuki.github.io/fromzero/exam.html\"\n", "my_tables <- xml2::read_html(my_url) %>% rvest::html_table()" ], - "id": "293dd877-7300-412f-8edd-28e7b0b37c9c" + "id": "76a014f6-1f8f-4405-9c9f-67130e56ec92" }, { "cell_type": "code", - "execution_count": 224, + "execution_count": 187, "metadata": { - "id": "40d41854-7c0f-4dee-8a59-12f5b333adf3", - "outputId": "7f79d7a4-338e-41e9-f6f7-04a167facd95", "colab": { "base_uri": "https://localhost:8080/", "height": 283 - } + }, + "id": "140e2238-924a-49d2-add0-f1a851982056", + "outputId": "b9dbc8c7-ab92-4f50-801d-2090f47521e0" }, "outputs": [ { @@ -7589,18 +7646,18 @@ "source": [ "my_tables" ], - "id": "40d41854-7c0f-4dee-8a59-12f5b333adf3" + "id": "140e2238-924a-49d2-add0-f1a851982056" }, { "cell_type": "code", - "execution_count": 225, + "execution_count": 188, "metadata": { - "id": "ddd67838-431d-4627-b84e-a89ae7a77fe0", - "outputId": "daffdd56-c2f6-4cca-8cc1-cf2104552286", "colab": { "base_uri": "https://localhost:8080/", "height": 255 - } + }, + "id": "f1c7145e-e3a0-4d8b-8595-6b211061beaa", + "outputId": "7b22d76a-f7cb-4ab3-aa1f-a7eb0464d26c" }, "outputs": [ { @@ -7640,18 +7697,18 @@ "tmp <- my_tables[[1]]\n", "tmp" ], - "id": "ddd67838-431d-4627-b84e-a89ae7a77fe0" + "id": "f1c7145e-e3a0-4d8b-8595-6b211061beaa" }, { "cell_type": "code", - "execution_count": 226, + "execution_count": 189, "metadata": { - "id": "03a871b1-a04b-4f09-bcdb-ba2287649a10", - "outputId": "4272c4c8-0c6a-479a-ab6e-0853897121e2", "colab": { "base_uri": "https://localhost:8080/", - "height": 224 - } + "height": 223 + }, + "id": "dd0bdef6-633c-461a-8599-e9fca422b9be", + "outputId": "40dd46b2-c612-44ea-abf9-f34d0e859a74" }, "outputs": [ { @@ -7693,18 +7750,18 @@ "my_data <- tmp[-1, -1]\n", "my_data" ], - "id": "03a871b1-a04b-4f09-bcdb-ba2287649a10" + "id": "dd0bdef6-633c-461a-8599-e9fca422b9be" }, { "cell_type": "code", - "execution_count": 227, + "execution_count": 190, "metadata": { - "id": "71b12f42-08ac-445c-9231-cd4caf69ac2d", - "outputId": "7c1a016d-7d9b-44b6-ec40-0add477752f9", "colab": { "base_uri": "https://localhost:8080/", - "height": 467 - } + "height": 385 + }, + "id": "1e658592-e14b-4763-b6c1-3f0750160f45", + "outputId": "2a4f9485-a949-4fb4-825f-b9ec9ce78b71" }, "outputs": [ { @@ -7715,11 +7772,6 @@ "Attaching package: ‘jsonlite’\n", "\n", "\n", - "The following objects are masked from ‘package:rlang’:\n", - "\n", - " flatten, unbox\n", - "\n", - "\n", "The following object is masked from ‘package:purrr’:\n", "\n", " flatten\n", @@ -7766,35 +7818,20 @@ "#my_data <- fromJSON(\"exam.json\") # (ファイルを使う場合)\n", "my_data" ], - "id": "71b12f42-08ac-445c-9231-cd4caf69ac2d" + "id": "1e658592-e14b-4763-b6c1-3f0750160f45" }, { "cell_type": "code", - "execution_count": 228, + "execution_count": 191, "metadata": { - "id": "43cb67e1-6cf2-48a4-bcef-202fe8bfb8f0", - "outputId": "6d87e68e-a7c1-41e4-cee9-48106c84859f", "colab": { "base_uri": "https://localhost:8080/", - "height": 191 - } + "height": 35 + }, + "id": "a4f2543e-9e92-4b0f-94ec-a2436a08f60c", + "outputId": "d61de77f-e529-43b7-b464-9ad532a27a48" }, "outputs": [ - { - "output_type": "stream", - "name": "stderr", - "text": [ - "\n", - "Attaching package: ‘xml2’\n", - "\n", - "\n", - "The following object is masked from ‘package:rlang’:\n", - "\n", - " as_list\n", - "\n", - "\n" - ] - }, { "output_type": "display_data", "data": { @@ -7813,25 +7850,25 @@ "#my_xml <- read_xml(\"exam.xml\") # (ファイルを使う場合)\n", "xml_ns(my_xml) # 名前空間の確認(d1)" ], - "id": "43cb67e1-6cf2-48a4-bcef-202fe8bfb8f0" + "id": "a4f2543e-9e92-4b0f-94ec-a2436a08f60c" }, { "cell_type": "code", - "execution_count": 229, + "execution_count": 192, "metadata": { - "id": "35a20890-ddf9-4537-a23f-b7820caaad35" + "id": "18d661a5-d1f0-425c-a69d-603341e43770" }, "outputs": [], "source": [ "my_records <- xml_find_all(my_xml, \".//d1:record\")" ], - "id": "35a20890-ddf9-4537-a23f-b7820caaad35" + "id": "18d661a5-d1f0-425c-a69d-603341e43770" }, { "cell_type": "code", - "execution_count": 230, + "execution_count": 193, "metadata": { - "id": "6838dc42-9bef-49a5-8fc5-5624ced43c9f" + "id": "cf6db405-8dad-468e-90aa-1582b4315633" }, "outputs": [], "source": [ @@ -7843,18 +7880,18 @@ " tmp\n", "}" ], - "id": "6838dc42-9bef-49a5-8fc5-5624ced43c9f" + "id": "cf6db405-8dad-468e-90aa-1582b4315633" }, { "cell_type": "code", - "execution_count": 231, + "execution_count": 194, "metadata": { - "id": "85cdc6a8-c201-4710-9302-db338fc510bc", - "outputId": "b1464028-4465-4720-ebab-71c1056a2b2d", "colab": { "base_uri": "https://localhost:8080/", - "height": 224 - } + "height": 223 + }, + "id": "9a0cd990-fbfb-4a9c-9712-d1c8955ded03", + "outputId": "848d0aca-3053-495d-fdbf-ba27c0a6a203" }, "outputs": [ { @@ -7894,28 +7931,28 @@ "my_data$math <- as.numeric(my_data$math)\n", "my_data" ], - "id": "85cdc6a8-c201-4710-9302-db338fc510bc" + "id": "9a0cd990-fbfb-4a9c-9712-d1c8955ded03" }, { - "id": "308b11d8", + "id": "feea1595", "cell_type": "markdown", "source": [ "## 5.2 データの変換" ], "metadata": { - "id": "308b11d8" + "id": "feea1595" } }, { "cell_type": "code", - "execution_count": 232, + "execution_count": 195, "metadata": { - "id": "48af90d0-5d2e-4186-92de-3d8e2775b4e8", - "outputId": "1aedb03e-2c43-4b4c-b99b-ac2fa5c942ad", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "02b03263-d7ad-4119-8d87-998593f4f524", + "outputId": "88864427-5df5-41ab-8565-a89f52716896" }, "outputs": [ { @@ -7947,18 +7984,18 @@ "\n", "z1" ], - "id": "48af90d0-5d2e-4186-92de-3d8e2775b4e8" + "id": "02b03263-d7ad-4119-8d87-998593f4f524" }, { "cell_type": "code", - "execution_count": 233, + "execution_count": 196, "metadata": { - "id": "f60a2354-c48d-42de-9e0f-a3488e4f921c", - "outputId": "d22e1469-b48a-4403-e3a9-4c213a1ace03", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "2f7f86d8-b4d9-4b74-a854-692591408301", + "outputId": "2e15d1ec-9926-43d4-977d-eb3391f1e670" }, "outputs": [ { @@ -7984,18 +8021,18 @@ "source": [ "c(mean(z1), sd(z1))" ], - "id": "f60a2354-c48d-42de-9e0f-a3488e4f921c" + "id": "2f7f86d8-b4d9-4b74-a854-692591408301" }, { "cell_type": "code", - "execution_count": 234, + "execution_count": 197, "metadata": { - "id": "97ab5686-9dd3-4570-bb43-bdedd33dc231", - "outputId": "6494e3a2-8bd5-4934-fa6e-3c337b5795d6", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "5b6d21d6-0cd7-4a32-83f0-2ab27aff1726", + "outputId": "6eb2e525-65db-4ed9-e07e-8e67b3fd1805" }, "outputs": [ { @@ -8021,18 +8058,18 @@ "source": [ "z1 * sd(x1) + mean(x1)" ], - "id": "97ab5686-9dd3-4570-bb43-bdedd33dc231" + "id": "5b6d21d6-0cd7-4a32-83f0-2ab27aff1726" }, { "cell_type": "code", - "execution_count": 235, + "execution_count": 198, "metadata": { - "id": "5d89af0c-a939-4e38-8abb-24c56b7ff862", - "outputId": "0c031e78-1cca-406b-ec44-f2beebdc24a3", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "49f3f75e-601e-4052-b2d7-fd4a39a3b85c", + "outputId": "3f204079-05f3-4080-9e9a-8380144920e5" }, "outputs": [ { @@ -8060,20 +8097,42 @@ "z2 <- (x2 - mean(x1)) / sd(x1)\n", "c(mean(z2), sd(z2))" ], - "id": "5d89af0c-a939-4e38-8abb-24c56b7ff862" + "id": "49f3f75e-601e-4052-b2d7-fd4a39a3b85c" }, { "cell_type": "code", - "execution_count": 236, + "execution_count": 199, "metadata": { - "id": "eb6c1427-d877-4d1a-b936-72efd4534362", - "outputId": "661816cf-a5b4-4fcc-b424-e80f176eed6b", "colab": { "base_uri": "https://localhost:8080/", - "height": 161 - } + "height": 449 + }, + "id": "bbcf9147-2fd7-40d1-ac6f-c07e482a1c21", + "outputId": "0816c1b4-0a25-4d03-9b9a-d19ba5c4f27f" }, "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "Loading required package: lattice\n", + "\n", + "\n", + "Attaching package: ‘caret’\n", + "\n", + "\n", + "The following object is masked from ‘package:future’:\n", + "\n", + " cluster\n", + "\n", + "\n", + "The following object is masked from ‘package:purrr’:\n", + "\n", + " lift\n", + "\n", + "\n" + ] + }, { "output_type": "display_data", "data": { @@ -8116,18 +8175,18 @@ "\n", "my_enc %>% predict(my_df)" ], - "id": "eb6c1427-d877-4d1a-b936-72efd4534362" + "id": "bbcf9147-2fd7-40d1-ac6f-c07e482a1c21" }, { "cell_type": "code", - "execution_count": 237, + "execution_count": 200, "metadata": { - "id": "2879da19-5499-4a0d-a05c-85e1656ba106", - "outputId": "8120106e-478c-4b1d-b5c4-f0963481834d", "colab": { "base_uri": "https://localhost:8080/", - "height": 161 - } + "height": 160 + }, + "id": "6c87bfa5-2a6f-4b57-a984-0f6fb2066c41", + "outputId": "20096e7c-ca3c-408a-a093-dae54f8664e8" }, "outputs": [ { @@ -8164,18 +8223,18 @@ " class = c(\"B\", \"C\", \"B\"))\n", "my_enc %>% predict(my_df2)" ], - "id": "2879da19-5499-4a0d-a05c-85e1656ba106" + "id": "6c87bfa5-2a6f-4b57-a984-0f6fb2066c41" }, { "cell_type": "code", - "execution_count": 238, + "execution_count": 201, "metadata": { - "id": "8b421365-ed38-45f1-9380-48c3a4838f00", - "outputId": "255e9c80-86a0-4f21-c29a-fe77fcec3982", "colab": { "base_uri": "https://localhost:8080/", - "height": 305 - } + "height": 304 + }, + "id": "5d6a9971-3d61-49a4-a52d-63c3a3328d60", + "outputId": "98e3ecc8-46a3-43fe-e03c-54cde1fd03d3" }, "outputs": [ { @@ -8241,10 +8300,10 @@ "\n", "my_enc %>% predict(my_df2)" ], - "id": "8b421365-ed38-45f1-9380-48c3a4838f00" + "id": "5d6a9971-3d61-49a4-a52d-63c3a3328d60" }, { - "id": "caf262b8", + "id": "1df89d43", "cell_type": "markdown", "source": [ "# 6 機械学習の目的・データ・手法\n", @@ -8252,11 +8311,11 @@ "\n" ], "metadata": { - "id": "caf262b8" + "id": "1df89d43" } }, { - "id": "b888519f", + "id": "9c6dc6ca", "cell_type": "markdown", "source": [ "## 6.1 機械学習の目的(本書の場合)\n", @@ -8264,29 +8323,29 @@ "\n" ], "metadata": { - "id": "b888519f" + "id": "9c6dc6ca" } }, { - "id": "e17120fa", + "id": "784c2e6e", "cell_type": "markdown", "source": [ "## 6.2 機械学習のためのデータ" ], "metadata": { - "id": "e17120fa" + "id": "784c2e6e" } }, { "cell_type": "code", - "execution_count": 239, + "execution_count": 202, "metadata": { - "id": "8a75f396-d1fb-430f-8a5f-75beeb2e19f6", - "outputId": "e681055e-c653-42b8-bedc-df176ea6a143", "colab": { "base_uri": "https://localhost:8080/", "height": 1000 - } + }, + "id": "f6627b4e-e0ee-4a8e-aadf-63a8a8ac0fa9", + "outputId": "27ec6ca9-e937-499a-bbb8-d0c986baa356" }, "outputs": [ { @@ -8438,10 +8497,10 @@ "iris\n", "# 以下省略" ], - "id": "8a75f396-d1fb-430f-8a5f-75beeb2e19f6" + "id": "f6627b4e-e0ee-4a8e-aadf-63a8a8ac0fa9" }, { - "id": "37607969", + "id": "4c72a568", "cell_type": "markdown", "source": [ "## 6.3 機械学習のための手法\n", @@ -8449,39 +8508,53 @@ "\n" ], "metadata": { - "id": "37607969" + "id": "4c72a568" } }, { - "id": "2366b3bd", + "id": "5b58c713", "cell_type": "markdown", "source": [ "# 7 回帰1(単回帰)" ], "metadata": { - "id": "2366b3bd" + "id": "5b58c713" } }, { "cell_type": "code", - "execution_count": 240, + "execution_count": 203, "metadata": { - "id": "118f055e-e3ce-433f-8f7b-ba85241135cb" + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "1fd3a3f0-1524-4bb8-8411-5dbd84fd04e9", + "outputId": "6446c2e1-1329-4e4f-9af2-a4296b7a7187" }, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "Installing package into ‘/usr/local/lib/R/site-library’\n", + "(as ‘lib’ is unspecified)\n", + "\n" + ] + } + ], "source": [ "# Google Colaboratoryの環境設定\n", "if (file.exists(\"/content\")) {\n", " options(Ncpus = parallel::detectCores())\n", - " packages_to_install <- c(\"caret\", \"doParallel\", \"pastecs\")\n", " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"caret\", \"doParallel\", \"pastecs\")\n", " install.packages(setdiff(packages_to_install, installed_packages))\n", "}" ], - "id": "118f055e-e3ce-433f-8f7b-ba85241135cb" + "id": "1fd3a3f0-1524-4bb8-8411-5dbd84fd04e9" }, { - "id": "6cdcfcd7", + "id": "b8c6b1c3", "cell_type": "markdown", "source": [ "## 7.1 自動車の停止距離\n", @@ -8489,24 +8562,24 @@ "\n" ], "metadata": { - "id": "6cdcfcd7" + "id": "b8c6b1c3" } }, { - "id": "930b5e8a", + "id": "1528c0a1", "cell_type": "markdown", "source": [ "## 7.2 データの確認" ], "metadata": { - "id": "930b5e8a" + "id": "1528c0a1" } }, { "cell_type": "code", - "execution_count": 241, + "execution_count": 204, "metadata": { - "id": "70e49dcd-f89d-4d87-ba42-e597900bd39a" + "id": "508e447d-4b57-4401-a870-34b94813ac9a" }, "outputs": [], "source": [ @@ -8514,18 +8587,18 @@ "library(tidyverse)\n", "my_data <- cars" ], - "id": "70e49dcd-f89d-4d87-ba42-e597900bd39a" + "id": "508e447d-4b57-4401-a870-34b94813ac9a" }, { "cell_type": "code", - "execution_count": 242, + "execution_count": 205, "metadata": { - "id": "897d14f0-bc30-4137-a65d-1d5a7d2f2390", - "outputId": "2019a83f-c455-41bf-b7f6-f68903f21165", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "f4688485-c843-42cd-a8af-61bd4415e199", + "outputId": "58f5b008-0cdd-45b6-99ba-f27d5c49e7e0" }, "outputs": [ { @@ -8551,18 +8624,18 @@ "source": [ "dim(my_data)" ], - "id": "897d14f0-bc30-4137-a65d-1d5a7d2f2390" + "id": "f4688485-c843-42cd-a8af-61bd4415e199" }, { "cell_type": "code", - "execution_count": 243, + "execution_count": 206, "metadata": { - "id": "8b8eb83f-f4ea-4aec-a78f-3c4fee476419", - "outputId": "335fe026-36a4-4d37-821a-2c25776a4e1c", "colab": { "base_uri": "https://localhost:8080/", - "height": 304 - } + "height": 303 + }, + "id": "29c54dc8-c636-4188-a9db-cdc3cb9905fd", + "outputId": "f61ca12c-3a49-4d7b-c233-ee780d54b184" }, "outputs": [ { @@ -8603,18 +8676,18 @@ "source": [ "head(my_data)" ], - "id": "8b8eb83f-f4ea-4aec-a78f-3c4fee476419" + "id": "29c54dc8-c636-4188-a9db-cdc3cb9905fd" }, { "cell_type": "code", - "execution_count": 244, + "execution_count": 207, "metadata": { - "id": "4c20b558-adfb-4197-8d8f-68081426e3de", - "outputId": "4d610d13-381a-4fac-f77d-de65610fa038", "colab": { "base_uri": "https://localhost:8080/", "height": 537 - } + }, + "id": "29ee980b-ca54-433d-a284-0146636f98ff", + "outputId": "d44c952a-ed06-4b0b-bab1-4d01ebfcca17" }, "outputs": [ { @@ -8672,18 +8745,18 @@ "options(digits = 3)\n", "pastecs::stat.desc(my_data)" ], - "id": "4c20b558-adfb-4197-8d8f-68081426e3de" + "id": "29ee980b-ca54-433d-a284-0146636f98ff" }, { "cell_type": "code", - "execution_count": 245, + "execution_count": 208, "metadata": { - "id": "fc24835c-b576-4985-a588-a6a59f78cf05", - "outputId": "f4b348b5-f96c-4350-ad78-274e4ad3fcd6", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "cfef8416-0c86-4356-9fc7-c05126d1709f", + "outputId": "bc0bc7f0-0563-4f41-b636-4b42a7980f3e" }, "outputs": [ { @@ -8707,28 +8780,28 @@ " ggplot(aes(x = speed, y = dist)) +\n", " geom_point()" ], - "id": "fc24835c-b576-4985-a588-a6a59f78cf05" + "id": "cfef8416-0c86-4356-9fc7-c05126d1709f" }, { - "id": "7dd21890", + "id": "e510dff5", "cell_type": "markdown", "source": [ "## 7.3 回帰分析" ], "metadata": { - "id": "7dd21890" + "id": "e510dff5" } }, { "cell_type": "code", - "execution_count": 246, + "execution_count": 209, "metadata": { - "id": "a84d3d0a-a688-49f2-a88d-0d8be01ae572", - "outputId": "9b3c2c78-1760-4d48-c208-0afbac573c42", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "ac373625-6356-4185-8a8c-d7fb6c9ca0d9", + "outputId": "1762e26f-8556-48c6-f593-fac40a6870b5" }, "outputs": [ { @@ -8759,13 +8832,13 @@ " geom_pointrange(data = tmp, aes(ymin = -9, ymax = dist), linetype = \"dotted\") +\n", " geom_pointrange(data = tmp, aes(xmin = 0, xmax = speed), linetype = \"dotted\")" ], - "id": "a84d3d0a-a688-49f2-a88d-0d8be01ae572" + "id": "ac373625-6356-4185-8a8c-d7fb6c9ca0d9" }, { "cell_type": "code", - "execution_count": 247, + "execution_count": 210, "metadata": { - "id": "17e2e500-8625-4d40-a1e2-8999cc6efc13" + "id": "bb24f245-cf1a-4bb3-b75d-39efc2a9bd91" }, "outputs": [], "source": [ @@ -8773,13 +8846,13 @@ "library(tidyverse)\n", "my_data <- cars" ], - "id": "17e2e500-8625-4d40-a1e2-8999cc6efc13" + "id": "bb24f245-cf1a-4bb3-b75d-39efc2a9bd91" }, { "cell_type": "code", - "execution_count": 248, + "execution_count": 211, "metadata": { - "id": "ccbdc870-019d-4fb2-a525-a603e032ba82" + "id": "58e797ab-6edc-4262-a25e-1ea7f362e821" }, "outputs": [], "source": [ @@ -8787,18 +8860,18 @@ " data = my_data, # データ\n", " method = \"lm\") # 手法" ], - "id": "ccbdc870-019d-4fb2-a525-a603e032ba82" + "id": "58e797ab-6edc-4262-a25e-1ea7f362e821" }, { "cell_type": "code", - "execution_count": 249, + "execution_count": 212, "metadata": { - "id": "faae5286-2119-44c8-8670-4077dcd8ca72", - "outputId": "0c245f2a-32ba-4e23-e5b2-c52c4183158a", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "66000a61-cdbf-4336-974b-ad6e79381cbc", + "outputId": "db6450d5-f380-4800-8ca6-082f81af9caa" }, "outputs": [ { @@ -8825,18 +8898,18 @@ "source": [ "coef(my_model$finalModel)" ], - "id": "faae5286-2119-44c8-8670-4077dcd8ca72" + "id": "66000a61-cdbf-4336-974b-ad6e79381cbc" }, { "cell_type": "code", - "execution_count": 250, + "execution_count": 213, "metadata": { - "id": "f4e985bc-d5db-4561-a8a6-35d6ef29e042", - "outputId": "30f9962c-4767-4872-980d-364aa2d23508", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "32f4fe3a-0d1f-4248-a97b-b12ea7001f7c", + "outputId": "f6448a80-2a60-45ac-af1d-a961e0b4590d" }, "outputs": [ { @@ -8859,30 +8932,30 @@ "tmp <- data.frame(speed = 21.5)\n", "my_model %>% predict(tmp)" ], - "id": "f4e985bc-d5db-4561-a8a6-35d6ef29e042" + "id": "32f4fe3a-0d1f-4248-a97b-b12ea7001f7c" }, { "cell_type": "code", - "execution_count": 251, + "execution_count": 214, "metadata": { - "id": "828eac4d-a08a-4c3a-aadc-e21e224a616d" + "id": "5e4892d5-4d99-4154-aa78-e9d7def0f4e6" }, "outputs": [], "source": [ "f <- function(x) { my_model %>% predict(data.frame(speed = x)) }" ], - "id": "828eac4d-a08a-4c3a-aadc-e21e224a616d" + "id": "5e4892d5-4d99-4154-aa78-e9d7def0f4e6" }, { "cell_type": "code", - "execution_count": 252, + "execution_count": 215, "metadata": { - "id": "f8305e1a-6015-422d-bb43-21ba1ff982a5", - "outputId": "ffc9d714-b52e-43d0-9edb-3306a38f7b69", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "1d7f8dc5-e510-42f6-b2f7-8a02fe305132", + "outputId": "86a750e7-4770-4f3b-d497-edd9b55fad07" }, "outputs": [ { @@ -8910,23 +8983,23 @@ " fun = f,\n", " mapping = aes(color = \"model\"))" ], - "id": "f8305e1a-6015-422d-bb43-21ba1ff982a5" + "id": "1d7f8dc5-e510-42f6-b2f7-8a02fe305132" }, { - "id": "1bb78121", + "id": "87a132e0", "cell_type": "markdown", "source": [ "## 7.4 当てはまりの良さの指標" ], "metadata": { - "id": "1bb78121" + "id": "87a132e0" } }, { "cell_type": "code", - "execution_count": 253, + "execution_count": 216, "metadata": { - "id": "647b916f-8819-436f-8ec9-ef9972f9eeb9" + "id": "5e1b68dd-e9f8-4977-813d-a80d0f476ac5" }, "outputs": [], "source": [ @@ -8939,18 +9012,18 @@ "y_ <- my_model %>% predict(my_data)\n", "my_data$y_ <- y_" ], - "id": "647b916f-8819-436f-8ec9-ef9972f9eeb9" + "id": "5e1b68dd-e9f8-4977-813d-a80d0f476ac5" }, { "cell_type": "code", - "execution_count": 254, + "execution_count": 217, "metadata": { - "id": "d1a374e4-a8d1-4298-9be8-f3f577b2df78", - "outputId": "73816a4c-d631-4014-97a9-01c88a701e5b", "colab": { "base_uri": "https://localhost:8080/", "height": 286 - } + }, + "id": "bba309a9-c921-4f36-aa50-ec6398fa9ed5", + "outputId": "b16522f1-5993-42d3-8014-6c95805888e1" }, "outputs": [ { @@ -8992,18 +9065,18 @@ "my_data$residual <- y - y_\n", "head(my_data)" ], - "id": "d1a374e4-a8d1-4298-9be8-f3f577b2df78" + "id": "bba309a9-c921-4f36-aa50-ec6398fa9ed5" }, { "cell_type": "code", - "execution_count": 255, + "execution_count": 218, "metadata": { - "id": "97e65c36-fa06-44ae-acd4-fc40cd30d526", - "outputId": "97a47393-d508-4ba6-e948-4cf46100ba03", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "3d1cb023-3abd-4b11-8228-260547e3582c", + "outputId": "79f16354-7057-443a-c67f-5b7683a090cf" }, "outputs": [ { @@ -9029,30 +9102,30 @@ " geom_line(aes(x = speed, y = y_)) +\n", " geom_linerange(mapping = aes(ymin = y_, ymax = dist), linetype = \"dotted\")" ], - "id": "97e65c36-fa06-44ae-acd4-fc40cd30d526" + "id": "3d1cb023-3abd-4b11-8228-260547e3582c" }, { "cell_type": "code", - "execution_count": 256, + "execution_count": 219, "metadata": { - "id": "8913e556-5ecf-407c-b8b2-04520163ec0d", - "outputId": "d89aedd7-276e-4674-f1d6-a05af27943ec", "colab": { "base_uri": "https://localhost:8080/", "height": 52 - } + }, + "id": "4bf75802-cc0a-4255-bedc-8817d5b9caee", + "outputId": "366d3470-ea2e-4051-ed69-2acb9480dbbb" }, "outputs": [ { "output_type": "display_data", "data": { "text/html": [ - "47.6549008914939" + "15.0688559957914" ], - "text/markdown": "47.6549008914939", - "text/latex": "47.6549008914939", + "text/markdown": "15.0688559957914", + "text/latex": "15.0688559957914", "text/plain": [ - "[1] 47.7" + "[1] 15.1" ] }, "metadata": {} @@ -9077,18 +9150,18 @@ "# あるいは\n", "mean((my_data$residual^2))**0.5\n" ], - "id": "8913e556-5ecf-407c-b8b2-04520163ec0d" + "id": "4bf75802-cc0a-4255-bedc-8817d5b9caee" }, { "cell_type": "code", - "execution_count": 257, + "execution_count": 220, "metadata": { - "id": "6a176d34-5758-4962-888f-116c24285db5", - "outputId": "df4fc7be-6551-44e4-ff2e-0d1bda864e74", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "f72754c6-0a8b-458d-b6a3-85fc560b8ecb", + "outputId": "71fc09e1-dd54-4fe8-bb04-317fa7829296" }, "outputs": [ { @@ -9110,18 +9183,18 @@ "R2(pred = y_, obs = y,\n", " form = \"traditional\")" ], - "id": "6a176d34-5758-4962-888f-116c24285db5" + "id": "f72754c6-0a8b-458d-b6a3-85fc560b8ecb" }, { "cell_type": "code", - "execution_count": 258, + "execution_count": 221, "metadata": { - "id": "82d375f3-b6a3-40ea-8d80-a1c78587d583", - "outputId": "7db2a755-7c3f-4162-ecb1-c12cdc619cc7", "colab": { "base_uri": "https://localhost:8080/", "height": 52 - } + }, + "id": "c17b2876-1303-4ba1-8009-a6d113f225a1", + "outputId": "a9725883-01ef-4fe6-f30d-f08bcbdee80a" }, "outputs": [ { @@ -9159,18 +9232,18 @@ "# あるいは\n", "summary(my_model$finalModel)$r.squared" ], - "id": "82d375f3-b6a3-40ea-8d80-a1c78587d583" + "id": "c17b2876-1303-4ba1-8009-a6d113f225a1" }, { "cell_type": "code", - "execution_count": 259, + "execution_count": 222, "metadata": { - "id": "9bc44ff9-f18a-47c9-b1f5-91a267f53586", - "outputId": "eacb0417-1086-4a2b-a521-30ee2a2ae6a1", "colab": { "base_uri": "https://localhost:8080/", "height": 52 - } + }, + "id": "4fb4ab7d-a394-42a0-b080-a9f7250e019c", + "outputId": "2667d1cf-fd26-4b01-d864-74bc697ed597" }, "outputs": [ { @@ -9213,13 +9286,13 @@ "R2(pred = y_, obs = y,\n", " form = \"corr\")" ], - "id": "9bc44ff9-f18a-47c9-b1f5-91a267f53586" + "id": "4fb4ab7d-a394-42a0-b080-a9f7250e019c" }, { "cell_type": "code", - "execution_count": 260, + "execution_count": 223, "metadata": { - "id": "1baf4162-2775-4b51-88c7-6d71897ddfd2" + "id": "d4b2f253-911a-44b0-bb4e-cd064fa3e70c" }, "outputs": [], "source": [ @@ -9229,13 +9302,13 @@ "my_idx <- c(2, 11, 27, 34, 39, 44)\n", "my_sample <- my_data[my_idx, ]" ], - "id": "1baf4162-2775-4b51-88c7-6d71897ddfd2" + "id": "d4b2f253-911a-44b0-bb4e-cd064fa3e70c" }, { "cell_type": "code", - "execution_count": 261, + "execution_count": 224, "metadata": { - "id": "ea696365-2a8e-491c-b2c6-b9e827e4b084" + "id": "a553db8e-4860-41bb-bc06-866860468a0d" }, "outputs": [], "source": [ @@ -9248,30 +9321,30 @@ "y <- my_sample$dist\n", "y_ <- my_model %>% predict(my_sample)" ], - "id": "ea696365-2a8e-491c-b2c6-b9e827e4b084" + "id": "a553db8e-4860-41bb-bc06-866860468a0d" }, { "cell_type": "code", - "execution_count": 262, + "execution_count": 225, "metadata": { - "id": "ec4841ef-c070-466d-9be7-93b312a2eeed", - "outputId": "5127e235-9a30-48cc-ad7c-694332b3b271", "colab": { "base_uri": "https://localhost:8080/", "height": 69 - } + }, + "id": "255768c1-34d6-49cb-8efa-eeb2e341c8c7", + "outputId": "19926d0e-dec4-4231-85ca-3f0d1fd80c5a" }, "outputs": [ { "output_type": "display_data", "data": { "text/html": [ - "46.6619045189285" + "1.0683696001688e-10" ], - "text/markdown": "46.6619045189285", - "text/latex": "46.6619045189285", + "text/markdown": "1.0683696001688e-10", + "text/latex": "1.0683696001688e-10", "text/plain": [ - "[1] 46.7" + "[1] 1.07e-10" ] }, "metadata": {} @@ -9314,18 +9387,18 @@ "R2(pred = y_, obs = y,\n", " form = \"corr\")" ], - "id": "ec4841ef-c070-466d-9be7-93b312a2eeed" + "id": "255768c1-34d6-49cb-8efa-eeb2e341c8c7" }, { "cell_type": "code", - "execution_count": 263, + "execution_count": 226, "metadata": { - "id": "25151bf6-ba12-4160-bdc5-d30fbb37bde7", - "outputId": "35353a01-0f1e-4b16-f5a1-c0d8c510d047", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "2255dc05-c57d-47f8-834a-25cac6e73ada", + "outputId": "4c9205e1-3115-4d3c-bd09-862a35fe175b" }, "outputs": [ { @@ -9354,23 +9427,23 @@ " stat_function(fun = f, mapping = aes(color = \"model\")) +\n", " coord_cartesian(ylim = c(0, 120))" ], - "id": "25151bf6-ba12-4160-bdc5-d30fbb37bde7" + "id": "2255dc05-c57d-47f8-834a-25cac6e73ada" }, { - "id": "a13d4468", + "id": "3e272c39", "cell_type": "markdown", "source": [ "## 7.5 K最近傍法" ], "metadata": { - "id": "a13d4468" + "id": "3e272c39" } }, { "cell_type": "code", - "execution_count": 264, + "execution_count": 227, "metadata": { - "id": "4a128a67-7615-492b-bce0-0426cec7e868" + "id": "edcb2fd7-7433-4ebf-9636-69a3a673e2de" }, "outputs": [], "source": [ @@ -9385,18 +9458,18 @@ "# 可視化の準備\n", "f <- function(x) { my_model %>% predict(data.frame(speed = x))}" ], - "id": "4a128a67-7615-492b-bce0-0426cec7e868" + "id": "edcb2fd7-7433-4ebf-9636-69a3a673e2de" }, { "cell_type": "code", - "execution_count": 265, + "execution_count": 228, "metadata": { - "id": "3ea54e86-a1f2-41b6-90d8-450bd6549910", - "outputId": "11123cbf-4428-4a8d-f732-9c93d51f5092", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "7c3d4d9a-eff1-4702-949f-ee3f98a08281", + "outputId": "f2fabcaf-f701-4ba2-800b-b69ec4b66710" }, "outputs": [ { @@ -9405,7 +9478,7 @@ "text/plain": [ "plot without title" ], - "image/png": "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\nCwaFEI3DcppdYcSukluxkAhXMwD4Sc6yX0ulp4SCdQFnljWo13UhROOwfDCWW7GQD8EOAPxk\ncyaTtmyn7sMKIRqCASFE47CcZpewLEGww/FYlqUoyurVq88777wJEybMnj178+bN3/rWt048\n8cTRo0d///vfL7ztwIEDX/jCF8aMGRONRs8444xXXnml0L558+bTTz89FovNnTt3w4YNxcPu\n379/2bJlY8aMicViZ5999ptvvulItQQ7APCTVzrTQginnpwQQjQEdFG6W7GWVZLDOqTNMIOK\nElEVtwuBp6mqqmnaz372s6eeemrnzp21tbXnnnvuGWecsXnz5oceemjlypVNTU1CiMsuu6y1\ntXXz5s3Nzc3z589fvHhxc3OzZVlLly6dMWNGU1PTM88888ADDxQPu2TJEiHE1q1bm5ubP/Wp\nT1100UXpdHrw1bJAMQD4hr7rg437D4mKqvP/e3WkviFz1vl2bFALFIviiJ2jt2KVbCb4ykvq\ne29n06lQda192kJjzjwHj++UNstiuM6nXu5M3bb/4CAPcmo0ctfokX188z/8wz+UlZUJIRYs\nWLBr166lS5cKIc4880zTNHft2vXxxx+/+uqr77777siRI4UQd955509/+tPnnntu8uTJu3fv\n/uMf/xiLxWKx2LXXXvviiy8KId58881XX331V7/6VU1NjRDijjvuuPfee5966qm//du/HeRJ\nEewAwB/0D3cGnnj0tU9/bnKqvaGtRbS1RA58kv7SFbY2qJ58hK6HFcXJFU9sO/zU/+i7dxZe\nKYcORp77dcYy83NPduxHOKTNNEfr/B30pbRl7xn0MHNDfyaqjh07tvBFOBweM2ZM8WshRCaT\n2bt3r6qqM2bMKLRHIpHx48fv3r07GAwqijJ+/PhC+9SpUwtfvP/++0KI4nEKdu3aNfCTOYIL\nGgD8IbT2t69XVrfr+t8eGajQDjbpWzblTzp1MIdVhKgPBhxco1j/cEcx1RWFXvxDfvY84aXh\nMdO2O0yrMsSUJF9aVB77YOaUofyJiqJ0+3VPLMvK5XLZbLbr+40jv2iRSEQIkU6nC9GwyBj0\nbyIXNAD4gGKaakvzS9UjhRBntTQV27Wm/YM/eEMw0G5abQ4tZac2HTi2Uclm1ESbI8d3SsK0\nbJ6cgEOmTp1qWda7775beNnZ2blnz56pU6fW19fbtr1nz55C+3vvvVd8vxBi8+bNxSM4Mlwn\n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\n8G9+WcbjPVtkuN27bXM2fQKAmxDsACGbmzKGmCzXdR2ALZ0xj5QXBgP5fFOlMcNmSj0lm48N\nuE8ZjchotG+7J9N79Z9ypKFvo9pQn02fAOAmBDtAyFNc+GUreb3QLWyaf0kkZwf8ofwuDnaq\nzTzVx9Ivp/pIs7vGzs74yfRZPxcASpZjB8TW1ta1a9fu3LkzlUpNnDjxlltumTp1qhDi7rvv\nPnjwYPfL/H7/s88+61SRKBFmbZ0dCvU6w2R7PObY8fks4/XOmOnEBXbm2PG2xyMNo2ejHaow\nhw4bcJ92WblZN1xtOtr7vSZktVSuOXGK2tx7fNzItCYvAJQmx4Ldww8/7PV6H3jggUAgsH79\n+gcffHDNmjV+v7+jo2PVqlULFy5Mv0zJ+22JKEWqGr/yusAvn5HmiXCTXHaFXVGZzyrSF9gt\nLsvrOKwQwq6oTF52uf+PL5xoUT3xK6/L8qbg5JXXBdavlanUiZaLLjHrhmfTZ+qiperH+9Qe\nY8Tm6LGpeRdm0ycAuIkzwS4ajQ4dOvTv/u7vxowZI4RYsWLFpk2b6uvrp0yZEo1Ghw8fXltb\n60hhKFnm2Amx2+7y73xbC7eb5aH49Bnm8JF5rmFLR8yryAX5vcAuTZ893xo2Qnt/p4yErZoh\n+twFVmW2K5WZQ+s6b/+a950/K81NdlmZfs4Mc9yELPu0PVr8y7drO98ONB21pYyPGKXPmJ3/\nWWkAoGA5E+xCodB9993X/fD48eOKotTW1uq6nkwmt27d+vTTT0ej0cmTJ69YsWLUqFGOFIlS\nY1VWGZ/5bLCiQo/FzFgsz+/eaph7kqkFwUDQoZhijhhljsjxvmaXlScvXpbjPlU1NXdBaMgQ\ny7L0trbcdg4Axc75i46j0egPfvCD6667rrq6OhwOV1VVGYZx1113CSGeeeaZ++6778knnywr\nK0u/+JVXXvnHf/zH7p/993//9wULFjhT94DU1NQ4XULuhUIhp0vIsWAwGAzm+0K3V5pbLCEu\nr6sdpNPV7jsLrqqq+zbKlYeIysq8XtKQH91/lVzD7/f7mQ/SFRwOdocPH37ooYdmz569cuVK\nIURlZeW6deu6n/3mN7+5cuXKN954Y/ny5emWUCg0ffr07hf4/X7j5Cu+C5aqqlLKYqm2nxRF\nsW3btm2nC8kZKaWqqpZlWZaV57feeLxNCLE0VJ7zXxIppaIopmnmtltneTwe27ZdtlGqqrps\n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\nm1tbWx944AFd1x3+IADAUdK2badrAFDcIpFIZWXlvffe+8gjj6Rb9u/f/+yzz65cuXLkyJFL\nlix5/fXXX3vttYsvvjj97O233/7jH//4k08+GTNmzNy5c6PR6M6dO4PBYPrZz33uc6+88kpT\nU5Pf7z/Nsz6fb/To0TU1Nbt27Uo/1djYOG7cOK/X29HRkd8PAAAKBUOxALIVCASGDBnyzDPP\nbNy40bIsIcSkSZPuu+++kSNHpl9QVla2ZMmS7tcvXbpUCPH+++83NTXt2LHjqquuUhQl8akr\nr7wyGo3u2rXr9M/W19cfOXJk2bJl3d2OGDFi/vz5+d10ACgsBDsA2dI07de//rWiKJ/5zGfq\n6uq++MUvrl+/3jCM7hcMGzZMStn9cMiQIUKIY8eOHTlyRAjxve99L9DD6tWrhRCHDx8+/bNH\njx4VQgwdOrRnJd1REgBKE9fYAciBxYsX7927d9OmTS+++OILL7xw0003Pf7446+99logEOj7\n4nTmU5Su/1jeeuutd9xxR6/XTJ48+fDhw6d5dv/+/X17Nk0z+20BgOJFsAOQG6qqLlu2bNmy\nZY899tiTTz551113pS+zE0I0NjaapqmqavqVx44dE0IMGzZs7NixQgjTNBcuXNi3w3TyO9Wz\nkUhECJE+b9ft4MGDud0oACguDMUCyNbbb799ww03NDU1dbdcfvnlQojm5ub0w3g8/oc//KH7\n2RdffNHn8y1YsKCmpmbBggXPPfdce3t797Pr1q371re+ZRjG6Z8dP358bW3tSy+9lL6qTwjx\n0Ucf7dy5c1C3FAAKnPrtb3/b6RoAFDdFUe6+++7nn3/e5/MdP358+/bt9957bzgcfuKJJ2pq\natIzz23cuFHTtPb29ieffHLt2rU33XTTjTfeKISYOnXq2rVrf/vb35aVlR07duynP/3pPffc\nM378+Ouvv/70z0opOzo6nnvuuffff1/TtE2bNt15552TJk1qaWn5p3/6J4c/EQBwig0AWdu5\nc+fnP//5uro6TdNGjhz5+c9//p133kk/tXjx4nPOOeett95aunRpMBisrq6+4447otFo989u\n3rx5+fLloVBI07SpU6c++uijuq7351nDMO69997hw4d7vd6ZM2f+93//99e+9jWv15vPDQeA\ngsI8dgAG15IlS1paWroXogAADB6usQMAAHAJgh0AAIBLEOwAAABcgmvsAAAAXIIzdgAAAC5B\nsAMAAHAJgh0AAIBLEOwAAABcgmAHAADgEgQ7AAAAlyDYAQAAuMT/B5UeorepNi21AAAAAElF\nTkSuQmCC" + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAIAAAByhViMAAAACXBIWXMAABJ0AAASdAHeZh94\nAAAgAElEQVR4nOzdeZxU1Z3//3PXqurqpehudpp9R0GNGsAdA0Y0iplkhmQm+sh3jBrzGHSS\n6LjEcSGPOFl+icm4zBgfcR6MEXUSY1yi2VyCAsYFBDdWQRahaWiqurvWe+/5/VHQdqBpWvpW\n37qnXs+/qNPF7c+F27ffdc4952hSSgEAAIDw04MuAAAAAP4g2AEAACiCYAcAAKAIgh0AAIAi\nCHYAAACKINgBAAAogmAHAACgCIIdAACAIsygC+iTtrY2x3GCrqJXqqqqLMtqa2vzPC/oWnwT\njUZd1y0UCkEX4hvTNOPxeDabzeVyQdfiG13XY7FYR0dH0IX4qba2VkrZ1tYWdCF+qq6u7ujo\nUGnR+Gg0GolE2tvbXdcNuhbf2LataZpKtwjDMKqrq/P5fCaT8f3gAwYM8P2Y6Fl/BLsdO3b8\n5Cc/2bhx4xNPPNHZuG/fvl/84hdvvfVWPp8fO3bsV7/61YkTJwohFi1atGXLls63RaPRxx57\n7EhH9jwvRPcLXddd11Up2AkhpJQh+i84KsMwdF0XQqh0UkWKnZGu6+H68e8NTdM8z1PsFqHr\numJ3iWLyVumMNE1T9b5XmUoe7JYtW/bAAw+ceOKJGzdu7Nr+3e9+17bt22+/PRaLPfzww3fc\ncccDDzwQjUbb29uvuOKKmTNnFt9WvNoAAABwVCWPTYVC4Uc/+lFnUCtqa2sbOHDgN77xjbFj\nxw4dOvTSSy9NpVLbtm0rfmnIkCGNB9XX15e6QgAAADWUvMduzpw5QohNmzZ1baypqbnxxhs7\nX+7du1fX9cbGxkKhkMvlVqxY8dBDD7W1tY0fP/7SSy8dPnx45zubm5vXrFnT+XLKlCm1tbWl\nPgVfGIYhhLBtW6UHaIonpRLTNIUQhmFEIpGga/GNruu6rqt0RkWapil2UpqmKXmLsCxLpbEX\n0zQVu/aK/zuK3fcqWfCTJ9ra2v7zP/9zwYIFAwYMSCaTiUTCcZyrr75aCLF06dIbb7zxvvvu\ni8fjxTe/8847N9xwQ+ffvffee7vGvvJXXV0ddAk4ukgkot4NrqamJugSfKZpmnonpeQtoqqq\nKugS/KfeLcKyLMuygq4CPgg42G3fvn3x4sUnnHDCZZddJoSoq6tbsmRJ51evv/76yy67bPny\n5XPnzi22TJo06aabbup8w5AhQ9rb2/u55mMTjUZN01RsylskEnFdNywTk3vDNM1oNJrP5/P5\nfNC1+EbXddu2s9ls0IX4KR6PSynT6XTQhfipqqoqk8kodouwLCuTyaj0VH4x/ai0GoCu61VV\nVcURM98PruRnlTIXZLB76623fvCDH3zpS1+68MILu31DLBYbOHBgS0tLZ8uwYcM+//nPd75M\nJpNh+XVlWZZpmrlcTqUpb4ZhOI6j0rR/27aj0ajjOGG5rnrDMAzTNFU6I3Ew2Cl2UtFoVL1b\nhGVZ+XxepRgkhNA0TaVrzzTNqqoq13VLcVIEu/4X2HMP77777ve///1vfvObXVPd1q1b7777\n7s4eoGw2u2fPniFDhgRUIwAAQJiUvMeutbXVdd3iOqLFvrfq6mpd1++6666LLrpo1KhRnR1y\n1dXV9fX1K1ascBxn4cKFrusuWbKkurp69uzZpS4SAABAAVqpn+e4/PLLm5ubD2kZNWrULbfc\ncsg7r7zyygsuuGDz5s0PPvjghg0bLMuaNGnS1772tcGDBx/p4MlkMiw9/DU1NZFIZN++fSqN\ns8TjcfWGYmtra9PptEoPbxmGEY/HU6lU0IX4qaGhwfO81tbWoAvxUyKRSKVSit0iYrFYiG7U\nvRGNRjVNK8UmDUExTTORSGSz2VI8s97Y2Oj7MdGzkvfYPfDAA922P/nkk922jx07dvHixaWs\nCAAAQE3qrC0EAABQ4Qh2AAAAiiDYAQAAKIJgBwAAoAiCHQAAgCIIdgAAAIog2AEAACiCYAcA\nAKAIgh0AAIAiCHYAAACKINgBAAAogmAHAACgCIIdAACAIgh2AAAAiiDYAQAAKIJgBwAAoAiC\nHQAAgCIIdgAAAIog2AEAACiCYAcAQDjo+1uNbVu1tlTQhaB8mUEXAAAAjkJLJWPPPml8+EHx\nZWHS1Ny8C2U0GmxVKEP02AEAUN48r+qpX3emOiGEte7dyO+fCrAilC2CHQAAZc3YvlXfuf2Q\nRmv9e3pyfyD1oJwR7AAAKGt6Mtltu7a/tZ8rQfkj2AEAUNZkdU337TXdt6OSEewAAChr7sjR\nXuPAQxtHjfHqGwOpB+WMYAcAQFmThpH53Be8gYM6W9zhTZn5CwIsCWWL5U4AACh3XuPAjkuv\nMHZu11L75YAGd8gwoWlBF4VyRLADACAMdN0dMVKIkUHXgbLGUCwAAIAiCHYAAACKINgBAAAo\ngmAHAACgCIIdAACAIgh2AAAAiiDYAQAAKIJgBwAAoAiCHQAAgCIIdgAAAIog2AEAACiCYAcA\nAKAIgh0AAIAiCHYAAACKINgBAAAogmAHAACgCIIdAACAIgh2AAAAiiDYAQAAKIJgBwAAoAiC\nHQAAgCIIdgAAAIog2AEAACiCYAcAAKAIgh0AAIAiCHYAAACKINgBAAAogmAHAACgCIIdAACA\nIgh2AAAAiiDYAQAAKIJgBwAAoAiCHQAAgCIIdgAAAIog2AEAACiCYAcAAKAIgh0AAIAiCHYA\nAACKINgBAAAoQpNSBl3DsSsUCroejmyq67qmaa7rBl2In3Rdl1KG+hI6hKZpuq57nqfYSWma\n5nle0IX4yTAMIYR6P1CK/TcV73vq/UAJIRQ7o+LNvBSXX/FHFf3JDLqAPkmn04VCIegqeqWm\npiYSiSSTSZVu3PF43HGcXC4XdCG+sW27trY2m82m0+mga/GNYRjxeDyVSgVdiJ8aGho8z2tt\nbQ26ED8lEolUKqXYLSIWi7W1tYXlRt0b0WhU07RMJhN0Ib4xTTORSORyufb2dt8P3tjY6Psx\n0bNwdHcBAADgqAh2AAAAiiDYAQAAKIJgBwAAoAiCHQAAgCIIdgAAAIog2AEAACiCYAcAAKAI\ngh0AAIAiCHYAAACKINgBAAAogmAHAACgCIIdAACAIgh2AAAAiiDYAQAAKIJgBwAAoAiCHQAA\ngCIIdgAAAIog2AEAACiCYAcAAKAIgh0AAIAiCHYAAACKINgBAAAogmAHAACgCIIdAACAIgh2\nAAAAiiDYAQAAKIJgBwAAoAiCHQAAgCIIdgAAAIog2AEAACiCYAcAAKAIgh0AAIAiCHYAAACK\nINgBAAAogmAHAACgCIIdAACAIgh2AAAAiiDYAQAAKIJgBwAAoAiCHQAAgCIIdgAAAIog2AEA\nACiCYAcAAKAIgh0AAIAiCHYAAACKINgBAAAogmAHAACgCIIdAACAIgh2AAAAiiDYAQAAKIJg\nBwAAoAiCHQAAgCIIdgAAAIog2AEAACiCYAcAAKAIgh0AAIAiCHYAAACKINgBAAAogmAHAACg\nCIIdAACAIgh2AAAAiiDYAQAAKIJgBwAAoAiCHQAAgCIIdgAAAIog2AEAACiCYAcAAKAIgh0A\nAIAizH74Hjt27PjJT36ycePGJ554orOxvb39/vvvX7NmTaFQmDRp0lVXXTVo0KAe2gEAANCz\nkvfYLVu27KabbhoxYsQh7XfddVdzc/Ott976wx/+sKqq6o477vA8r4d2AAAA9Kzkwa5QKPzo\nRz+aOXNm18aWlpbXXnvtiiuuGDNmzLBhw6666qodO3asXbv2SO2lLhIAAEABJR+KnTNnjhBi\n06ZNXRs3bNhgWdaYMWOKL6urq0eMGLFu3bp0Ot1t+4wZM4ot+/bt27hxY+dxmpqaqqqqSn0K\nvtB1XQhhWZZKHZC6rhuGYVlW0IX4xjRNIYSu6yqdlGEYip1RkaZpip1U8YwUu0UIIQzDCLoQ\nPxmGodi1V/wPUvIuUZn64xm7w6VSqZqaGk3TOlvq6uqSyWRdXV237Z0v33rrreuuu67z5b33\n3nvqqaf2T82+qKmpCboEHF00Go1Go0FX4bO6urqgS/CZpmnqnZSSt4jq6uqgS/CfercI27Zt\n2w66CvggmGAnhOia3nrTXjRq1KjLLrus82VDQ0Mmk/G5stKwbdswjGw2K6UMuhbfFHsXXNcN\nuhDfGIZh23ahUHAcJ+hafFPsXcjn80EX4qfir9VsNht0IX6KRCL5fF6xW4RpmrlcTqVuyGKP\nnUq3CF3XI5GI4ziFQsH3g8diMd+PiZ4FE+wSiUQqlZJSdsa4ZDI5YMCAI7V3/sWxY8f+y7/8\nS+fLZDLZ0dHRn5Ufs+KoZTqdVukGF4/HHcfJ5XJBF+Kb4mfWQqGQTqeDrsU3xaHYsPyk9FI0\nGvU8T7GTsixLvVuEaZrZbLYUiSEo0WhU07Sw9Cn0hmmaxWBXih8ogl3/C2YduwkTJhQKhc4H\n71Kp1LZt26ZMmXKk9kCKBAAACJeSB7vW1taWlpa2tjYhREtLS0tLSzabra+vnzVr1j333PPB\nBx8UV7kbN27c1KlTj9Re6iIBAAAUoJX6eY7LL7+8ubn5kJaLLroonU7ff//9q1atcl132rRp\nV111VXHI9Ujt3Uomk2Hp4a+pqYlEIvv27VNsnEW9odja2tp0Oq3YUGw8Hk+lUkEX4qeGhgbP\n81pbW4MuxE/FZ1EUu0XEYrEQ3ah7Q8mh2EQikc1m29vbfT94Y2Oj78dEz0oe7EoqRPcLgl0o\nEOzCgmAXCgS7UCDYKYa9YgEAABRBsAMAAFAEwQ4AAEARBDsAAABFEOwAAAAUQbADAABQBMEO\nAABAEQQ7AAAARRDsAAAAFEGwAwAAUATBDgAAQBEEOwAAAEUQ7AAAABRBsAMAAFAEwQ4AAEAR\nBDsAAABFEOwAAAAUQbADAABQBMEOAABAEQQ7AAAARRDsAAAAFEGwAwAAUATBDgAAQBEEOwAA\nAEUQ7AAAABRBsAMAAFAEwQ4AAEARBDsAAABFEOwAAAAUQbADAABQBMEOAABAEQQ7AADCQSsU\n9H17hesGXQjKlxl0AQAA4Ggy6djzfzDfWyukFIaRP+Hk/JnnSpNf4jgU1wQAAOVNytgzvzE/\n2HTgpevab7yqOU523gWBloVyxFAsAABlzdi5/eNUd5C15k0tlQykHpQzgh0AAGVNb93bTauU\neuu+fq8F5Y5gBwBAWZOxqu6/UBXv30IQAgQ7AADKmjtyjKytO7RxyDC3cWAg9aCcEewAAChr\n0rLS8y4UpvVxSzSaO/8ioWkBVoXyRLADAKC8SRl5Y6VwCp0NWjZrvflagBWhbLHcCQAAZe1I\ns2K3n3rajki0rwc3jBGR6Aj6/lRBsAMAoKwdaVbsZ3c0b5Wy78c/v37A4xPH9v04KAcEOwAA\nylq3s2L3WfZWKcfa9oV1NX05uK7r0wck+nIElBWCHQAAZa04K/ZvliOW4t2RY4UQc6qrbhnc\n2JeDm6aZSCSy2Wwfi0SZYPIEAABlTVpW+sLPy+qPe+a8+oa3P326EGJiNBJcXShH9NgBAFDu\nvOFNHf/8DXPzBi2130s0OOMmrN+zTwgxMWIHXRrKC8EOAIAQkLZdmDyt8+X6XE4IMTFCjx3+\nBkOxAACEz/psvs4wBppG0IWgvBDsAAAImayU2wuFiRHr6G9FhSHYAQAQMhtzeU+ICYzD4jAE\nOwAAQubgA3bMnMChCHYAAITMhlxeMHMC3SHYAQAQMuuzxWBHjx0ORbADACBkNuTzEU0bYbFm\nGQ5FsAMAIExcKTfl8uMjtqFpQdeCskOwAwAgTLYWCnkpJzAOi+4Q7AAACJODD9gxcwLdINgB\nABAmrHWCHhDsAAAIkwNrnUTpsUM3CHYAAITJhnzB0LSxNvuJoRsEOwAAwmRDLjfSMiNMiUV3\nCHYAAITGroKTcj1mTuBICHYAAIRGceYEa53gSAh2AACExnpmTqBHBDsAAEJjY74ghJjAzAkc\nAcEOAIDQKA7FjmcoFkdAsAMAIDTWZ/ODTTNhGEEXgjJFsAMAIBzaXG+340yM0l2HIzKDLqBP\nYrFYPB4PuopeMQxDCFFbWxt0IX7Sdd227VgsFnQhvtE0TQgRjUZtW537pqZpuq4nEomgC/GT\nkidlGIZ6twghRHV1tZQy6Fp8UzypSECrjaxraxdCTKup8fHiL973bNtW7AeqYoU72OVyOcdx\ngq6iV+LxuG3bHR0dnucFXYtvYrGY67r5fD7oQnxjWVZ1dXUul8tms0HX4hvDMGKxWHt7e9CF\n+CmRSEgp29ragi7ETzU1NerdIqLRaDqdDsuNujcikYimaUHdIlbt2y+EGKNrPl78xU8UhUIh\nnU77dcxOAwYM8P2Y6Fm4g53nea7rBl1FrxQ/sLquq9JdW0oZov+C3ih2rEopVTopoeIZCUVP\nSr1bhAjVjbo3PM/TNC2oM1qfzQohxlumjwUUe+yU/IGqTDxjBwBAOKzP5oUQbDuBHhDsAAAI\nh/W5XI2hD7bCPdqGkiLYAQAQAnkptxWciZGIFnQlKGcEOwAAQmBTvuBIyS6x6BnBDgCAEFif\nzQk2E8PREOwAAAiB9TlmTuDoCHYAAITAhlxOCMG2E+gZM2sAACih/97bestHzb5svmFr2kiL\noVj0hGAHAEAJ/W9r0tS0qdG+DqFqQsypjpua35NipZTJ/UJnBE8RBDsAAEpla76wLpubUx1/\ndPSIoGs5jJT26yvtlcvy2aymabFxE7NzzpN17BgbbiR0AABK5bm2diHEeTXxoAvphr3qtciL\nf9SK+95KaW5cF3v8Ec1VZ2PfykSwAwCgVP7Q1i6EmFtbE3Qhh/E8+5UXD2kzWprN994Oohr4\nhmAHAEBJtLneynRmajTSVH6bgGkdHQf66rqQQuh79wZSD/xCsAMAoCSeb+/Ie7I8x2FFNHL4\nhAlNCBmLBlIO/EKwA4CQ0drbtEI+6CpwdL8/8IBdddCFdENadmHC5L9pEUJaljNpWlAlwRdl\n1zkMADgSa82qyLLntXSH0DR31NjsZz7rDWgIuih0z5Xyz20djaZxYiwWdC3dy86dr+9vNXZ/\ndOC1Zec++zmPWbEhR7ADgHCw3lsb/f1TB15IqW/ZFPu/X6Yvu0JGGDsrR69nsvtc90uJWt3v\nhed8E6tKf+XyyNbNValkIRLpGD5SVpffJA98QgQ7AAgH+y/Pd32pCaEl91trVuVPmRVUSejB\ngXHY2nIch/2YprnjJxmJRCGble3tQVcDH/CMHQCEgOY6eip5eLu+t6X/i0Fv/KGtw9a0s6rL\ncuYE1EWwA4AQkLohu9skVMaq+r8YHFVxw4nT4rFqtupC/+KCA4Aw0DRn6vRD2qRhOlOOC6Qc\n9Kyc58NCbQQ7AAiH3Dlz3REjO19Kw8zNmecOGhxgSTiSYrCbV4YbTkB1TJ4AgHCQlp1eeJm5\nZbOx+yMvGnXHjGdlivJUzhtOQHlccwAQHprmjBnnjBkXdB3oyQsdHXlPzivPDSegOoZiAQDw\n0+9THYIH7BAQgh0AAL5xpfxTW3uDYZxUrhtOQG0MxQIAIIQQG3P5Ds/r+T2262malsvljvSG\n9bn8PtddOKCufDecgNIIdgAAiNfTmfM3f+jX0RiHRVAIdgAAiF2OK4Q4pSo2JRrp4W2GYWia\n5jhOD+8ZbBrz2HACASHYAQAgMp4nhPhCXc3/axjQw9ui0aimaZlMpr/qAj4ZJk8AACCyUgoh\nYoYRdCFAnxDsAAAQOSmFEBFmPCDkCHYAAIiM6wkhohrJDuFGsAMA4OBQrM5QLMKNYAcAAEOx\nUATBDgAAkfWKQ7H8WkS4cQUDANA5K5Zfiwg3rmAAAA4EO4ZiEXYEOwClpbW3CdcNugrgKBiK\nhRrYeQJAaUhpv/GqvXKZlskIXS9MmJw797MyzgaaKFNZTwohojpddgg3PpoAKAn7zb9GXviD\nVtx5yfOsde/GHn+ErjuUreJQLOvYIewIdgBKwHXtV148pM3YtdPa8H4Q1QBHVxyKjRDsEHIE\nOwD+09vbtFzu8HatZU//FwP0RlZKW9cMgh1CjmAHwH8yEhHd/oKMxfq9FqBXclLSXQcFEOwA\n+E9GY87YCYc2WnZh/KRA6gGOKuN5PGAHBRDsAJRE9rwLvcZBnS+lZeXOv0jWJQIsCehB1pME\nOyiA5U4AlISMV3dcdoW1cZ22Z7eMVzvjJsqa2qCLAo4oJ2WtYQRdBdBXBDsAJaPrhYlTxMQp\nQdcBHF3G86IavxMRegzFAgAqnRQiL2VU53ciQo+LGABQ6XJSSradgBIIdgCASndwo1iCHUKP\nYAcAqHTFjWJZxw4KINgBACpdcaPYGM/YIfy4iAEAlY6hWCiDYAcAqHTFHjuGYqEAgh0AoNLl\nikOxBr8TEXpcxACASpfxPEGPHZRAsAMAVLrirFiesYMCCHYAgEpXHIpl5wkogIsYAFDpMsyK\nhSoIdgCASlecFUuwgwIIdgCASsdQLJTBRQwAYZNJC9cNugilHBiK1emxQ+iZQRcAAOgt8501\n0Zdf0FJJoevOmPG5cz/r1SWCLkoFOYZioQp67AAgHKx178Z+94SWSgohhOeZm9bH/u8hrZAP\nui4VHFjuhKFYhB8XMQCEg/3Snw5p0Vv3WW+9GUgximGvWCiDYAcAIaC5jp7cf3i73rKn/4tR\nD3vFQhkEOwAIAakb0rS6aY/F+r8Y9RSDXYyhWIRfMJMn1q5de/PNNx/SeOWVV15wwQWLFi3a\nsmVLZ2M0Gn3sscf6tTgAKEOa5kyZZq1dfUizM2lqIOUoJsusWKgimGA3efLkX/ziF50vm5ub\nb7vttunTpwsh2tvbr7jiipkzZxa/pPP5CQCEEELkzjlPb9ljfLSj+FIaRv7sue6QYcFWpQaG\nYqGMYIKdZVmNjY2dL3/6059ecsklTU1NQoi2trYhQ4Z0/SoAQAghI5H0P/4/c9N6ffdHIhJ1\nxk3wBjQEXZQicgzFQhXBr2O3bNmyjz766NZbbxVCFAqFXC63YsWKhx56qK2tbfz48Zdeeunw\n4cM739zW1rZ9+/bOlw0NDbZtB1D0J1fsejRN0/O8oGvxja7rhmGYZvBXkV8MwxBC6Lqu0knp\nuq5pmkpnVKTeSRXP6Oi3iMnTvMnThBB62T8lXbzvGYYhpQy6lqPIelITosqyjtplp94PlJL3\nvUoW8P+i53kPP/zwwoULi9dTOp1OJBKO41x99dVCiKVLl95444333XdfPB4vvv/111+/7rrr\nOv/6vffee+qppwZS+bGpra0NugT/VVVVBV2Cz6LRaDQaDboKnyUSqi1jq2maeiel5C2iuro6\n6BKOrqDrUV0f0OsrKqbcnBXbtsPSUYKeBRzsXnnllWw2e8455xRf1tXVLVmypPOr119//WWX\nXbZ8+fK5c+cWW4YPH/75z3++8w0DBgzIZrP9WfAxsyzLMIxcLlf+n1x7zzRNKaWr0NZGuq7b\ntu04juM4QdfiG03TLMvK55VaxjYSiQghcrlc0IX4ybbtQqGg2C3CNM18Pl/+IxUZ141oWm9+\noRiGoWmaYreISCTium6hUPD94Op9SC5/AQe7F154Yfbs2cV+4MPFYrGBAwe2tLR0tkycOPGm\nm27qfJlMJtvb20tepR9qamoMw+jo6Cj/G1zvxeNxx3FU+uVa/Myaz+fT6XTQtfjGMIx4PB6W\nn5ReikQinucpdlKJREK9W4RpmplMphSJwV9p143qWm+uqGg0qmlaJpPph6r6h2makUikUCiU\n4geKYNf/gnxCo6OjY9WqVV3HUrdu3Xr33Xd3fhLKZrN79uwZMmRIQAUCACpCxvOYEgs1BNlj\nt3HjRtd1hw4d2tlSX1+/YsUKx3EWLlzouu6SJUuqq6tnz54dYJEAAOXlpGxkSiyUEGSwa21t\n1TStvr6+s6Wmpmbx4sUPPvjgtddea1nWpEmT7rzzzuLDNAAAlEjWk2wUCzUEGezOPvvss88+\n+5DGsWPHLl68OIhyAACVyJWyICVDsVADPc8AgIrGRrFQCdcxAKCiFbedYKNYqIFgBwCoaBnP\nE2wUC1UQ7AAAFY2NYqESrmMAQEXLelLQYwdVEOwAABWtOBTLcidQA8EOAFDRGIqFSriOAQAV\nrbjcCUOxUAPBDgBQ0Q4MxbLcCZRAsAMAVLSD69jxCxEq4DoGAFS04qxYJk9ADQQ7AEBFyzIr\nFgoh2AEAKlqWoVgohOsYAFDRDgQ7euygBIIdAKCiZdkrFgoh2AEAKtrBoViCHVRAsAMAVLSc\nFIKdJ6AKrmMAQEXLuK5gKBaqINgBACpasceOyRNQA8EOAFDRis/YhWUoVstmgi4BZc0MugAA\nAIKU8UIwFKsV8vbLL1pr3tTyeRGryp88M3fKLGEYQdeFskOwAwBUtANDseU9Kzby7JPWuncP\nvMik7WXPi1wud9a5gRaFchSOnmcAAEokKz1D06wy7rEzdu38ONUdZL+2XOtoD6QelDOCHQCg\nomVcr8zHYfWWPd20Sqnv7a4dlY1gBwCoaDlZ7lNipR3p/guRaP8WghAg2AEAKlpWemU+JdYd\nOVpWxQ9p9Boa3UFDAqkH5aysL2UAAEotK2WZD8XKaDQzf4Es9s9JIYSQ8ers5/5OlHfZCASz\nYgEAFS3ryahZ7gnJHTOu4/JvWO+/q6X2ewManCnHSdsOuiiUI4IdAKCi5aQs86HYIlkVz590\nStBVoNyF4FIGAKBE8p50y34oFug9gh0AoHLlpBRsFAuFEOwAAEK4ruY6QRcRgHBtFAscFc/Y\nAUBFM/bsjvz598aOD4WU7qAhuXPmuU2jgi6q/xSDHUOxUAafUQCgcmltqapH/9fYtkV4npDS\n2P1R7Fe/NJp3B11X/8l6nij7jWKB3iPYAUDlirz6isiku7ZojmMv+3NQ9fS/Yo9dlKFYqIJL\nGQAql97SfHij0e3OpIrKekyegFIIdgBQuWR3m416kSPsTKqiA0OxBDuogmAHAJXLmTy1u8bj\n+r+SoDAUC8VwKQNA5SpMOb4w41NdW5xxE/Onzg6qnv7HOnYV5fTTT588eXLQVcxtz4IAACAA\nSURBVJQWy50AQEXLzrugMG26ufUD6TreiFHOmHFBV9SvMp4nhIiQ66AKgh0AVDp3eJM7vCno\nKoJxYIFiwwi6EMAfDMUCACpX7sACxUHXgU/oj3/841lnnVVTUzNkyJC///u/37hxY+eXnn32\n2TPPPLOmpiYWix133HE//vGPpZTdHqSHd55wwgknnHBC1zcvWLCgsbGx+OfTTz/9zDPPfPrp\np5uammbPLq9HFwh2AIDKlXGZFRs+f/zjH88777xoNPpf//Vf3/ve9954440zzzxz165dQogn\nnnjiggsuiMfjDz300NNPP33eeed961vf+rd/+7fDD9L7dx4uEokkk8nrrrvuxhtvvPnmm30+\nvb5hKBYAULkODMVKITxPMDc2JG666abRo0c/88wzpmkKIY477rgzzjjjscceW7Ro0Y033tjU\n1PTb3/7Wtm0hxLnnnrt58+a77rrr3/7t3xoaGroepPfvPJymaWvWrHn88ccvueSSkp3lMeIi\nBgBUrvz+fUKIAb/+Zc1dd8Z+9bC+b2/QFeEo9u7d+/rrr59//vnFVCeEOPXUU3O53KJFi3bu\n3Pn+++/Pnz+/mNWKPve5zxUKhZUrV3Y9SO/feSS2bV944YV+nJDPCHYAgAql79jmbFgvhIg6\nrnBd84ONVY8u0TKZoOtCTz766CMhxKBBgw7/0o4dO4QQw4cP79o4dOhQIcTOnTuP7Z1H0tjY\naFnWJ6q8fxDsAAAVKrrs+ayuCSFinlts0dpT9msrAi0KR6HruhDC87zDv6Rp2uFfKs6H0P92\nnL337zyS8kx1gmAHAKhYektzRjeEEFHPOdim6Xt2B1gSjqqpqUkIsW3btq6NW7du3bNnz4gR\nI8TB3rhOxZfFL3U66jt1XXddt+tXi5Mzyh/BDgBQoaQdyRmGECLmftxz0+3+uSgfNTU1xx9/\n/NNPP93W1lZsef/990ePHn3vvfcOGTLkuOOOe/rpp7PZbOf7H3/88aqqqlmzZnU9yFHfOWDA\ngF27dnWuftLc3LxmzZqSn5sfCHYAgArlTJ52WI9d9/vnoqzceeede/funTt37tKlS3/+859f\nfPHFgwYNuvLKK4UQ3//+93ft2nXxxRc/+eSTzz333NVXX/3cc8/dcssttbW1hxyk53dedNFF\nLS0t3//+93fv3r1q1aqFCxeOHTs2gFP95Ah2AIAKlT/trHRVXAgRPTjolj95pjN+UqBF4egu\nuOCCp556StO0yy+//Dvf+c60adNefvnlIUOGCCHmz5//3HPPpdPpL3/5ywsWLFi5cuUvfvGL\nG2644fCD9PzOr3/969/85jfvvvvuUaNGffWrX/3mN7959tln5/P5fj3PY6IdaTnmUEgmk4VC\nIegqeqWmpiYSiezbt6/b5z1DKh6PO46Ty+WCLsQ3tm3X1tam0+l0Oh10Lb4xDCMej6dSqaAL\n8VNDQ4Pnea2trUEX4qdEIpFKpRS7RcRisTK/UV+4+cNX05nWfdsN0yqMHusNG9Hz+6PRqKZp\nGYVmzpqmmUgkstlse3u77wfv3KoB/YYFigEAlSsrpa1rzpnnOkd/LxACDMUCACpXVsoI+4lB\nIQQ7AEDlynoeG8VCJQQ7AEDJlP3D5llPEuygEp6xAwD4TMtmIn95Xl/3Ti6bjdQlxMzTC8ef\nKMoyP+WkrDWMoKsAfEOwAwD4SsrYb39lfPhB8ZWW3B/9/dPCdQsnnhJsXd3KeF5U41ch1MFQ\nLADAT+bmDZ2prlPkL3/W/naDpnIghchLGdXLsSsRODYEOwCAn4w9zYc3avm8liy7dQdzUkoh\nor3b9B0IBa5mAICfPNvutr0M92DNep4QgskTUAnBDgDgJ3f8JGlZhzaOGCnj1YHU04OsJ4UQ\nrGMHlfDEKADAT15tXfYz86N/eEZzD+zmIOsS2fkLgq2qW1kphRAxhmJDpaWlpRSHVWb3M4Id\nAMBnznEz0iOaqj7YZGYz2dpEbtIUaR7ah1cOGIqFenr1MeXkk09+7733Dm//9a9/PXXqVL9L\nAgCEnpeol6efbX7u8+4JnyrPVCcO9tgxFAuV9CrYvfHGGx0dHYc0Oo7zzjvvbNq0qQRVAQBQ\ncrniUKzBUCzUcZShWO3g55hTTul+YcmTTjrJ54oAAOgXGYZioZyjBLvVq1e/9NJL11xzzcUX\nX3zIc4Wapg0bNuxrX/taKcsDAKBUmBUL9Rwl2M2YMWPGjBm/+93vfvjDH06YMKF/auq9aDQa\njZbdwkjdsixLCFFdXS2lDLoW35imaZqmfYQ1q8JI13UhhG3bhkJ7R2qaZppmTU1N0IX4TNd1\nxU7KMAz1bhFCiKqqKs/zgq6le1quIISoi8V6fy0Vbw7FU1NDcWjOsizFfqAqVq8uzeeeey6d\nTn/00UdDhw4VQmQymUcffXTv3r2XXHLJ2LFjS1xhT/L5vFt+e9R0S9d1Xdez2WzZ3uCOQSwW\nc103n88HXYhvLMuyLMtxnGw2G3QtvjEMQ9f1TCYTdCF+sm1bSqnYSZmmqd4twjCMXC7nOE7Q\ntXQvlcsJIQzH6f21FIlENE1T7BZh27bruqX4gYpEIr4fEz3rVbB7//33zzrrrH/913+94YYb\nHMc588wzX3/9dSHE4sWLX3jhhRNPPLHERR6R53lle784RPFm7TiOSndtz/Nc1w3Lf0FvFHvs\nQnRd9YaUUrEzKpJSKnZSxTNS7BYhhCjnu0SH4wgh7E9yLZmmqWla2Z7RMVPyLlEiW7ZsGTNm\nzNq1a4877riga+lGr6YC3XzzzYMHD/7iF78ohHjkkUdef/31e++9d+PGjdOmTfve975X4goB\nACiJ4qxY9oqF755//vliF1j/69XV/PLLL99www3jxo0TQjz++OPHHXfc17/+9XHjxn3jG994\n9dVXS1whAAAlcWBWrM7kCdXoLc32X5fbL79grn9fBPHc6o9//OOyDnb79+8vPl3nuu6LL744\nf/78YvvAgQN3795dwuoAACiZAz12zIpVi/3X5fElP4+89KfIimWx3z4Wf/gXWp+fBV+9evWn\nP/3peDw+ffr0FStWdLa//fbb8+bNq6+vTyQS55133saNG4UQc+bM+d3vfnfttdd+6lOfOtJ7\nSqdXwW7w4MGbN28WQjz//POtra2f/exni+3btm1raGgoYXUAAJRMcbkThmJVou/cHnnpT8J1\nurTsiLzw+74c0/O8Sy65ZPLkyc3NzU8//fT999/f+aUvfOELQ4cO3bZt24cfflhTU3PZZZcJ\nIZ5//vmRI0feddddb7zxxpHeUzq9mjwxb96873znOxs3bly6dOm4cePOPPNMIURzc/NPf/rT\n0047raT1AQBQIuwVqx5r3btCCCH+5v/UfO8dMe9Ccaz/0StXrtyyZcuf//zneDwej8evueaa\nF198sfilFStWRCKRqqoqIcSXv/zlhQsXSim1v/1GvXmPj3oV7BYvXvzOO+/8x3/8R2Nj41NP\nPVVcxWfRokVbt2793//93xJVBgBASbFXrHq0XDcr0WhOQXieONYFSrdt26Zp2qhRo4ovuy7r\nu2rVqu9+97vvvvuuECKXyxUKBdd1D1nmsDfv8VGv+p+HDh26YsWKZDK5c+fOmTNnFhu//e1v\nr1u3bvr06SWqDACAkioGuxhDsQrxGgd10zig/phTnRAil8uJLpusdq4Ls3Hjxvnz58+dO3fL\nli27du36n//5n8P/bm/e469PcDXX1tYWt08oOvnkkwcPHlyCkgAA6A9ZZsUqpzD9JC9Rf0hj\n7qzP9OWYI0aMkFJu3bq1+PK9994r/uH11193HOfb3/52cROslStXHv53e/Mef/UU7CZPnnzn\nnXcW/9CDUpcIINQ0l1VPUaYYilWPtO3M3/+TM35SsYvOSwzIXvQFZ/ykvhxz1qxZDQ0Nt99+\ne2tr6/r16++5555i++jRo13XXblyZS6XW7p06fLly4UQO3fuFEJUVVVt3Lhx//79PbynRHoa\n4k0kErFYrPiH0lUAQFXm229FVi7T97fKSNSZPC13xjkyGgu6KOBjxVmxDMUqxqtLZC75B+G6\nWqEg/dhQPhaLPfPMM1dfffWwYcMmTJjwgx/84Pzzz/c8b+bMmdddd93FF1+sadoll1zyxBNP\nzJ07d8aMGatWrbryyitvvPHGRx99dNu2bUd6z+jRo/te2+G0UG84nUwmC4VC0FX0Sk1NTSQS\n2bdvn0r7BcXjccdxig8fqMG27dra2nQ6nU6ng67FN4ZhxOPxVCrVz9/XWrsq+txTXVvcptHp\nv/8n4ccv0YaGBs/zWltb+36o8pFIJFKplGK3iFgsVs436vmbP3w9ndl93KTed9lFo1FN01Ta\np9g0zUQikc1m29vbfT94Y2Oj78dsaWnx/ZiiNKUGgo8pAErA8yIv/emQNmPbFnPjukDKAbqV\n8bxI6ZadAILQ01BsdXX1Uf9+oVBQqcMGgC/09jatuy4Nfc9uMXFK/9cDdCsnJasTQzE9BbsL\nL7yw88+rV6/evHnzySefPGzYMNd1t2zZ8tZbb5100kmzZs0qfZEAQkZadvdfsCP9WwjQk6yU\nTImFYnoKdo888kjxD7/61a/eeeedrVu3FneMLVq3bt2CBQvmzZtX2gIBhJCMxdyRo40Pt/xN\no2k64ycGVBHQjYznVdNjB7X06oK+/fbb//3f/71rqhNCTJo06ZprrrnllltKUxiAcMt89iJZ\nW9f5UhpG7tzPegPYXRplhKFYqKdXO1qsX7++vv7Q5f6EEI2Nje+//77fJQFQgaxLdPzz1eY7\na42WZhmvLkyc7NUrMukMysh6ko1ioZheBbvGxsYHH3zw3HPP7doopfzVr37VbeADACGENK3C\njJPKdKELVDxXyoKUrE4MxfQq2H3ta1+7/fbb16xZc8455wwcOFAIsWvXrueff/6999674YYb\nSlwhAAD+Y6NYKKlXwe7WW2+tqqq66667fvazn3U2NjY23nLLLbfeemvJagMAoFRyUgo2ioVy\nehXsNE27/vrrr7vuum3btu3atUtKOXDgwNGjR+t80AEAhFPG8wQbxUI5vQp2RZqmjRw5cuTI\nkaWrBgCA/pFjKBYq+gTBDgBQJvKe/OftOz8qOH0/lKVp/9+wwVOjFbd2dNaTgh47KIdgBwDh\n81om81yqPappfVyGrSBlh+f9sa29YoMdy51AMQQ7AAifVzrSQoh7m4Z9rvbom3r3YHUmO3fT\n1h1+9PyFTlZ6gqFYKIcLGgDCZ3lHRhNiZlWsj8cZaVtCiA/zlbjaYHG5E4ZioRiCHQCETF7K\n19OZidHIQNPo46HqDaNa17c7ldhjV5wVy3InUAzBDgBC5o10Nifl7D531xUNt60P83lfDhUu\nB9ex4/cglMIFDQAhszydFkLMjlf5crQmy8x4cq/r+nK0EGHyBPrfli1bNE17++23j/QGx3E0\nTXvuueeO+VsQ7AAgZJZ3pIUfD9gVjbRtIcS2ynvMLlsciiXYQS0EOwAIk7wnX0tnxkfsIZY/\nyxqMME0hxLbKmxibZSgWKuKCBoAwWZ3NZjzp1zisEKLJtoQQ2yrvMbsDwY4eOxyN53mapi1Z\nsmTOnDmjR4+eNm3a6tWrv/3tb59wwglDhw794Q9/WHzb7t27v/SlLw0bNqyqquq000575ZVX\niu2rV6/+9Kc/HY/Hp0+fvmLFis7D7tq1a+HChcOGDYvH42edddabb77pS7UEOwAIk1c6MkII\nv2ZOCCGaLFOUbijW80pyWD9k2SsWvaPrumEYP//5z5988slNmzY1Njaec845p5122urVqx98\n8MEbb7yxublZCHHxxRe3trauXr26paVl5syZ8+fPb2lp8TzvkksumTx5cnNz89NPP33//fd3\nHnbBggVCiLVr17a0tJxxxhnnn39+JpPpe7UsUAwAoWFu3rBy115RO+Dc/1sSG9GUPfNcGe/T\nAsWis8fO16FYLZe1X3lJf+/tXCYdqW+Up852jpvh4/F9cXAolmAXSi93pG/btaePBzmlKnbn\n0EG9fPM//uM/VldXCyFmzZq1efPmSy65RAhx+umnu667efPmHTt2vPrqq+++++6gQYOEEN/9\n7nf/+7//+9lnnx03btyWLVv+/Oc/x+PxeDx+zTXXvPjii0KIN99889VXX/3Nb37T0NAghLjj\njjvuueeeJ5988u/+7u/6eFIEOwAIB/ODTdbjj7z2mc+PS7c17d8n9u+L7f4o85XLpdGnO/lA\n04xqmp8rnkgZffLX5pZNxVfa3j2xZ3+b9dzC9JN8+xZ+yEkh2HkitDKe3NrnbuamT/Kg6vDh\nw4t/iEajw4YN6/yzECKbzW7fvl3X9cmTJxfbY7HYqFGjtmzZYtu2pmmjRo0qtk+YMKH4h/Xr\n1wshOo9TtHnz5mM/mYMIdgAQDpHnf/96XX2baf7dwY4KY0+zuWZV4cRT+nJYTYgRtuXjGsXm\nBxs7U12nyIt/KkybIYy+rqjso4zrCoZiQ2tuTXzDlPH9+R21LpeK1ovLxvO8fD6fy+W6vt85\n+IMWi8WEEJlMphgNOzl9/knkkwoAhIDmuvq+lpfqBwkhztzX3NluNO/q+8GbbKvN9fb7tJSd\n3rz78EYtl9WT+305vl+YPAEfTZgwwfO8d999t/iyo6Nj69atEyZMGDFihJRy69atxfb33nuv\n8/1CiNWrV3cewZfuOkGwA4BQkLouDWNZ/SAhxBl7D/TYSSGkHen7wZssXx+zO0JJ0rb9Ob5P\nGIqFj2bMmDF79uzrrrtu79697e3t119/fU1NzYIFC2bNmtXQ0HD77be3trauX7/+nnvuKb5/\n6tSpc+bM+da3vvXhhx8WCoX77rvv+OOP37lzZ98r4YIGgDDQtOzEKSsHNIxOdzRl0wfahHAm\nTun7sQ8EO58es3PGjpfmoc/5eMObZHWNL8f3S8ZjKBZ+Wrp0qW3bU6dOHTNmzJYtW5YtW1Zb\nWxuLxZ555pm1a9cOGzbsC1/4ws033yyE8DxPCPHLX/5yxIgR06dPb2hoeOihh5599tlDHrk7\nNjxjBwDh8Npp56Z27Lp41/bOlvxpZ7nDm/p+5BGWn2sUe4kBuXPPj/zpd9rBsV1ZXZOZf7Ev\nB/dRsceOWbHoja6Pvt1222233XZb8c+maUopi38eOXLkE088cfjf/fSnP/3GG290vux8/5Ah\nQx599NFD3tz1gMeGYAcA4fCK6wohZg0fUTClF4m4Eya7Q3z4fC+EGHlgjWLflrIrTD/RHd5U\ntXmDmc1ka+tyU4+XVnmNwwohstIzNM2ixw5qIdgBQDgc2CJ28uTs8cf5e+QRliWE2O7rUnZe\nQ6McOcqMxdxkUhbKcSPajOsxcwLq4Rk7AAgBV8q/prPDLesTrbzVS0NM09Z9XcouDHKSB+yg\nIIIdAITA29lc0nVPr/Zti9iudE0MM00fl7ILhaz0mBIL9XBNAwghKUXfni8OneV+bxF7iCbb\nanXcNrd8t3b1XVbKkvfYlfFWuVAVz9gBCBOjeVfkxT/md24Xmh5rGpU7+zNefWPQRfWH5em0\nEGJ2vCQ9duLgiifbHWeKUXazHEok68moWZJgp7W1RV76k/nBBq1Q8AYPzZ4xxx05uhTfCDgc\nwQ5AaOit+2IP/49WOPAomLlpvbFze8dXr5Lx6mAL68HP9ux9MtXem3caxnb3yHs/vJ/NDbXM\n0bblX2l/ozgx9sN8fkqkUoJdTspSrHWiFQpVjy3R9+0tvtR3bq96dEn6y1/1ZWEa4KgIdgBC\nw172fGeqK9Iy6cjyv2Tnzg+qpKN6LNm2Lpvr+3FMTfuHRF3fj3MkI0xT+LriSZnLe9KVMqr5\n/zySteqvnamuU+T536e/crnv3ws4HMEOQGgY3W1CauzpprF87HfcJtt6c+LYo74zkUikUikv\noKeymmz/VzwpZ7mSbRSrNzcf3mjs2S2kFEzC9UNjY0U8fXHMmDwBIDS63Wy0DFe+7Wq/69aG\nYerlwV3FKqXHLiulKNFGsVY3w+XSskl16B8huN0AQJHb3b6ohYmT+7+SXspLmZMyYRhBF3J0\nQy3T1LRtZbmScCkUg10pZsV2u3uvU8ZXKRRDsAMQGrlTZrmjxnRtKUycUph+UlD1HNV+1xVC\n1IUh2JmaNtQyP6ycHjvPE6XZKNYZMy5/8syuLe7AQbmz5/r+jYBu8YwdgPAwjPQX/8na8H68\npVlqWsegIc64iUHX1JOk6wkhakOyzXyTZS3Pp9OeVxWGseM+KvbYRUtzprlz5jkTJpubN2i5\nnDN0uDPlOBGGcA81EOwAhIqmFSZOMWad7nme09oadDVHkXRdIURtSH6pj7St5R1iW74wKRoJ\nupae5D2ZlkeZYuIJsS1f+CBf2JzPb84XNuXyW/P5Qpc1rZ0DQ7GlKtIdMdIdMbJURweOjGAH\nAKWS8jwhRCiesRNCjLBMIcR2x5kkyjfY5T05e+MHWz/hkLEuxFDLqvrb7rlhmnlOPO5ncUAZ\nINgBQKkUh2LrjHCMbIZiYuwf29u35gtTo5Hx3U2R7mqAaYyxrbG2PS5ij7Ytm0mpqAwEOwAo\nlVbHEULUheSRtQM9dv4uZef3lr4Pt6aEED8dPuSEWNTfIwNqINgBQKmkPClCMitWCDHStoUQ\nH+bzR33nUWn5vL38Jf29t3PpDruhUXz6tMKU4/t+2D2O+0J7x5RohFQHHAnBDgBKpTh5ImGG\nI9gNM03dlx47KaNP/crcvLH4St/THH36N8JxC8ef0McDP9KaLEj55QEl3FoNCLtwDBAAQBgl\nw7OOnRDC1rXBfixlZ27Z1JnqOkVe/INw3T4e+ZH9SVPTPl9X08fjAAoj2AFAqRyYPBGSZ+yE\nEE2W1ew4ub49GKfv3nV4o5bN6sn9fTnsa+nM+lz+vJrqQSZjTcARheZ2AwChk/TCNCtWCNFk\nW1KIHX3cWOwI81X7uKvv0takEOJLA2r7chBAeaG53QBA6CRd19S0EG3k0GSZQog+jsY6Y8fL\nwzrVvGHDZc2xD6FmpXwy1T7QNOZUs/Ic0JPQ3G4AIHSSrlurh2RDMSHEwaXs+jh/wkvU5+ac\n13UTLRmvzsxf0JdjPplMJV33HxJ1FsvRAT3iSQUAKJWk54Vl24kiv9YoLsz4lDusqeqDDWYm\nnasbkJ1yvIz0aTeLpa0pIcTCBOOwwFEQ7ACgJKQQKdcbZVlBF/IJNNmWEGJbH5+xE0II4Q0c\nJEePMWOxjmRS9u2A2wrO8o70yVWxMt/EFigHDMUCQEl0eJ4jZVjWOilqsi2t/HYVW9q63xPi\nS3TXAb1AsAOAktjvFBexC9NtNqJpA01zm7+7ivWNFOKx/amopl3M8nVALwQ2FLto0aItW7Z0\nvoxGo4899pgQor29/f7771+zZk2hUJg0adJVV101aNCgoIoEgGOWOrDWSZh67IQQTba1OpMt\nSFkm0xT+0t6xNV/4YqI2dP+SQCACC3bt7e1XXHHFzJkziy/1g8sB3HXXXe3t7bfeemskEnn4\n4YfvuOOOn/3sZ3p4FgsAACGE8Lz0e28Lq7rxjVfjz2wtnHhK/qRTRRhuZU2W+UZa7iw4o+xu\nng5Mud6mfH5TLr+zF4/N2ck2y7Ky2azbhz0n/tjWIYT4UoJtxIBeCSzYtbW1DRkypLGxsWtj\nS0vLa6+99pOf/GTMmDFCiKuuuuorX/nK2rVrZ8yYEVCZAHAsIi+/kP7gA/GpM+oKeX1/a+SF\nP2htqdw584Ku6+iK8yf+fdeexi5b3BY878OCsyGXb3YCGKUdbVunxav6//sCYRRMsCsUCrlc\nbsWKFQ899FBbW9v48eMvvfTS4cOHb9iwwbKsYqoTQlRXV48YMWLdunWdwc5xnHQ63Xkcz/O0\n8hgsOKpinZqmhaXg3tAOCroQ33Sei3onpdIZdSrbk9JSSfvVV/YPGy2EGFDIFxvt11c6J53q\nJQb09BfL4AdqWjQqhPhdqu3wLw2zzDOqq8bZ9riIPcw6+q+PSCRi23Y6ne5Lj50mtJNiUaNs\nVgNU777XScmTqkDBBLt0Op1IJBzHufrqq4UQS5cuvfHGG++7775UKlVTU9P12qqrq0smk50v\nly1bdt1113W+vPfee0899dT+rLyPBgzo6Z4eUtXV1UGX4LOqqqqqKtW6BxoaGoIuwWeGYZTt\nSXnNHxWE2G/ZQog6J9/ZXpdu18eN7+EvlsMt4oqGhtlDBuc9r2ujpWljY9FqnnI7SL1bRDQa\njUajQVcBHwQT7Orq6pYsWdL58vrrr7/sssuWL18ujvaJob6+vmuSq6qqKvix3lI/MAxD13XH\ncWTfdtcuK4ZhSCm9v/0FEGq6rhuG4bquSiclhCieVNBV+MmyLCmlE8SwYG9IXRdCtNqW6NJj\nJ4RwdEM78i3LNM0yOaPJ3T1dJzyv8Al/LpS87xWf+VbpFqFpmmmanueV4i5hhWodRzWUxQLF\nsVhs4MCBLS0tY8eOTaVSUsrOeJdMJrt+hJ0xY8a9997b+TKZTHbtzytnNTU1kUgklUqpdDuI\nx+OO4+RyuaAL8Y1t27W1tblcruuIf9gZhhGPx1OpVNCF+KmhocHzvLL98dfqBsTj1UnTFkIk\nDiY5WRVvr2+QR645kUi0tbUpdouIxWIdHR1h+QTeG9FoVNO0TCYTdCG+MU0zkUjk8/n29nbf\nD37Ik/ToB8FM0dq6devdd9/d+dk0m83u2bNnyJAhEyZMKBQKmzZtKranUqlt27ZNmTIlkCIB\n4NhI08rMX9AaiQghEoV8sSU7f4G07KBLA6C4YHrs6uvrV6xY4TjOwoULXdddsmRJdXX17Nmz\nI5HIrFmz7rnnnkWLFtm2/cADD4wbN27q1KmBFAkAx8wdPXavZ4h0Nj5uYr62Jj9thqxlwQ4A\nJRdMsKupqVm8ePGDDz547bXXWpY1adKkO++8MxKJCCEWLVp0//3333bbba7rTps27Tvf+Q7z\ndACEUVLThRDRefNz3MQA9JfAnrEbO3bs4sWLD2+vqqq69tpr+78eAPDXpF2UpwAAIABJREFU\nfteNappNqgPQj0KwDDoAhFHK8xIm64MA6FcEOwAoiaTrsr0pgH5WFsudAIBiXCnbXa8uUqEf\nnrVC3l6+TF/3Tq69zW4YKGaeXpjENDigP1ToTQcASirpelKIOqMi77FSRp963P7rKyK5X7iu\n3rwr+uSvrLffCrosoCJU5E0HAEos5XlCiMocijW3bDY3rT+kMfLCH4Ra258A5YlgBwD+S7qu\nECJRkcFO3/3R4Y1aNqMn9/d/MUClIdgBgP/2u64QolavyHvsEbYHlWwbCpReRd50AKDEUp4U\nlfqMnTN2gjQPnZnnDhkma2oDqQeoKJV40wGAUiv22FXmM3begPrc2XO7tshYVfaCBUHVA1QU\nljsBAP8lKzjYCSEKJ57ijRgZ27jezHTkEvXZqdNlNBp0UUBFINgBgP8OBLvKfMZOCCGEO3Cw\nHD3WjMU6kklZKARdDlApKvemAwClU8nP2AEIEDcdAPBfhQ/FAggKwQ4A/LffKQY77rEA+hXP\n2AEQmuvaf11url2lt7d59Q35k2cVpk0XmhZ0XSGW8jxNiJowPGOnJ/fbL/3J/PAD4XnusBH5\nsz7jDhwcdFEAjhHBDoCI/uFp8+BWnvqe5uizv9WymfzJM4OtKtSSrltj6EbZh2Mtk6l6+EGt\nva340vxgk7F9W/qyK7wB9cEWBuDYhODTJICSMnbtNA/boN3+y/NaLhtIPWrY73qheMDOXrms\nM9UVaYV85C9/CqoeAH1EsAMqnb571+GNmuvoe1v6vxhlJF03FGudGN3973fbCCAUQnDfAVBS\n0jrCIxns7Hms8lLmpAxFj123//ts6gqEF8EOqHTuqLHSsg9p9BL1buOgQOpRQIj2E3MmTD68\nsTB+Uv9XAsAXBDug0sl4dXbeBbJLCpGRaPbCS5gVe8z2u54Qok4PwT9g4fgTnYlTura4w0YU\nZp8ZVD0A+ohZsQCEM/X49JCh5jtrjLY2r74hP/1EWRUPuqgQC9PqxJqWufiL5ob3za0fCM91\nhjU5U48XYXg6EEC3CHYAhBDCq2/MnzEn6CoUkfI8EZZgJ4QQwpkwudsxWQChw8cyAPDZwW0n\nQhPsACiDYAcAPjs4FBuCZ+wAKIZgBwA+S3lS0GMHIAgEOwDwWZgmTwBQC8EOAHx2YB075pYC\n6HfcdwDAZ/TYAQgKwQ4AfHbwGTtusAD6G/cdAPDZfte1NK2KoVgA/Y77DgD4LOm6tXoYNhQD\noByCHQD4LOV5PGAHIBAEOwDwkxQi5Xo8YAcgEOwVC6C02j3vN8m2h1uTG3P5vh/NEOK7Qwdd\n2dDQ90OVSIfnOVLSYwcgEAQ7AKWyOpNdsm//b5Jt7Z6nCzHCsrS+PXfmCbEtX/hDW/uVPlVY\nCsW1TmqZOQEgCAQ7AB97P5v7v2Rb34/jSflSe8fabE4IMdg0L29IfKU+MdKy+njYvJRN76zf\nUXD6XmHpsNYJgAAR7AB87J69rY+0Jn05lC7EudXxS+vr5tVUm33sqTvI1rRG09zplHWwY3Vi\nAAEi2AH42D7HFUL8z8hh1X0eSZwYiQy1/L/DDLfMtdmcK2XZLiay3ykGu5L02BnbtkReflHf\nvUvEYs74SbnZZ8lYrBTfCEBIEewAfKzVdTUhPltTbfjUx+a7YZa1KpPdlS+UIjX6orhRbKIE\nPXbGti1Vjyw58KKQt978q75ze/rLXxX0DgI4iKdAAHxsv+vWGkbZpjohxDDLEEJsy+WCLuSI\nkp4nSjMUG/3zc4e0GLt2Wm+/5fs3AhBeBDsAH2t13bryns453LJEmQe70vTYaa6rt+w5vN3Y\ntdPfbwQg1Mr6Dg6gn6U8b4BZ1uN6B4Jd1ocl8Uok6XpCiFq/dxSTmia6y9yyz3ONAaiEYAfg\ngA7Py3uyFA+H+agY7LbnyzfYpUo0FKvrzrgJhzc74yf6/I0AhBnBDsABrf9/e/ceH1V953/8\ne25zSTK5cwvhEq4iIAiIKF5ZL61aq677W/3ZQr1T2/XXx/a3VffRPqyXx8+t7mO12+26P39I\nt6yLrnWprbbeihZvoKgUsQoCcgkhEALJzCSTmXP9/TExhGQSIHMmZ+bM6/kX853hO58zk3Py\nzvme8/2a6THEvD4sFMA1djm7eSJ50WVORWXvFv2Ms6zxDa6/EYDClae3lQEYfumr/vP8jN1o\nVVUlKZ+DXfqu2PIc5GOntKzzxm9rH3+kHDxgB4Pm1FOs8RNdfxcABY1gB6Bbm2UJIaryO9gp\nkjRSVfL8GruwLAVyc2exo2n6/DNz0TMAf8jrMRcAwymnM+u6aKymHdR13Xa8LiSzqGWz7AQA\nr+T7ERzAsGkvhKFYIUSdptpC7M/X+yeilpX/nyEAvyLYAejWvWRCfs9jJ/L7xljLcTptuzzv\nP0MAfsU1dgC6pSdgq8zveeyEEGM1VQjRmEzN1NwpVUolA++sU3dsk5Jd9ohRqXMusMZNHFpX\nUct20sPZjqN9vCmw6X2pvc2pqNJPX2CcNi/jRHQA4CKOMgC65W6RU3fVqapwccYT2w7/99OB\nD9+To+1SKqXs21vyzCplz66hddZzZ3HgnXWhV1+UD7VIhiG3toRe+33w7T+6UzAADIxgB6Bb\nW6EMxQbSQ7GGK72pn25Rmhr7NIb+8Puh9ZaexK7CsoLvvd3nqcB7b8vR9qF1CwAnKN+P4ACG\nTYENxbp0xk452Ny/UT5yWBrSNXzdsxN3JYRtn+B7AYCLCHYAurVZlipJpXl/xq5WUQOy1Jh0\naShWzbTWqiyLIQ1JR7vXE8v8GToZ3wsA3JPvR3AAw6bdsioVt9euzwFZEmMDQbeGYjOutWpO\nnOQMLdhZthAiUlXthEv6PhcuscaOG0KfAHDiCHYAurVbdv7fOZE2LhQ4bBhJx4U5iq2x4/Qz\nz+nd4kQiyUuuGFpv3dfYaVry8qsc9ei0A46idn3la04wmE2pAHBcTHcCQAghbEfELWtaMOB1\nISdkXDDoCNFsmA0BFwY3U+ctMSdOUrd/JiWT9sjRxpz5TmCIn0N3sFMUs2FK4qY71I8/kqPt\nTkWlMft0u7Iq+1IBYHAEOwBCCBG1LLsQ1hNLGxcMCiGaDMOVYCeEsMZPtMZPzL6fmO2ILz9G\nu6JSP3dJ9n0CwIkrjIM4gFxLrydWVSBDsekZT5pcuszORen1dvP/zmIAfsUZOwBC9BpD9LqQ\nE5I+Y7fftHL3Fq/FO+890KKf5GV8h0xLCBGR+JsZgDcIdgCEEKLNtIQQFXk/10nauFD3UGzu\n3mJ1e3R7Sq9QlJO6TTggSaeWhDljB8ArBDsAQnw5FFtdIIlkXDAgchzs3u/sqlWVz06Zkru3\nAADXFcZf5wByLb1QbKGcsavVtBJFzt01dnt0o8U0zygJ56h/AMiRwjiIA8i19gJZT6zH2EAw\nd9fYbUx0CSEWhEM56h8AcoRgB0CIL8/YFcpdsUKI+qAWtayOTEuyZu+DrqQQYmFpv9UjACC/\nEewACFFoQ7Gi58ZYw8xF5+93JjRJmhPijB2AAlMwB3EAOZUeiq0qnKHY7jmKc3CZXcK2P0vp\ns0LBcAEsnAsAxyjsu2KDwWCwQNZeVFVVCFFaWuq4sbplnlBVVVVVTXNn6v98IMuyECIQCMiF\nc+LquCRJUlW1rKxs8JfFhRBCjC0vDxbItqdvjD2sKMfdtJP1YSxuOs7iygrXex6cLMv+O0QI\nIcLhcKEcqE+EoiiSJCmFc9HCcUmSJITQNG2Yf+CRI4Ud7CzLsnNzhY3r0gc4wzD8dNSWZdm2\nbSOXU04Ms/TXZFmWnzZKlmVFUY67RUcMIyxLsmUZVg5n/XVLMBhMT2W3N5l0/ct6pz0mhJgf\nCg7zj4Gmaf47RAghTNO0CuGH6sRJkuSzQ0QwGMzRwTzE9QzDrrCDnWmahbJ3BQIBVVV1XS+U\nJHoiVFU1TTOVSnldiGscxwmHw5Zl+WmjFEXRNO24W9RmmlWKUigbXlZWVh8ICCH2dCVdr3lD\nPC6EmKupw/xphMNh/x0ihBCGYRTKgfpESJIkSVKh7CknoucP2lxsVCQScb1PDK4wxlwA5Fqb\nZRXQnRNCiHSwc/3mCUeIDxPJ0ZpaH/DPNQYAikchHccB5IhuO122U6UW0in8ClWJKLLri0/s\nSOlHLGthmKmJARQkgh0A0W5bQojKQrsevE7Tmtw+Y5eewe6MUoIdgIJUSH+gA8iRNjM9iZ3L\ns3uou3YG1r8pH2l1wiXmjFn6wsWOqycF61RlWzLVblkuRtKNnQkhxBnFtOaEFI+H3n5d2btb\nmKZZP14/d4ldXeN1UQCGiGAHQETt9CR2bh4Q1M8/C//mV0IIIRypqyvwzjr54IGuq/6HkFyL\nj2M1TQix3zDdDHZdyYAkzS6aYCclu0pXr5Ri0fRD7fPP1D27EstusysqvS0MwNAwFAuge9kJ\nN4diHSf0h5e+fNCd5NQd29RdO117iy+DnYujsXHL/jyZmhsOBdxLn3ku8N67PakuTUolA+v+\n4FU9ALJEsAPg/lCsFItKnR392+XmJrfeQggxNpAOdq7dP/FBV9IWYmFJEV1gpxzI8I0orn5N\nAIYTwQ5ADoZiB1qPxO1r7ISrwW5jIiGEWFBSLOOwQghH6fuNOEIIlalegEJFsAPg/lCsU1Jq\nja7r325NmurWW4ij19i5tqrBxkRSCLGgmM7YmZP7fiOSEOaUaZ4UAyB7BDsA3UOxlYqbB4Tk\nV7/uHDsbXOq8JdaIkS6+xZfX2Llzxs52xEddXeM1bVRBzeeXJWPuArNhSu8Wa9QYffH5XtUD\nIEtFdPwCMJD0UKy789jZtSM6b/5uYNNGqbVFlJYZM2ZZdfUu9i+ECMtSlarsdynYbdP1mGVf\nEimyddAlqesvr9e2fqLs2SVZtlk/zpg1VxTajIYAehDsAIi29FCs20uKOeFw6uzz3O2zjzpV\n3Z7SnZ47b7PwfmdCCLGgaCY6OUqSjBmzjRmzva4DgAsYigUgopYtC1Hu6lDs8BirabrjHLFc\nuMyue82JYrrADoD/FN5xHIDr2iwroihKAU7eVqepQogm3YXR2I2JrhJZPjUUzL4rAPAKwQ6A\naLcsd++cGDZuzVF8xLK+SOnzwiG1ANMtAPTgGjugm7bt08CHG1JtR+RIRWDmafrpZwi3rznL\nWzHLqu/sKHv0/wjLlLSAMWd+8oKLvS7qhNRpihDit7H4ITOrbLdD150im+gEgC8R7AAhhNA2\nbexZAktKJIIHm+Ujh5MXX+ZtVcOj07Z1R1THY1I6G+m6tnG96Ignr7jG69KOryEQFEI81x57\nrj2WfW+LSgl2AAobwQ4Qkq4H/9h3cUztTx8Yc+ZbI0d5UtJw6vx8qxBKlaH3btQ++0S/4BK7\nLN/n/jijJPTMxPpO286+q7AkLykrzb4fAPAQwQ4QUmuLZGa4+l4+0FQMwS7auEeMmVRl6n3a\n5Z3b7DnzPSnppPwFaQwAvlQslxABg5AGWGmg/zKavnRECwghqvW+wU4Kcn8oABQYgh0grNqR\nTnlFn0ZH1azxDZ7UM8wON0wVQlT2OWMny8aUU7wpCAAwVAQ7QAhZ7rr8KkfVerelLvqqE4l4\nVdFwOlJeIYToc41d8sJLRTEtmQoA/sCBGxBCCKt+QufNd4S2bArEolZZpGv6zGK4ui6t3bKE\nEGWnzbP0hNTZ6VRUJC+4xHZ7XVcAwDAg2AHdnPIK68JLtPJyI5GwEgmvyxk+UcsWQpRNmJg4\n9VSvawEAZIWhWKDYtVmWEKJKUbwuBACQLYIdUOzSQ7EVRbPMBgD4GIdyoNi1W7YQokrljB0A\nFDyusQOKXbtlaZJUUsRn7CRDD2x4W/18q5TsskaOTp19nj12XLadOo76548DmzbK0Xa7otI4\nfYExc46QJDfqLQCSZWkb10vbPtUTnYHqGufMxebEyV4XBRQFgh1Q7NpMq0KRiyVx9Gfb4f9+\nRmncnX6k7t6p7t6ZuG6ZNW5CNr0GN7wdePuN9L+VroTy0m+laLu++ILsai0Ywd/9Wtv2qRDC\nEULuiIf37k5eea0xnbtzgJwr3r/RAaRFbbuyiO+cULf+uSfV9Qj94ffZ9Cl1dgTeXdenMbjh\nbSkWzabbQqHs3ZVOdb0FX/u9cGNJXwCDI9gBRc1ynLhlFfMtsUpzU/9GufWQ1G+NtZPo82Bz\nhhBj2+qB/UPus4Bk/EilroQcbRv+YoBiQ7ADilrMsm0hKpQiPhRkXGBDkkQWYdeRM/9fp0gW\n8xhgkeUiWXwZ8FYRH80BCNFu26K4J7EzJ03p0+IIYU2c5GTxmdhj60W4pG+3oZBVl/U9GYUg\n430S1ogMKzIDcB3BDihqTGJnjZuozz/zmKaS0q6LL8+mT0cLdH3la72joaMoqUu/5oRC2XRb\nKOzaEanz/qJ3ixMMpi672qt6gKLCiXGgqDGJnRAiteRSq2GKuv0zqavLHjlaP/2M7BOYOWV6\n4lvLtc0fyu1tdmWVcdo8u6bWlWoLgn7mYqt+fPjzz5RkQq+sTp42zykt87oooCgQ7ICilj5j\nV8x3xaaZDZPNBpcnWrOra1IXXuJunwXEGjvOmXaKFg4nolHHMLwuBygWxTv+AkAI0WaaoriH\nYgHATziaA0Utajui6IdiAcA3CHZAUWMoFgD8hGAHFLX0UCzBDgD8gWAHFLX0UGxlMU9QDAA+\nwtEcKGptFmfsAMA/CHZAUWs3rbAsBSTJ60IAAC4g2AFFrd22i3k9MQDwGYIdUNTaLYtJ7ADA\nNzigA8VLd5wu26lSWYEGAHyCYAcULyaxAwCfIdgBxavNTAc7jgMA4BMc0IHiFbVtwRk7APAR\ngh1QvNoYigUAfyHYAcWrnaFYAPAX7oYDckhuPRR854/Kgf2OqpmTpuhnneuEwln2KSW7Au++\nqe7aIZmmObpOP+dCu6Z2aF21MxQLAP5CsANyRW49VPLUCskwhBCSEIEjrcqeXV3fvNlRhr7f\nSZYZfuaXyqGW9EMtFlV37Uh889ZYVfVTbVHdtjOUIcuBQCyZTPZ/6u1ElyDYAYCPEOyAXAn9\n8dV0quuhHDqofbRRP+OsIfepfbSxJ9WlSYYReuOVf19y+Y+aWwb6X4MboxLsAMAnCHZArsj7\nm4RwhJCObdyXXZ8Z/rvc1Lg9pQshHqobNTWg9XlWUZRQKNTZ2Zmxw3JFOSUUzKYkAED+INgB\nOSPLfVKdEEJkMQ4rhBAZV4lQlHSwu6o8Utvv9JuiKKWlpbF+hQAA/Ie74YBcsSZN7d9oTpqS\nTZ9mQ4b/bk2atj2lVypK/1QHACgqBDsgV5IXXmJXVPZuMabNMGfMyqZPc8YsY9qM3i12RWX7\nBRc1mebUYCCbngEAPsBQLJArTjicuPHb2kfvKwf2C00zG6YYp8wUUnZjopKUvPJaa+sn6q6d\nwjCs0XXGvIVf2I7lOJP7XV0HACg2BDsghxxN089c7HKnkmTMmG3MmN3TsD0WF0JM4YwdABQ9\nhmKBgrcjpQshGIoFABDsgIKXDnZTgsxaAgDFjmAHFLwdKV2VpIka19gBQLHjGjugm7pjW+DD\n9/S2I3KkXJs1x5h9upAL4y+fHbo+IaAF5Cxuy7Bt7eOPtC1/kuMxu7pGP+Msc/K07AtTGvcE\nN7wtHzpol5aZp8zUFywSWS9fJkXbQ+/80WhuEpIcqh+XWnyBU1qWfakA4A8EO0AIIbSPPwq9\n8qJIrxQRj4X275NbD6X+4ite13V8Bwwzbtlnl2R1gV3wjVcCH21M/1vp7Ag37kle+jXjtNOz\n6VPd+Xl4zTM9fSotB+SDzckrr82mT6kjXvof/0/q6nKEEEJohw+pu7/oXHqbEwpl0y0A+EZh\nnJAAckoy9ODrr/RpDHz0vtI6xNVXh9MOPX2B3dCDnXKopSfV9Qi+/kqfhW5PjuOEXvtdnzZt\n26fKrp1D71OI0FuvS11dvVukaHtgw1vZ9AkAfkKwA4R0qCVjiMlyXdfhsT2VbbCTmzNspmTo\n0qGDQ+5TisekeLx/u5rpvU6cvL+pf6PS1JhNnwDgJwQ7QEgDXPjlyAWwQlf2c50MtJkDfSwn\nZKCPNLtr7Bwl0yEr4/q5AFCUPDsgHjlyZOXKlZs3b9Z1fdKkSTfeeOO0adOEEHfeeefu3bt7\nXhYKhZ599lmvikSRsGpHOpFInzNMjqpa4yd6VNFJ2JH1GTtr/ERHVSXT7N3oRMqtEaOG3KdT\nWmaNHK20HOj7XpnWuj1x1qSpyqG+4+NmpjV5AaA4eRbsHnzwwUAgcN9994XD4dWrV99///0r\nVqwIhUIdHR233XbbokWL0i+TC+S2RBQ2Rem67Krwc09L1tFwk1pyqVNe4WFRJ2h7KlWlKjVZ\nnAlzyitSF14Seu33R1sUteuyq7K8KTh12VXh1SslXT/acvb51sjR2fSpn32e8sUOpdcYsVU/\nXp9/ZjZ9AoCfeBPs4vH4iBEjvvGNb4wbN04IsXTp0nXr1jU2Nk6dOjUej48ePbq2ttaTwlC0\nrPENiZvvCG3+UIu2W2WRrhmzrNF1Xhd1fCnH2W9a88LZTk1szF1gjxqjfbJZikXt6hpj3kK7\nojLLPq0RIztv+W7go/flQy1OaalxyixrQkOWfTqq1vXNW7TNH4ZbDjiS1DVmrDFrbqHMSgMA\nw8CbYBeJRO65556eh4cPH5Zluba21jCMVCq1fv36p556Kh6PT5kyZenSpWPHjvWkSBQbu6LS\nvOirJeXlRiJhJRJel3NCdqZ0y3GmBFxYTMwaM9Ya4/K+5pSWpc5d4nKfiqLPWxipqbFt22hr\nc7dzACh03l90HI/Hf/azn1111VVVVVXRaLSystI0zTvuuEMI8fTTT99zzz2PP/54aWlp+sVv\nvPHG3/3d3/X833/9139duHChN3UPSXV1tdcluC8SiXhdgstKSkpKSkq8ruKEHDzUKoSYU111\n3JPc/jsLriiK/zbKl4eIiooCuKThZPX8VvKNUCgUYj5IX/A42O3bt++BBx6YO3fusmXLhBAV\nFRWrVq3qefYHP/jBsmXL3n333YsvvjjdEolEZsyY0fOCUChkHnvFd95SFEWSpEKp9gTJsuw4\njuM4XhfiGkmSFEWxbdu2ba9rOSGfdnQKIaYGg4P8aEmSJMuyZVnDWFfOqarqOI7PNkpRFJ9t\nkSzL6Z89Px0l0ld+F8oh4kTk9LinctP6sPPyE9+8efPDDz98/fXXX3HFFRlfEA6HR4wY0dra\n2tOyYMGC//iP/+h5GI1G29vbc16oGyKRSDAYjMVifjoclJaWmqaZSqW8LsQ1gUCgvLw8mUy+\neqj119EM07ANwZXlZeeX5eqP+0+iMSHEGNMYZEdQFKW0tDQWi+WoBk/U1NTYtl0ou/8Jqqys\n9N8hIhwOd3R0GNlMdp1nQqGQJEldx06UXdBUVa2srNR1vaOjw/XO/XdaPf95Fuw+/fTTn/zk\nJ9///vfnz5/f07hnz54XXnhh+fLl6YyfTCYPHTo0enRWt9EBJ8tynO/sa95vuHN69Q/xjk3T\nJmezjmsfUjIZWP+muvsLoae+WHC+GgxP0DTXegcAFDJvgp2u64899tiVV145YcKEnhNyZWVl\n1dXV69evN03zuuuusyxr1apVZWVlZ599tidFomi91B7bb5hXVUS+W5vtBU+PHTr8Yqzj3UTi\nnFJ3LtqTLCv8X79UWg4KIRxJ2q5oDYmOUPthu5o/iwEAHgW7zz777MCBA6tXr169enVP4+23\n33755Zc/8MADv/jFL773ve9pmjZ9+vSHHnooGMx2KgfgpDzZ0iqE+E5t9ZxwtpcSL62qfDHW\n8Vx7zK1gp23amE51QojmYCiuqucfiQbXvtL1Vze40j8AoKB5E+zmzJnz29/+NuNTkyZNeuCB\nB4a5HqDHnmRqbSw+KxScm3WqE0KcX1Y6RlN/G4v/Q92okOTCcGzv5Ws/LykXQkzriCvZLcAK\nAPANJvYEjvFv+w9YjnNzTZUrvcmSuLI8ErfsP8Q7XelQ9FrXdVtZRAgxrTPODL0AgDR+HwBH\n6bbziwMHy2T5qgrXJue7trJcCPFcuzs3pZoNk3v+/XlZRAgxvTNmsVgqAEAIQbADenshGjuo\nG98YUVPm3jmwueHQ9FDwtY6OI6YLU5SZp842p52S/vfnpREhxFRFSl54afY9AwB8gGAHHLXy\n0GEhxE0jXb7D9OqKiG47L8bcmBhPkrqu/Kuuy68yZszaVllTJezQDTc74bALPQMACh/BDui2\nPaW/09F5TkX5TDdum+jtf1SUS0I8F3VpimBJMk89rf3yq/epgaklpY4bC8UCAPyBYAd0++WR\ndkeI2+vcnxB7XEBbUBLa0NnV6NKkx0KInSndFmJKkFQHADiKYAcIIUTScZ6NxqpV5doRNbno\n/9qKckeINe1RtzrckdKFEFM4XQcA6IVgBwghxPPReJtpfaOmOpSbqUOurigPyNKvXFp/Vgix\nPaULIaZyxg4A0Itna8UiDykHmwPvvqkcOmiHwtbU6foZZztqsfyE/PJIuyTEMpemr+uvSlUu\nKC19Nd7x52RqZsiFxVR26LpgKBYAcCzO2KGbsn9f+D9Xqju2SdF25WBz4O0/hp//L+E4Xtc1\nHD5Npj5IdJ1XVjrFjcg1EHcntNuR0jVJmhDQXOkNAOAPxXI+BscVfPVFyTpmojVl105t26fG\nKTO9KilHHmk5/E+HDpv9Muuy6sqcvu9Xy8siivzf0diPRo2Qs1tdzBFiZ0qfENA0N5YpAwD4\nBsEOQgghGYZyqKV/u9zUKPwV7NZ1dP5jS2uFqozXjjnXVa9pX4mU5vStQ5J0eXnkmbboO52J\nc8tKsunqgGF22DbjsACAPgh2EEIIIUtCkjIMvCpKplcXqsOW9Z19B2RJ+s/xY88o8WBS32sr\nIs+0Ra/Z3ehKb9w5AQDog2AHIYRwFNUaN1HZu6tPuzlxcsbXFyJHiDv3HThomveMqvUk1Qkh\nziktubI8sscwsu9KlaSvlbu2oC0AwB8IduiWvPTykqeelLq6elpYGHHdAAAZP0lEQVSMuQus\niZM8LMldKw63vxrvWFQS/l+11V7VoEjSk+PrvHp3AIDvEezQza6s7rz5O9oHG5SWgyIUNqae\n0rPYvA98lkzdf6ClUlEerx+jcMMBAMCnCHY4ygmX6Ocu8boK96Uc5/bG/UnH+Ze6UfXMDwIA\n8C/msYP//X1zy2cp/cbqyq9XcFEaAMDPOGOHPNVsmP97/8FU1jMkm47zTmfilFDw/jEjXSkM\nAIC8RbBDnvpZ6+FX4x2udFWpKE/UjwlxaR0AwO8IdshHcct+pj1Wqyp/mj45SCA7lpRKBTa8\nrezeIem6NaZeX3y+XeXZfb7DT4rHgu+sMw40OZIcqh+fOvs8J5zVbM8A4CcEO+SjX7a1xy37\nu6NqSXV9SJYV/q9VysFm4QghCbm9Td2xLbHsVruqxuvShoPU2VG66v9Jic70CL3WckDZ+Xli\n2W1OMORxZQCQH7h5AnnHdJwnj7SHJOlbOV68tRBpf/pAOdgshBBfJl7J0INrX/GwpOEUfOt1\nKdHZu0WOtgc2vO1VPQCQbwh2yDu/jcX36cZfV1VU+2tBM1fITf2XI3OU/e6sUZb/lKZ9mRqL\nZfMB4LgIdsg7Txxul4S4rabK60Lyktw/7EpShkZ/cmRZ9L9Pumg2HwCOi2CH/PJeouvDRNdf\nREqnscJ9JmamRd6MBv8s6Ts4q2Gy6HfVpVk0mw8Ax0WwQ375t8NtQojlnK4bgDnzNHPytN4t\nTnlF6sJLvKpnmOmLL7Brj5mP0Kqr1xcs8qoeAMg33BWLPNJomC/FOmaEgueVlXpdS76SpK6r\n/1r788fKF9slw7DrxurzznSCQa/LGiaOpiW+eYu2aWO45YAjSV1jxhqnzRNciwkAXyLYIY/8\nW+sRy3G+XVvNHCeDkSRj1hxj1hyv6/CGo6r6GWdFamps2zba2rwuBwDyC0OxyBdxy366PVqr\nKtewoisAAENCsEO+WNXWHrfsW2qqmJQYAIChYSgWg/kkmfoo0TXQs8HOLsuyTNN05b1WHGkP\nMikxAABZINhhMMv2NO01jGF7u29WVdR4dyG8smun9tF7enubEilXTz3NnHma4NwhAKCgEOww\nIN129hnG5GDgjgEmHwkGgy6esVMk6YryMle6GgL1k83hl34jhHCEEEcOh/fs0ltbUhdc7FU9\nAAAMAcEOA2oyTVuIOaHQ0gGGR0tLS03TTKVSw1yY6yTTCK19qU9jYON6Y9acPrOmAQCQz7h5\nAgPaq+tCiPEBzetCck5qaZF0vX+7sr9p+IsBAGDICHYYUKNhCiHqNf+f1pWUAXYEmR0EAFBI\n+L2FATXqhhBifMD/a7ZatSOd0r6X9zmKao6b4Ek9AAAMjf9PxmDIGg1DCDGuCM7YCUVJXvb1\n0JpnJMvqadMvuMipyHbuFbm9LfjuOrm5ydECZsNkY9E5jub/oAwA8EoR/M7GUO3VDUmIcUVw\njZ0Qwpw4OfGt20N/+lCLtlll5V0zZln147PsU247UrLqiZ6r95SDzeruLxL/80bWNgUA5AjB\nDgNqNIyRqlo860DY1bXmV75WUl5uJBJWIpF9h8HXX+5zT4ZyYH/gTx/o88/MvnMAAPrjGjtk\nptvOAcMshltic0fZv69/o7xv7/BXAgAoEgQ7ZJaexG6cRrAbOknKtH8xDgsAyBmCHTIrnkns\ncseYOKl/ozVx8vBXAgAoElxjh8xcm8SuKxFc/5ayd7ckHGvs+NTZ5/WfWMSvUksuVfftkeLx\nnhZz8jRj5mkelgQA8DeCHTJzZRI7KZUqeepJuf2IEJIQQj7Uom7f2vmt252SUneqzG9OSWnn\nt76tffiesn+fEwhYk6YYs+aKorkZBQAw/Ah2yMyVSewCG96W29vSqS5N6uwIvvV68tKvZVtf\ngXBCIX3x+V5XAQAoFlxjh8xcmcROacpwB6iyrzGbPgEAwEAIdsjMnUns+q+16ggx0MKsAAAg\nO/yKRQZuTWKX4Q5QSZjcFgoAQG4Q7JCBW5PY6WecZY2u691i19RyzRkAADnCzRPIwK1J7BxF\nSfzPGwN/+kDZu1vYllU/wZi/0FGZGw8AgJwg2CED1yaxE0Ioij7/TMHqqAAA5B5DscjgyzN2\nWU1iBwAAhhnBDhmkz9iNd+WMHQAAGC4EO2SQnsSunoViAQAoKJySQQaNhjFKy3oSO+SGZBja\ne++ou3ZIpmmNHqMvvsAur/C6KABAXiDYoS/ddg4a5vySkNeFIBPLCv/XKqW5Kf1Ibm1Rt29N\nLL3Nrqzyti4AQD5gKBZ97TMNmzsn8lVg84c9qS5NSqWCa1/2qh4AQF4h2KGvvbohhBjHnRN5\nSd6XafndJpbfBQAIQbBDf+lbYrNfdgI50X/5XSGEzNWQAAAhCHbor1HXBcEuX1kTJ/VvNCdk\naAQAFCGCHfrqnsSOuU7ykjFzjtkwpXeLUxZJLbnUq3oAAHmF66jQF5PY5TVJ6rrmOm3LJnX3\nTknXzTFjjQWLnFDY67IAAHmBYIe+mMQu38myMWe+MWe+13UAAPIOQ7E4RnoSO26JBQCgEBHs\ncAwmsQMAoHAR7HAMJrEDAKBwFfbvb03TVLUwNkFRFCFEKBRyHMfrWgZzoCMhhJhUUhIOH/96\nfFVVZVmWM86sVpjSX5Oqqiey+YVClmVFUfy0RWmSJPlso2RZzv9DxElJH5+DwWChHKhPhOa7\nqaDSx3CfHfeKWcHvbIV1EHQcJ88L3ptKCSHGBwInUqfzpdzXNdz8tFHpbfHTFvXw30b5cofy\n2UY5jiNJks+2SPjuaypmhR3sDMMwDMPrKk5I+uRiKpWybdvrWgazqysphBgtnGQyedwXK4pi\nmmYqlcp9XcMkEAiEQiHTNE9k8wuFoiiqqvppi4QQpaWljnNCP6UFJBQK5f8h4qQoiqJpmq7r\nhXKgPkGSJPnpZ09V1ZKSEsuycrFRZWVlrveJwflnEA2uYBI7AAAKF8EOx2ASOwAAChfBDkcx\niR0AAAWNYIejmMQOAICCRrDDUUxiBwBAQSPY4ahGwxRCjPPdLE0AABQJgh2OatR1QbADAKBg\nMeiWQcK2l+7d726fiqLIsjyckzkFJWm8pjYEAxMC2kRNmxgMHPde1/QZu/HMdQIAQGEi2GVg\nOmJdR6fXVbivUlEGf0GnbTOJHQAAhYtgdwypsyO4/q1wU2NTIGCNm6jPP9Nx6RbRsrKyYDDY\n1tY2bNPKpxxnr27u1vXdurHHMHan9AOmOfh/qVTks0tLCmASO9vWtmzStv5Z6uywakcai86x\nRo72uiYAALxHsDtKSnSW/vIJqbNDCFEjhNi3196+NfHNmx3VhTNYEVUNqqqjKPYwxqZRqnpG\nSWjY3m7YhF55Qftkc/rf8uFWbdunib/+pjW+wduqAADwHDdPHBVc94d0qusht7YE3n/Xq3qQ\nkdK4pyfV9Qi9/IJg+WoAQNEj2B2l7NubobExQyM8pGb6muRouxSPDX8xAADkFYJdLxkHSWU+\nojwz0Fi2xDcFACh2/C48ypowqX+jOWHisBeCwRiZrqWza2qdSGT4iwEAIK8Q7I5KnXuhXVHZ\nu8WuG6vPX+RVPcjIrhurzz+zd4ujqMmvft2regAAyB/cFXuUEwonlt2ufbBebWp0ZNmaMMmY\nt1Acb+43DL/Ukkvt+vHKZ5/InR32iFH6GWfZlVVeFwUAgPcIdsdwgkF98QW612XguIxpM4xp\nM7yuAgCA/MJQLAAAgE8Q7AAAAHyCYAcAAOATBDsAAACfINgBAAD4BMEOAADAJwh2AAAAPkGw\nAwAA8AmCHQAAgE8Q7AAAAHyCYAcAAOATBDsAAACfINgBAAD4BMEOAADAJwh2AAAAPkGwAwAA\n8AmCHQAAgE8Q7AAAAHyCYAcAAOATBDsAAACfINgBAAD4BMEOAADAJwh2AAAAPkGwAwAA8AmC\nHQAAgE8Q7AAAAHyCYAcAAOATqtcFII/IbUeCG96SWg6IcIkxZboxd4GQif4AABQMgh26KS0H\nw//5pGSawhFCEsqeXWrjnq6v/5XXdQEAgBPF+Rh0C77ygmSaQgghdbeon3+mbt/qYUkAAOCk\nEOwghBCSaSoH9vdvVxr3DH8xAABgaAh2+JIknWgjAADISwQ7CCGEo6rWmLH9263xE4e9FgAA\nMEQEO3RLXnKFo2m9W4wZs83J07yqBwAAnCzuikU3e8TIzhu/Hdy4Xj7Y7ITC5rQZxqw5XhcF\nAABOAsEORzkVlcmLvup1FQAAYIgYigUAAPAJgh0AAIBPEOwAAAB8gmvsjiF1dQU2vKXub3Rk\nxRzfYCw8u8+NogAAAHmLYHeU1JUo/eX/leLx9ENl3151+9aub97sKHxKAACgADAUe1Rw3dqe\nVJemHDoYeH+9V/UAAACcFILdURnXRVUadw97IQAAAENBsOsl47KoLJYKAAAKBMHuqIzroprj\nMjQCAADkIYLdUclzlzjlFb1brFFjjDPO8qoeAACAk8L9nr2ESzqX3RZ4f73StFfIijWhQV+w\nyFEUr8sCAAA4IQS7YzihcOq8JV5XAQAAMBQMxQIAAPgEwQ4AAMAn8m4otqOj44knnvj4448N\nw5g+ffry5ctHjhzpdVEAAAAFIO/O2D322GMtLS333nvvI488UlJScv/999u27XVRAAAABSC/\ngl1ra+vGjRtvu+22hoaGurq65cuXNzU1bdmyxeu6AAAACkB+Bbvt27drmtbQ0JB+WFZWVl9f\nv23bNm+rAgAAKAj5dY1dLBaLRCJSr1W8KioqotFoz8MNGzY89NBDPQ/vu+++2bNnD2uJQyXL\nshCioqLiuK8sILIsO45TUlLidSGuSf/shUKhYDDodS2ukSRJkqSqqiqvC3GTJEmKovhso2RZ\nrqysdBzH60Jckz7uRSIRP21UeocKhUJeF+Ka9HEvGAxqmuZ1LXBBfp2xE1/+hAEAAOBk5dcZ\nu8rKylgs5jhOT7yLRqO9/yhftGjRb37zm56H0Wi0ra1tuKsckkgkEgwGo9Gon+4FKS0tNU0z\nlUp5XYhrAoFAeXl5MplMJBJe1+IaRVFKS0tjsZjXhbippqbGtu1C2f1PUPoA6LNDRDgcjsfj\nhmF4XYtrQqGQJEldXV1eF+IaVVUrKytTqVRHR4frndfW1rreJwaXX2fspk6dahjGzp070w9j\nsVhjY+OMGTO8rQoAAKAg5Fewq66uPuuss37+85/v2rWrqanp0UcfnTx58qmnnup1XQAAAAUg\nv4ZihRB33nnnE0888eMf/9iyrJkzZ/7whz/kqjsAAIATkXfBrqSk5Hvf+57XVQAAABSe/BqK\nBQAAwJAR7AAAAHyCYAcAAOATBDsAAACfINgBAAD4BMEOAADAJwh2AAAAPkGwAwAA8AmCHQAA\ngE8Q7AAAAHyCYAcAAOATBDsAAACfINgBAAD4BMEOAADAJwh2AAAAPkGwAwAA8AmCHQAAgE9I\njuN4XUNRWLNmzdatW//mb/4mEol4XQsGtH379l/96lfnn3/+4sWLva4Fg/mnf/qncDj87W9/\n2+tCMJi1a9e+9957S5cura+v97oWDKilpWXFihVz58697LLLvK4FLuCM3TDZsGHDmjVrurq6\nvC4Eg2lubl6zZs22bdu8LgTH8bvf/e61117zugocx5YtW9asWXP48GGvC8FgYrHYmjVrNm3a\n5HUhcAfBDgAAwCcIdgAAAD5BsAMAAPAJbp4AAADwCc7YAQAA+ATBDgAAwCcIdgAAAD6hel2A\n/9155527d+/ueRgKhZ599lnvykFfTU1Njz766I4dO55//vmexo6OjieeeOLjjz82DGP69OnL\nly8fOXKkh0Ui49fEzpVXjhw5snLlys2bN+u6PmnSpBtvvHHatGmCvSn/DPRNsUP5A8Eu5zo6\nOm677bZFixalH8oyZ0nzyFtvvbVixYrTTz99x44dvdsfe+yxjo6Oe++9NxgMrl69+v777//n\nf/5nvjuvDPQ1sXPllQcffDAQCNx3333hcDi916xYsSIUCrE35ZuBvil2KH/ga8u5eDw+evTo\n2i9VV1d7XRGOMgzjH//xH3sOZGmtra0bN2687bbbGhoa6urqli9f3tTUtGXLFq+KRMavSbBz\n5ZN4PD5ixIjvfOc7kyZNGjNmzNKlS2OxWGNjI3tTvhnomxLsUH7BGbvcMgwjlUqtX7/+qaee\nisfjU6ZMWbp06dixY72uC92WLFkihNi5c2fvxu3bt2ua1tDQkH5YVlZWX1+/bdu2OXPmeFAi\nBvia2LnySiQSueeee3oeHj58WJbl2trarVu3sjfllYG+KXYo3+CMXW4lEonKykrTNO+44467\n7rpL1/V77rmns7PT67owmFgsFolEJEnqaamoqIhGox6WhP7YufJWPB7/2c9+dtVVV1VVVbE3\n5bPe3xQ7lG9wxi63KioqVq1a1fPwBz/4wbJly959992LL77Yw6pwXL1/DyE/sXPlp3379j3w\nwANz585dtmxZuoW9KT/1+abYoXyDYDeswuHwiBEjWltbvS4Eg6msrIzFYo7j9PxCikajVVVV\n3laFwbFz5YPNmzc//PDD119//RVXXJFuYW/KT/2/qT7YoQoXQ7G5tWfPnn/5l38xTTP9MJlM\nHjp0aPTo0d5WhcFNnTrVMIyeK7rSVxbPmDHD26rQBztXvvn0009/8pOf/O3f/m3vrMDelIcy\nflPsUL7BGbvcqq6uXr9+vWma1113nWVZq1atKisrO/vss72uC93a2tosy4rH40KI9N+mZWVl\n1dXVZ5111s9//vM777wzEAisWLFi8uTJp556qtfFFq+BviZ2rvyh6/pjjz125ZVXTpgwoec0\nD3tTHhrkm2KH8gfJcRyva/C5L7744he/+EX6Rsvp06ffeuuto0aN8roodLvllltaWlr6tFx5\n5ZWJROKJJ57YtGmTZVkzZ85cvnw5g0ceGuhrYufKH5s3b/7Rj37Up/H222+//PLL2ZvyyiDf\nFDuUPxDsAAAAfIJr7AAAAHyCYAcAAOATBDsAAACfINgBAAD4BMEOAADAJwh2AAAAPkGwAwAA\n8AmCHQD/uO6668rKyryuAgA8Q7ADAADwCYIdAACATxDsALigubn51ltvnTBhQigUGj169F/+\n5V9u3bo1/dT8+fPPOuus119/feHChSUlJdXV1TfddFM0Gu35v+vWrbv44ovLy8tLSkrmzZu3\ncuXK3j0P8qzjOPfff/+4ceNCodDs2bOfe+654dlYAMhbqtcFAPCDa665Zvfu3Q8++OCkSZOa\nm5v/4R/+4fzzz9+1a1dJSUkwGNyxY8ddd93105/+dNq0aS+//PJNN93U3t6+Zs0aIcTatWsv\nvfTSxYsXr169OhgMrlmz5uabb25ra/v+979/3GcfeeSRe++994YbbvjWt7515MiR++67zzAM\njz8IAPCU5DiO1zUAKGyxWKyiouLuu+9+6KGH0i07d+589tlnly1bVldXd84557zzzjtvvvnm\nueeem372lltuefLJJ/fu3Ttu3Lh58+bF4/HNmzeXlJSkn/3617/+xhtvtLS0hEKhQZ4NBoP1\n9fXV1dVbtmxJP9Xc3DxhwoRAINDR0TG8HwAA5AuGYgFkKxwO19TUPP3002vXrrVtWwgxefLk\ne+65p66uLv2C0tLSc845p+f15513nhDik08+aWlp2bRp0+WXXy7LcvJLl112WTwe37Jly+DP\nNjY27t+/f8mSJT3djhkzZsGCBcO76QCQXwh2ALKladpvfvMbWZYvuuiikSNHXnvttatXrzZN\ns+cFo0aNkiSp52FNTY0Q4uDBg/v37xdC/PSnPw33snz5ciHEvn37Bn/2wIEDQogRI0b0rqQn\nSgJAceIaOwAuWLx48fbt29etW/fSSy/9/ve/v+GGGx599NE333wzHA73f3E688ly9x+WN910\n06233trnNVOmTNm3b98gz+7cubN/z5ZlZb8tAFC4CHYA3KEoypIlS5YsWfLII488/vjjd9xx\nR/oyOyFEc3OzZVmKoqRfefDgQSHEqFGjxo8fL4SwLGvRokX9O0wnv4GejcViQoj0ebseu3fv\ndnejAKCwMBQLIFsffvjhdddd19LS0tNyySWXCCEOHTqUftjV1fXqq6/2PPvSSy8Fg8GFCxdW\nV1cvXLjw+eefb29v73l21apVP/zhD03THPzZiRMn1tbWvvzyy+mr+oQQn3/++ebNm3O6pQCQ\n55Qf//jHXtcAoLDJsnznnXe+8MILwWDw8OHDGzduvPvuu6PR6GOPPVZdXZ2eeW7t2rWaprW3\ntz/++OMrV6684YYbrr/+eiHEtGnTVq5c+eKLL5aWlh48ePDf//3f77rrrokTJ15zzTWDPytJ\nUkdHx/PPP//JJ59omrZu3brbb7998uTJra2tf//3f+/xJwIAXnEAIGubN2+++uqrR44cqWla\nXV3d1Vdf/dFHH6WfWrx48SmnnPLBBx+cd955JSUlVVVVt956azwe7/m/b7311sUXXxyJRDRN\nmzZt2sMPP2wYxok8a5rm3XffPXr06EAgMHv27F//+tff/e53A4HAcG44AOQV5rEDkFvnnHNO\na2trz0IUAIDc4Ro7AAAAnyDYAQAA+ATBDgAAwCe4xg4AAMAnOGMHAADgEwQ7AAAAnyDYAQAA\n+ATBDgAAwCcIdgAAAD5BsAMAAPAJgh0AAIBP/H9C2g1VvUywLwAAAABJRU5ErkJggg==" }, "metadata": { "image/png": { @@ -9425,30 +9498,30 @@ " fun = f,\n", " mapping = aes(color = \"model\"))" ], - "id": "3ea54e86-a1f2-41b6-90d8-450bd6549910" + "id": "7c3d4d9a-eff1-4702-949f-ee3f98a08281" }, { "cell_type": "code", - "execution_count": 266, + "execution_count": 229, "metadata": { - "id": "5d568ffb-f988-4712-a274-34d70c2bb48c", - "outputId": "7fff4a7d-99e5-4ed8-ac35-825a3fb9e61c", "colab": { "base_uri": "https://localhost:8080/", "height": 69 - } + }, + "id": "6dd21a1c-45bc-4c8d-93f3-e383848f1da8", + "outputId": "52039b8d-62bb-451e-f6b8-c4a3252300be" }, "outputs": [ { "output_type": "display_data", "data": { "text/html": [ - "47.5056249965197" + "13.9684451404354" ], - "text/markdown": "47.5056249965197", - "text/latex": "47.5056249965197", + "text/markdown": "13.9684451404354", + "text/latex": "13.9684451404354", "text/plain": [ - "[1] 47.5" + "[1] 14" ] }, "metadata": {} @@ -9457,12 +9530,12 @@ "output_type": "display_data", "data": { "text/html": [ - "0.690112906861635" + "0.700178893681743" ], - "text/markdown": "0.690112906861635", - "text/latex": "0.690112906861635", + "text/markdown": "0.700178893681743", + "text/latex": "0.700178893681743", "text/plain": [ - "[1] 0.69" + "[1] 0.7" ] }, "metadata": {} @@ -9471,12 +9544,12 @@ "output_type": "display_data", "data": { "text/html": [ - "0.694994374157731" + "0.701731426533392" ], - "text/markdown": "0.694994374157731", - "text/latex": "0.694994374157731", + "text/markdown": "0.701731426533392", + "text/latex": "0.701731426533392", "text/plain": [ - "[1] 0.695" + "[1] 0.702" ] }, "metadata": {} @@ -9494,28 +9567,28 @@ "R2(pred = y_, obs = y,\n", " form = \"corr\")" ], - "id": "5d568ffb-f988-4712-a274-34d70c2bb48c" + "id": "6dd21a1c-45bc-4c8d-93f3-e383848f1da8" }, { - "id": "cd524efc", + "id": "3f54daa7", "cell_type": "markdown", "source": [ "## 7.6 検証" ], "metadata": { - "id": "cd524efc" + "id": "3f54daa7" } }, { "cell_type": "code", - "execution_count": 267, + "execution_count": 230, "metadata": { - "id": "e6d3c31e-5dd9-4f22-b080-ba1c11fc2b81", - "outputId": "47e3ea3e-a5bf-4984-919a-bf31e74ca9d9", "colab": { "base_uri": "https://localhost:8080/", "height": 129 - } + }, + "id": "7753fb65-72a6-42b9-ae4c-4ffb2f4b6205", + "outputId": "b8975692-5d04-419d-ab14-801828e3ae0e" }, "outputs": [ { @@ -9529,15 +9602,15 @@ "\t<lgl><dbl><dbl><dbl><dbl><dbl><dbl>\n", "\n", "\n", - "\t1TRUE15.90.6612.42.570.122.05\n", + "\t1TRUE15.90.62912.32.220.122\n", "\n", "\n" ], - "text/markdown": "\nA data.frame: 1 × 7\n\n| | intercept <lgl> | RMSE <dbl> | Rsquared <dbl> | MAE <dbl> | RMSESD <dbl> | RsquaredSD <dbl> | MAESD <dbl> |\n|---|---|---|---|---|---|---|---|\n| 1 | TRUE | 15.9 | 0.66 | 12.4 | 2.57 | 0.12 | 2.05 |\n\n", - "text/latex": "A data.frame: 1 × 7\n\\begin{tabular}{r|lllllll}\n & intercept & RMSE & Rsquared & MAE & RMSESD & RsquaredSD & MAESD\\\\\n & & & & & & & \\\\\n\\hline\n\t1 & TRUE & 15.9 & 0.66 & 12.4 & 2.57 & 0.12 & 2.05\\\\\n\\end{tabular}\n", + "text/markdown": "\nA data.frame: 1 × 7\n\n| | intercept <lgl> | RMSE <dbl> | Rsquared <dbl> | MAE <dbl> | RMSESD <dbl> | RsquaredSD <dbl> | MAESD <dbl> |\n|---|---|---|---|---|---|---|---|\n| 1 | TRUE | 15.9 | 0.629 | 12.3 | 2.22 | 0.12 | 2 |\n\n", + "text/latex": "A data.frame: 1 × 7\n\\begin{tabular}{r|lllllll}\n & intercept & RMSE & Rsquared & MAE & RMSESD & RsquaredSD & MAESD\\\\\n & & & & & & & \\\\\n\\hline\n\t1 & TRUE & 15.9 & 0.629 & 12.3 & 2.22 & 0.12 & 2\\\\\n\\end{tabular}\n", "text/plain": [ " intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD\n", - "1 TRUE 15.9 0.66 12.4 2.57 0.12 2.05 " + "1 TRUE 15.9 0.629 12.3 2.22 0.12 2 " ] }, "metadata": {} @@ -9551,18 +9624,18 @@ "\n", "my_model$results" ], - "id": "e6d3c31e-5dd9-4f22-b080-ba1c11fc2b81" + "id": "7753fb65-72a6-42b9-ae4c-4ffb2f4b6205" }, { "cell_type": "code", - "execution_count": 268, + "execution_count": 231, "metadata": { - "id": "3683466c-3242-4318-8ca0-cbdaeb747436", - "outputId": "8493790b-e216-4538-bac0-fdc67cdb2858", "colab": { "base_uri": "https://localhost:8080/", "height": 129 - } + }, + "id": "4d66dc36-1c88-40de-a633-bbc45285fe0d", + "outputId": "fbf74156-94af-4cbb-ad2a-65cd9274d713" }, "outputs": [ { @@ -9576,15 +9649,15 @@ "\t<lgl><dbl><dbl><dbl><dbl><dbl><dbl>\n", "\n", "\n", - "\t1TRUE14.90.65611.63.970.1913.31\n", + "\t1TRUE14.70.696124.540.2483.13\n", "\n", "\n" ], - "text/markdown": "\nA data.frame: 1 × 7\n\n| | intercept <lgl> | RMSE <dbl> | Rsquared <dbl> | MAE <dbl> | RMSESD <dbl> | RsquaredSD <dbl> | MAESD <dbl> |\n|---|---|---|---|---|---|---|---|\n| 1 | TRUE | 14.9 | 0.656 | 11.6 | 3.97 | 0.191 | 3.31 |\n\n", - "text/latex": "A data.frame: 1 × 7\n\\begin{tabular}{r|lllllll}\n & intercept & RMSE & Rsquared & MAE & RMSESD & RsquaredSD & MAESD\\\\\n & & & & & & & \\\\\n\\hline\n\t1 & TRUE & 14.9 & 0.656 & 11.6 & 3.97 & 0.191 & 3.31\\\\\n\\end{tabular}\n", + "text/markdown": "\nA data.frame: 1 × 7\n\n| | intercept <lgl> | RMSE <dbl> | Rsquared <dbl> | MAE <dbl> | RMSESD <dbl> | RsquaredSD <dbl> | MAESD <dbl> |\n|---|---|---|---|---|---|---|---|\n| 1 | TRUE | 14.7 | 0.696 | 12 | 4.54 | 0.248 | 3.13 |\n\n", + "text/latex": "A data.frame: 1 × 7\n\\begin{tabular}{r|lllllll}\n & intercept & RMSE & Rsquared & MAE & RMSESD & RsquaredSD & MAESD\\\\\n & & & & & & & \\\\\n\\hline\n\t1 & TRUE & 14.7 & 0.696 & 12 & 4.54 & 0.248 & 3.13\\\\\n\\end{tabular}\n", "text/plain": [ - " intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD\n", - "1 TRUE 14.9 0.656 11.6 3.97 0.191 3.31 " + " intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD\n", + "1 TRUE 14.7 0.696 12 4.54 0.248 3.13 " ] }, "metadata": {} @@ -9595,18 +9668,18 @@ " trControl = trainControl(method = \"cv\", number = 5))\n", "my_model$results" ], - "id": "3683466c-3242-4318-8ca0-cbdaeb747436" + "id": "4d66dc36-1c88-40de-a633-bbc45285fe0d" }, { "cell_type": "code", - "execution_count": 269, + "execution_count": 232, "metadata": { - "id": "e975b84d-41f8-4a0f-b3e1-14c721801586", - "outputId": "d716f78f-2298-48e9-91b1-3686d965c612", "colab": { "base_uri": "https://localhost:8080/", "height": 129 - } + }, + "id": "4643044d-8edc-42f2-969d-ac6849451e1c", + "outputId": "c22d64f3-066d-459c-a8de-6b9da7c5b6ba" }, "outputs": [ { @@ -9639,17 +9712,17 @@ " trControl = trainControl(method = \"LOOCV\"))\n", "my_model$results" ], - "id": "e975b84d-41f8-4a0f-b3e1-14c721801586" + "id": "4643044d-8edc-42f2-969d-ac6849451e1c" }, { "cell_type": "code", - "execution_count": 270, + "execution_count": 233, "metadata": { - "id": "9098a54a-22b8-49d8-a505-9cd3f392e582", - "outputId": "277dcd8d-d070-40b7-8f07-d3e7fc3be359", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "a487ca56-b9d2-41d8-86cc-fd64bb74b8e2", + "outputId": "48a96fd3-ae47-4533-9f51-004c90015d87" }, "outputs": [ { @@ -9679,13 +9752,13 @@ "cl <- makeCluster(detectCores())\n", "registerDoParallel(cl)" ], - "id": "9098a54a-22b8-49d8-a505-9cd3f392e582" + "id": "a487ca56-b9d2-41d8-86cc-fd64bb74b8e2" }, { "cell_type": "code", - "execution_count": 271, + "execution_count": 234, "metadata": { - "id": "faf2b3aa-f8d9-442c-bd3f-d1b07bedf8bf" + "id": "3628dc2f-3e14-4527-82da-61cf309a1fcf" }, "outputs": [], "source": [ @@ -9696,30 +9769,30 @@ "y <- my_data$dist\n", "y_ <- my_model %>% predict(my_data)" ], - "id": "faf2b3aa-f8d9-442c-bd3f-d1b07bedf8bf" + "id": "3628dc2f-3e14-4527-82da-61cf309a1fcf" }, { "cell_type": "code", - "execution_count": 272, + "execution_count": 235, "metadata": { - "id": "b2058db1-70ad-4433-bed3-e95bc3db179a", - "outputId": "02226eab-8e87-4d7e-b9e9-252f190d13b1", "colab": { "base_uri": "https://localhost:8080/", "height": 69 - } + }, + "id": "ccae4bf2-a512-43fa-b002-54c77c15f69d", + "outputId": "476ee9a3-2a59-4d7a-f3d0-36ba5e754897" }, "outputs": [ { "output_type": "display_data", "data": { "text/html": [ - "47.6549008914939" + "15.0688559957914" ], - "text/markdown": "47.6549008914939", - "text/latex": "47.6549008914939", + "text/markdown": "15.0688559957914", + "text/latex": "15.0688559957914", "text/plain": [ - "[1] 47.7" + "[1] 15.1" ] }, "metadata": {} @@ -9765,18 +9838,18 @@ "R2(pred = y_, obs = y,\n", " form = \"corr\")" ], - "id": "b2058db1-70ad-4433-bed3-e95bc3db179a" + "id": "ccae4bf2-a512-43fa-b002-54c77c15f69d" }, { "cell_type": "code", - "execution_count": 273, + "execution_count": 236, "metadata": { - "id": "643a7cbd-66fb-43a8-9f51-f768300c7887", - "outputId": "719e9fc8-6ff0-46b4-8ffb-999b6922609d", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "8592f7c4-6174-4f3c-b69b-909544c66228", + "outputId": "24f6746b-8f2d-441d-cf6e-e174cc6e3f85" }, "outputs": [ { @@ -9803,18 +9876,18 @@ "source": [ "postResample(pred = y_, obs = y)" ], - "id": "643a7cbd-66fb-43a8-9f51-f768300c7887" + "id": "8592f7c4-6174-4f3c-b69b-909544c66228" }, { "cell_type": "code", - "execution_count": 274, + "execution_count": 237, "metadata": { - "id": "82c0f430-0575-446e-9582-91d6f44dbffb", - "outputId": "a788ee10-048b-4ef1-fe8e-fe791e415ca1", "colab": { "base_uri": "https://localhost:8080/", "height": 129 - } + }, + "id": "3f3e57bc-4fae-4003-8db3-c99ca05e4729", + "outputId": "64b94c5d-8b01-45bc-d85c-8a350e17858a" }, "outputs": [ { @@ -9828,15 +9901,15 @@ "\t<lgl><dbl><dbl><dbl><dbl><dbl><dbl>\n", "\n", "\n", - "\t1TRUE15.90.65712.32.140.1051.52\n", + "\t1TRUE15.10.64811.72.370.1221.89\n", "\n", "\n" ], - "text/markdown": "\nA data.frame: 1 × 7\n\n| | intercept <lgl> | RMSE <dbl> | Rsquared <dbl> | MAE <dbl> | RMSESD <dbl> | RsquaredSD <dbl> | MAESD <dbl> |\n|---|---|---|---|---|---|---|---|\n| 1 | TRUE | 15.9 | 0.657 | 12.3 | 2.14 | 0.105 | 1.52 |\n\n", - "text/latex": "A data.frame: 1 × 7\n\\begin{tabular}{r|lllllll}\n & intercept & RMSE & Rsquared & MAE & RMSESD & RsquaredSD & MAESD\\\\\n & & & & & & & \\\\\n\\hline\n\t1 & TRUE & 15.9 & 0.657 & 12.3 & 2.14 & 0.105 & 1.52\\\\\n\\end{tabular}\n", + "text/markdown": "\nA data.frame: 1 × 7\n\n| | intercept <lgl> | RMSE <dbl> | Rsquared <dbl> | MAE <dbl> | RMSESD <dbl> | RsquaredSD <dbl> | MAESD <dbl> |\n|---|---|---|---|---|---|---|---|\n| 1 | TRUE | 15.1 | 0.648 | 11.7 | 2.37 | 0.122 | 1.89 |\n\n", + "text/latex": "A data.frame: 1 × 7\n\\begin{tabular}{r|lllllll}\n & intercept & RMSE & Rsquared & MAE & RMSESD & RsquaredSD & MAESD\\\\\n & & & & & & & \\\\\n\\hline\n\t1 & TRUE & 15.1 & 0.648 & 11.7 & 2.37 & 0.122 & 1.89\\\\\n\\end{tabular}\n", "text/plain": [ " intercept RMSE Rsquared MAE RMSESD RsquaredSD MAESD\n", - "1 TRUE 15.9 0.657 12.3 2.14 0.105 1.52 " + "1 TRUE 15.1 0.648 11.7 2.37 0.122 1.89 " ] }, "metadata": {} @@ -9847,18 +9920,18 @@ "my_model$results\n", "# 左から,RMSE(検証),決定係数6(検証),MAE(検証)" ], - "id": "82c0f430-0575-446e-9582-91d6f44dbffb" + "id": "3f3e57bc-4fae-4003-8db3-c99ca05e4729" }, { "cell_type": "code", - "execution_count": 275, + "execution_count": 238, "metadata": { - "id": "79836209-c487-46f0-9b67-b18052fb30b1", - "outputId": "bc35b159-3ee0-477d-f2c9-81ab22234877", "colab": { "base_uri": "https://localhost:8080/", - "height": 147 - } + "height": 146 + }, + "id": "687d4c3b-1f77-475a-a233-1e8100c7b145", + "outputId": "95dd9175-41f7-4110-a02b-417dfe964386" }, "outputs": [ { @@ -9912,18 +9985,18 @@ "y_ <- my_model$pred$pred\n", "mean((y - y_)^2)**0.5" ], - "id": "79836209-c487-46f0-9b67-b18052fb30b1" + "id": "687d4c3b-1f77-475a-a233-1e8100c7b145" }, { "cell_type": "code", - "execution_count": 276, + "execution_count": 239, "metadata": { - "id": "d518b464-ac8d-4f03-9817-67704f42dcec", - "outputId": "ab4ba0b1-638d-4e82-f274-c732790b3fbe", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "4bf36f9c-8bd9-43a6-ad9e-76a2d3b0fce7", + "outputId": "d96f8d0a-0811-4c81-e6fa-615d3611ee4f" }, "outputs": [ { @@ -9944,13 +10017,13 @@ "source": [ "mean(((y - y_)^2)**0.5)" ], - "id": "d518b464-ac8d-4f03-9817-67704f42dcec" + "id": "4bf36f9c-8bd9-43a6-ad9e-76a2d3b0fce7" }, { "cell_type": "code", - "execution_count": 277, + "execution_count": 240, "metadata": { - "id": "7ee15e63-0708-490e-ae55-657d5984e78a" + "id": "972f259b-cfeb-46b2-b4ff-8a12f238173c" }, "outputs": [], "source": [ @@ -9965,18 +10038,18 @@ " tuneGrid = data.frame(k = 5),\n", " trControl = trainControl(method = \"LOOCV\"))" ], - "id": "7ee15e63-0708-490e-ae55-657d5984e78a" + "id": "972f259b-cfeb-46b2-b4ff-8a12f238173c" }, { "cell_type": "code", - "execution_count": 278, + "execution_count": 241, "metadata": { - "id": "1912de65-59db-4369-b63f-f8fdb56631e6", - "outputId": "ad3979ff-ed67-451f-f3ab-ebd66ef3f728", "colab": { "base_uri": "https://localhost:8080/", "height": 52 - } + }, + "id": "97306e53-7deb-4259-b5f9-2f99b756db38", + "outputId": "3439cff2-859d-40c1-ac01-2e22a05aa4c0" }, "outputs": [ { @@ -10013,18 +10086,18 @@ "\n", "my_knn_model$results$RMSE" ], - "id": "1912de65-59db-4369-b63f-f8fdb56631e6" + "id": "97306e53-7deb-4259-b5f9-2f99b756db38" }, { "cell_type": "code", - "execution_count": 279, + "execution_count": 242, "metadata": { - "id": "35498df9-3057-440f-bd0b-2af68aa6897a", - "outputId": "9a806479-bace-4c40-90be-86ef842f1ce8", "colab": { "base_uri": "https://localhost:8080/", "height": 286 - } + }, + "id": "2778cbd1-e1b8-497f-99a6-605c374e2856", + "outputId": "ff9c94df-4249-4274-ae61-cd07ed755efa" }, "outputs": [ { @@ -10073,18 +10146,18 @@ "\n", "head(my_df)" ], - "id": "35498df9-3057-440f-bd0b-2af68aa6897a" + "id": "2778cbd1-e1b8-497f-99a6-605c374e2856" }, { "cell_type": "code", - "execution_count": 280, + "execution_count": 243, "metadata": { - "id": "82b5ae07-8406-438d-9025-7aaa2b59ea53", - "outputId": "a834e95c-2d25-4ead-96fc-3d769ff16e61", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "d3445fd9-f6ad-45bb-b347-976b412464d7", + "outputId": "2ff55b29-2fa2-41e2-c9b0-55158dccdd01" }, "outputs": [ { @@ -10106,18 +10179,18 @@ "source": [ "boxplot(my_df, ylab = \"r^2\")" ], - "id": "82b5ae07-8406-438d-9025-7aaa2b59ea53" + "id": "d3445fd9-f6ad-45bb-b347-976b412464d7" }, { "cell_type": "code", - "execution_count": 281, + "execution_count": 244, "metadata": { - "id": "989c6d38-c145-4b43-b82d-69c7b071b758", - "outputId": "72894256-aeaa-46e3-bd29-a22c6a6e69db", "colab": { "base_uri": "https://localhost:8080/", - "height": 208 - } + "height": 215 + }, + "id": "6b0b5c2e-2d29-4dc0-9561-4588a56a74e5", + "outputId": "89084786-f6f4-4225-b22a-8f0d7fe2bde5" }, "outputs": [ { @@ -10146,28 +10219,28 @@ " paired = TRUE,\n", " alternative = \"two.sided\")\n" ], - "id": "989c6d38-c145-4b43-b82d-69c7b071b758" + "id": "6b0b5c2e-2d29-4dc0-9561-4588a56a74e5" }, { - "id": "ebe0a3ee", + "id": "0ea83b94", "cell_type": "markdown", "source": [ "## 7.7 パラメータチューニング" ], "metadata": { - "id": "ebe0a3ee" + "id": "0ea83b94" } }, { "cell_type": "code", - "execution_count": 282, + "execution_count": 245, "metadata": { - "id": "ac41117a-1b43-488c-a0ba-5da8e5ad5426", - "outputId": "7ebabe95-3584-48c4-c23f-a79a6efd41ea", "colab": { "base_uri": "https://localhost:8080/", "height": 192 - } + }, + "id": "a0559a26-b79b-47b3-801d-c8f0a49c9e8e", + "outputId": "710dfc81-a891-4ea8-ce2c-0036a0fd5fb5" }, "outputs": [ { @@ -10181,19 +10254,19 @@ "\t<int><dbl><dbl><dbl><dbl><dbl><dbl>\n", "\n", "\n", - "\t1517.00.62513.23.570.1302.61\n", - "\t2717.00.62213.23.570.1342.59\n", - "\t3917.40.61213.43.700.1372.52\n", + "\t1515.90.63212.42.600.1052.18\n", + "\t2716.20.62212.72.950.1112.33\n", + "\t3916.40.61912.83.170.1132.47\n", "\n", "\n" ], - "text/markdown": "\nA data.frame: 3 × 7\n\n| | k <int> | RMSE <dbl> | Rsquared <dbl> | MAE <dbl> | RMSESD <dbl> | RsquaredSD <dbl> | MAESD <dbl> |\n|---|---|---|---|---|---|---|---|\n| 1 | 5 | 17.0 | 0.625 | 13.2 | 3.57 | 0.130 | 2.61 |\n| 2 | 7 | 17.0 | 0.622 | 13.2 | 3.57 | 0.134 | 2.59 |\n| 3 | 9 | 17.4 | 0.612 | 13.4 | 3.70 | 0.137 | 2.52 |\n\n", - "text/latex": "A data.frame: 3 × 7\n\\begin{tabular}{r|lllllll}\n & k & RMSE & Rsquared & MAE & RMSESD & RsquaredSD & MAESD\\\\\n & & & & & & & \\\\\n\\hline\n\t1 & 5 & 17.0 & 0.625 & 13.2 & 3.57 & 0.130 & 2.61\\\\\n\t2 & 7 & 17.0 & 0.622 & 13.2 & 3.57 & 0.134 & 2.59\\\\\n\t3 & 9 & 17.4 & 0.612 & 13.4 & 3.70 & 0.137 & 2.52\\\\\n\\end{tabular}\n", + "text/markdown": "\nA data.frame: 3 × 7\n\n| | k <int> | RMSE <dbl> | Rsquared <dbl> | MAE <dbl> | RMSESD <dbl> | RsquaredSD <dbl> | MAESD <dbl> |\n|---|---|---|---|---|---|---|---|\n| 1 | 5 | 15.9 | 0.632 | 12.4 | 2.60 | 0.105 | 2.18 |\n| 2 | 7 | 16.2 | 0.622 | 12.7 | 2.95 | 0.111 | 2.33 |\n| 3 | 9 | 16.4 | 0.619 | 12.8 | 3.17 | 0.113 | 2.47 |\n\n", + "text/latex": "A data.frame: 3 × 7\n\\begin{tabular}{r|lllllll}\n & k & RMSE & Rsquared & MAE & RMSESD & RsquaredSD & MAESD\\\\\n & & & & & & & \\\\\n\\hline\n\t1 & 5 & 15.9 & 0.632 & 12.4 & 2.60 & 0.105 & 2.18\\\\\n\t2 & 7 & 16.2 & 0.622 & 12.7 & 2.95 & 0.111 & 2.33\\\\\n\t3 & 9 & 16.4 & 0.619 & 12.8 & 3.17 & 0.113 & 2.47\\\\\n\\end{tabular}\n", "text/plain": [ " k RMSE Rsquared MAE RMSESD RsquaredSD MAESD\n", - "1 5 17.0 0.625 13.2 3.57 0.130 2.61 \n", - "2 7 17.0 0.622 13.2 3.57 0.134 2.59 \n", - "3 9 17.4 0.612 13.4 3.70 0.137 2.52 " + "1 5 15.9 0.632 12.4 2.60 0.105 2.18 \n", + "2 7 16.2 0.622 12.7 2.95 0.111 2.33 \n", + "3 9 16.4 0.619 12.8 3.17 0.113 2.47 " ] }, "metadata": {} @@ -10206,13 +10279,13 @@ "my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\")\n", "my_model$results" ], - "id": "ac41117a-1b43-488c-a0ba-5da8e5ad5426" + "id": "a0559a26-b79b-47b3-801d-c8f0a49c9e8e" }, { "cell_type": "code", - "execution_count": 283, + "execution_count": 246, "metadata": { - "id": "5971e0f0-d9d8-49f6-8c35-ad11dda378b1" + "id": "cc1f8c95-68f3-4515-bf0d-3a7160c3afd6" }, "outputs": [], "source": [ @@ -10222,18 +10295,18 @@ " tuneGrid = my_params,\n", " trControl = trainControl(method = \"LOOCV\"))" ], - "id": "5971e0f0-d9d8-49f6-8c35-ad11dda378b1" + "id": "cc1f8c95-68f3-4515-bf0d-3a7160c3afd6" }, { "cell_type": "code", - "execution_count": 284, + "execution_count": 247, "metadata": { - "id": "b4b88185-935d-47b7-adc7-a66062fb3d16", - "outputId": "6effacd7-6db4-49d9-cedc-bf6ede7694ff", "colab": { "base_uri": "https://localhost:8080/", "height": 286 - } + }, + "id": "9ff42297-43ae-43e5-ab72-4d764c62c273", + "outputId": "2ca0e9c0-0965-41a6-8e41-37eca3ebf68f" }, "outputs": [ { @@ -10274,18 +10347,18 @@ "source": [ "head(my_model$results)" ], - "id": "b4b88185-935d-47b7-adc7-a66062fb3d16" + "id": "9ff42297-43ae-43e5-ab72-4d764c62c273" }, { "cell_type": "code", - "execution_count": 285, + "execution_count": 248, "metadata": { - "id": "b31a050f-bd17-4d6b-b885-3c12a8e25b13", - "outputId": "2d5d2a09-51d8-4a1b-dbe2-1e9d4674a43c", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "9ae94d33-100b-47ae-bc69-b8de5a86ad77", + "outputId": "29ad9259-21b0-42de-caa5-283cb1904087" }, "outputs": [ { @@ -10307,18 +10380,18 @@ "source": [ "ggplot(my_model)" ], - "id": "b31a050f-bd17-4d6b-b885-3c12a8e25b13" + "id": "9ae94d33-100b-47ae-bc69-b8de5a86ad77" }, { "cell_type": "code", - "execution_count": 286, + "execution_count": 249, "metadata": { - "id": "5cbc07b4-0405-4f3f-ae42-833b7731dacd", - "outputId": "0af6a3e9-cb90-4a22-956d-5bbc6df6417d", "colab": { "base_uri": "https://localhost:8080/", "height": 164 - } + }, + "id": "eb736cba-9583-42d9-b2f6-28b2e12cd86f", + "outputId": "e945be52-b201-4af0-b5f6-e704825007f9" }, "outputs": [ { @@ -10349,18 +10422,18 @@ "source": [ "my_model$bestTune" ], - "id": "5cbc07b4-0405-4f3f-ae42-833b7731dacd" + "id": "eb736cba-9583-42d9-b2f6-28b2e12cd86f" }, { "cell_type": "code", - "execution_count": 287, + "execution_count": 250, "metadata": { - "id": "c7fe15a7-a751-4e87-9394-a68c6b433310", - "outputId": "4c6118c0-a19f-4a7f-f76c-d2a08f60de11", "colab": { "base_uri": "https://localhost:8080/", "height": 129 - } + }, + "id": "2c184213-648e-4712-b2a9-6a3ed7ae98a2", + "outputId": "c9f0b931-ae88-41bc-e181-816da0b9aca0" }, "outputs": [ { @@ -10392,30 +10465,30 @@ "my_model$results %>%\n", " filter(RMSE == min(RMSE))" ], - "id": "c7fe15a7-a751-4e87-9394-a68c6b433310" + "id": "2c184213-648e-4712-b2a9-6a3ed7ae98a2" }, { "cell_type": "code", - "execution_count": 288, + "execution_count": 251, "metadata": { - "id": "2f2120a5-8f27-4cb3-bb41-35b3b0769a39", - "outputId": "5fa78704-2838-414f-93d3-c184c49114e9", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "2f65a922-d32d-46d2-a9f5-1e390a5f08d5", + "outputId": "882a19d2-4904-4be5-b19e-4df4e645cbdd" }, "outputs": [ { "output_type": "display_data", "data": { "text/html": [ - "48.2168140146676" + "13.9684451404354" ], - "text/markdown": "48.2168140146676", - "text/latex": "48.2168140146676", + "text/markdown": "13.9684451404354", + "text/latex": "13.9684451404354", "text/plain": [ - "[1] 48.2" + "[1] 14" ] }, "metadata": {} @@ -10426,13 +10499,13 @@ "y_ <- my_model %>% predict(my_data)\n", "RMSE(y_, y)" ], - "id": "2f2120a5-8f27-4cb3-bb41-35b3b0769a39" + "id": "2f65a922-d32d-46d2-a9f5-1e390a5f08d5" }, { "cell_type": "code", - "execution_count": 289, + "execution_count": 252, "metadata": { - "id": "ad109682-1cd0-4bb6-b7c6-d45e12845ad3" + "id": "ed1a64ad-eea1-4239-9034-e8e10d70bec8" }, "outputs": [], "source": [ @@ -10453,18 +10526,18 @@ "\n", "my_results <- 1:15 %>% map_dfr(my_loocv)" ], - "id": "ad109682-1cd0-4bb6-b7c6-d45e12845ad3" + "id": "ed1a64ad-eea1-4239-9034-e8e10d70bec8" }, { "cell_type": "code", - "execution_count": 290, + "execution_count": 253, "metadata": { - "id": "79f6ed12-0489-4e94-915e-70844f59b0f5", - "outputId": "473509e3-2a00-4db9-b5db-e7d03727f6dd", "colab": { "base_uri": "https://localhost:8080/", - "height": 506 - } + "height": 509 + }, + "id": "f208065f-0020-477b-a10f-ce5bc125f61d", + "outputId": "a9fd4a9b-dd0e-44b9-91ac-1ab11cb31927" }, "outputs": [ { @@ -10483,7 +10556,7 @@ "text/plain": [ "plot without title" ], - "image/png": "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\nm9+DVIf6+vpSqdTa2ur3INUhHo+nUinP8/wepArYth2JRNLpdKFQ8HuWKmBZVjgcTqfTfg/i\nG9M0E4nE6Z7tbIvdokWLKjAPAAAAKqKzsLvnnnt6awwAAAB8XGc4xk4I4XmeYRgnPnz11Vf3\n7dvX2Ng4derUSs4GAACAbjjDWbGPPvromDFjcrlc+WFbW9tFF110ySWX3Hbbbeeee+43vvGN\nyk8IAACALuks7P70pz/dfvvtruuWz4cVQnz/+99fsWLFl7/85Yceeujqq6/+yU9+8swzz/TK\nnAAAADiDzs6KnTt37q5du1atWlW+vonruoMHD548efIrr7wipXRdd8aMGaNGjXr22WcrPSVn\nxXJWbBdxVmy3cFZst3BWbLdwVmzXcVZst3BWbOdnxXa2xW7t2rVf+tKX2q9at2rVqqNHj955\n553ly6CYpnn99devXr26Z8cFAADAR9NZ2LW0tIwePbr94bJly4QQl19+efuSkSNH9vNtaQAA\nAH1HZ2FXW1t74lb0V155ZdiwYaNGjWpfkk6nTdOs3HAAAADous7CbuTIkcuXLy9/fOzYsRdf\nfPGyyy47cYVNmzaNGDGigtMBAACgyzoLuxtvvHHx4sVLlizZsWPHl770pUKhcNddd7U/u337\n9ieffPLSSy+t9IgAAADois7C7utf//qgQYPmz58/fvz4Z5555pZbbmk/wO7pp5++8MILpZT/\n+I//2CtzAgAA4Aw6u/NEfX39mjVrHnrooQMHDsycOXP+/PntT2UymUQi8cADD0yaNKnyQwIA\nAODMOruOXScKhUIwGCxf96QX9PNzb7mOXddxHbtu4Tp23cJ17LqF69h1Hdex6xauY9f5dezO\nfK/YUwqFQh91HgAAAFREZ2H3iU98oisv8eqrr/bQMAAAAPjoOgu71157zbKsxsbGUCjkuu5H\n22kLAACA3tFZ2H35y19esmTJhg0bPvWpT91888033XRTLBbrtckAAADQLZ1d7uTBBx88ePDg\nr371KyHEV77ylcGDBy9YsGDp0qWu6/bSdAAAAOiyzsJOCGHb9oIFC/7yl7+88847ixYtWr9+\n/ZVXXjly5MhvfetbGzdu7J0RAQAA0BVnCLt2w4cP/+d//uctW7asXLnyhhtueOihhxobG6dP\nn/7jH/+4ovMBAACgi7oadu1mzZr1n//5n7/85S9nzpy5YcOGb33rW5UYCwAAAN3VvbBbtWrV\n17/+9aFDh1533XUtLS333HPPzp07KzQZAAAAuqVLFyg+dOjQI488snjx4s2bN8disXnz5t15\n550XX3xxr915AgAAAGfUWdg5jvPcc88tXrz4T3/6k+d5l1122Xe+853rr7++pqam1+YDAABA\nF3UWdsOHDz927NicOXPuvffe+fPnDx8+vLw8n8+fuFo4HK7ggAAAAOiazsLuyJEjhmGsXLny\n9ddf/+53v3u61bgjBQAAQF/QWdgtWrSo1+YAAADAx9RZ2N1zzz29NQYAAAA+rm5fx66DPXv2\n9MQYAAAA+LjOEHbLli2bO3fu+PHj586d++c///nEpwqFwr/+679Onjy5kuMBAACgqzoLuxUr\nVnz6059+4YUXisXiX//616uuumrJkiXlp55//vlzzz33e9/73llnndUrcwIAAOAMOgu7f/u3\nf6upqVm3bt3evXvffffdmTNnLlq06N133503b97cuXOPHDly3333bdq0qddmBQAAQCc6O3li\nw4YNd911V2NjoxCioaHhBz/4wZVXXjl+/HjHcf7+7//+3nvvra+v7605AQAAcAadhd277747\nYcKE9oeTJk0SQsyZM+enP/3p1KlTKz4aAAAAuqOzXbGlUikYDLY/DIVCQohvf/vbVB0AAEAf\n9HEvdwIAAIA+grADAADQRGfH2Akhdu3atWLFivLHx44dE0Js3bo1Ho+fuM75559foeEAAADQ\ndVIpddrnpOzKS3TyCj2lubm50p+iL0skEi0tLX5PUR0ikYht28lk0nEcv2epAqFQKBAItLW1\n+T1Idaivry+VSq2trX4PUh3i8XgqlfI8z+9BqoBt25FIJJ1OFwoFv2epApZlhcPhdDrt9yC+\nMU0zkUic7tnOttgtWrSoAvMAAACgIjoLu3vuuae3xgAAAMDHxckTAAAAmiDsAAAANEHYAQAA\naIKwAwAA0ARhBwAAoAnCDgAAQBOEHQAAgCYIOwAAAE0QdgAAAJog7AAAADRB2AEAAGiCsAMA\nANAEYQcAAKAJwg4AAEAThB0AAIAmCDsAAABNEHYAAACaIOwAAAA0QdgBAABogrADAADQBGEH\nAACgCcIOAABAE4QdAACAJgg7AAAATRB2AAAAmiDsAAAANEHYAQAAaIKwAwAA0ARhBwAAoAnC\nDgAAQBOEHQAAgCYIOwAAAE0QdgAAAJog7AAAADRB2AEAAGiCsAMAANBEoNKfYN++fQ899NBb\n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\n7R4wYIDWIooix3FZWVlTpkzxvQFCs3Tp0q1bt86ePXvDhg2+8YsQ8tBDDz366KNNtu/atavv\nQ7fbTQih6Qt+9zY5Tuua7KuqqtaoHcQ3Avqu1R76JkJCyO23337ixInvvvtuy5Ytmzdvvv/+\n+5cuXfr9998bjUb/6wGA6weCHQB0dMXFxbt3737uued27NhBCJFlOSwszG63C4LQ4vadOnVa\nuHDhnDlzNm7c6M1JSUlJhBBFUfr169f604WHh5Pz/XZeeXl5/hdcWlrq8Xi8Wa20tJQQEhMT\nk5CQQAjx3u2h0R5qq1rEMMygQYMGDRr0+uuvL1++fNasWZ9++imG3AOAFuFULAAEgYMHD/bs\n2VNbPnLkSJcuXS6W6jSzZ8++6aabZs+e7e1pCw8P79Onz/r1631HHvnwww9ffPHFJic3U1NT\nrVbrli1bvC179+5tch1e6+rr63NycrwPN27cSNP0b37zm9jY2B49emzatMnlcnnXZmdnm0ym\n2267rflx9u/ff99995WXl3tbhg0bRgi54rH6AED3EOwAIAj4BrsDBw74jmDXIpZlly9ffvr0\n6d27d3sbX3vttYaGhoEDB3744YdfffXVvHnzHnnkkZKSEpZlm+z78MMPHz58+MEHH/zqq69W\nrFhx7733ei/vuySPx5OQkPD444+/++67OTk5c+fOXb9+/aRJk7Qr7ZYsWVJaWjp27NiNGzdu\n3bp11qxZW7dunTdvXmhoaPNDderUafPmzUOHDl25cuU333yzdu3aadOmhYaGjh8/3s9iAOB6\ng2AHAEEgNzf3soIdIeT2229/4IEHVJ/ZYwcOHLht27aYmJjHH3981KhRn3766SuvvNLiLGSv\nvvrqE088sWnTpgkTJnz88cdr165NTk728zI7t9udmJi4evXqf//736NHj16xYsUjjzyyYsUK\nbe2IESO2bt3a0NAwZcqUcePG7dmzZ+XKlXPnzm3xULGxsTt37tTuhB0xYsTTTz8dExOzffv2\nLl26+FMJAFyHKLXZnNkAANDEkCFDjhw54r13FQCgY0KPHQBAU8uWLbvnnnu8197V1NTs27fP\n22UIANBh4a5YAICmIiIisrOzx48f/+ijj7pcrmXLljkcDt9JwwAAOiYEOwCApqZOnUoIWbp0\n6ZQpU1RV7dmz56ZNm7T5vgAAOjJcYwcAAACgE7jGDgAAAEAnEOwAAAAAdALBDgAAAEAnEOwA\nAAAAdALBDgAAAEAnEOwAAAAAdALBDgAAAEAn/h/+SjqFNsd1HwAAAABJRU5ErkJggg==" + "image/png": "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\nQQAg/toqdocOHRoyZEjr02XLlgkh5s2b1zoyYMCA2traxIUDgPgya/abu6vcgUPc/F66swBA\n/LVV7LKzsz3Pa336/vvv9+vXb/Dgwa0jjY2NpmkmLhwAxJe97kMhRHTSFN1BACAh2ip2AwYM\nWLVqVcvjurq6d999d+7cuUevUFlZ2b9//wSmA4D4keGQtfkjlZ0TGz5SdxYASIi2it1VV131\n2GOPLVy4cOvWrTfffHMkErnxxhtbl3766afPPffcnDlzEh0RAOLCrlgnY050YrEwTjHTEwCk\nqbY+3W6//faePXtee+21I0aMePnllxcsWNB6gt1LL700ffp0KeUPf/jDpOQEgDPjeXZFmTJN\nZ/wk3VEAIFHauvNEfn5+WVnZ448/vnfv3uLi4muvvbZ10ZEjR/Ly8v7yl7+MGTMm8SEB4ExZ\n27YYDfXOuEKVkak7CwAkyiluKda9e/c77rjj+PFrrrnm61//umTSdgBpwldeKoRwuGwCQKd2\n6nvFnpDf749vDgBIHONgrblrh1cwwO3TT3cWAEigtordOeec055NfPDBB3EKAwAJ4SsvFUpF\nmZQYQGfXVrFbsWKFbduFhYV+v991XaVU0mIBQLzIaNTatEFldnNGjtWdBQASq61id8sttyxc\nuLCiouLcc8+97rrrrr766qysrKQlA4C4sDeul5FIpHiaYEJ1AJ1dW9OdPProo/v27fu///s/\nIcStt97au3fv66+//s0333RdN0npAOAMKWWXlwrTdCYU6Y4CAAl3ilk6g8Hg9ddf/9Zbb+3a\ntevee+9dv379V7/61QEDBtx5550bNmxITkQA6DBr53aj7qAzYrTigAOALqC9068XFBT8+Mc/\n3rRp05o1a6688srHH3+8sLBw4sSJv/3tbxOaDwDOhL2uVAjhFE3VHQQAkuG076szZcqU3/zm\nN3/961+Li4srKiruvPPORMQCgDNnHG6wPtvq9urtFgzQnQUAkuH0il1paentt9/et2/fyy67\n7NChQ/fdd9+2bdsSlAwAzpC9bo3wPKeoRHcQAEiSdk1QvH///ieffPKxxx776KOPsrKyrrnm\nmhtuuGHmzJnceQJAypIxx964XgWCsTFn6c4CAEnSVrFzHOf1119/7LHHFi1a5Hne3Llz7777\n7iuuuCIjIyNp+QCgY6yPKmUoFJ06Q1m27iwAkCRtFbuCgoK6urqSkpIHHnjg2muvLSgoaBkP\n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\nWQAASCeO4wghju4Mf/zjH8PhsOu6p7up7t27T5069aWXXqqvr28dfOKJJ+65555YLBaXtKkp\n4cXOcZzf/OY3x/TlxsbGnj17fve73x06dGjfvn2/9a1vHT58uKqqKtFhEk4p3wfvCSmj55yr\nOwoAAGlm+PDhAwYM+Mtf/vLKK6+sWLHizjvvfPHFF+fMmfPRRx8tXbq0qanptLb261//urm5\nefbs2U888cTbb7/9//7f/7v11lt3795tWZ35PLSEf29z584VQmzbtu3owaysrLvvvrv16cGD\nBw3DOPp0yG3bth08ePDziJY1bNiwROeMC6NyvXlgvzuu0CjoH8fKLKW0baY4bhfDMIQQnftN\nG0emaRqGwW9X+/FmbL+Wn9XR57zjZFrO9zdNk98u27ZffPHF73//+wsWLMjKyrr88stffvnl\nZcuW3XTTTVddddXq1atPa2uzZ89esmTJAw888L3vfS8cDg8ZMuShhx664447EhQ+RUilVBJe\nZvXq1b/85S+PPseuVWNj409+8pMpU6bceOONrYP33HPPm2++2fI4Ly+vdXqblOa60YcfUvWH\nfP/5/8ke+adeHwAAIK4079iorq5+8MEHJ06ceMMNNxw9fsEFF4wYMaLlcSAQON29r1oYa1cb\nB2u94pLmQFDENXAwGAyFQnHcYCfm8/ls2+7YCRldkGVZhmFEo1HdQdJDZmam53m8GdspGAyG\nw+Hk7DtId7Zt+3y+SCTSac79yszM1B2h69JZ7CoqKn79618vWLDg4osvPmbRrFmzZs2a1fq0\ntrY2udFOm4zFMpcvUZbVPOVsFe/P/UAgwN+Sdmo5sBiJRFrOwEXb/H6/ZVn8drUTxe60+P3+\ncDjModh28vl80Wg0EonoDhIfFDuNtBW7TZs2/epXv/rP//zP4uJiXRniyLd2tWxsjJaco7Ky\ndWcBAABdVMKL3aFDh1zXbWxsFP/a8datWzfDMB555JFLL7100KBBrXvjunXrlqb3bpPhsL12\nlQoEolPO1p0FAAB0XQkvdnfddVdNTU3L45tvvlkIceuttw4aNGjfvn1PPfXUU0891brmbbfd\n1nqL3/TiW7NChkKRmXNVMKg7CwAA6LoSXuweffTRE46/8soriX7p5JBNR+yyNSqzm1NcojsL\nAADo0hI+QXGn51+5TMacyNkzVZeffwgAAOhFsTsjRkO9XVnuZec4E4p0ZwEAAF0dxe6M+JYv\n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\nxnV4cpfIF54AAAAASUVORK5CYII=" }, "metadata": { "image/png": { @@ -10503,13 +10576,13 @@ " theme(legend.position = c(1, 0),\n", " legend.justification = c(1, 0))" ], - "id": "79f6ed12-0489-4e94-915e-70844f59b0f5" + "id": "f208065f-0020-477b-a10f-ce5bc125f61d" }, { "cell_type": "code", - "execution_count": 291, + "execution_count": 254, "metadata": { - "id": "2afedfc1-dfa4-4716-8eb8-1f7bf093fa9f" + "id": "10c01915-113a-4af2-aca7-03ab714a4b2a" }, "outputs": [], "source": [ @@ -10517,56 +10590,73 @@ "stopCluster(cl)\n", "registerDoSEQ()" ], - "id": "2afedfc1-dfa4-4716-8eb8-1f7bf093fa9f" + "id": "10c01915-113a-4af2-aca7-03ab714a4b2a" }, { - "id": "5f4eaf85", + "id": "ea88df27", "cell_type": "markdown", "source": [ "# 8 回帰2(重回帰)" ], "metadata": { - "id": "5f4eaf85" + "id": "ea88df27" } }, { "cell_type": "code", - "execution_count": 292, + "execution_count": 255, "metadata": { - "id": "4cc7db89-f2a6-4e52-a296-22cea7addff9" + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "379f2240-2aa4-492c-87e7-bbef33e4b5cc", + "outputId": "b9c1635f-110f-4f5f-8ce6-acf0752978fc" }, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "Installing packages into ‘/usr/local/lib/R/site-library’\n", + "(as ‘lib’ is unspecified)\n", + "\n", + "also installing the dependencies ‘gridExtra’, ‘RcppEigen’, ‘Deriv’\n", + "\n", + "\n" + ] + } + ], "source": [ "# Google Colaboratoryの環境設定\n", "if (file.exists(\"/content\")) {\n", " options(Ncpus = parallel::detectCores())\n", - " packages_to_install <- c(\"caret\", \"ggfortify\", \"glmnet\", \"glmnetUtils\", \"leaps\", \"neuralnet\", \"psych\")\n", " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"caret\", \"ggfortify\", \"glmnet\", \"glmnetUtils\", \"leaps\", \"neuralnet\", \"psych\")\n", " install.packages(setdiff(packages_to_install, installed_packages))\n", "}" ], - "id": "4cc7db89-f2a6-4e52-a296-22cea7addff9" + "id": "379f2240-2aa4-492c-87e7-bbef33e4b5cc" }, { - "id": "82815cd6", + "id": "279fba58", "cell_type": "markdown", "source": [ "## 8.1 ブドウの生育条件とワインの価格" ], "metadata": { - "id": "82815cd6" + "id": "279fba58" } }, { "cell_type": "code", - "execution_count": 293, + "execution_count": 256, "metadata": { - "id": "4273ae19-b303-4511-a55e-c44ce5ba88c0", - "outputId": "6ee569b8-612f-4503-b256-92981fb9d243", "colab": { "base_uri": "https://localhost:8080/", - "height": 318 - } + "height": 337 + }, + "id": "b4cdd59c-5582-447d-ad7e-4757bf9ede01", + "outputId": "09c30618-0881-4cc1-b7b9-d093491fa605" }, "outputs": [ { @@ -10624,18 +10714,18 @@ " nrows = 38) # 読み込む行数\n", "psych::describe(tmp)" ], - "id": "4273ae19-b303-4511-a55e-c44ce5ba88c0" + "id": "b4cdd59c-5582-447d-ad7e-4757bf9ede01" }, { "cell_type": "code", - "execution_count": 294, + "execution_count": 257, "metadata": { - "id": "59fb08b8-d7d8-42ff-9738-192400b8dd2a", - "outputId": "18d137d1-153b-4192-91a6-ac51bd461672", "colab": { "base_uri": "https://localhost:8080/", "height": 286 - } + }, + "id": "774c85de-89e3-4469-9a19-aa70446d9d33", + "outputId": "61311987-a414-4eeb-d3d0-b5eb6c8fd73a" }, "outputs": [ { @@ -10677,18 +10767,18 @@ "my_data <- na.omit(tmp[, -c(1, 2)])\n", "head(my_data)" ], - "id": "59fb08b8-d7d8-42ff-9738-192400b8dd2a" + "id": "774c85de-89e3-4469-9a19-aa70446d9d33" }, { "cell_type": "code", - "execution_count": 295, + "execution_count": 258, "metadata": { - "id": "f184ba87-7d4c-4941-b05d-7d4c4f242996", - "outputId": "dea69115-6079-4400-da8c-dbc905b711ce", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "40c05e43-7232-4a54-a4f1-206148569a7e", + "outputId": "cfcb5a01-179f-42c9-bc84-53eb5d283649" }, "outputs": [ { @@ -10714,29 +10804,29 @@ "source": [ "dim(my_data)" ], - "id": "f184ba87-7d4c-4941-b05d-7d4c4f242996" + "id": "40c05e43-7232-4a54-a4f1-206148569a7e" }, { "cell_type": "code", - "execution_count": 296, + "execution_count": 259, "metadata": { - "id": "ce146d55-f23f-4dde-83d1-688e9e73d846" + "id": "99996286-13cb-4fff-887e-4a205000b882" }, "outputs": [], "source": [ "my_data %>% write_csv(\"wine.csv\")" ], - "id": "ce146d55-f23f-4dde-83d1-688e9e73d846" + "id": "99996286-13cb-4fff-887e-4a205000b882" }, { "cell_type": "code", - "execution_count": 297, + "execution_count": 260, "metadata": { - "id": "cf838107-01a2-498a-a7d6-a9ed054942ac", - "outputId": "cf2c4ba4-351f-4d91-ed70-45dc6ff2cca2", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "b43b73da-3c6c-4375-8bf4-0987ff7bdebb", + "outputId": "3fedfa73-cb07-402d-b827-3c98edc9f921" }, "outputs": [ { @@ -10759,27 +10849,27 @@ " \"/fromzero/master/data/wine.csv\")\n", "my_data <- read_csv(my_url)" ], - "id": "cf838107-01a2-498a-a7d6-a9ed054942ac" + "id": "b43b73da-3c6c-4375-8bf4-0987ff7bdebb" }, { - "id": "fea096f8", + "id": "7d8ec028", "cell_type": "markdown", "source": [ "## 8.2 重回帰分析" ], "metadata": { - "id": "fea096f8" + "id": "7d8ec028" } }, { "cell_type": "code", - "execution_count": 298, + "execution_count": 261, "metadata": { - "id": "d71f906f-10d9-4476-bc8a-9d84a77c3ea3", - "outputId": "a4cc2dcf-6b1c-40b1-fd00-521d0047249f", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "d36b3c29-acaf-4e7e-8a16-a84746375d2d", + "outputId": "a2f574c4-8620-4a0c-861d-30b45217bd1e" }, "outputs": [ { @@ -10808,18 +10898,18 @@ " method = \"lm\",\n", " trControl = trainControl(method = \"LOOCV\"))" ], - "id": "d71f906f-10d9-4476-bc8a-9d84a77c3ea3" + "id": "d36b3c29-acaf-4e7e-8a16-a84746375d2d" }, { "cell_type": "code", - "execution_count": 299, + "execution_count": 262, "metadata": { - "id": "78924381-94e0-4f93-aa31-fa6cf3ef07b4", - "outputId": "d0a4d67a-0481-416b-8af0-d0bc912c0193", "colab": { "base_uri": "https://localhost:8080/", "height": 255 - } + }, + "id": "0c8623c4-6a3a-45cb-8115-ba99c60e56c0", + "outputId": "dbb431f4-46fb-4e64-ed72-340467a84ba4" }, "outputs": [ { @@ -10859,18 +10949,18 @@ "coef(my_model$finalModel) %>%\n", " as.data.frame" ], - "id": "78924381-94e0-4f93-aa31-fa6cf3ef07b4" + "id": "0c8623c4-6a3a-45cb-8115-ba99c60e56c0" }, { "cell_type": "code", - "execution_count": 300, + "execution_count": 263, "metadata": { - "id": "dd7cb69b-3391-4d1f-9011-73307de6ce70", - "outputId": "363e50e1-c96a-46f2-db4f-12afcef2c842", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "8711900e-222e-4771-aac5-6ac837440378", + "outputId": "8f53a5b9-47b5-4d37-ed70-03584b83a683" }, "outputs": [ { @@ -10895,30 +10985,30 @@ " HRAIN = 120, TIME_SV = 2)\n", "my_model %>% predict(my_test)" ], - "id": "dd7cb69b-3391-4d1f-9011-73307de6ce70" + "id": "8711900e-222e-4771-aac5-6ac837440378" }, { "cell_type": "code", - "execution_count": 301, + "execution_count": 264, "metadata": { - "id": "538ae62f-29d5-447b-8776-4ad2775eb1c9", - "outputId": "14d7d9e1-e636-4964-cd29-f97af2b452ca", "colab": { "base_uri": "https://localhost:8080/", "height": 69 - } + }, + "id": "cb7940b2-35c1-453c-8cd6-27f647930805", + "outputId": "a81fa4bd-94f1-43ef-ac04-67045ede50ef" }, "outputs": [ { "output_type": "display_data", "data": { "text/html": [ - "1.55837324076635" + "0.258616662013062" ], - "text/markdown": "1.55837324076635", - "text/latex": "1.55837324076635", + "text/markdown": "0.258616662013062", + "text/latex": "0.258616662013062", "text/plain": [ - "[1] 1.56" + "[1] 0.259" ] }, "metadata": {} @@ -10964,18 +11054,18 @@ "R2(pred = y_, obs = y,\n", " form = \"corr\")" ], - "id": "538ae62f-29d5-447b-8776-4ad2775eb1c9" + "id": "cb7940b2-35c1-453c-8cd6-27f647930805" }, { "cell_type": "code", - "execution_count": 302, + "execution_count": 265, "metadata": { - "id": "9738ad98-30b3-4f12-860a-7d82d79f932f", - "outputId": "4132e704-ad4e-4a0e-8a03-bd8339b0bd1f", "colab": { "base_uri": "https://localhost:8080/", "height": 129 - } + }, + "id": "b2f4a62e-7b3c-4f77-a0e1-aa8539bc4f75", + "outputId": "e76107f6-d13a-4641-f2f7-655aeaba26cc" }, "outputs": [ { @@ -11006,18 +11096,18 @@ "source": [ "my_model$results" ], - "id": "9738ad98-30b3-4f12-860a-7d82d79f932f" + "id": "b2f4a62e-7b3c-4f77-a0e1-aa8539bc4f75" }, { "cell_type": "code", - "execution_count": 303, + "execution_count": 266, "metadata": { - "id": "fc337752-9f5b-493a-9cb1-cf09dc3534a8", - "outputId": "0e7d1f3a-3ad6-48a0-f467-860163882eca", "colab": { "base_uri": "https://localhost:8080/", - "height": 209 - } + "height": 208 + }, + "id": "a96f0d55-68b0-4309-b298-c3d9b03bbbb3", + "outputId": "84a48e26-86e5-44a1-b932-28de33435dab" }, "outputs": [ { @@ -11056,28 +11146,28 @@ "matrix(b,\n", " dimnames = list(colnames(M)))" ], - "id": "fc337752-9f5b-493a-9cb1-cf09dc3534a8" + "id": "a96f0d55-68b0-4309-b298-c3d9b03bbbb3" }, { - "id": "519bf369", + "id": "b859ec38", "cell_type": "markdown", "source": [ "## 8.3 標準化" ], "metadata": { - "id": "519bf369" + "id": "b859ec38" } }, { "cell_type": "code", - "execution_count": 304, + "execution_count": 267, "metadata": { - "id": "f73fcbc4-1c33-42cc-9281-49bae8601769", - "outputId": "51b7ec4e-cc5d-482e-926c-79875708bc65", "colab": { "base_uri": "https://localhost:8080/", - "height": 559 - } + "height": 563 + }, + "id": "e1923c9f-3807-4823-955d-8903797d1dd2", + "outputId": "be148af1-0636-4d8e-d296-0a857ff6647c" }, "outputs": [ { @@ -11124,13 +11214,13 @@ " stat_summary(fun = mean, geom = \"point\", size = 3) +\n", " xlab(NULL)" ], - "id": "f73fcbc4-1c33-42cc-9281-49bae8601769" + "id": "e1923c9f-3807-4823-955d-8903797d1dd2" }, { "cell_type": "code", - "execution_count": 305, + "execution_count": 268, "metadata": { - "id": "48c1b86a-6fdc-4a38-b16a-7345e2caec1a" + "id": "9819300a-46bc-429f-948f-9fb4c1939bd0" }, "outputs": [], "source": [ @@ -11140,18 +11230,18 @@ " method = \"lm\",\n", " preProcess = c(\"center\", \"scale\"))" ], - "id": "48c1b86a-6fdc-4a38-b16a-7345e2caec1a" + "id": "9819300a-46bc-429f-948f-9fb4c1939bd0" }, { "cell_type": "code", - "execution_count": 306, + "execution_count": 269, "metadata": { - "id": "6d2941a3-2981-473d-bb58-045929a9b7d3", - "outputId": "2e689ce5-0065-45a3-ec7c-d3a630ba3d37", "colab": { "base_uri": "https://localhost:8080/", "height": 255 - } + }, + "id": "282283bc-e325-457a-8551-e41f821a3e49", + "outputId": "3bdeb473-d9c4-41fc-de0b-15edcf10b1c5" }, "outputs": [ { @@ -11191,18 +11281,18 @@ "coef(my_model$finalModel) %>%\n", " as.data.frame" ], - "id": "6d2941a3-2981-473d-bb58-045929a9b7d3" + "id": "282283bc-e325-457a-8551-e41f821a3e49" }, { "cell_type": "code", - "execution_count": 307, + "execution_count": 270, "metadata": { - "id": "c5f1dd71-5a1f-4ba1-96f4-fe276dbb270b", - "outputId": "1791858a-f7ee-4bc8-fcf8-af071931b7bc", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "b496b090-c1be-46d4-ba82-f27970687596", + "outputId": "a28a98d8-909e-4583-9816-502a874abe25" }, "outputs": [ { @@ -11227,28 +11317,28 @@ " HRAIN = 120, TIME_SV = 2)\n", "my_model %>% predict(my_test)" ], - "id": "c5f1dd71-5a1f-4ba1-96f4-fe276dbb270b" + "id": "b496b090-c1be-46d4-ba82-f27970687596" }, { - "id": "d431e3b9", + "id": "5b0a2ab0", "cell_type": "markdown", "source": [ "## 8.4 入力変数の数とモデルの良さ" ], "metadata": { - "id": "d431e3b9" + "id": "5b0a2ab0" } }, { "cell_type": "code", - "execution_count": 308, + "execution_count": 271, "metadata": { - "id": "337ba6fb-09f5-4359-8c4e-c65897089a59", - "outputId": "89cce72b-9328-4d4f-e2bb-a7ea841d0845", "colab": { "base_uri": "https://localhost:8080/", - "height": 408 - } + "height": 412 + }, + "id": "1d2314ce-930d-40ec-9909-dd587fb91d4f", + "outputId": "9b2bfac9-607d-4059-f431-77068fc5735b" }, "outputs": [ { @@ -11311,30 +11401,30 @@ " v2 = 0:(n - 1) %% 3)\n", "head(my_data2)" ], - "id": "337ba6fb-09f5-4359-8c4e-c65897089a59" + "id": "1d2314ce-930d-40ec-9909-dd587fb91d4f" }, { "cell_type": "code", - "execution_count": 309, + "execution_count": 272, "metadata": { - "id": "5da903a3-7dd5-4e8e-ab19-17fdd2253b15", - "outputId": "5e28bfdd-b20f-40ac-bb00-ceabb91bb8f7", "colab": { "base_uri": "https://localhost:8080/", "height": 52 - } + }, + "id": "63baa206-2408-4fe4-8dc8-17b1fb965182", + "outputId": "d14f6c6e-bbfa-491c-aff8-dce073429d65" }, "outputs": [ { "output_type": "display_data", "data": { "text/html": [ - "1.55877039490398" + "0.256212004750575" ], - "text/markdown": "1.55877039490398", - "text/latex": "1.55877039490398", + "text/markdown": "0.256212004750575", + "text/latex": "0.256212004750575", "text/plain": [ - "[1] 1.56" + "[1] 0.256" ] }, "metadata": {} @@ -11364,27 +11454,27 @@ "\n", "my_model2$results$RMSE" ], - "id": "5da903a3-7dd5-4e8e-ab19-17fdd2253b15" + "id": "63baa206-2408-4fe4-8dc8-17b1fb965182" }, { - "id": "b2f9867a", + "id": "3f208f93", "cell_type": "markdown", "source": [ "## 8.5 変数選択" ], "metadata": { - "id": "b2f9867a" + "id": "3f208f93" } }, { "cell_type": "code", - "execution_count": 310, + "execution_count": 273, "metadata": { - "id": "e4a6b0b6-08ad-47ec-a71f-a8adab63917a", - "outputId": "2891671c-5dbd-4a17-c172-7adbc682dbff", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "5a1305d0-1af5-4d7b-875b-f2db94543ff7", + "outputId": "908e4b24-90b8-4a05-99c0-3a4b2614dded" }, "outputs": [ { @@ -11411,18 +11501,18 @@ "my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2,\n", " v2 = 0:(n - 1) %% 3)" ], - "id": "e4a6b0b6-08ad-47ec-a71f-a8adab63917a" + "id": "5a1305d0-1af5-4d7b-875b-f2db94543ff7" }, { "cell_type": "code", - "execution_count": 311, + "execution_count": 274, "metadata": { - "id": "56b54f9d-4c9e-40cf-b3e1-ca0648796720", - "outputId": "7b87f790-2a3c-4556-fd52-993e6f9fc810", "colab": { "base_uri": "https://localhost:8080/", "height": 192 - } + }, + "id": "cf36f080-8614-4677-bfee-d0edde1849ef", + "outputId": "a326f089-1d66-412e-e9ff-4b1cbff5abdd" }, "outputs": [ { @@ -11463,27 +11553,27 @@ " tuneGrid = data.frame(nvmax = 1:6)) # 選択する変数の上限\n", "summary(my_model$finalModel)$outmat" ], - "id": "56b54f9d-4c9e-40cf-b3e1-ca0648796720" + "id": "cf36f080-8614-4677-bfee-d0edde1849ef" }, { - "id": "a3372c6a", + "id": "061ea0e0", "cell_type": "markdown", "source": [ "## 8.6 補足:正則化" ], "metadata": { - "id": "a3372c6a" + "id": "061ea0e0" } }, { "cell_type": "code", - "execution_count": 312, + "execution_count": 275, "metadata": { - "id": "d8e79e04-b908-439a-a43f-34b0f823fe64", - "outputId": "d6433af5-3ef7-4248-9e5d-8c10a785b099", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "01cf2326-fc3a-4afd-b88d-6cbdb0e213d5", + "outputId": "f46b72b9-6181-4dab-bd69-85c207e039e0" }, "outputs": [ { @@ -11507,13 +11597,13 @@ " \"/fromzero/master/data/wine.csv\")\n", "my_data <- read_csv(my_url)" ], - "id": "d8e79e04-b908-439a-a43f-34b0f823fe64" + "id": "01cf2326-fc3a-4afd-b88d-6cbdb0e213d5" }, { "cell_type": "code", - "execution_count": 313, + "execution_count": 276, "metadata": { - "id": "1d28288e-71b6-4c8d-9cb4-58652295760c" + "id": "54d36924-aa0c-4a41-a0a9-7707321ed393" }, "outputs": [], "source": [ @@ -11529,18 +11619,18 @@ " lambda = A,\n", " alpha = B))" ], - "id": "1d28288e-71b6-4c8d-9cb4-58652295760c" + "id": "54d36924-aa0c-4a41-a0a9-7707321ed393" }, { "cell_type": "code", - "execution_count": 314, + "execution_count": 277, "metadata": { - "id": "65466ec4-2159-4ea1-ba8e-e19b7a04d8d1", - "outputId": "02724cde-815e-43af-8d9a-e120b99e3008", "colab": { "base_uri": "https://localhost:8080/", - "height": 139 - } + "height": 143 + }, + "id": "71c8216a-b035-4fa4-9ea9-c8110e7ffe3b", + "outputId": "13f17be6-20a1-42e9-f6c9-c3469739aed7" }, "outputs": [ { @@ -11562,18 +11652,18 @@ "source": [ "coef(my_model$finalModel, A)" ], - "id": "65466ec4-2159-4ea1-ba8e-e19b7a04d8d1" + "id": "71c8216a-b035-4fa4-9ea9-c8110e7ffe3b" }, { "cell_type": "code", - "execution_count": 315, + "execution_count": 278, "metadata": { - "id": "3bf2785c-1263-4676-943f-744f76e5ab24", - "outputId": "0a1916fc-09f6-41a5-aa67-9cbe0ce68d2b", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "6d3b37b5-4293-4f84-89b6-04e97e0767a4", + "outputId": "5a33fa4a-00c2-42cb-a765-defd5ce32f4a" }, "outputs": [ { @@ -11597,18 +11687,18 @@ " HRAIN = 120, TIME_SV = 2)\n", "my_model %>% predict(my_test)" ], - "id": "3bf2785c-1263-4676-943f-744f76e5ab24" + "id": "6d3b37b5-4293-4f84-89b6-04e97e0767a4" }, { "cell_type": "code", - "execution_count": 316, + "execution_count": 279, "metadata": { - "id": "fc1caba4-968a-48e5-9b4f-14d9f7707b88", - "outputId": "65f9c198-a293-4ff0-f346-701809540832", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "e74f3dbe-15d0-471c-bf72-7846b8ac9780", + "outputId": "9c5db196-90ae-420c-a190-945938263695" }, "outputs": [ { @@ -11644,18 +11734,18 @@ " xlab(\"log A ( = log lambda)\") +\n", " theme(legend.position = c(0.15, 0.25))" ], - "id": "fc1caba4-968a-48e5-9b4f-14d9f7707b88" + "id": "e74f3dbe-15d0-471c-bf72-7846b8ac9780" }, { "cell_type": "code", - "execution_count": 317, + "execution_count": 280, "metadata": { - "id": "1f29c330-7ca2-4c76-9d5f-45fdfc9bc6d1", - "outputId": "5c8c19bf-050b-424f-d0ca-536872fe6d03", "colab": { "base_uri": "https://localhost:8080/", - "height": 147 - } + "height": 146 + }, + "id": "e6ec587d-3448-4356-800c-30101e758c23", + "outputId": "bc5aeb3b-e7d6-424e-8982-c8dd6e4b3d3a" }, "outputs": [ { @@ -11694,18 +11784,18 @@ "\n", "my_model$bestTune" ], - "id": "1f29c330-7ca2-4c76-9d5f-45fdfc9bc6d1" + "id": "e6ec587d-3448-4356-800c-30101e758c23" }, { "cell_type": "code", - "execution_count": 318, + "execution_count": 281, "metadata": { - "id": "d8d2475f-75ab-48bb-9298-0da92c5378db", - "outputId": "06b4f3dd-4e96-451d-8c05-1c1a024037de", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "d942dde7-2a49-49e6-abf0-1d1e4e640998", + "outputId": "cb3e6799-5aeb-47ee-a24d-8cca73132c36" }, "outputs": [ { @@ -11731,18 +11821,18 @@ " xlab(\"A ( = lambda)\") +\n", " guides(shape = guide_legend(tmp), color = guide_legend(tmp))" ], - "id": "d8d2475f-75ab-48bb-9298-0da92c5378db" + "id": "d942dde7-2a49-49e6-abf0-1d1e4e640998" }, { "cell_type": "code", - "execution_count": 319, + "execution_count": 282, "metadata": { - "id": "141f7edd-0b69-4890-a65d-34fd03ae3473", - "outputId": "e984ab38-f3ae-49dc-b3ca-cf5af1c0f339", "colab": { "base_uri": "https://localhost:8080/", "height": 349 - } + }, + "id": "18faf59f-03a9-4dc4-882a-da67947a1eb6", + "outputId": "01b31fd9-b64f-4d3a-c532-aa05bef8eadd" }, "outputs": [ { @@ -11788,28 +11878,28 @@ "my_model$results %>%\n", " filter(RMSE == min(RMSE))" ], - "id": "141f7edd-0b69-4890-a65d-34fd03ae3473" + "id": "18faf59f-03a9-4dc4-882a-da67947a1eb6" }, { - "id": "5c8cf2ac", + "id": "3cdeadb0", "cell_type": "markdown", "source": [ "## 8.7 ニューラルネットワーク" ], "metadata": { - "id": "5c8cf2ac" + "id": "3cdeadb0" } }, { "cell_type": "code", - "execution_count": 320, + "execution_count": 283, "metadata": { - "id": "f34efdee-53ce-4554-8db8-bada5a87c728", - "outputId": "a0b233ec-602b-4848-d83b-9cc5840c06dc", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "ed4cee84-4d3e-4734-97e3-94aa20787822", + "outputId": "a846fcb6-25b8-4574-c844-593149877c30" }, "outputs": [ { @@ -11831,17 +11921,17 @@ "source": [ "curve(1 / (1 + exp(-x)), -6, 6)" ], - "id": "f34efdee-53ce-4554-8db8-bada5a87c728" + "id": "ed4cee84-4d3e-4734-97e3-94aa20787822" }, { "cell_type": "code", - "execution_count": 321, + "execution_count": 284, "metadata": { - "id": "e2b8354f-9bdf-40cc-ad1b-44f5714532f6", - "outputId": "82a71df8-61e7-4346-f766-1ee57dc592bf", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "a4d8b731-55cb-4875-9fec-c1a2eab16bcd", + "outputId": "96357d7a-c1f5-4127-9685-e82512368357" }, "outputs": [ { @@ -11865,13 +11955,13 @@ " \"/fromzero/master/data/wine.csv\")\n", "my_data <- read_csv(my_url)" ], - "id": "e2b8354f-9bdf-40cc-ad1b-44f5714532f6" + "id": "a4d8b731-55cb-4875-9fec-c1a2eab16bcd" }, { "cell_type": "code", - "execution_count": 322, + "execution_count": 285, "metadata": { - "id": "f1070952-466c-4367-b1bb-890c802babe5" + "id": "56fd7f2c-ef8f-4fa0-b991-1d7f433e3a19" }, "outputs": [], "source": [ @@ -11882,18 +11972,18 @@ " trControl = trainControl(method = \"LOOCV\"))\n", "plot(my_model$finalModel) # 訓練済ネットワークの描画" ], - "id": "f1070952-466c-4367-b1bb-890c802babe5" + "id": "56fd7f2c-ef8f-4fa0-b991-1d7f433e3a19" }, { "cell_type": "code", - "execution_count": 323, + "execution_count": 286, "metadata": { - "id": "6ac57a3f-d2dc-44c5-8651-71c352f6a3d5", - "outputId": "c8dd616d-49a2-4a28-da96-3a559086b10a", "colab": { "base_uri": "https://localhost:8080/", "height": 192 - } + }, + "id": "510d326f-342e-4132-ba30-b4a4800878e6", + "outputId": "399a9bdc-cd8f-4c76-f8cd-e273c641d041" }, "outputs": [ { @@ -11907,19 +11997,19 @@ "\t<dbl><dbl><dbl><dbl><dbl><dbl>\n", "\n", "\n", - "\t11000.3200.7460.275\n", - "\t23000.3410.7370.263\n", - "\t35000.3130.7520.244\n", + "\t11000.3300.7260.278\n", + "\t23000.3620.7340.274\n", + "\t35000.3480.7050.282\n", "\n", "\n" ], - "text/markdown": "\nA data.frame: 3 × 6\n\n| | layer1 <dbl> | layer2 <dbl> | layer3 <dbl> | RMSE <dbl> | Rsquared <dbl> | MAE <dbl> |\n|---|---|---|---|---|---|---|\n| 1 | 1 | 0 | 0 | 0.320 | 0.746 | 0.275 |\n| 2 | 3 | 0 | 0 | 0.341 | 0.737 | 0.263 |\n| 3 | 5 | 0 | 0 | 0.313 | 0.752 | 0.244 |\n\n", - "text/latex": "A data.frame: 3 × 6\n\\begin{tabular}{r|llllll}\n & layer1 & layer2 & layer3 & RMSE & Rsquared & MAE\\\\\n & & & & & & \\\\\n\\hline\n\t1 & 1 & 0 & 0 & 0.320 & 0.746 & 0.275\\\\\n\t2 & 3 & 0 & 0 & 0.341 & 0.737 & 0.263\\\\\n\t3 & 5 & 0 & 0 & 0.313 & 0.752 & 0.244\\\\\n\\end{tabular}\n", + "text/markdown": "\nA data.frame: 3 × 6\n\n| | layer1 <dbl> | layer2 <dbl> | layer3 <dbl> | RMSE <dbl> | Rsquared <dbl> | MAE <dbl> |\n|---|---|---|---|---|---|---|\n| 1 | 1 | 0 | 0 | 0.330 | 0.726 | 0.278 |\n| 2 | 3 | 0 | 0 | 0.362 | 0.734 | 0.274 |\n| 3 | 5 | 0 | 0 | 0.348 | 0.705 | 0.282 |\n\n", + "text/latex": "A data.frame: 3 × 6\n\\begin{tabular}{r|llllll}\n & layer1 & layer2 & layer3 & RMSE & Rsquared & MAE\\\\\n & & & & & & \\\\\n\\hline\n\t1 & 1 & 0 & 0 & 0.330 & 0.726 & 0.278\\\\\n\t2 & 3 & 0 & 0 & 0.362 & 0.734 & 0.274\\\\\n\t3 & 5 & 0 & 0 & 0.348 & 0.705 & 0.282\\\\\n\\end{tabular}\n", "text/plain": [ " layer1 layer2 layer3 RMSE Rsquared MAE \n", - "1 1 0 0 0.320 0.746 0.275\n", - "2 3 0 0 0.341 0.737 0.263\n", - "3 5 0 0 0.313 0.752 0.244" + "1 1 0 0 0.330 0.726 0.278\n", + "2 3 0 0 0.362 0.734 0.274\n", + "3 5 0 0 0.348 0.705 0.282" ] }, "metadata": {} @@ -11928,13 +12018,13 @@ "source": [ "my_model$results" ], - "id": "6ac57a3f-d2dc-44c5-8651-71c352f6a3d5" + "id": "510d326f-342e-4132-ba30-b4a4800878e6" }, { "cell_type": "code", - "execution_count": 324, + "execution_count": 287, "metadata": { - "id": "75253c06-5c44-4c33-a386-f1f2bb05a7da" + "id": "e6b0ebc5-58cb-4b4c-8684-f50e3434774c" }, "outputs": [], "source": [ @@ -11948,18 +12038,18 @@ " layer2 = 0:2,\n", " layer3 = 0))" ], - "id": "75253c06-5c44-4c33-a386-f1f2bb05a7da" + "id": "e6b0ebc5-58cb-4b4c-8684-f50e3434774c" }, { "cell_type": "code", - "execution_count": 325, + "execution_count": 288, "metadata": { - "id": "9d9f45df-c6ca-4716-861c-05b4c20b0812", - "outputId": "72010e0a-f38c-4df4-8f1a-2e4dd22b782a", "colab": { "base_uri": "https://localhost:8080/", "height": 129 - } + }, + "id": "abd1a6ae-afa5-4fdc-aaf2-e81be2dc098e", + "outputId": "ee040a23-b0fe-4af6-9311-591659ba27b3" }, "outputs": [ { @@ -11973,15 +12063,15 @@ "\t<int><int><dbl><dbl><dbl><dbl>\n", "\n", "\n", - "\t3000.2480.8570.192\n", + "\t4000.250.8480.198\n", "\n", "\n" ], - "text/markdown": "\nA data.frame: 1 × 6\n\n| layer1 <int> | layer2 <int> | layer3 <dbl> | RMSE <dbl> | Rsquared <dbl> | MAE <dbl> |\n|---|---|---|---|---|---|\n| 3 | 0 | 0 | 0.248 | 0.857 | 0.192 |\n\n", - "text/latex": "A data.frame: 1 × 6\n\\begin{tabular}{llllll}\n layer1 & layer2 & layer3 & RMSE & Rsquared & MAE\\\\\n & & & & & \\\\\n\\hline\n\t 3 & 0 & 0 & 0.248 & 0.857 & 0.192\\\\\n\\end{tabular}\n", + "text/markdown": "\nA data.frame: 1 × 6\n\n| layer1 <int> | layer2 <int> | layer3 <dbl> | RMSE <dbl> | Rsquared <dbl> | MAE <dbl> |\n|---|---|---|---|---|---|\n| 4 | 0 | 0 | 0.25 | 0.848 | 0.198 |\n\n", + "text/latex": "A data.frame: 1 × 6\n\\begin{tabular}{llllll}\n layer1 & layer2 & layer3 & RMSE & Rsquared & MAE\\\\\n & & & & & \\\\\n\\hline\n\t 4 & 0 & 0 & 0.25 & 0.848 & 0.198\\\\\n\\end{tabular}\n", "text/plain": [ - " layer1 layer2 layer3 RMSE Rsquared MAE \n", - "1 3 0 0 0.248 0.857 0.192" + " layer1 layer2 layer3 RMSE Rsquared MAE \n", + "1 4 0 0 0.25 0.848 0.198" ] }, "metadata": {} @@ -11991,56 +12081,70 @@ "my_model$results %>%\n", " filter(RMSE == min(RMSE))" ], - "id": "9d9f45df-c6ca-4716-861c-05b4c20b0812" + "id": "abd1a6ae-afa5-4fdc-aaf2-e81be2dc098e" }, { - "id": "51088a5f", + "id": "a9630aa3", "cell_type": "markdown", "source": [ "# 9 分類1(多値分類)" ], "metadata": { - "id": "51088a5f" + "id": "a9630aa3" } }, { "cell_type": "code", - "execution_count": 326, + "execution_count": 289, "metadata": { - "id": "d31055b1-1523-4205-b9d1-95195908c959" + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "da8d2c4f-aa1d-4a15-b64b-36f135598018", + "outputId": "ced800b5-579c-40ce-ce17-887a31430e5e" }, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "Installing packages into ‘/usr/local/lib/R/site-library’\n", + "(as ‘lib’ is unspecified)\n", + "\n" + ] + } + ], "source": [ "# Google Colaboratoryの環境設定\n", "if (file.exists(\"/content\")) {\n", " options(Ncpus = parallel::detectCores())\n", - " packages_to_install <- c(\"caret\", \"furrr\", \"psych\", \"randomForest\", \"rpart.plot\", \"xgboost\")\n", " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"caret\", \"furrr\", \"psych\", \"randomForest\", \"rpart.plot\", \"xgboost\")\n", " install.packages(setdiff(packages_to_install, installed_packages))\n", "}" ], - "id": "d31055b1-1523-4205-b9d1-95195908c959" + "id": "da8d2c4f-aa1d-4a15-b64b-36f135598018" }, { - "id": "9a64115c", + "id": "fa17bbec", "cell_type": "markdown", "source": [ "## 9.1 アヤメのデータ" ], "metadata": { - "id": "9a64115c" + "id": "fa17bbec" } }, { "cell_type": "code", - "execution_count": 327, + "execution_count": 290, "metadata": { - "id": "9fe9a469-4733-4080-bbbf-dbf40c404978", - "outputId": "a534e286-7963-481c-dd3b-294800013f7e", "colab": { "base_uri": "https://localhost:8080/", "height": 286 - } + }, + "id": "650a8f09-bae6-45d0-af8f-133b5f89eca6", + "outputId": "8e471077-e8ae-450b-83bf-159375e6f793" }, "outputs": [ { @@ -12082,18 +12186,18 @@ "my_data <- iris\n", "head(my_data)" ], - "id": "9fe9a469-4733-4080-bbbf-dbf40c404978" + "id": "650a8f09-bae6-45d0-af8f-133b5f89eca6" }, { "cell_type": "code", - "execution_count": 328, + "execution_count": 291, "metadata": { - "id": "a9448fa6-0213-4271-8783-b4650146cbb0", - "outputId": "dff866c3-f9d9-4b59-d176-fcb52b764d2b", "colab": { "base_uri": "https://localhost:8080/", - "height": 255 - } + "height": 275 + }, + "id": "d859e5ee-f0c1-40ad-9d1d-e5cc4381f168", + "outputId": "17741982-3b29-4b83-8783-196f500965e9" }, "outputs": [ { @@ -12138,23 +12242,23 @@ "source": [ "psych::describe(my_data)" ], - "id": "a9448fa6-0213-4271-8783-b4650146cbb0" + "id": "d859e5ee-f0c1-40ad-9d1d-e5cc4381f168" }, { - "id": "3ec703a8", + "id": "20e5dc1f", "cell_type": "markdown", "source": [ "## 9.2 木による分類" ], "metadata": { - "id": "3ec703a8" + "id": "20e5dc1f" } }, { "cell_type": "code", - "execution_count": 329, + "execution_count": 292, "metadata": { - "id": "1d275a19-15ce-45ea-9abd-98670975347f" + "id": "6e74f98b-3801-4ffb-be78-9ed420162d06" }, "outputs": [], "source": [ @@ -12163,18 +12267,18 @@ "my_data <- iris\n", "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart\")" ], - "id": "1d275a19-15ce-45ea-9abd-98670975347f" + "id": "6e74f98b-3801-4ffb-be78-9ed420162d06" }, { "cell_type": "code", - "execution_count": 330, + "execution_count": 293, "metadata": { - "id": "438cad24-bb46-4cee-8180-87f2a6115676", - "outputId": "166905a3-7ff7-4669-c679-5abd6f61d38d", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "db506107-f8b0-4013-9deb-5a3508a6c30e", + "outputId": "d693e46c-1ead-4022-fd29-4222920cc5d1" }, "outputs": [ { @@ -12196,18 +12300,18 @@ "source": [ "rpart.plot::rpart.plot(my_model$finalModel, extra = 1)" ], - "id": "438cad24-bb46-4cee-8180-87f2a6115676" + "id": "db506107-f8b0-4013-9deb-5a3508a6c30e" }, { "cell_type": "code", - "execution_count": 331, + "execution_count": 294, "metadata": { - "id": "f14aa92a-c1e4-457b-b30d-8bec9a8d4760", - "outputId": "d68feec4-6a9f-4dc2-83ac-41cd15f70ef0", "colab": { "base_uri": "https://localhost:8080/", "height": 52 - } + }, + "id": "2b4f0351-be1b-42b9-8c2a-80ccd94c1bd1", + "outputId": "beb8ec7f-4873-4911-d618-1c29dddf4a46" }, "outputs": [ { @@ -12251,18 +12355,18 @@ "\n", "my_model %>% predict(my_test)" ], - "id": "f14aa92a-c1e4-457b-b30d-8bec9a8d4760" + "id": "2b4f0351-be1b-42b9-8c2a-80ccd94c1bd1" }, { "cell_type": "code", - "execution_count": 332, + "execution_count": 295, "metadata": { - "id": "41cf90d3-a2c8-46a7-b220-666105e5b560", - "outputId": "e71bcfdb-f86b-4372-f8f3-691daebc6edc", "colab": { "base_uri": "https://localhost:8080/", - "height": 161 - } + "height": 160 + }, + "id": "2541cbf3-b89e-4278-ba42-ba8588db7de1", + "outputId": "cae14fe3-ae5a-48a3-88a6-15cebc3dcec9" }, "outputs": [ { @@ -12296,28 +12400,28 @@ "my_model %>% predict(my_test,\n", " type = \"prob\")" ], - "id": "41cf90d3-a2c8-46a7-b220-666105e5b560" + "id": "2541cbf3-b89e-4278-ba42-ba8588db7de1" }, { - "id": "cc80a3b2", + "id": "03363422", "cell_type": "markdown", "source": [ "## 9.3 正解率" ], "metadata": { - "id": "cc80a3b2" + "id": "03363422" } }, { "cell_type": "code", - "execution_count": 333, + "execution_count": 296, "metadata": { - "id": "6b03a7e8-607c-4aa1-8a47-adee138c812c", - "outputId": "63adb9a2-fd47-45a8-81e3-be88fa90899c", "colab": { "base_uri": "https://localhost:8080/", - "height": 590 - } + "height": 612 + }, + "id": "50c7ea81-372c-4c09-901b-aa331fd75fb7", + "outputId": "9ddc1ee7-f6fa-4312-c7cb-b91d39fcd829" }, "outputs": [ { @@ -12379,18 +12483,18 @@ "confusionMatrix(data = y_, reference = y)\n", "# 以下は割愛" ], - "id": "6b03a7e8-607c-4aa1-8a47-adee138c812c" + "id": "50c7ea81-372c-4c09-901b-aa331fd75fb7" }, { "cell_type": "code", - "execution_count": 334, + "execution_count": 297, "metadata": { - "id": "375f0305-85bc-4c6b-8bf6-afcfc644997f", - "outputId": "8c6622c9-6c9b-45fe-e6ec-920daef313b2", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "32d598e9-f9d9-4b80-bc39-e1560c2d4377", + "outputId": "3ccc5481-26d1-4ed3-f46b-16b8041c68e3" }, "outputs": [ { @@ -12413,18 +12517,18 @@ "y_ <- my_model %>% predict(my_data)\n", "mean(y_ == y)" ], - "id": "375f0305-85bc-4c6b-8bf6-afcfc644997f" + "id": "32d598e9-f9d9-4b80-bc39-e1560c2d4377" }, { "cell_type": "code", - "execution_count": 335, + "execution_count": 298, "metadata": { - "id": "8a60dc75-e18d-4b76-8e0f-117da6af4725", - "outputId": "fe9a0523-7fa4-4d68-da66-2d8e6124e047", "colab": { "base_uri": "https://localhost:8080/", - "height": 213 - } + "height": 215 + }, + "id": "1ec7e210-99bc-4389-93d9-54e9d4176ac2", + "outputId": "df5998af-f468-46f6-ed25-6229349e98cd" }, "outputs": [ { @@ -12468,18 +12572,18 @@ " trControl = trainControl(method = \"LOOCV\"))\n", "my_model$results" ], - "id": "8a60dc75-e18d-4b76-8e0f-117da6af4725" + "id": "1ec7e210-99bc-4389-93d9-54e9d4176ac2" }, { "cell_type": "code", - "execution_count": 336, + "execution_count": 299, "metadata": { - "id": "4fcf7529-42a5-4dcb-99f4-8960fe3d5def", - "outputId": "85e4a15a-fbf1-410c-94b1-4f28830438b3", "colab": { "base_uri": "https://localhost:8080/", "height": 129 - } + }, + "id": "ea688a43-90b9-4831-97c4-6dd3e665842e", + "outputId": "68a5de8f-f621-4f6d-9e5e-c5a0f66d1cc1" }, "outputs": [ { @@ -12513,13 +12617,13 @@ " trControl = trainControl(method = \"LOOCV\"))\n", "my_model$results %>% filter(Accuracy == max(Accuracy))" ], - "id": "4fcf7529-42a5-4dcb-99f4-8960fe3d5def" + "id": "ea688a43-90b9-4831-97c4-6dd3e665842e" }, { "cell_type": "code", - "execution_count": 337, + "execution_count": 300, "metadata": { - "id": "32a6e5a1-36c6-410e-9ad2-b667edbec52d" + "id": "239dd8d3-7eee-40c0-873d-fa7db1fbe026" }, "outputs": [], "source": [ @@ -12537,18 +12641,18 @@ " Accuracy = my_model$results$Accuracy)\n", "}" ], - "id": "32a6e5a1-36c6-410e-9ad2-b667edbec52d" + "id": "239dd8d3-7eee-40c0-873d-fa7db1fbe026" }, { "cell_type": "code", - "execution_count": 338, + "execution_count": 301, "metadata": { - "id": "8b321bdd-723f-4128-9988-062ade717c1a", - "outputId": "4964af55-12c4-4935-c959-353336a540da", "colab": { "base_uri": "https://localhost:8080/", "height": 286 - } + }, + "id": "13f50948-0762-4bc3-a0f3-9b2014eece6f", + "outputId": "0bd636fd-7d56-452a-f408-8de30f4fb48c" }, "outputs": [ { @@ -12599,13 +12703,13 @@ "\n", "my_results %>% filter(Accuracy == max(Accuracy)) # 正解率(検証)の最大値" ], - "id": "8b321bdd-723f-4128-9988-062ade717c1a" + "id": "13f50948-0762-4bc3-a0f3-9b2014eece6f" }, { "cell_type": "code", - "execution_count": 339, + "execution_count": 302, "metadata": { - "id": "b899a9b0-5482-4d18-8039-3fc6bdc8660a" + "id": "ffe886ce-a444-4b7a-8bb1-7ed2f4fef7df" }, "outputs": [], "source": [ @@ -12616,18 +12720,18 @@ " minbucket = 5,\n", " minsplit = 2))" ], - "id": "b899a9b0-5482-4d18-8039-3fc6bdc8660a" + "id": "ffe886ce-a444-4b7a-8bb1-7ed2f4fef7df" }, { "cell_type": "code", - "execution_count": 340, + "execution_count": 303, "metadata": { - "id": "7bfbb978-c73d-4f70-9457-faf41e47220b", - "outputId": "1e5444b5-1885-4e98-dd7d-2939493081cb", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "8c7d8162-9fe2-4645-b10c-079fad793141", + "outputId": "a8fd2e4b-a1e5-4082-defa-291a24a47094" }, "outputs": [ { @@ -12650,28 +12754,28 @@ "rpart.plot::rpart.plot(\n", " my_model$finalModel, extra = 1)" ], - "id": "7bfbb978-c73d-4f70-9457-faf41e47220b" + "id": "8c7d8162-9fe2-4645-b10c-079fad793141" }, { - "id": "9df15a81", + "id": "35362e76", "cell_type": "markdown", "source": [ "## 9.4 複数の木を使う方法" ], "metadata": { - "id": "9df15a81" + "id": "35362e76" } }, { "cell_type": "code", - "execution_count": 341, + "execution_count": 304, "metadata": { - "id": "8dc1d856-c69e-4baa-856b-22b4c7a90b4d", - "outputId": "9f4edda0-7112-4212-aa3d-38257af028d6", "colab": { "base_uri": "https://localhost:8080/", "height": 192 - } + }, + "id": "c0370be0-073f-43a7-8b6b-3402c28330ef", + "outputId": "91c0ffcd-0c9e-49b8-8098-e7c21eeb1367" }, "outputs": [ { @@ -12685,19 +12789,19 @@ "\t<int><dbl><dbl>\n", "\n", "\n", - "\t120.9530.93\n", - "\t230.9600.94\n", - "\t340.9600.94\n", + "\t120.960.94\n", + "\t230.960.94\n", + "\t340.960.94\n", "\n", "\n" ], - "text/markdown": "\nA data.frame: 3 × 3\n\n| | mtry <int> | Accuracy <dbl> | Kappa <dbl> |\n|---|---|---|---|\n| 1 | 2 | 0.953 | 0.93 |\n| 2 | 3 | 0.960 | 0.94 |\n| 3 | 4 | 0.960 | 0.94 |\n\n", - "text/latex": "A data.frame: 3 × 3\n\\begin{tabular}{r|lll}\n & mtry & Accuracy & Kappa\\\\\n & & & \\\\\n\\hline\n\t1 & 2 & 0.953 & 0.93\\\\\n\t2 & 3 & 0.960 & 0.94\\\\\n\t3 & 4 & 0.960 & 0.94\\\\\n\\end{tabular}\n", + "text/markdown": "\nA data.frame: 3 × 3\n\n| | mtry <int> | Accuracy <dbl> | Kappa <dbl> |\n|---|---|---|---|\n| 1 | 2 | 0.96 | 0.94 |\n| 2 | 3 | 0.96 | 0.94 |\n| 3 | 4 | 0.96 | 0.94 |\n\n", + "text/latex": "A data.frame: 3 × 3\n\\begin{tabular}{r|lll}\n & mtry & Accuracy & Kappa\\\\\n & & & \\\\\n\\hline\n\t1 & 2 & 0.96 & 0.94\\\\\n\t2 & 3 & 0.96 & 0.94\\\\\n\t3 & 4 & 0.96 & 0.94\\\\\n\\end{tabular}\n", "text/plain": [ " mtry Accuracy Kappa\n", - "1 2 0.953 0.93 \n", - "2 3 0.960 0.94 \n", - "3 4 0.960 0.94 " + "1 2 0.96 0.94 \n", + "2 3 0.96 0.94 \n", + "3 4 0.96 0.94 " ] }, "metadata": {} @@ -12713,384 +12817,384 @@ " trControl = trainControl(method = \"LOOCV\"))\n", "my_model$results" ], - "id": "8dc1d856-c69e-4baa-856b-22b4c7a90b4d" + "id": "c0370be0-073f-43a7-8b6b-3402c28330ef" }, { "cell_type": "code", - "execution_count": 342, + "execution_count": 305, "metadata": { - "id": "230afc19-1a45-44e6-95c4-270d4848a534", - "outputId": "89e345f4-ff64-4b30-d88d-8c38947483bf", "colab": { "base_uri": "https://localhost:8080/", "height": 1000 - } + }, + "id": "a8688ff3-024d-4d59-ad01-5a22d436746f", + "outputId": "0923a8f0-b7e2-4346-8657-f85a4c2ef69a" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:24:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:03] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:03] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:04] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:04] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:04] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:04] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:04] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:04] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:04] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:04] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:05] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:06] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:07] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n" + "[13:57:42] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:42] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:42] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:42] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:42] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:42] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:42] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:42] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:42] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:42] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:42] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:42] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:42] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:42] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:42] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:42] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:43] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:44] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:45] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:46] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:47] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:47] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:47] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:47] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:47] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:47] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:47] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:47] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:48] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:49] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:50] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:50] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:50] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:50] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:50] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:50] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:50] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:50] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:50] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:50] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:50] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:50] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:51] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:51] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:52] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:52] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:52] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:52] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:53] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:53] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:53] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:53] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:53] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:53] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:54] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:54] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:54] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:54] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:54] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:54] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:54] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:54] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:54] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:54] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:54] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:54] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:55] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:55] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:55] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:55] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:55] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:55] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:55] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:55] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:55] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:55] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:56] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:56] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:56] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:56] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:56] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:56] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:56] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:56] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:56] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:56] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:56] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:56] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:57] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:58] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:57:59] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:00] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:01] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:02] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n" ] }, { @@ -13098,40 +13202,40 @@ "data": { "text/html": [ "\n", - "\n", + "\n", "\n", - "\t\n", + "\t\n", "\n", "\n", - "\t\n", - "\t\n", - "\t\n", - "\t\n", - "\t\n", - "\t\n", - "\t\n", - "\t\n", - "\t\n", - "\t\n", - "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", + "\t\n", "\n", "
A matrix: 11 × 3 of type dblA matrix: 11 × 5 of type dbl
123
12345
eta 0.3000 0.3000 0.3000
max_depth 1.0000 1.0000 2.0000
gamma 0.0000 0.0000 0.0000
colsample_bytree 0.6000 0.8000 0.6000
min_child_weight 1.0000 1.0000 1.0000
subsample 1.0000 1.0000 0.5000
nrounds50.000050.000050.0000
Accuracy 0.9600 0.9600 0.9600
Kappa 0.9400 0.9400 0.9400
AccuracySD 0.0435 0.0435 0.0435
KappaSD 0.0652 0.0652 0.0652
eta 0.3000 0.3000 0.3000 0.300 0.3000
max_depth 1.0000 1.0000 1.0000 3.000 3.0000
gamma 0.0000 0.0000 0.0000 0.000 0.0000
colsample_bytree 0.6000 0.8000 0.8000 0.600 0.6000
min_child_weight 1.0000 1.0000 1.0000 1.000 1.0000
subsample 1.0000 0.7500 1.0000 0.500 0.7500
nrounds50.000050.000050.000050.00050.0000
Accuracy 0.9533 0.9533 0.9533 0.953 0.9533
Kappa 0.9300 0.9300 0.9300 0.930 0.9300
AccuracySD 0.0183 0.0183 0.0183 0.038 0.0183
KappaSD 0.0274 0.0274 0.0274 0.057 0.0274
\n" ], - "text/markdown": "\nA matrix: 11 × 3 of type dbl\n\n| | 1 | 2 | 3 |\n|---|---|---|---|\n| eta | 0.3000 | 0.3000 | 0.3000 |\n| max_depth | 1.0000 | 1.0000 | 2.0000 |\n| gamma | 0.0000 | 0.0000 | 0.0000 |\n| colsample_bytree | 0.6000 | 0.8000 | 0.6000 |\n| min_child_weight | 1.0000 | 1.0000 | 1.0000 |\n| subsample | 1.0000 | 1.0000 | 0.5000 |\n| nrounds | 50.0000 | 50.0000 | 50.0000 |\n| Accuracy | 0.9600 | 0.9600 | 0.9600 |\n| Kappa | 0.9400 | 0.9400 | 0.9400 |\n| AccuracySD | 0.0435 | 0.0435 | 0.0435 |\n| KappaSD | 0.0652 | 0.0652 | 0.0652 |\n\n", - "text/latex": "A matrix: 11 × 3 of type dbl\n\\begin{tabular}{r|lll}\n & 1 & 2 & 3\\\\\n\\hline\n\teta & 0.3000 & 0.3000 & 0.3000\\\\\n\tmax\\_depth & 1.0000 & 1.0000 & 2.0000\\\\\n\tgamma & 0.0000 & 0.0000 & 0.0000\\\\\n\tcolsample\\_bytree & 0.6000 & 0.8000 & 0.6000\\\\\n\tmin\\_child\\_weight & 1.0000 & 1.0000 & 1.0000\\\\\n\tsubsample & 1.0000 & 1.0000 & 0.5000\\\\\n\tnrounds & 50.0000 & 50.0000 & 50.0000\\\\\n\tAccuracy & 0.9600 & 0.9600 & 0.9600\\\\\n\tKappa & 0.9400 & 0.9400 & 0.9400\\\\\n\tAccuracySD & 0.0435 & 0.0435 & 0.0435\\\\\n\tKappaSD & 0.0652 & 0.0652 & 0.0652\\\\\n\\end{tabular}\n", + "text/markdown": "\nA matrix: 11 × 5 of type dbl\n\n| | 1 | 2 | 3 | 4 | 5 |\n|---|---|---|---|---|---|\n| eta | 0.3000 | 0.3000 | 0.3000 | 0.300 | 0.3000 |\n| max_depth | 1.0000 | 1.0000 | 1.0000 | 3.000 | 3.0000 |\n| gamma | 0.0000 | 0.0000 | 0.0000 | 0.000 | 0.0000 |\n| colsample_bytree | 0.6000 | 0.8000 | 0.8000 | 0.600 | 0.6000 |\n| min_child_weight | 1.0000 | 1.0000 | 1.0000 | 1.000 | 1.0000 |\n| subsample | 1.0000 | 0.7500 | 1.0000 | 0.500 | 0.7500 |\n| nrounds | 50.0000 | 50.0000 | 50.0000 | 50.000 | 50.0000 |\n| Accuracy | 0.9533 | 0.9533 | 0.9533 | 0.953 | 0.9533 |\n| Kappa | 0.9300 | 0.9300 | 0.9300 | 0.930 | 0.9300 |\n| AccuracySD | 0.0183 | 0.0183 | 0.0183 | 0.038 | 0.0183 |\n| KappaSD | 0.0274 | 0.0274 | 0.0274 | 0.057 | 0.0274 |\n\n", + "text/latex": "A matrix: 11 × 5 of type dbl\n\\begin{tabular}{r|lllll}\n & 1 & 2 & 3 & 4 & 5\\\\\n\\hline\n\teta & 0.3000 & 0.3000 & 0.3000 & 0.300 & 0.3000\\\\\n\tmax\\_depth & 1.0000 & 1.0000 & 1.0000 & 3.000 & 3.0000\\\\\n\tgamma & 0.0000 & 0.0000 & 0.0000 & 0.000 & 0.0000\\\\\n\tcolsample\\_bytree & 0.6000 & 0.8000 & 0.8000 & 0.600 & 0.6000\\\\\n\tmin\\_child\\_weight & 1.0000 & 1.0000 & 1.0000 & 1.000 & 1.0000\\\\\n\tsubsample & 1.0000 & 0.7500 & 1.0000 & 0.500 & 0.7500\\\\\n\tnrounds & 50.0000 & 50.0000 & 50.0000 & 50.000 & 50.0000\\\\\n\tAccuracy & 0.9533 & 0.9533 & 0.9533 & 0.953 & 0.9533\\\\\n\tKappa & 0.9300 & 0.9300 & 0.9300 & 0.930 & 0.9300\\\\\n\tAccuracySD & 0.0183 & 0.0183 & 0.0183 & 0.038 & 0.0183\\\\\n\tKappaSD & 0.0274 & 0.0274 & 0.0274 & 0.057 & 0.0274\\\\\n\\end{tabular}\n", "text/plain": [ - " 1 2 3 \n", - "eta 0.3000 0.3000 0.3000\n", - "max_depth 1.0000 1.0000 2.0000\n", - "gamma 0.0000 0.0000 0.0000\n", - "colsample_bytree 0.6000 0.8000 0.6000\n", - "min_child_weight 1.0000 1.0000 1.0000\n", - "subsample 1.0000 1.0000 0.5000\n", - "nrounds 50.0000 50.0000 50.0000\n", - "Accuracy 0.9600 0.9600 0.9600\n", - "Kappa 0.9400 0.9400 0.9400\n", - "AccuracySD 0.0435 0.0435 0.0435\n", - "KappaSD 0.0652 0.0652 0.0652" + " 1 2 3 4 5 \n", + "eta 0.3000 0.3000 0.3000 0.300 0.3000\n", + "max_depth 1.0000 1.0000 1.0000 3.000 3.0000\n", + "gamma 0.0000 0.0000 0.0000 0.000 0.0000\n", + "colsample_bytree 0.6000 0.8000 0.8000 0.600 0.6000\n", + "min_child_weight 1.0000 1.0000 1.0000 1.000 1.0000\n", + "subsample 1.0000 0.7500 1.0000 0.500 0.7500\n", + "nrounds 50.0000 50.0000 50.0000 50.000 50.0000\n", + "Accuracy 0.9533 0.9533 0.9533 0.953 0.9533\n", + "Kappa 0.9300 0.9300 0.9300 0.930 0.9300\n", + "AccuracySD 0.0183 0.0183 0.0183 0.038 0.0183\n", + "KappaSD 0.0274 0.0274 0.0274 0.057 0.0274" ] }, "metadata": {} @@ -13151,18 +13255,18 @@ " trControl = trainControl(method = \"cv\", number = 5)) # 5分割交差検証\n", "my_model$results %>% filter(Accuracy == max(Accuracy)) %>% head(5) %>% t" ], - "id": "230afc19-1a45-44e6-95c4-270d4848a534" + "id": "a8688ff3-024d-4d59-ad01-5a22d436746f" }, { "cell_type": "code", - "execution_count": 343, + "execution_count": 306, "metadata": { - "id": "79b16506-9dd2-4fd0-ba59-e0d85ac1df97", - "outputId": "2825033e-d618-485d-95da-f1e3e6e1a41c", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "de6f287c-4213-4d60-8e1f-bddcc691aaac", + "outputId": "2b387b1a-c509-449e-bc8a-bfbfc1fde7f9" }, "outputs": [ { @@ -13171,7 +13275,7 @@ "text/plain": [ "plot without title" ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAAC2VBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8RERESEhITExMUFBQVFRUWFhYX\nFxcZGRkaGhobGxscHBwdHR0eHh4fHx8hISEiIiIkJCQmJiYnJycoKCgpKSkrKyssLCwtLS0u\nLi4vLy8xMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6Ojo7Ozs8PDw9PT0+Pj4/Pz9AQEBB\nQUFCQkJDQ0NERERFRUVGRkZHR0dISEhLS0tNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVW\nVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1eXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2do\naGhpaWlqampra2tsbGxtbW1vb29wcHBxcXFycnJzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7\ne3t8fHx9fX1+fn5/f3+AgICBgYGDg4OFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6P\nj4+QkJCRkZGSkpKTk5OUlJSVlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKCh\noaGioqKjo6OkpKSlpaWmpqanp6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKz\ns7O0tLS1tbW2tra3t7e4uLi5ubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTF\nxcXGxsbHx8fIyMjJycnKysrLy8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX\n19fY2NjZ2dna2trb29vc3Nzd3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp\n6enq6urr6+vs7Ozt7e3u7u7v7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7\n+/v8/Pz9/f3+/v7///+vTdj+AAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO3d/Z9U\n9X338WkIqZrglV5JellztY1Na3NZklxJrTZVm9qzw82u3MiNSEBCQKgSKChKlIRCMNomXjRE\niQbTYJKKhBpQ4m64AEMNoERUVBDtIktYYZfdZdnd+f4FPWd2Z/FxOO531s+bnTOzr+cPM4fZ\n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" + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAAC2VBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8RERESEhITExMUFBQVFRUWFhYX\nFxcZGRkaGhobGxscHBwdHR0eHh4fHx8hISEiIiIkJCQmJiYnJycoKCgpKSkrKyssLCwtLS0u\nLi4vLy8xMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6Ojo7Ozs8PDw9PT0+Pj4/Pz9AQEBB\nQUFCQkJDQ0NERERFRUVGRkZHR0dISEhLS0tNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVW\nVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1eXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2do\naGhpaWlqampra2tsbGxtbW1vb29wcHBxcXFycnJzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7\ne3t8fHx9fX1+fn5/f3+AgICBgYGDg4OFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6P\nj4+QkJCRkZGSkpKTk5OUlJSVlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKCh\noaGioqKjo6OkpKSlpaWmpqanp6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKz\ns7O0tLS1tbW2tra3t7e4uLi5ubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTF\nxcXGxsbHx8fIyMjJycnKysrLy8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX\n19fY2NjZ2dna2trb29vc3Nzd3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp\n6enq6urr6+vs7Ozt7e3u7u7v7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7\n+/v8/Pz9/f3+/v7///+vTdj+AAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO3d/59V\n1Xno8dMQUjXBm3uT9Fpzexub1uZaktykVpuqTe1m+DIjXwQRCUiICFUCBUWJmlAJRtvES0OU\naDA3mKQioQaUyIQLGGoENaKigmgHGcIAM8AwzMxZf8HdZw0HfO3ZrnXWPA9zzqx83j+c2Z7Z\n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\n8P8BBiVlPRsu718AAAAASUVORK5CYII=" }, "metadata": { "image/png": { @@ -13185,28 +13289,28 @@ "my_model <- train(form = Species ~ ., data = my_data, method = \"rf\")\n", "ggplot(varImp(my_model))" ], - "id": "79b16506-9dd2-4fd0-ba59-e0d85ac1df97" + "id": "de6f287c-4213-4d60-8e1f-bddcc691aaac" }, { - "id": "17678a88", + "id": "38bb6546", "cell_type": "markdown", "source": [ "## 9.5 欠損のあるデータでの学習" ], "metadata": { - "id": "17678a88" + "id": "38bb6546" } }, { "cell_type": "code", - "execution_count": 344, + "execution_count": 307, "metadata": { - "id": "f9347304-2a44-4f1f-83a3-1bd9da7b570f", - "outputId": "500829f5-0766-4cc6-f740-7cf1ac2c9176", "colab": { "base_uri": "https://localhost:8080/", - "height": 255 - } + "height": 275 + }, + "id": "cbfac048-be87-48ed-b5e0-b7b6b96019d5", + "outputId": "0c7e1b7a-7ccd-4a55-fdef-3f2e3b193497" }, "outputs": [ { @@ -13259,18 +13363,18 @@ "\n", "psych::describe(my_data) # nの値が135の変数に,150 - 135 = 15個の欠損がある." ], - "id": "f9347304-2a44-4f1f-83a3-1bd9da7b570f" + "id": "cbfac048-be87-48ed-b5e0-b7b6b96019d5" }, { "cell_type": "code", - "execution_count": 345, + "execution_count": 308, "metadata": { - "id": "3aa38c8c-3c0b-4f75-83f5-dca42f7ae514", - "outputId": "9f1b5873-b54f-4967-8c70-ca3c94e6b5e9", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "97ea12b0-7b3a-4674-b399-8ffd919b2160", + "outputId": "c8b8da5e-285a-4f47-f774-1eb22d8ddaf1" }, "outputs": [ { @@ -13299,396 +13403,396 @@ " minbucket = 1)) # 終端ノードの条件\n", "max(my_model$results$Accuracy)" ], - "id": "3aa38c8c-3c0b-4f75-83f5-dca42f7ae514" + "id": "97ea12b0-7b3a-4674-b399-8ffd919b2160" }, { "cell_type": "code", - "execution_count": 346, + "execution_count": 309, "metadata": { - "id": "7eb8f79c-0524-4feb-877c-87390df663e9", - "outputId": "4155b830-12d9-40a1-e5f5-c597c0905d29", "colab": { "base_uri": "https://localhost:8080/", "height": 1000 - } + }, + "id": "30a3082a-40e2-45b6-8bc7-c30383d069c2", + "outputId": "b866ae0e-2223-4e88-ac84-50a7f143136c" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ - "[15:25:19] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:19] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:19] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:19] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:19] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:19] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:27] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:27] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:27] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:27] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:28] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:28] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:28] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:28] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:28] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:29] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:30] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:31] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:32] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:33] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:34] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", - "[15:25:35] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n" + "[13:58:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:08] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:09] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:10] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:11] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:12] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:13] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:14] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:15] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:15] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:15] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:15] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:15] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:15] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:15] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:15] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:15] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:15] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:15] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:15] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:15] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:15] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:15] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:15] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:16] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:16] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:16] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:16] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:16] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:16] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:16] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:16] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:16] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:16] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:16] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:16] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:17] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:17] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:17] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:17] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:17] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:17] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:17] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:17] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:18] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:18] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:18] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:18] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:18] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:18] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:19] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:19] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:19] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:19] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:19] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:19] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:19] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:19] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:20] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:21] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:22] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:23] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:24] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:25] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n", + "[13:58:26] WARNING: src/c_api/c_api.cc:935: `ntree_limit` is deprecated, use `iteration_range` instead.\n" ] }, { "output_type": "display_data", "data": { "text/html": [ - "0.96" + "0.953333333333333" ], - "text/markdown": "0.96", - "text/latex": "0.96", + "text/markdown": "0.953333333333333", + "text/latex": "0.953333333333333", "text/plain": [ - "[1] 0.96" + "[1] 0.953" ] }, "metadata": {} @@ -13700,28 +13804,28 @@ " trControl = trainControl(method = \"cv\", number = 5))\n", "max(my_model$results$Accuracy)" ], - "id": "7eb8f79c-0524-4feb-877c-87390df663e9" + "id": "30a3082a-40e2-45b6-8bc7-c30383d069c2" }, { - "id": "074c51e1", + "id": "bacf46dd", "cell_type": "markdown", "source": [ "## 9.6 他の分類手法" ], "metadata": { - "id": "074c51e1" + "id": "bacf46dd" } }, { "cell_type": "code", - "execution_count": 347, + "execution_count": 310, "metadata": { - "id": "56066be0-7265-4e16-9652-b76d45184240", - "outputId": "18a6133a-03e0-4c51-b072-0204101105ef", "colab": { "base_uri": "https://localhost:8080/", "height": 129 - } + }, + "id": "d57eb209-48af-4958-bcd8-46712c5f84a2", + "outputId": "f9ea73dc-1148-421f-86d2-30f078b2eaed" }, "outputs": [ { @@ -13735,15 +13839,15 @@ "\t<int><dbl><dbl>\n", "\n", "\n", - "\t70.9730.96\n", + "\t90.9730.96\n", "\n", "\n" ], - "text/markdown": "\nA data.frame: 1 × 3\n\n| k <int> | Accuracy <dbl> | Kappa <dbl> |\n|---|---|---|\n| 7 | 0.973 | 0.96 |\n\n", - "text/latex": "A data.frame: 1 × 3\n\\begin{tabular}{lll}\n k & Accuracy & Kappa\\\\\n & & \\\\\n\\hline\n\t 7 & 0.973 & 0.96\\\\\n\\end{tabular}\n", + "text/markdown": "\nA data.frame: 1 × 3\n\n| k <int> | Accuracy <dbl> | Kappa <dbl> |\n|---|---|---|\n| 9 | 0.973 | 0.96 |\n\n", + "text/latex": "A data.frame: 1 × 3\n\\begin{tabular}{lll}\n k & Accuracy & Kappa\\\\\n & & \\\\\n\\hline\n\t 9 & 0.973 & 0.96\\\\\n\\end{tabular}\n", "text/plain": [ " k Accuracy Kappa\n", - "1 7 0.973 0.96 " + "1 9 0.973 0.96 " ] }, "metadata": {} @@ -13758,18 +13862,18 @@ " trControl = trainControl(method = \"LOOCV\"))\n", "my_model$results %>% filter(Accuracy == max(Accuracy))" ], - "id": "56066be0-7265-4e16-9652-b76d45184240" + "id": "d57eb209-48af-4958-bcd8-46712c5f84a2" }, { "cell_type": "code", - "execution_count": 348, + "execution_count": 311, "metadata": { - "id": "2dec1d5b-89a1-4e41-8a2b-27fc69abed3c", - "outputId": "8737adff-1ea3-4daf-ac6f-c0e2047121ef", "colab": { "base_uri": "https://localhost:8080/", - "height": 161 - } + "height": 160 + }, + "id": "2bea54d9-6321-462b-b100-f5878a3bb419", + "outputId": "f6f1f89f-c6ea-4d4d-9095-908f435e42c1" }, "outputs": [ { @@ -13810,69 +13914,83 @@ " trace = FALSE) # 途中経過を表示しない\n", "my_model$results %>% filter(Accuracy == max(Accuracy))" ], - "id": "2dec1d5b-89a1-4e41-8a2b-27fc69abed3c" + "id": "2bea54d9-6321-462b-b100-f5878a3bb419" }, { - "id": "f400d294", + "id": "2521a809", "cell_type": "markdown", "source": [ "# 10 分類2(2値分類)" ], "metadata": { - "id": "f400d294" + "id": "2521a809" } }, { "cell_type": "code", - "execution_count": 349, + "execution_count": 312, "metadata": { - "id": "4d63096d-2761-48ab-92fd-2fe22330ee41" + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "2192e8c0-f1d3-40a1-ac08-8ab5845a96d6", + "outputId": "538395bc-44e5-41b9-8ee4-a182e4fdd3d9" }, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "Installing package into ‘/usr/local/lib/R/site-library’\n", + "(as ‘lib’ is unspecified)\n", + "\n" + ] + } + ], "source": [ "# Google Colaboratoryの環境設定\n", "if (file.exists(\"/content\")) {\n", " options(Ncpus = parallel::detectCores())\n", - " packages_to_install <- c(\"caret\", \"PRROC\", \"rpart.plot\")\n", " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"caret\", \"PRROC\", \"rpart.plot\")\n", " install.packages(setdiff(packages_to_install, installed_packages))\n", "}" ], - "id": "4d63096d-2761-48ab-92fd-2fe22330ee41" + "id": "2192e8c0-f1d3-40a1-ac08-8ab5845a96d6" }, { - "id": "526009e5", + "id": "f5cc5c86", "cell_type": "markdown", "source": [ "## 10.1 2値分類の性能指標" ], "metadata": { - "id": "526009e5" + "id": "f5cc5c86" } }, { "cell_type": "code", - "execution_count": 350, + "execution_count": 313, "metadata": { - "id": "a93eb3c8-9a72-4599-ba36-4f98d6c017a4" + "id": "f7616375-1812-41e1-bb58-5eb76cc2125c" }, "outputs": [], "source": [ "y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1)\n", "y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5)" ], - "id": "a93eb3c8-9a72-4599-ba36-4f98d6c017a4" + "id": "f7616375-1812-41e1-bb58-5eb76cc2125c" }, { "cell_type": "code", - "execution_count": 351, + "execution_count": 314, "metadata": { - "id": "339b6729-b39a-4e8f-8c82-3cefbde31f47", - "outputId": "8d256be9-1950-4622-fa56-02f4f6cf458f", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "c7c88d74-cba1-4e20-85f4-5adb837fabf0", + "outputId": "c16b1e30-1206-4d7f-9f94-9c79ee7963ab" }, "outputs": [ { @@ -13899,18 +14017,18 @@ "y_ <- ifelse(0.5 <= y_score, 1, 0)\n", "y_" ], - "id": "339b6729-b39a-4e8f-8c82-3cefbde31f47" + "id": "c7c88d74-cba1-4e20-85f4-5adb837fabf0" }, { "cell_type": "code", - "execution_count": 352, + "execution_count": 315, "metadata": { - "id": "6e2473c9-7485-428b-8d87-a04130c24db0", - "outputId": "af704add-7817-40e6-b766-d4293484b77e", "colab": { "base_uri": "https://localhost:8080/", - "height": 538 - } + "height": 558 + }, + "id": "c7472736-6226-4d5a-9e24-c688744f2ece", + "outputId": "51aa6ba9-764d-4007-8a91-57c17ccb5bf0" }, "outputs": [ { @@ -13959,28 +14077,28 @@ " positive = \"1\", # 「1」を陽性とする.\n", " mode = \"everything\") # 全ての指標を求める." ], - "id": "6e2473c9-7485-428b-8d87-a04130c24db0" + "id": "c7472736-6226-4d5a-9e24-c688744f2ece" }, { - "id": "6f2df4dd", + "id": "41d14b33", "cell_type": "markdown", "source": [ "## 10.2 トレードオフ" ], "metadata": { - "id": "6f2df4dd" + "id": "41d14b33" } }, { "cell_type": "code", - "execution_count": 353, + "execution_count": 316, "metadata": { - "id": "5f647672-a1bb-412f-87cb-00b1276bcb2c", - "outputId": "cb5257c2-54de-4b43-b99a-54d45834df75", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "4466f9c5-d703-4d27-975d-557b3916b7ad", + "outputId": "71489a05-eaa4-40d3-e507-62b8fc59e331" }, "outputs": [ { @@ -14014,18 +14132,18 @@ "c(sum((y == 0) & (y_ == 1)) / sum(y == 0), # FPR\n", " sum((y == 1) & (y_ == 1)) / sum(y == 1)) # TPR" ], - "id": "5f647672-a1bb-412f-87cb-00b1276bcb2c" + "id": "4466f9c5-d703-4d27-975d-557b3916b7ad" }, { "cell_type": "code", - "execution_count": 354, + "execution_count": 317, "metadata": { - "id": "720879ed-2b84-43ef-9a94-ea805e9f3608", - "outputId": "7fead293-7b4f-4d1e-9eb5-c8500ecaf3fb", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "a1fa6503-9620-4546-a6de-1e21dfa1a691", + "outputId": "d6fd6ac9-33ef-4b71-adbd-7bccdf31edce" }, "outputs": [ { @@ -14053,18 +14171,18 @@ " ylab = \"True Positive Rate\",\n", " legend = FALSE)" ], - "id": "720879ed-2b84-43ef-9a94-ea805e9f3608" + "id": "a1fa6503-9620-4546-a6de-1e21dfa1a691" }, { "cell_type": "code", - "execution_count": 355, + "execution_count": 318, "metadata": { - "id": "f9feb1d1-807c-45a1-bc44-b44a5b777354", - "outputId": "c25d1c45-5a35-4188-801a-cd74aa776fd3", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "6baf9c27-2b3f-43de-b343-9d27f2eb6c7c", + "outputId": "1c0334cf-4ea2-4d3a-c544-b77e59155af4" }, "outputs": [ { @@ -14085,18 +14203,18 @@ "source": [ "my_roc$auc" ], - "id": "f9feb1d1-807c-45a1-bc44-b44a5b777354" + "id": "6baf9c27-2b3f-43de-b343-9d27f2eb6c7c" }, { "cell_type": "code", - "execution_count": 356, + "execution_count": 319, "metadata": { - "id": "e73599dd-ecff-410a-bfba-2b931f4fba8a", - "outputId": "ce495a17-ef94-409b-e820-54a1d904ac84", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "7c8f0d03-652c-4021-8c61-6e4fa6213a65", + "outputId": "afafc70d-af3e-4bcd-be6c-80e67e5046a7" }, "outputs": [ { @@ -14123,18 +14241,18 @@ "c(sum((y == 1) & (y_ == 1)) / sum(y == 1), # Recall == TPR\n", " sum((y == 1) & (y_ == 1)) / sum(y_ == 1)) # Precision" ], - "id": "e73599dd-ecff-410a-bfba-2b931f4fba8a" + "id": "7c8f0d03-652c-4021-8c61-6e4fa6213a65" }, { "cell_type": "code", - "execution_count": 357, + "execution_count": 320, "metadata": { - "id": "63cdcff3-8e4e-4a0a-a0f8-80f28ad0dd67", - "outputId": "b9dcbd02-2734-4386-c0ed-011f74468eb7", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "2a0a34c7-8980-4a2e-b0ab-fdf8559b2e4e", + "outputId": "64ea3570-faad-436a-d215-adcdc0ea2fd3" }, "outputs": [ { @@ -14162,18 +14280,18 @@ " ylab = \"Precision\",\n", " legend = FALSE)" ], - "id": "63cdcff3-8e4e-4a0a-a0f8-80f28ad0dd67" + "id": "2a0a34c7-8980-4a2e-b0ab-fdf8559b2e4e" }, { "cell_type": "code", - "execution_count": 358, + "execution_count": 321, "metadata": { - "id": "fed34ec1-716a-4eca-b269-e7162ad87b13", - "outputId": "cb01b5be-0aa7-479a-b0ed-67f49d2bd681", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "2ad79e87-e0ac-43f9-bf1a-a762a5e85df5", + "outputId": "40b7c4e1-5c07-4c74-bcd6-fe7b44fbffc6" }, "outputs": [ { @@ -14194,27 +14312,27 @@ "source": [ "my_pr$auc.integral" ], - "id": "fed34ec1-716a-4eca-b269-e7162ad87b13" + "id": "2ad79e87-e0ac-43f9-bf1a-a762a5e85df5" }, { - "id": "3efa5787", + "id": "17a0ed00", "cell_type": "markdown", "source": [ "## 10.3 タイタニック" ], "metadata": { - "id": "3efa5787" + "id": "17a0ed00" } }, { "cell_type": "code", - "execution_count": 359, + "execution_count": 322, "metadata": { - "id": "79a8a176-2287-4cbc-b85a-72b1b229bffd", - "outputId": "77e8eb19-2c89-4c98-a22c-271006a1c6bb", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "d7b676a0-5133-43a2-ac1a-858643d17010", + "outputId": "8cbb0a88-2433-4281-c8b2-5e958b8d3690" }, "outputs": [ { @@ -14240,18 +14358,18 @@ " \"/fromzero/master/data/titanic.csv\")\n", "my_data <- read_csv(my_url)" ], - "id": "79a8a176-2287-4cbc-b85a-72b1b229bffd" + "id": "d7b676a0-5133-43a2-ac1a-858643d17010" }, { "cell_type": "code", - "execution_count": 360, + "execution_count": 323, "metadata": { - "id": "d9da2777-1b8e-45bc-bcdb-50901d3ee358", - "outputId": "5e7695fc-9a7f-434f-858b-e371fd625a94", "colab": { "base_uri": "https://localhost:8080/", "height": 286 - } + }, + "id": "a23fbd41-362e-44d1-8ed6-8a176ba10133", + "outputId": "742d1fa5-775e-4ecf-bf98-d459715e6b79" }, "outputs": [ { @@ -14292,13 +14410,13 @@ "source": [ "head(my_data)" ], - "id": "d9da2777-1b8e-45bc-bcdb-50901d3ee358" + "id": "a23fbd41-362e-44d1-8ed6-8a176ba10133" }, { "cell_type": "code", - "execution_count": 361, + "execution_count": 324, "metadata": { - "id": "90486c9a-2860-4135-9828-d347168ab541" + "id": "b26a4b88-beba-4d4e-b5da-71c85bc45e04" }, "outputs": [], "source": [ @@ -14306,18 +14424,18 @@ " tuneGrid = data.frame(maxdepth = 2),\n", " trControl = trainControl(method = \"LOOCV\"))" ], - "id": "90486c9a-2860-4135-9828-d347168ab541" + "id": "b26a4b88-beba-4d4e-b5da-71c85bc45e04" }, { "cell_type": "code", - "execution_count": 362, + "execution_count": 325, "metadata": { - "id": "de5dbb08-8250-4439-81e1-4580e67fe584", - "outputId": "aa041c1b-d95c-4233-ab5b-1a0ee14149b9", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "567a8a34-47fa-475f-a0ac-d324a3d857d7", + "outputId": "3560a947-9dde-416d-a22a-670cfc31808b" }, "outputs": [ { @@ -14339,18 +14457,18 @@ "source": [ "rpart.plot::rpart.plot(my_model$finalModel, extra = 1)" ], - "id": "de5dbb08-8250-4439-81e1-4580e67fe584" + "id": "567a8a34-47fa-475f-a0ac-d324a3d857d7" }, { "cell_type": "code", - "execution_count": 363, + "execution_count": 326, "metadata": { - "id": "86838273-454f-426d-9201-52a3ec6bcfa5", - "outputId": "39e66aac-63a3-4772-8e78-6c2f4eab98db", "colab": { "base_uri": "https://localhost:8080/", "height": 129 - } + }, + "id": "29e2f0ee-59c0-43c5-b093-2997b92c27bb", + "outputId": "54bb3c91-fad5-4ef2-a4c3-545e67d79968" }, "outputs": [ { @@ -14381,18 +14499,18 @@ "source": [ "my_model$results" ], - "id": "86838273-454f-426d-9201-52a3ec6bcfa5" + "id": "29e2f0ee-59c0-43c5-b093-2997b92c27bb" }, { "cell_type": "code", - "execution_count": 364, + "execution_count": 327, "metadata": { - "id": "c9f2400e-5eb0-4dea-8833-b09a6aa3a37a", - "outputId": "af38debe-b49f-4237-c712-a62c4f07b43c", "colab": { "base_uri": "https://localhost:8080/", "height": 454 - } + }, + "id": "22f88d9c-413d-4c2f-a16a-883ffb471071", + "outputId": "75043678-df95-40e4-facd-ef398da7c2c5" }, "outputs": [ { @@ -14440,18 +14558,18 @@ " ylab = \"True Positive Rate\",\n", " legend = FALSE)" ], - "id": "c9f2400e-5eb0-4dea-8833-b09a6aa3a37a" + "id": "22f88d9c-413d-4c2f-a16a-883ffb471071" }, { "cell_type": "code", - "execution_count": 365, + "execution_count": 328, "metadata": { - "id": "d8b02c53-a617-42c4-b808-a7f8001cc3d9", - "outputId": "9a14042f-9a4a-40e0-e98c-19f4c23de2e3", "colab": { "base_uri": "https://localhost:8080/", "height": 549 - } + }, + "id": "ea947bac-5fb5-48ba-b426-c319eee6478d", + "outputId": "15b7f091-8452-4142-dd7f-a191a274421a" }, "outputs": [ { @@ -14507,18 +14625,18 @@ "rpart.plot::rpart.plot(my_model1$finalModel, extra = 1)\n", "my_model1$results" ], - "id": "d8b02c53-a617-42c4-b808-a7f8001cc3d9" + "id": "ea947bac-5fb5-48ba-b426-c319eee6478d" }, { "cell_type": "code", - "execution_count": 366, + "execution_count": 329, "metadata": { - "id": "54a8c99b-7a9e-4666-98f0-f9a0d8af4d70", - "outputId": "1ca7e05d-7e4b-438e-c5e5-3a24ebd40feb", "colab": { "base_uri": "https://localhost:8080/", "height": 549 - } + }, + "id": "0403b893-2b00-44f0-bef7-002e37d8eb9f", + "outputId": "bbf314bd-f3f6-43f8-e78f-0b4bc4d5d3fb" }, "outputs": [ { @@ -14574,18 +14692,18 @@ "rpart.plot::rpart.plot(my_model2$finalModel, extra = 1)\n", "my_model2$results" ], - "id": "54a8c99b-7a9e-4666-98f0-f9a0d8af4d70" + "id": "0403b893-2b00-44f0-bef7-002e37d8eb9f" }, { "cell_type": "code", - "execution_count": 367, + "execution_count": 330, "metadata": { - "id": "c82ccc2d-f1ad-436f-b26d-990df8e558db", - "outputId": "bdab6c4e-52c6-49ec-c3fa-c5bf2996aefd", "colab": { "base_uri": "https://localhost:8080/", "height": 549 - } + }, + "id": "a0eec41e-f6b0-43b6-a408-7632979f27cf", + "outputId": "6fd22996-db80-4f9a-a208-6903165e7cce" }, "outputs": [ { @@ -14635,28 +14753,28 @@ "rpart.plot::rpart.plot(my_model3$finalModel, extra = 1)\n", "my_model3$results" ], - "id": "c82ccc2d-f1ad-436f-b26d-990df8e558db" + "id": "a0eec41e-f6b0-43b6-a408-7632979f27cf" }, { - "id": "03992e37", + "id": "47603a96", "cell_type": "markdown", "source": [ "## 10.4 ロジスティック回帰" ], "metadata": { - "id": "03992e37" + "id": "47603a96" } }, { "cell_type": "code", - "execution_count": 368, + "execution_count": 331, "metadata": { - "id": "53e552ae-8489-418a-a759-53950d3dd4ee", - "outputId": "24908637-7c3c-4d5f-af59-e46aff3e9fb9", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "240e9fe9-e13a-49a0-be5c-56f54f2f1f37", + "outputId": "e3effbd5-625c-44e3-b2de-6ec190e72782" }, "outputs": [ { @@ -14678,17 +14796,17 @@ "source": [ "curve(1 / (1 + exp(-x)), -6, 6)" ], - "id": "53e552ae-8489-418a-a759-53950d3dd4ee" + "id": "240e9fe9-e13a-49a0-be5c-56f54f2f1f37" }, { "cell_type": "code", - "execution_count": 369, + "execution_count": 332, "metadata": { - "id": "c0308476-a1a1-49e6-8a57-4af78c1eba85", - "outputId": "9fa05604-d756-4625-83ae-5439e92c4cd6", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "16b09cc8-2127-41d9-af7f-7d1614704210", + "outputId": "d9af4b96-594e-440a-b6e8-92dc577170f7" }, "outputs": [ { @@ -14717,18 +14835,18 @@ "my_model <- train(form = Survived ~ ., data = my_data, method = \"glm\",\n", " trControl = trainControl(method = \"LOOCV\"))" ], - "id": "c0308476-a1a1-49e6-8a57-4af78c1eba85" + "id": "16b09cc8-2127-41d9-af7f-7d1614704210" }, { "cell_type": "code", - "execution_count": 370, + "execution_count": 333, "metadata": { - "id": "238a1659-2591-4b24-978e-34a253cb7f85", - "outputId": "0f839aca-66dd-4f9d-e6f3-0b2cbed27d52", "colab": { "base_uri": "https://localhost:8080/", "height": 286 - } + }, + "id": "a1312f09-30f8-4c04-adc1-7ef23a335c3a", + "outputId": "ea49a8ea-a463-4e23-da76-dee5acdc1fcf" }, "outputs": [ { @@ -14770,18 +14888,18 @@ "coef(my_model$finalModel) %>%\n", " as.data.frame" ], - "id": "238a1659-2591-4b24-978e-34a253cb7f85" + "id": "a1312f09-30f8-4c04-adc1-7ef23a335c3a" }, { "cell_type": "code", - "execution_count": 371, + "execution_count": 334, "metadata": { - "id": "aa23b2b2-149d-4fa2-b352-a8166964f0ea", - "outputId": "7cf43c12-fe36-40ad-ea08-6dcd4036031c", "colab": { "base_uri": "https://localhost:8080/", "height": 129 - } + }, + "id": "752a312b-0c66-477e-8364-851fe0d947f4", + "outputId": "75fc7cfd-1b98-40e4-936c-c0aba9db9379" }, "outputs": [ { @@ -14812,55 +14930,72 @@ "source": [ "my_model$results" ], - "id": "aa23b2b2-149d-4fa2-b352-a8166964f0ea" + "id": "752a312b-0c66-477e-8364-851fe0d947f4" }, { - "id": "6361bfae", + "id": "c69f1ad0", "cell_type": "markdown", "source": [ "# 11 深層学習とAutoML" ], "metadata": { - "id": "6361bfae" + "id": "c69f1ad0" } }, { "cell_type": "code", - "execution_count": 372, + "execution_count": 335, "metadata": { - "id": "73592674-75ed-42e2-9307-a20e39c95b6a" + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "270d8808-f766-47d9-b42e-77f50952f07b", + "outputId": "98d07e5c-ce5e-458c-af53-4b273657cbff" }, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "Installing package into ‘/usr/local/lib/R/site-library’\n", + "(as ‘lib’ is unspecified)\n", + "\n", + "also installing the dependencies ‘bitops’, ‘RCurl’\n", + "\n", + "\n" + ] + } + ], "source": [ "# Google Colaboratoryの環境設定\n", "if (file.exists(\"/content\")) {\n", " options(Ncpus = parallel::detectCores())\n", - " packages_to_install <- c(\"h2o\", \"keras\")\n", " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"h2o\", \"keras\")\n", " install.packages(setdiff(packages_to_install, installed_packages))\n", "}" ], - "id": "73592674-75ed-42e2-9307-a20e39c95b6a" + "id": "270d8808-f766-47d9-b42e-77f50952f07b" }, { - "id": "00525c1e", + "id": "4c03a295", "cell_type": "markdown", "source": [ "## 11.1 Kerasによる回帰" ], "metadata": { - "id": "00525c1e" + "id": "4c03a295" } }, { "cell_type": "code", - "execution_count": 373, + "execution_count": 336, "metadata": { - "id": "200d1f16-236f-4dc8-a9c7-4001ec52265c", - "outputId": "49b3f0af-7355-4374-83de-8f24cc3d7e6b", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "7a77be40-ba1e-4aa6-b0bf-74bc21fe828d", + "outputId": "af98233d-d078-4bc4-a67c-79b967f803fb" }, "outputs": [ { @@ -14876,11 +15011,6 @@ " %<-%\n", "\n", "\n", - "The following object is masked from ‘package:fabletools’:\n", - "\n", - " new_model_class\n", - "\n", - "\n", "\u001b[1mRows: \u001b[22m\u001b[34m27\u001b[39m \u001b[1mColumns: \u001b[22m\u001b[34m5\u001b[39m\n", "\u001b[36m──\u001b[39m \u001b[1mColumn specification\u001b[22m \u001b[36m────────────────────────────────────────────────────────\u001b[39m\n", "\u001b[1mDelimiter:\u001b[22m \",\"\n", @@ -14898,25 +15028,25 @@ " \"/fromzero/master/data/wine.csv\")\n", "tmp <- read_csv(my_url)" ], - "id": "200d1f16-236f-4dc8-a9c7-4001ec52265c" + "id": "7a77be40-ba1e-4aa6-b0bf-74bc21fe828d" }, { "cell_type": "code", - "execution_count": 374, + "execution_count": 337, "metadata": { - "id": "493d8624-730d-4ef2-92fb-a6eaef0658bc" + "id": "ffd26607-6971-4c6b-b3a2-631606555bff" }, "outputs": [], "source": [ "my_data <- tmp[sample(nrow(tmp)), ]" ], - "id": "493d8624-730d-4ef2-92fb-a6eaef0658bc" + "id": "ffd26607-6971-4c6b-b3a2-631606555bff" }, { "cell_type": "code", - "execution_count": 375, + "execution_count": 338, "metadata": { - "id": "ad468e5a-70d5-40fc-97dd-6a7b69dca1b6" + "id": "2326e6ce-3762-445f-88e4-5b4854b3a18d" }, "outputs": [], "source": [ @@ -14924,18 +15054,18 @@ " select(-LPRICE2) %>% scale\n", "y <- my_data$LPRICE2" ], - "id": "ad468e5a-70d5-40fc-97dd-6a7b69dca1b6" + "id": "2326e6ce-3762-445f-88e4-5b4854b3a18d" }, { "cell_type": "code", - "execution_count": 376, + "execution_count": 339, "metadata": { - "id": "da417a09-07cd-48b7-8869-1aa8eec7b901", - "outputId": "152c7747-e20e-4ced-d456-58bf27f621fa", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "204dddec-c298-435f-902a-6f8c346fb39b", + "outputId": "d51b16cc-5ec6-4e57-f1f4-f770c106f3f8" }, "outputs": [ { @@ -14957,17 +15087,17 @@ "source": [ "curve(activation_relu(x), -3, 3)" ], - "id": "da417a09-07cd-48b7-8869-1aa8eec7b901" + "id": "204dddec-c298-435f-902a-6f8c346fb39b" }, { "cell_type": "code", - "execution_count": 377, + "execution_count": 340, "metadata": { - "id": "d9895f75-a710-41bf-be36-002cb7eb081e", - "outputId": "6411ec6c-80cd-40a5-9f63-28b95bb9430a", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "ba55237e-8561-4352-aad1-fef7e9fca4bd", + "outputId": "707630ed-e9e7-4d3b-d64d-0298d35c488a" }, "outputs": [ { @@ -14996,13 +15126,13 @@ "summary(my_model) # ネットワークの概要\n", "# 割愛(Pythonの結果を参照)" ], - "id": "d9895f75-a710-41bf-be36-002cb7eb081e" + "id": "ba55237e-8561-4352-aad1-fef7e9fca4bd" }, { "cell_type": "code", - "execution_count": 378, + "execution_count": 341, "metadata": { - "id": "baeab163-8e5c-4370-9ec0-96bf195a6617" + "id": "afcbb90d-126d-4c9b-968e-26ed66b037f1" }, "outputs": [], "source": [ @@ -15010,13 +15140,13 @@ " loss = \"mse\",\n", " optimizer = \"rmsprop\")" ], - "id": "baeab163-8e5c-4370-9ec0-96bf195a6617" + "id": "afcbb90d-126d-4c9b-968e-26ed66b037f1" }, { "cell_type": "code", - "execution_count": 379, + "execution_count": 342, "metadata": { - "id": "ff9f9cfe-81f6-4af2-baba-5c9f24babc80" + "id": "f6c8cb88-ace4-4771-8778-8e9efdd6990a" }, "outputs": [], "source": [ @@ -15024,13 +15154,13 @@ " patience = 20,\n", " restore_best_weights = TRUE)" ], - "id": "ff9f9cfe-81f6-4af2-baba-5c9f24babc80" + "id": "f6c8cb88-ace4-4771-8778-8e9efdd6990a" }, { "cell_type": "code", - "execution_count": 380, + "execution_count": 343, "metadata": { - "id": "fce294dd-2945-45ce-8e39-77772855d551" + "id": "706c14cb-3430-4645-949a-75b388ccfdc1" }, "outputs": [], "source": [ @@ -15043,18 +15173,18 @@ " callbacks = list(my_cb),\n", " verbose = 0)" ], - "id": "fce294dd-2945-45ce-8e39-77772855d551" + "id": "706c14cb-3430-4645-949a-75b388ccfdc1" }, { "cell_type": "code", - "execution_count": 381, + "execution_count": 344, "metadata": { - "id": "18f8b406-c617-4b70-b6e3-93d175203bf1", - "outputId": "fed2a04d-f04e-4d11-8cb0-886ed588bd23", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "c5ba663e-2082-4351-a82e-5162855d1a9b", + "outputId": "26ba1da0-7a34-4ff2-b83a-dc32d00bc9ba" }, "outputs": [ { @@ -15063,7 +15193,7 @@ "text/plain": [ "plot without title" ], - "image/png": "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\nSURBVPNNhTqdTq2DnJaQkBBVVR2OwFgWx2Kx2O12rVOcFpPJpNfr7XZ7bft4/FNGo1FVVY/H\no3WQUwusTwPfBFigfBpYLBYRqYlfsZCQkGp/T9SoWlfsfFRVHTNmzNixYwcNGvRXY/Ly8qrx\nvxgZGWk0GvPz88/+N2TixInefbu/Tk616Q0isvmuST1V9wvN2sxo72+u8xvE3Vwv9rdfEhYW\n5nQ6A+ITx2w2h4eHl5aWBsRf6kaj0WKx2GyBcc9KXFycy+UqLi7WOshpiYmJKSgo0DrFaQkP\nDzebzYWFhQHRlqxWq9vtDoh+bzKZIiIiysvLy8vLtc5yanq93mq1lpSUaB3ktMTGxqqqWlhY\nWL1vazQaIyMjq/c9UdNqyxUkO3funDhxYtVnk6IodWf697777vs0KbVXo/iL42IkMmpJp+4i\nMjYjKVT1/6P25cwsTQMCAIDAUFuKXevWre12+6JFi9LS0rKyslasWGG328877zytc50NrVq1\nOv/888+Pb3hDp/YSEvKhR8mpsEe5XMNP+G+JPaI37K4IgOkuAACgrdpS7MLCwh577LGKiop7\n7rnnrrvuOnz48KxZsxo2bKh1rrOkTZs2ycUlHxw8IqkpztkPrbRViMiEtKNVA5Zn5WiXDgAA\nBIZadLqzadOmjzzyiNYptDF69OjBr60OMRiubt3ig0PHXn5m4b3b/tu7MK+DrXhfeKSIfGQr\ne1JVwwJh8QUAAKAVikKt0LVr10su639Jk8Sp550rRsOJ8Mj1+cUiMr7yKRQOne4jnkIBAAD+\nFsWutujWrZtL9Xx2LFmcTnlq7tJde0VkTGZySOV9eZyNBQAAf49iV1v07dv3m+S0hVt33Njx\nHPnv15tHj90bHhXtcl6dleYbcMCj7uQWCgAA8NcodrVF9+7dL+rXr2V01JP9eovXK40aL7dV\niMitaceqxqzKr+Y1igAAQDCh2NUi1113nUv1bD+RLSLy6SdvLllaLErPwryuJf4+92FRSaE7\nAFZMBQAAmqDY1SK9evVKL7ffvH7D4FbN5e03S0eNfqtpKxG5JdU/aecQebc4MJZBBwAAZx/F\nrhZp0KDB5MmTbU7nG0Mvt4pI+/aLxegVuS4zJcLt8o1ZmV9YG58BBwAAagGKXe0yePBgRaTE\n4fR4VTly5OjM+/5b4QjzuEdnpvgGJDld35WWaRsSAADUThS72qVdu3ZhkZFXf7i+aWSErH5F\n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\nYVpuBQCAB4ZgBwB30aVLFyIym82DBg260z43btwwm81CodC6WFlZSUTt27cPCAggIuvczsa6\nGBAQEBgYSETXrl27dWtpaalMJvPz83PwaQAAPALwUSwA3IWvr29kZGRWVlZ9fb1t5fbt25cu\nXWqdzBGRTqf7+uuvbVsPHDggkUgiIyM7dOjQt2/f7OzspqYm29bMzEyZTDZ48GClUtmvX7/s\n7Gy1Wm3ddOHCha5du3700UcP5cwAANwNJnYAcHdr1qwZNWrUsGHDFixY0KFDh2PHjq1evTo+\nPt520UNgYOD8+fNLS0tDQkK++uqrrKys6dOn+/j4ENHq1atjYmImTpw4b948sVi8b9++L7/8\nMi0tzdPTk4jS0tImTJgwatSoV155RaPR/O1vf/P39587d64zzxYAwHU5+7JcAHANx44dGzVq\nlFKpFIlEPXv2XLNmje0eJUOGDOnVq9epU6eioqJkMpmPj8/s2bPVarXt2K+//nro0KFyuVwi\nkURERGRkZNz6yPv37x80aJBMJvP394+Li7t48aJ1fXR0dFBQ0K17Wu+iwu95AgC4MgF3y/3f\nAQAewNChQ6urqy9cuODsQgAAHnX4jh0AAACAm0CwAwAAAHATCHYAAAAAbgLfsQMAAABwE5jY\nAQAAALgJBDsAAAAAN4FgBwAAAOAmEOwAAAAA3ASCHQAAAICbQLADAAAAcBMIdgAAAABu4v8B\na0D4j7MCGdoAAAAASUVORK5CYII=" + "image/png": "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\npdLs7Gzdz0IkEgmbzc7JydH9N3UVq9xJfn6+xsudCAQCDQ5IykEFWOJQxMnJSSaTFS3Cy8zM\njI+P/0D1KQ1KTU394Ycf9PT0GjVqZG9vP2PGDN3PRQgh/8XQ0PC33367deuWs709nichNgbb\nt2HaZISFFXfi8fD9EKxYjW/aqBgmKCjIxsYmMDBQ9yeZCCFfMx1K7NLS0pKTk9Xv4JOTk5OT\nk9XvPE6dOqXepGZkZNSkSZN169ZFR0c/ffp0xYoVjo6OGl9F9y6VSjV69Ojo82evDe6b/tPo\nU328r/xxcObMmWX9dQkhZcrS0vLSpUtbtmzhFxQgNQW3wjBzCmZPx7PE4k7WNpg2AwuWoG49\nuUi0+JdfHBwcTp48qb2oCSHkQ3QosZs8ebKPj8+aNWuUSqWPj4+Pj8/ff/8N4NatW//884+6\nz7hx4+zs7ObOnTt16lQejzdr1qxy2LMTGhp69cL5/d071zOtIuCwPawsfvfuuGvnzoSEhLL+\n0oSQsubt7R0dHT121Cghn4+CAly9gsHf4X8bUHKFrkcTBK7ChEkQ6eXk5AwaNKhhw4a3bt3S\nXtSEkDIhl8sZhjl58qT6g9OnT7/VISYmhmGYO3fufPpo7w5SpnRovciWLVve2z558uSij0Ui\nkZ+fX3lF9Mrjx4+rGxmaiIp3bjobG1YRi6Kioqytrcs5GEKIxnG5XH9/f39//3379k2ePDm3\nsBBH/sSdf+Hji/qvl+1yOPimNeq5ImgXzpyOiYtr165d7dq1f/vtN1tbW62GTwjRPDabffbs\n2aJ6ap8lJCREX1/f3d29NIN8MR2asdNZxsbGz7JzFCUW1mQVFqbnF9DJdIRUMn369Hn8+PGw\nwYNZuTmIjMSCeQj8BYlPi3sYGmL0j1i5GnXrg8+/c++em5tbmzZtoqOjtRc1IZXNvXv3Jk6c\n2Lt37wkTJoSHh2slBoZhvvnmmy+rc7R8+fLQ0NBSDvLFKLH7uKZNm/KMjOdcuKJUqQAUKhQT\nTl+oWbu2i4uLtkMjhGgYh8NZvHhxVFRUcw8PJL/EXycwfix++xXZJTbw2thh+SrMX4zadQD8\nGxHRqFGjIUOG6P7eSUJ039GjR9u1a7fj2fNztersSk336tx5z549pRnQw8NjzJgxRQ/PnTvH\nZrOfPn16584dLy8vIyMjqVTavn37t44zLXkX9datW40bNxaLxXXr1r169WpRn/eO0Lp16+PH\n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\nqVNbWlrq6+uHu1GjSXt7+yOPPLJ58+aVK1eWdx6uqqh2v3p6elasWLFhw4YwDE888cTrrrvu\nlFNOISjpIOzcufNPf/rTf/7zH6315MmTr7766mnTphGUdCi8/vrry5Ytu+eee84991yCkg7C\n4sWLD1ymznGcF154gaCkcAhMnujfr371q0KhcNNNN9m2/fzzz2/fvv2xxx5jDJ2dA/L2228/\n9dRTZ5999htvvHFgsDtcVVHtft1xxx2WZd14442JROL5559ft27dU0895TgOSnp0hBCLFi06\n88wzr7rqKsbYX/7yl3fffXfFihWJRAIlHaS+vr7FixeXSqUf//jHcbBDSY/awoULr7zyyriM\nhBDGWHzfDpQUDqbhS+3du3fu3LlbtmyJN/P5/Lx589avXz+8rRpFXn/99c7OzjVr1lxxxRXl\nnYerKqrdr1wu98ADD+zYsSPe7OzsnDNnzqeffoqSHrW+vr7W1tZSqRRv7tq1a86cOVu2bEFJ\nB2/p0qVPP/301VdfvWbNGo03/uB873vfe++99w7aiZLCoRDe+/HZZ5+Zpjl58uR4M5VKNTU1\nbdq0aXhbNYpceOGFdXV1B+08XFVR7X6l0+m77767ubk53uzu7maMjR07FiU9aplMZv78+YlE\nghCSz+dfeumlpqam5uZmlHSQ1qxZs2XLlh/84AflPSjpUYuiKAiCNWvW3H777ddff/3SpUvb\n29sJSgpfBMGuH7lcLp1OU0rLezKZTBe/4hgAAAfoSURBVDabHcYmVYDDVRXVPiL5fP7xxx+f\nN29eTU0NSjpISqnvfve7CxYs2Llz5/3332+aJko6GIVC4Yknnrj11lsdxynvREmPWqlUqq6u\nFkLccsstS5YsCcPw7rvvLhaLKCkcCpMn+nfgewOGyuGqimoP0K5du+6///6zzjrr2muvjfeg\npIPBGFu2bFlvb+8rr7xyzz33PPzwwwQlHYSnn356+vTpZ5111kH7UdKjk8lknn322fLmXXfd\nde211/7rX/8iKCkcAj12/aiurs7lcvqAKSbZbLampmYYm1QBDldVVHuANmzYsGTJkjlz5tx8\n883xxzdKOnhNTU2nn376XXfdlc1m33zzTZT0qK1fv/6DDz5YuHDhQftR0qGSSCTq6uq6urpQ\nUjgUgl0/Tj755CiKtmzZEm/mcrmdO3eeeuqpw9uq0e5wVUW1B+KTTz558MEH77jjjssvv7y8\nEyU9auvWrbvxxhuDIIg3KaWGYRCUdBBWr15dLBZbWloWLFiwYMGCbDb7yCOPLF26FCU9am1t\nbb///e+FEPGm7/t79+5tbGxESeFQ/L777hvuNoxoiUSira3tn//859SpU0ul0vLly5PJ5IIF\nC9DLPUC9vb3FYrGtre299967+OKLS6USYyydTn9hVV3XRbW/XBiGP//5z7/zne9Mnz69tB9K\nOhjpdPrFF1/cunXrxIkTPc/785//vGnTpkWLFtXV1aGkR+eMM8649ABvvPHGddddN3/+/Orq\napT06HDOn3jiifb29kmTJmWz2T/+8Y+FQuHmm2/GGx8OhXXs+lcqlZ588sl169ZJKb/+9a+3\ntLSgQ3vgFi1a1NnZedCeuXPnHq6qqPaX27Bhw89+9rODdt50002zZ89GSY9aW1vbM88888kn\nn1BKJ0yY8MMf/vDMM88khy8dSnpErrnmmltuuSVegA0lPWpbt2595pln4umuU6dOveGGGxoa\nGghKCodAsAMAAACoELjGDgAAAKBCINgBAAAAVAgEOwAAAIAKgWAHAAAAUCEQ7AAAAAAqBIId\nAAAAQIVAsAMAAACoEAh2ADA6XHzxxZMmTRruVgAAjGgIdgAAAAAVAsEOAAAAoEIg2AHA0Xjz\nzTdnzZpVVVXluu706dNXrFhRPnTOOeecd955//jHP2bMmOG6bm1t7cKFC7PZbPmEV199debM\nmel0OpFInHbaab/73e8OvLfh6tWrv/3tb6fT6cbGxquuumrz5s3lQ4ZhbNu27dJLL02n0+l0\n+vvf/35PT89X83oBAEYFBDsAOGKvv/76RRddFIbh888//+KLL37zm9+8/vrrH3744fiobdtb\ntmxZsmTJo48+umPHjscee+y555677rrr4qMrV66cPXt2Mpl87rnnXn755UsuueTOO+9csmRJ\nfHT16tWXXHKJ4zhPPPHEAw888P7778+cOXP37t3xUSnl/PnzZ86c+dxzz7W0tPz1r3+98847\nv/qXDwAwcmkAgCN09tlnT5kypVgslvfMnTs3nU57nqe1Pv/88wkhb731Vvno9ddfTwjZsWOH\n1nratGkTJkwIgqB8dN68eaZpdnV1aa2/8Y1vTJ48OYqi+NC7775rWdayZcu01hdddBEhpLW1\ntfzAb33rW/X19cf2pQIAjCrosQOAI9PZ2blu3brZs2czxvz9Lrvssnw+/9FHH8XnJJPJCy64\noPyQmTNnEkI+/vjjzz//fOPGjZdddpllWeWjc+bMiaLonXfe6e7uXrt27aWXXmoYRnxoxowZ\nQRAsXrw43nQcZ968eeUHTpkypaur61i/XgCAUQTBDgCOzOeff04IWbZsWeIALS0thJBdu3bF\n5zQ0NFBKyw8ZM2YMIWTPnj3t7e2EkPHjxx/4hCeccEL8tB0dHYSQ+vr6w33rg57WNE2l1NC9\nMgCAUc8Y7gYAwKi0cOHCG2644aCdU6ZM+cKThRCEEMZYHMsOSmNa6/goY+zQowAAMHAIdgBw\nZCZMmEAIkVKee+65hzuno6NDSsk5jzf37NlDCGloaGhqaiKExP12ZfFmU1NTc3MzIWTnzp0H\nHm1ra3Ndt66ubohfBgBAJcJQLAAcmdra2hkzZqxcubKvr6+889lnn7333nvjnjlCiOd5q1at\nKh999dVXbdueMWNGY2Pjaaed9vLLL/u+Xz7a2trquu55552XTqdPP/30l19+OZ/Px4c2btw4\nadKk5cuXfyWvDABg1EOPHQAcsYceemjWrFnf/va377zzzsbGxrfffvvBBx9csGBBedJDc3Pz\n7bff3tbWNmXKlL///e8rV6685pprampqCCEPPvjgnDlzrrjiiltvvdWyrJdeeum1115bunRp\nVVUVIWTp0qVz586dNWvWbbfdVigUfvvb39bX1990003D+WoBAEaR4Z6WCwCj0ttvvz1r1qx0\nOm2a5imnnPLQQw+V1yg5//zzp02btnbt2pkzZ7quW1NTc8MNN+Tz+fJjV61adcEFFySTSdu2\nzz777BUrVhz4zK+88sq5557rum59ff38+fM//fTTeP9FF100ceLEA8+MV1E5tq8TAGBUofqA\nBd8BAAbvggsu6Orq2rhx43A3BADguINr7AAAAAAqBIIdAAAAQIVAsAMAAACoELjGDgAAAKBC\noMcOAAAAoEIg2AEAAABUCAQ7AAAAgAqBYAcAAABQIRDsAAAAACoEgh0AAABAhUCwAwAAAKgQ\n/x+NDneRaSFkowAAAABJRU5ErkJggg==" }, "metadata": { "image/png": { @@ -15076,18 +15206,18 @@ "source": [ "plot(my_history)" ], - "id": "18f8b406-c617-4b70-b6e3-93d175203bf1" + "id": "c5ba663e-2082-4351-a82e-5162855d1a9b" }, { "cell_type": "code", - "execution_count": 382, + "execution_count": 345, "metadata": { - "id": "d0ec3576-ec80-4193-9150-2dba46c0183c", - "outputId": "598818f6-4dc1-4efa-fea4-5da2f1cdb1d7", "colab": { "base_uri": "https://localhost:8080/", - "height": 86 - } + "height": 89 + }, + "id": "f893fbf4-0e06-469b-8696-3f09ee60c540", + "outputId": "1482fe7b-410e-4a36-dd6b-98c5dd9bd718" }, "outputs": [ { @@ -15096,8 +15226,8 @@ "text/plain": [ "\n", "Final epoch (plot to see history):\n", - " loss: 0.2077\n", - "val_loss: 0.1025 " + " loss: 0.04329\n", + "val_loss: 0.731 " ] }, "metadata": {} @@ -15106,30 +15236,30 @@ "source": [ "my_history" ], - "id": "d0ec3576-ec80-4193-9150-2dba46c0183c" + "id": "f893fbf4-0e06-469b-8696-3f09ee60c540" }, { "cell_type": "code", - "execution_count": 383, + "execution_count": 346, "metadata": { - "id": "08875606-ac30-4255-a055-7d2ba843ef49", - "outputId": "b8748f5c-f3cf-42fd-9ace-b734c3eb2cfb", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "a0f9cbd8-bb5e-4b58-b2d3-69860b30a25f", + "outputId": "0d363fe6-66c6-4f8b-9f05-4a636d85923f" }, "outputs": [ { "output_type": "display_data", "data": { "text/html": [ - "0.422995515523347" + "0.469698780964581" ], - "text/markdown": "0.422995515523347", - "text/latex": "0.422995515523347", + "text/markdown": "0.469698780964581", + "text/latex": "0.469698780964581", "text/plain": [ - "[1] 0.423" + "[1] 0.47" ] }, "metadata": {} @@ -15139,23 +15269,23 @@ "y_ <- my_model %>% predict(X)\n", "mean((y_ - y)^2)**0.5" ], - "id": "08875606-ac30-4255-a055-7d2ba843ef49" + "id": "a0f9cbd8-bb5e-4b58-b2d3-69860b30a25f" }, { - "id": "ea6a5cf1", + "id": "2ddf726c", "cell_type": "markdown", "source": [ "## 11.2 Kerasによる分類" ], "metadata": { - "id": "ea6a5cf1" + "id": "2ddf726c" } }, { "cell_type": "code", - "execution_count": 384, + "execution_count": 347, "metadata": { - "id": "7eb34baa-773d-4991-ade6-c83016884d2b" + "id": "0e1532c0-36dd-48f0-995b-e7e44168b796" }, "outputs": [], "source": [ @@ -15163,13 +15293,13 @@ "library(tidyverse)\n", "my_data <- iris[sample(nrow(iris)), ]" ], - "id": "7eb34baa-773d-4991-ade6-c83016884d2b" + "id": "0e1532c0-36dd-48f0-995b-e7e44168b796" }, { "cell_type": "code", - "execution_count": 385, + "execution_count": 348, "metadata": { - "id": "927c7dd6-9df6-4dc9-b871-92af96765d5a" + "id": "db5cda5a-326a-41bb-bff4-df697d822092" }, "outputs": [], "source": [ @@ -15177,13 +15307,13 @@ " select(-Species) %>% scale\n", "y <- as.integer(my_data$Species) - 1" ], - "id": "927c7dd6-9df6-4dc9-b871-92af96765d5a" + "id": "db5cda5a-326a-41bb-bff4-df697d822092" }, { "cell_type": "code", - "execution_count": 386, + "execution_count": 349, "metadata": { - "id": "69a0373a-8954-4e54-8a6a-44976e74b035" + "id": "ebdf7309-f0aa-45eb-9cf3-27ced560bc26" }, "outputs": [], "source": [ @@ -15191,13 +15321,13 @@ " layer_dense(units = 3, activation = \"relu\", input_shape = c(4)) %>%\n", " layer_dense(units = 3, activation = \"softmax\")" ], - "id": "69a0373a-8954-4e54-8a6a-44976e74b035" + "id": "ebdf7309-f0aa-45eb-9cf3-27ced560bc26" }, { "cell_type": "code", - "execution_count": 387, + "execution_count": 350, "metadata": { - "id": "ad36f909-aa4c-4424-99b3-95ef781113e0" + "id": "ab622858-6ecc-4389-b1f9-6aceb1d1bf83" }, "outputs": [], "source": [ @@ -15205,18 +15335,18 @@ " optimizer = \"rmsprop\",\n", " metrics = c(\"accuracy\"))" ], - "id": "ad36f909-aa4c-4424-99b3-95ef781113e0" + "id": "ab622858-6ecc-4389-b1f9-6aceb1d1bf83" }, { "cell_type": "code", - "execution_count": 388, + "execution_count": 351, "metadata": { - "id": "cdb8676e-4c27-4158-b3b6-de150e1fea6d", - "outputId": "4d26d6cb-d723-4a05-e03b-68f532ad394b", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "a3b72d4a-17b3-49d1-98c7-cf9c1dc6e360", + "outputId": "e30d1320-5054-4303-a940-69c3c993b7bf" }, "outputs": [ { @@ -15225,7 +15355,7 @@ "text/plain": [ "plot without title" ], - "image/png": "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\nfXj0n++7BuqJfr8V766RZiQnf/HFF0uXLiUinaOT2q+lMDaaiNjCAuHl86p2Hat8dwEAAKDS\nVXQeO19f35YtW546derIkSPh4eHh4eGXL1/28vJav3593759X7y9iZh2Hjsey7KNGzfe+9VM\nPRGtWE0jR9Pbw8lCcm7l8iFDhlhbWxORgGEEDPuPvJiItERqol7WVoYWxGJxs2bN1m/bLhJw\n9W1t8xTK7Tfi3m/p187VmWXowJmzbdq29fb2JiKti5vwyiVGpyMiLj1V1aI1PZxN2txgHjsj\nwjx2xoV57IwL89gZF+axA15FL8US0Ztvvnnz5s2UlJTz589fuHAhPT396tWr/fr1e/GWtV7n\nzp2FQiF98hm5uBIRsSwNH5HvWXfPnj2GOmPsZJ4Pe+k25+XfV6vLt9CrV6+g4OCrmdmWQsH+\n+Lsb+/fZcyv+q4izl9OzNDrd6NGjc3JyiEgvtdZ26MJvwigU4qjTVbODAAAAUJWMkNjx3Nzc\n2rVr5+/vb85PEjM3RUVFCoWCPDyIiBIT6PBfFBFOdZzT0tIMdUQsM9XJgV9W6fRLMnOeaGT1\n6tVCa5vL6ZmdPdy+DD/jJrX6qWcXB4mFmONYrSY4OFitVhORrmNnklqXtRlzkcV8xQAAADXO\nK46xa9y48ctUu3Xr1qu1X0vIZDIbG5vCuFt0+hT98zd5+1BpKaU8yLYZWL7aO3ayX7Nzk1Rq\nItqRXzjZ0b6B+NE4PLFYfPDgwc6dO9tbWCQWFAxo4DPvzPmp7VrF5+Vfy8q5nXz/3Xff3bVr\nl14o0vfoy/y5m4hIqxWfOFY6ZETV7i4AAABUrlfssXN8OcaNtebhOG7SpEm04H8UfZk2bKE1\nYbR5O333v0OHDsXExBiqCRlmWp2yTjutXv9z1pOddj4+PosWLYrNyq5rYz0/8vz/Xuv407lL\nSQWFbZydWtRxOnPq5LRp04iI2rTTurjxmwgS7wgS71TFTgIAAEBVYfS1csba7GyjXYiUSqUW\nFhb5+fmvNrRWq9X6+voWffI59ez1qHTB9++5uZR/3q5Wr+96J+m2UkVELFGEr3eTcp12vHHj\nxoUfPSJkWA8baWdP97Qi+eGEJD8nx8zikuTConnz5n3xxRelcTctd2zkpynW2TsWv/cBmdl0\ng/b29kRkmIfPbEmlUpVKZeY3JXAcZ2dnp1Ao5HK5qWN5ATs7u7y8PFNH8QISicTKyqqoqMjM\n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\nrtpz52VBjuNcVWED4TiOZVmed80R9+X5b6PCByenVjnPqvbui6xMbN6I8AhoWiLlIvwDEB6O\nC+ftDseMGTNmzZpV97vuGI1W+cQzJ5Yt6eCjBcCx7D1R4ftnTPrweOKuzCwJx73xxhtt2rS5\n5557XNKWm8OyLMdxrno/G4jzY+nC495wGIZx/510/mN3//eTZdnb4v1kGAYAz/NufinWedzd\n//1EA/w7cof7XsiNcpdPqk6nU6lUTM3NVQDUavU17hWorKx8//33x4wZo9FoKioqvLy8bDab\n8yLdd99999xzz3388cdKpdJZ2Gq1zpgxo3bd+++//7HHHnPt/qtUKtdW2EBcmGi7AT9IJCNO\nn7c7v5SnzUR+HhISEBkJDw+UFEOjgbcPTEZotF98883hw4cPHjzo5eVVl8qDoqNVb737x6MP\nDw6rDujNfbSjY5tYHPaE/CKH6JgxY8bBgwfj4uJc1Zyb4MI3s0E5b69s7L24vjp+Nhpd7ReL\nm7td3s/b5RYu5512bo7nedcedze/d5xclbsEO9T89VYX2dnZS5cubdeu3X333QdArVZ//fXX\nta8+/fTT991338GDBwcNGuRcwnGcs6RThw4dXHgbrCAIPM+bzeZ/3hHoVpxnmG504q9r6yOX\nvRYW/ExGdvXzxxfglcXIyYZ/ALKykJuLbt1RXISDByCVnT9/vnXr1kePHr32945MJgNgMpl4\nuaLJCy9/9tTjD7Zt6XxpUGSYUiKoJSknC4sulpV369Ztz549HTt2dGGL6k4QBLvd7v4HXSqV\n2mw21x73hiCTyZz3y7oznucFQbBYLHa7vbH35VoYhpFIJG7ewwOAVCplWdb9OyU4z4G5f8SR\ny+UOh8Plx/22OFVJruQuB8zLy0un04miWBvvKioqNBrNP0smJia++eab995774gRI65alVwu\n9/X1vbLfK8/z8+bNu7KMa3vF8jxvNBrd/J+987SNXq93bbUPqJRntV5fl5YDAC9gwdN4egGK\niuDji+JCZGfD4cCoMdi2FUB2Tk779u337t17jZsgpVIpAOd++gXNHVHnAAAgAElEQVQESCfc\nu+TzlYt7dXV+LLoHB6qlkg/jT1kcdpvd0adPn82bN3fr1s21jaqL26VXrDPYufy4u1xDfDhd\nTi6XC4JgNpvdPDNxHMdxnPu/nzzPsyxrMBjc/FLs7dIrVi6X2+121x53QRBui1OV5Erucvk8\n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\no9G4efPmq1evSsOWlpaEhIT6+nrytENbW5tOpzObzdLw2rVrCQkJDQ0NhDlM+fn5e/bsSU1N\nraqqsvLDPgwvv/zymTNnBk2SJwahc7fTL7/8olQqQ0JCpOHo0aMDAwMvXrzo2KpGhOeff97X\n13fQ5FB5kvPdaTSadevWBQUFScNbt24pFIqxY8eSpx28vLySk5NVKpUQwmQyHT58ODAwMCgo\niDCHo6qqqqGh4dVXX7XNkKd9ent7u7u7q6qqVq1alZGRkZ+f39TUJMgTf0BjZyej0ajRaFxc\nXGwzXl5eBoPBgSWNaEPlSc73z2Qy7dixIykpSavVkqfd+vv7X3rppZSUlMbGxk2bNimVSsK0\nW3t7e1FR0YoVKzw8PGyT5Gkfs9ns7e3d19e3fPnyvLy8np6edevWdXR0kCcG4eYJ+w38gcHw\nDZUnOd+Pa9eubdq0afr06UuWLJFmyNM+CoWisLDwzp07R44cWb9+/datWwVh2mvPnj2RkZHT\np08fNE+edvDy8tq3b59tuHbt2iVLlnz33XeCPPF77NjZydvb22g0WgfcemIwGLRarQNLGtGG\nypOc70dtbW1eXl5CQsKyZcuk/8rJczgCAwOnTp26du1ag8Fw4sQJwrTPuXPnzp49m56ePmie\nPB8IlUrl6+vb2tpKnhiExs5Ojz32WG9vb0NDgzQ0Go2NjY2PP/64Y6sauYbKk5zv6cKFCwUF\nBatXr37xxRdtk+Rph5qamqVLl3Z3d0tDFxcXV1dXQZj2Ki8v7+joyMnJSUlJSUlJMRgM27Zt\ny8/PJ0/76PX6Dz/8sK+vTxp2dXXdvHkzICCAPDHIqI0bNzq6hhFJpVLp9fpvvvkmLCzMbDbv\n3LnT09MzJSWFre97unPnTkdHh16vP3PmzOzZs81ms0Kh0Gg0/zZPtVpNznfR09Pz9ttvv/DC\nC5GRkeZ/IU/7aDSaQ4cOXb58ecKECZ2dnQcPHrx48WJmZqavry9h2uGJJ56YO8Dx48fT0tKS\nk5O9vb3J0w6jRo0qKipqamoKDg42GAwfffRRe3v7smXL+GHHIDzHzn5ms3nXrl01NTUWi2Xy\n5Mk5OTnsct+PzMzMlpaWQTOJiYlD5UnOd1FbW/vWW28NmszOzp4/fz552kGv1+/du/fChQsu\nLi7jx49/7bXXpk2bJoYOjTDv3+LFi5cvXy49g4087XP58uW9e/dKt7uGhYVlZWX5+/sL8sTv\n0dgBAADIBJ+xAwAAkAkaOwAAAJmgsQMAAJAJGjsAAACZoLEDAACQCRo7AAAAmaCxAwAAkAka\nOwAj0uzZs4ODgx1dBQA4Fxo7AAAAmaCxAwAAkAkaOwAPwIkTJ+Lj48eMGaNWqyMjI4uLi21L\nTz755IwZM44dOxYVFaVWq318fNLT0w0Gg+2AsrKy2NhYjUajUqmmTJny/vvvD/xTh+Xl5bNm\nzdJoNAEBAYsWLbp06ZJtydXV9ddff507d65Go9FoNK+88srt27cfzvkCgHOisQMwXBUVFXFx\ncT09PQcOHDh06NDTTz+dkZGxdetWadXd3b2hoSEvL++DDz64evXq9u3b9+/fn5aWJq2WlJTM\nnz/f09Nz//79paWlc+bMyc3NzcvLk1bLy8vnzJnj4eFRVFS0efPm77//PjY29rfffpNWLRZL\ncnJybGzs/v37c3Jyvvjii9zc3Id/+gDgRKwAMDwRERGhoaEdHR22mcTERI1G09nZabVaZ86c\nKYT49ttvbasZGRlCiKtXr1qt1vDw8PHjx3d3d9tWk5KSlEpla2ur1Wp96qmnQkJCent7paXT\np0+7ubkVFhZarda4uDipraH7AAADCklEQVQhhE6ns73wmWee8fPz+3NPFQCcGzt2AIalpaWl\npqZm/vz5CoWi61/mzZtnMpl+/PFH6RhPT8+YmBjbS2JjY4UQ58+fb25urqurmzdvnpubm201\nISGht7f31KlTt27dqq6unjt3rqurq7QUFRXV3d29cuVKaejh4ZGUlGR7YWhoaGtr6599vgDg\nzGjsAAxLc3OzEKKwsFA1QE5OjhDi2rVr0jH+/v4uLi62lzzyyCNCiBs3bjQ1NQkhHn300YFv\nOG7cOOltr1+/LoTw8/Mb6ksPelulUtnf3//gzgwARh5XRxcAQA7S09OzsrIGTYaGhv7bg/v6\n+oQQCoVCassGdWNWq1VaVSgUf1wFANwFjR2AYRk/frwQwmKxREdHD3XM9evXLRbLqFGjpOGN\nGzeEEP7+/oGBgUIIad/ORhoGBgYGBQUJIRobGweu6vV6tVrt6+v7gE8DAGSBS7EAhsXHxycq\nKqqkpKStrc02uW/fvg0bNkg7c0KIzs7Oo0eP2lbLysrc3d2joqICAgKmTJlSWlra1dVlW9Xp\ndGq1esaMGRqNZurUqaWlpSaTSVqqq6sLDg7euXPnQzkzABh52LEDMFxbtmyJj4+fNWtWbm5u\nQEBAZWVlQUFBSkqK7aaHoKCgVatW6fX60NDQr7/+uqSkZPHixVqtVghRUFCQkJCwYMGCFStW\nuLm5HT58+KuvvsrPzx8zZowQIj8/PzExMT4+/o033mhvb3/vvff8/Pyys7MdebYA4MwcfVsu\nADmorKyMj4/XaDRKpXLSpElbtmyxPaNk5syZ4eHh1dXVsbGxarVaq9VmZWWZTCbba48ePRoT\nE+Pp6enu7h4REVFcXDzwnY8cORIdHa1Wq/38/JKTk+vr66X5uLi4CRMmDDxSeorKn3ueAODc\nXKwDnvAOAA9cTExMa2trXV2dowsBAPnjM3YAAAAyQWMHAAAgEzR2AAAAMsFn7AAAAGSCHTsA\nAACZoLEDAACQCRo7AAAAmaCxAwAAkAkaOwAAAJmgsQMAAJAJGjsAAACZ+H/QajcUtdGiqQAA\nAABJRU5ErkJggg==" + "image/png": "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\n7n/ikrH469+QaFeAZ7dsv+fMwfudrj9/8fU+p8uq08TC4cmTJ7erRENRr2ela4+Mk3i+0flt\nINi6gNizMDZgiLpNxWK6pR9RXX6ye4IgCII4hZFgd2qyWCwTJ07EN6tw5STs2YNrr8ZTT2Dh\nfHjcFEXta3IFhdjX5ZVfT56YnZBQ7vGZNZodW7e+9tpr7eop1GoeTEtWt2XgbzUOV9vFlCKj\nLvrpZjuXU7v8U7KMLEEQBEGcKCTYnbIefvhhLhyCIGDOE/jb37HgI9z3AG6/U7FYJVn+/FDZ\n3wcPuH7ZV1U+/5zzRjx/4Tljuuc//PDDFRUV7eq5xWa5JKF54rq6mDitqq5NcGOY8GVXKDq9\nusceOsBv2dQJrSMIgiAI4udIsDtlJSYmXn755Vi1EsNHIi0dN16HO/+Gee/B42FYttLn21zn\nsOt0s849+5nN2/+09MtPDx5iFOWmm25qVw8FPJ+Rmsax6u43geCbTk/rAkqCOXzZFT8tI7tu\nNVN+uBMaSBAEQRBEOyTYncpmzpzJ1jtgt+OB+zDqfHy+Ai+/ipn3i0nJCsNurau/OD9nwsfL\neiVaV1w9YeZZQ0dmZxzat2/BggXt6rExzKuZaS3vlYfqG7aG2qwSK+XkCWed07wjy7ovPqX8\n/uPdOoIgCIIg2iHB7lSWnZ09btw4bP4eaWm4dAzuuQvXXIlnZsNRJ0lStT+wvro23WgYnJoy\nbvFn2xz1mSZTdoLprrvuqqqqalfV2Qb9nUmJ6rYgK3+uqnO2vdkueuZwsWcvdZsKBfWffYS2\nBQiCIAiCON5IsDvF/fOf/+Sqq5Cdgwf/jQQzlnyGL1fh5VfFrOzu3bt/X+soTLTds3rdu5eN\n7pNkX1py+IDLzQFXXHGF9LNY9q9k+yiTQd2uicX+UlUrtR4nQVGR0ZfLFqu6R9dWa9Z83SlN\nJAiCIAiiGQl2p7j8/PxrrrkGe3+E24W7/4VPP8H4MZh+G5oaDx8+bEtJ+aG+cUh6yqcHDi0/\nXPbs+ef844xBZ2WmO2tq/vWvf7WriqbwSkZa+pGb7dYFQnPazWyn1UbGTVLY5gL89s3cvj2d\n0EaCIAiCIFQk2J36ZsyYoXc2ITcP/30Nq7/GPTMwbyGmTpNTUrt167bH6aJALS05/NCIYf+3\nas23lTVZCcZuNvPcuXOXLFnSrio7y7ydlc7TzTPbPdvo/NLXZp1ZKTkleuGYll3NimVMfd3x\n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\n9ttjogidDrKMSARWG7JzQFPYuxcDB2HL97Da4PVAEHief/DBB6dOnao+1mazAXC5XIqivPrq\nq4+//HLs8dlKj57qb2lBMM96WPn+u/7JSTX+QFM4bNfrNDSzaOKYfItZLaNwfHj8JCk3/7i2\n0Wg0CoIgdO1JkhmGsVqtkUikc173jrBarW63+0SfxVHodDqDweD3+6NdewJFhmGMRqPX29Xv\nTDCbzRzHOZ3OrvNn6BfpdDoA4S4/Qstut8disfi+7hzHmc3mOFZIdIIuFOwee+yxQCBw6623\najSa+fPnl5eXv/jiizTdpk/xrrvu4nl+6tSpOp1u/vz5O3bsePPNN7Va7c033zxx4sQzzzxT\nLUbTtJoPfg0JdsdbKBS64YYb1q5dC4qCooCiYE9CZiY4Hj9sR04uRBExAQ4HNFoEg2lpqR99\n9FFBQUFLsGupaubjs/7bvQC9i9VdSozpn5kT+erLganJJo1mU3VtQaI1IMQ+nji2INGqlpEo\nSrj8KrFnr+PXQBLs4osEuzgiwS6+SLCLY4VEJ+gql2Kbmpq2bNkyderUvLy89PT02267raam\nZvfu3a3L+P3+pKSk6dOn5+fnp6Wl3XDDDT6fr6qqSv1Vamqq/YjfTnVEJ9Dr9YsXL37nnXc0\nPA+Og14PSYTTiWgEhb3R1ARZRkoqNBokmKDT1dXVDR8+fPTo0RUVFe2qmnXfzJ2jzzcePqTu\nKiwXvGeGfOWkbY6G+kDwnOzMhmAoLIp3r/72h/pGtQyjKOwnH9Z8+XmntpkgCIIgTrSuEuxK\nSko4jsvLy1N3jUZjZmbmgQMHWpcxmUz33ntvVlaWuut0OmmaVr+jRKPRTZs23XnnnbfccssT\nTzxRU1PT2Q0gfsnYsWMPHDhwwTnnIBhEIACPBx4PYjFkZsHrRWUlevdBKITsbLAsjKbtO3d2\n69Zt+PDhrS+sA0i3WPZedulg6UifKE0r026X/3Jbhd9f5fcX2RPtOt3G6rqnvtuytqr5BjuO\npgv2bH93yrVbtmzp3EYTBEEQxAnDnugTaObz+UwmE0VRLT8xm82/0aXs9/tfeuml8ePHW61W\nr9drsVhEUZw2bRqABQsW3Hvvva+++qrBYFALC4Jw5513tjx29OjRl156abzOnGEYAEajsYtf\nTaAoiqbpzu9UN5vNy5cvb2xsvPLKKzdt2oRQEFYr9AbYrHA4sOsHDBqCinKwLDIzUXpY4flN\n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" }, "metadata": { "image/png": { @@ -15251,18 +15381,18 @@ "\n", "plot(my_history)" ], - "id": "cdb8676e-4c27-4158-b3b6-de150e1fea6d" + "id": "a3b72d4a-17b3-49d1-98c7-cf9c1dc6e360" }, { "cell_type": "code", - "execution_count": 389, + "execution_count": 352, "metadata": { - "id": "8b261dcc-4d28-4058-8ef5-5c8879a92439", - "outputId": "f8051c64-da20-403d-ca92-51e9834d4bb9", "colab": { "base_uri": "https://localhost:8080/", - "height": 121 - } + "height": 125 + }, + "id": "a7af21c5-e6c0-4e4c-bd89-27c0b3c142c1", + "outputId": "874c1863-b689-48c1-f609-14e0f094c351" }, "outputs": [ { @@ -15271,10 +15401,10 @@ "text/plain": [ "\n", "Final epoch (plot to see history):\n", - " loss: 0.05125\n", - " accuracy: 0.9911\n", - " val_loss: 0.07347\n", - "val_accuracy: 0.9474 " + " loss: 0.04919\n", + " accuracy: 0.9732\n", + " val_loss: 0.09455\n", + "val_accuracy: 0.9211 " ] }, "metadata": {} @@ -15283,30 +15413,30 @@ "source": [ "my_history" ], - "id": "8b261dcc-4d28-4058-8ef5-5c8879a92439" + "id": "a7af21c5-e6c0-4e4c-bd89-27c0b3c142c1" }, { "cell_type": "code", - "execution_count": 390, + "execution_count": 353, "metadata": { - "id": "d49c4ef1-b092-413a-bd18-5b3675df33ca", - "outputId": "7a6ce55f-2c0a-47dc-e43e-cffc29d5dab4", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "b8e6f656-2f70-4676-a9e7-ffb461adbccc", + "outputId": "3a824cac-b1a1-4636-cdde-e0b9c3415cf0" }, "outputs": [ { "output_type": "display_data", "data": { "text/html": [ - "0.986666666666667" + "0.96" ], - "text/markdown": "0.986666666666667", - "text/latex": "0.986666666666667", + "text/markdown": "0.96", + "text/latex": "0.96", "text/plain": [ - "[1] 0.987" + "[1] 0.96" ] }, "metadata": {} @@ -15317,18 +15447,18 @@ "y_ <- apply(tmp, 1, which.max) - 1\n", "mean(y_ == y)" ], - "id": "d49c4ef1-b092-413a-bd18-5b3675df33ca" + "id": "b8e6f656-2f70-4676-a9e7-ffb461adbccc" }, { "cell_type": "code", - "execution_count": 391, + "execution_count": 354, "metadata": { - "id": "2f6510b7-a6c6-4f15-853c-7a007414adde", - "outputId": "cd4d20c7-1bb0-4fc7-ee20-08ac627582e7", "colab": { "base_uri": "https://localhost:8080/", "height": 52 - } + }, + "id": "2b895387-7206-4507-b895-6159bd4d2160", + "outputId": "abe37e4f-d581-4d02-f2e2-ee7053756f5a" }, "outputs": [ { @@ -15365,13 +15495,13 @@ "\n", "-mean(log(c(0.7, 0.6, 0.2, 0.7)))" ], - "id": "2f6510b7-a6c6-4f15-853c-7a007414adde" + "id": "2b895387-7206-4507-b895-6159bd4d2160" }, { "cell_type": "code", - "execution_count": 392, + "execution_count": 355, "metadata": { - "id": "0a03d8e7-b36c-455a-ba94-60043dbcbb5e" + "id": "c8d6f9bd-6386-4562-8c10-1fe706c491b5" }, "outputs": [], "source": [ @@ -15385,18 +15515,18 @@ " c(0.2, 0.5, 0.3),\n", " c(0.2, 0.7, 0.1))" ], - "id": "0a03d8e7-b36c-455a-ba94-60043dbcbb5e" + "id": "c8d6f9bd-6386-4562-8c10-1fe706c491b5" }, { "cell_type": "code", - "execution_count": 393, + "execution_count": 356, "metadata": { - "id": "49a50418-4ea1-4e32-8919-dce698699113", - "outputId": "6de94539-b740-48a3-d321-151fed7dc003", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "e292173c-2379-421f-b07e-f85e776d7f95", + "outputId": "b0b3565b-0923-46fa-f611-1d38466a5c35" }, "outputs": [ { @@ -15423,23 +15553,23 @@ "c(mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_1))),\n", " mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_2))))" ], - "id": "49a50418-4ea1-4e32-8919-dce698699113" + "id": "e292173c-2379-421f-b07e-f85e776d7f95" }, { - "id": "f58cd388", + "id": "630bfa2d", "cell_type": "markdown", "source": [ "## 11.3 MNIST:手書き数字の分類" ], "metadata": { - "id": "f58cd388" + "id": "630bfa2d" } }, { "cell_type": "code", - "execution_count": 394, + "execution_count": 357, "metadata": { - "id": "019fb7bd-363a-4ea1-95b5-87a52e137825" + "id": "6637d327-5399-40c9-abbb-f67a822e9394" }, "outputs": [], "source": [ @@ -15447,18 +15577,18 @@ "library(tidyverse)\n", "keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist())" ], - "id": "019fb7bd-363a-4ea1-95b5-87a52e137825" + "id": "6637d327-5399-40c9-abbb-f67a822e9394" }, { "cell_type": "code", - "execution_count": 395, + "execution_count": 358, "metadata": { - "id": "544df123-5113-4636-a4e2-793dbf386818", - "outputId": "ab1cdc3a-fb30-4879-e887-2077b48c82cb", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "38e2c258-ef74-4b69-906d-e415d4740146", + "outputId": "7d7d245a-bd3c-4f9c-8c34-8aa1886f617f" }, "outputs": [ { @@ -15484,18 +15614,18 @@ "source": [ "dim(x_train)" ], - "id": "544df123-5113-4636-a4e2-793dbf386818" + "id": "38e2c258-ef74-4b69-906d-e415d4740146" }, { "cell_type": "code", - "execution_count": 396, + "execution_count": 359, "metadata": { - "id": "5b5629cc-785e-4bdf-ad45-e2484ac456f4", - "outputId": "d4a0fbdc-ac47-4b94-f947-eb8c4c39a93d", "colab": { "base_uri": "https://localhost:8080/", "height": 912 - } + }, + "id": "d78e4877-3f31-47da-832c-6a02aa69a4a4", + "outputId": "a9dacc10-285d-4ca0-fb8d-cd769a4ee5e2" }, "outputs": [ { @@ -15605,18 +15735,18 @@ "source": [ "x_train[5, , ]" ], - "id": "5b5629cc-785e-4bdf-ad45-e2484ac456f4" + "id": "d78e4877-3f31-47da-832c-6a02aa69a4a4" }, { "cell_type": "code", - "execution_count": 397, + "execution_count": 360, "metadata": { - "id": "38113f92-5ccf-4008-b534-ce8ea3ccaa19", - "outputId": "ac6684b3-9bb7-4416-cc76-ad091dd3f1d5", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "21c13ef9-0329-48d5-8ade-b402d12f7bfe", + "outputId": "2a427cf8-2d5d-4d94-8cf5-22989d12edfa" }, "outputs": [ { @@ -15639,18 +15769,18 @@ "plot(as.raster(x = x_train[5, , ],\n", " max = max(x_train)))" ], - "id": "38113f92-5ccf-4008-b534-ce8ea3ccaa19" + "id": "21c13ef9-0329-48d5-8ade-b402d12f7bfe" }, { "cell_type": "code", - "execution_count": 398, + "execution_count": 361, "metadata": { - "id": "b6766199-aee6-4479-b119-2b30c10e2a70", - "outputId": "673fd464-36e1-463f-8b8c-0db44b25f461", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "20f2ab02-9e36-4ea3-b212-9b4d7ee65c42", + "outputId": "b6dda9bf-cf41-4265-fca9-4df032c5ead0" }, "outputs": [ { @@ -15676,18 +15806,18 @@ "source": [ "head(y_train)" ], - "id": "b6766199-aee6-4479-b119-2b30c10e2a70" + "id": "20f2ab02-9e36-4ea3-b212-9b4d7ee65c42" }, { "cell_type": "code", - "execution_count": 399, + "execution_count": 362, "metadata": { - "id": "d6c32f64-e99e-4198-bb39-aaefda651aec", - "outputId": "0ece86a2-998a-415c-e7d9-8a9c26b51ea8", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "9d8baf8b-c43a-4a23-b894-33d7a9850e3a", + "outputId": "ff9fa571-0b78-4ac0-e208-a608e137acb3" }, "outputs": [ { @@ -15713,26 +15843,26 @@ "source": [ "c(min(x_train), max(x_train))" ], - "id": "d6c32f64-e99e-4198-bb39-aaefda651aec" + "id": "9d8baf8b-c43a-4a23-b894-33d7a9850e3a" }, { "cell_type": "code", - "execution_count": 400, + "execution_count": 363, "metadata": { - "id": "ce02b2ee-0f3b-4114-be2a-e13bf2c17bf8" + "id": "971617a3-220d-4f90-89c5-06a9db9845a7" }, "outputs": [], "source": [ "x_train <- x_train / 255\n", "x_test <- x_test / 255" ], - "id": "ce02b2ee-0f3b-4114-be2a-e13bf2c17bf8" + "id": "971617a3-220d-4f90-89c5-06a9db9845a7" }, { "cell_type": "code", - "execution_count": 401, + "execution_count": 364, "metadata": { - "id": "347fc752-b42c-49da-814a-392335f35084" + "id": "b3f0db09-c310-4148-9007-8bfa7d4f88d9" }, "outputs": [], "source": [ @@ -15740,17 +15870,17 @@ "x_train <- x_train[my_index, , ]\n", "y_train <- y_train[my_index]" ], - "id": "347fc752-b42c-49da-814a-392335f35084" + "id": "b3f0db09-c310-4148-9007-8bfa7d4f88d9" }, { "cell_type": "code", - "execution_count": 402, + "execution_count": 365, "metadata": { - "id": "70f81106-e64b-46a6-bfe5-05077f5aa752", - "outputId": "245635e7-d31e-41f0-f61e-438077b4c3a6", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "5d260e35-d03b-4f06-87a2-cd866e0c2062", + "outputId": "3f395209-88af-4633-a0a7-3766139c8d51" }, "outputs": [ { @@ -15787,18 +15917,18 @@ "my_cb <- callback_early_stopping(patience = 5,\n", " restore_best_weights = TRUE)" ], - "id": "70f81106-e64b-46a6-bfe5-05077f5aa752" + "id": "5d260e35-d03b-4f06-87a2-cd866e0c2062" }, { "cell_type": "code", - "execution_count": 403, + "execution_count": 366, "metadata": { - "id": "16234cff-9298-4b95-a43e-d8474f4a2507", - "outputId": "2dffd414-2977-4513-9a15-efed457d8fea", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "4513ef65-be2b-4306-b936-d17ac3a2ab1b", + "outputId": "bd2fe3bc-0d7a-4bd5-b7ff-23bc2f142646" }, "outputs": [ { @@ -15807,7 +15937,7 @@ "text/plain": [ "plot without title" ], - "image/png": "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\n7Cw03d1i6m4xBbb4JTnH78/187l+/1FeOOL3H/HzR/2876LTniDLJ3jhBC+cawcDTcUyTBOO\njWPYJkZDsskYJUlJHJvAsokcG8ewuM0LDe+PP/4gg4ecTHWEkJtuXvfcM9pVBACXA8EOGo6/\nRx+qstywYyshhIii+afvqu+8T4yLP+vO1dXVPM+f8jFDCIlyVFVV1WuRBppSFlKpu1EmpJAX\njvB8Ps8f54UCXigQhOO8kM/zxYJ4qTdz/ZJcIAkFSvI742pYiopjmWSOS+bYFI5LMXBNObYp\nxyVzrJ2pl3m7PM8LgmA2m+vj4BAuJEki9Kk/YAwtne05fhAMWZaLi4tjY2NpGstqQr1AsIMG\n5Rs8jHY62UOZhBDK7zf/8KV77D9lW+SZe0ZGRqakpBzbspmMuqFmk99Pdu1o98QTDVmwgiKk\nCcc24VhCTk8/oiyXiGIhLxQK4tsLF24pLSN9+5GoKOL3k+pqLi6OZy/tt0yQ5eO8cJwXtp3x\nT5E03cLApRoNLQyGVAPX3MC14LgkjrvsHr6srKznn39+/fr1giC0bdt26tSpV1999WUeC8Jc\nnz59vpv1f+See4klombT8p/79OmjaVG64vV6Z82aNX/+fI/HYzabx48f/+yzz1osl/8cbYCz\nwhg7ndB8jN3atWu//PLL48ePp6WlTZw4sUOHDufakxJ486LPmOP5yksxIbH6jvFnXQBlyZIl\n9z/6KJn4MOnZm1SUk4UL2lc5f/vtN6Px9CfGhoK9e/cO/sdQ8tmXJLF2sPnfGcxjj2zL2CtF\n2Qt5oUQQCwWhWBCLBeGEIJQIQiEvFotidXCdIgaKSjUa0gxcqsGQauCURvJFpL2ysrKrrrrq\nROeu5LY7iMlE1v1OPv142eLFvXv3DqaeAIyxCy+CINx4442bC4vITTeTiAjy5x/W7VtXr16d\nlpamdWlq0nCM3ZNPPvnZ7+vIo4+Rlq3I4Vzy/rtjrug+e/ZstY6PMXagQLDTCW2D3fvvvz/r\n1Vf+2aVjuiNq+4mirzMPffzxx8OHDz/X/pTbFfHFx5Sz5g1ISEuvvuk2crYbEz/88MPMmTNz\ncnJMJtO11147bdq0xMTE+rqM4CxatOjRd98jcxecsvWG6xZ/+smAAQPO9VVGo9FFUdkVlcd5\noVAQjgtikSAoN3zz/PxZV+C7GEraa1kn6qUZuSSOqxv2XnnllbfX/E7efu/k0jPz5/bKOvDz\n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\nRUUJCQkWi0XFgxuNxotZIvHiud1u4jh1oWNbZDB9qCaKMjFMJEWd/og5WSaHslpJYh9LUEuX\n/fbGf6umvUK6dT+56fOFNzaJnzlz5uUdsFqSffLJLBgZGclxXFlZmSr3cyoqKgYOHFj9+FOk\n75U1mzZttLwybef27UGu8pg8qD95dzZp0/bkptUre1ZVzJ8//zxfdZGzYvfv379q1SqXy9Wl\nS5fhw4fTITxmdMaMGRuGDDn+yEQyYCCpriY/Lxt6RffbbrtN67pAM6Ee7JxOp81mo+r89WO3\n28+zTk9VVdV777134403OhyOwEa/3//4448HXg4bNmzEiBH1VLCGaJrWT5+53S6PvVf+YoHy\nBB7p4AHq+6/st4/T35B8mqYpigry6RShyeFwNG/ePDB1NGRdccUVS7/6moy7lwQ6Djes79q1\n6/l/mxiGYRjmPNFnyJAhFleV568/Sb8BNZvWro6UpMGDBwf5e3rzzTd/+ukC0qEjUaY9Zh8i\na1ffvmTJZR/2tC9jWZaiKGudt9Bg7Nu8uVqUTqY6Qkifvh6jaf/+/UG+D7dt23bPju0ng50k\nkZ3bu9w8+vz/HyiKuuD/qP/+978zZszwd+5KbDbyyad92ny4fPlytRYQUZ3dbt+9e/d77723\ndetWq9U69LVXx40bp1YSDfFfXjirMPg4oS66T/vYsWMzZszo2rXrPfec0rsjy/KWLVsCL9u3\nb18fawSEAl1dV7sO0rj7+c/mEUEghMj7MqjvvuTuHK+/bEcICeX+gCApAUjrKs7niSee+Oyz\nz3JemkJuu4OYzeTPP0yLv39j7doL/jad/7uWlJT07rvv3v+vf5FrryMtUkn2IfLbrx8tXBj8\nzYS33npr+8CBGePuJD17EVcV2fDX5CefHDp0aJCHPY1abyb0WadIMzRN00Ge4vXXXx9x003E\nYiH9BxCPh3z5eUplxWOPPXbBw55/h/Xr17/w8svkzXdIh06EEOJxb3rqieeee+7DDz8Mptp6\nFRcXN3369Po4siCcZyozhKhQD3ZRUVFOp1OW5UC8q6ysdJztT8ndu3fPnDnzjjvuGDly5Gn/\nZDQat23bVncLJk+Eh5g49rqbzEt/IJJECJEydrm//KR6+PWkAcev1Df9TZ4IMJvNERERVVVV\nPp9P61ou4Pvvv582bdqa5//j8/m6dOky5ZtvWrVqdf53iYtZoPiGG25ISkr69NNPj27Z2KJF\n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\nAAAfk5ub++6776ampqrV6iFDhsycObPau1RVYacTV5iwuQJXmChzBbZUUBUVlNWCTUZstSCe\n74tQ3wl/bfDJUlSH4ECEELrbVEdEIiKT2yn64ImTfSPDVDcnkOVXmKfv2v3Bxk/CElohqYQw\nd7krR+/evT/78qulS5cu++xriUQyePDg7xYtUjQs1bmNHj16wIABp06dMplMnTp1io2NbXib\nbhjjjh07duzY0VMN+rRoluXRrSNkgiBcv36daHWocsahy4nKyiLCw6sNTFSdJgugRx555M03\n33zvvfe2bds2btw4pVKZkZExcuTIhQsX7tq1SyKR/PDDD+PHj6/2te7JJJXjcJVbwNS9hWoJ\nguC8uTNOHec81BEEOwAA8CUZGRlDhw4dGh7yQqs4o8P54fv/OXDgwNdff01RFLbZKLMJm4y4\nwoTNZrrC6E5y2GRyb8PmKYRhiVyOFEpBIiUymSBXIJlckMqITIbkSkEiRTJZ5cyzHy+/OnfL\n1/8a2LdTSFBqUcmCA4f7j58Q2rlLw+d3Dxw4cODAgU6nk2VZz340qlSq++67r/Z6oAH+bB1X\nbfmGQ/tfe3IZemgyatUaXctGX34x/5/PvDxkYEO+18SJE59++umjR49+9913W7ZsQQidPHmS\n47hXXnnFveHfsWPH7vTayMhIQsi1a9fcB1xdvHjRXV73FhBCiYmJgiCkpaW577FaLJZr165V\nHfzzIAh2AADQiFwuV1FRUWhoqKfOF3nrtQXPdmyzqN+NY7VndG7/Z34heX+FghDMeXIxR6HZ\ncsVq7zVkiKBQEpmcyJVELidyOZErSX02v126dOl7gYGzPv5Yr9frdLonn5rh2SnRtY5WAt8y\nY8aMyMjIjRs3Xt39a3R09BOr3x03blwD21SpVKNGjXrrrbcoirr//vsRQrGxse6FGj169Pju\nu++OHDmCEMrPz7/9LJDevXsHBAS8/fbba9asKSkpqVxde6cWoqOjZTJZRkZGeXl55RByp06d\n+vTpM3fu3M8++0wsFs+bN0+pVNZrhK/uINgBAECjMJvNixcv/vzzz10ul3t6++uvvy6VSuv4\ncuxy4vJyylROGY3YaMAmI1VhokzGnd07VK0moun+URGovgNyFEVkckGhJO4/coWZpuctWRqG\nyZT2bWQM8+OVq28cPPLp1q32Bg9ciUSiV1999dVXXzWbzR65VQr83ogRI0aMGOHZNqdMmTJx\n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" + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAIAAAByhViMAAAACXBIWXMAABJ0AAASdAHeZh94\nAAAgAElEQVR4nOzdd2AUZd4H8Gfa1mw2u4SEFEgjdBCR3lGOJqAecHrnqSCKsXF4p7566qGc\nnp6K2OGwgYoVOT0BCwLSu3RIgJBASICQtn1np71/TAihB7LJ7E6+n7+encw++xsSNt88+8zz\nUIqiEAAAAACIfrTWBQAAAABAeCDYAQAAAOgEgh0AAACATiDYAQAAAOgEgh0AAACATiDYAQAA\nAOgEgh0AAACATiDYAQAAAOgEq3UB2qisrNS6hPCz2Wwej0frKsKPpmmbzSYIgt/v17qW8OM4\njmGYYDCodSHhZzAYzGaz3+8XBEHrWsLPbDYLgiCKotaFhJ/VamVZ1u1263L5er2+TxJC7Ha7\nKIo+ny+MfbIsa7PZwtghNIImGuwkSdK6hDCjKIqiKP1dl4qmaaLH7xohhGVZotNLI4TQNK0o\nii6vjqIoWZb1emk0TUuSpMtgp16a1lU0CJqmw/5bQH3vheiC7xkAAACATiDYAQAAAOgEgh0A\nAACATiDYAQAAAOgEgh0AAACATiDYAQAAAOgEgh0AAACATiDYAQAAAOgEgh0AAACATiDYAQAA\nAOgEgh0AAACATiDYhYHL5crNzdXlPu4AAAAQRRDs6uXkyZMTJ05s3br1gAEDMjMzn376aZ7n\ntS4KAAAAmihW6wKimCRJkydPjjlZsuueP2fG2bceP3nfwq8kSXrxxRe1Lg0AAACaIozYXb3V\nq1cf3Lnz85tHtXE6WJrunZL08ZjhH374YVlZmdalAQAAQFOEYHf1Dh8+3KG5M9ZgqDlyTUJz\nM8MUFBRoWBUAAAA0WQh2Vy8+Pv6Y26vUOlLmD/gFoXnz5prVBAAAAE0Ygt3VGzJkCG+x/nPt\nRllRCCF+QXzo55V9+/VLT0/XujQAAABoinDzxNWLjY1977337rnnnk/35GY67HtOlSdmZC54\n5x2t6wIAAIAmCsGuXnr16rVhw4aVK1eWlJTktG49ePBghmG0LgoAAACaKAS7+oqJiRkzZozW\nVQAAAABgjh0AAACAXiDYAQAAAOgEgh0AAACATiDYAQAAAOgEgh0AAACATiDYAQAAAOhEFCx3\n4vV6586du2vXLkEQ2rZtm5OTk5CQcM45x44d++ijj/Ly8kRRzMjIuOOOOzp06KBJtQAAAABa\niYIRu9dff720tHT69OmvvPKKxWKZMWOGLMu1T1AUZcaMGQ6HY+7cufPnz+/UqdOzzz7r8Xi0\nKhgAAABAE5Ee7MrKyrZs2TJlypSMjIzk5OScnJzi4uLdu3fXPsftdp84cWLo0KEWi8VoNI4a\nNSoYDB4/flyrmgEAAAA0EekfxR48eJDjuIyMDPVhTExMampqXl7eNddcU3OO3W5v167djz/+\nmJKSwnHcjz/+mJiYmJ6eXnOCoii1B/CMRiNFUY11BY1EvSL9XVdturw66jStC2koOr46HV8a\n0el/N5WOL42E++r0/W+lV5Ee7Nxut81mq/2zZbfbXS7XOac98cQT//jHP26//XZCiMPh+Mc/\n/mEwGGq+GgqFrr/++pqHEydOfOihhxq4cG00a9ZM6xIaitFoNBqNWlfRUEwmk9YlNJSYmJiY\nmBitq2gQOv6BJIQ4nU6tS2goOn6f5DguvFcnimIYe4PGEenBjtThLwZRFGfMmNGuXbsXXniB\n47ilS5dOnz79rbfecjgc6gk0TQ8dOrTm/NatW/M834AVa4GiKI7jQqGQ1oWEH0VRBoNBlmVB\nELSuJfwYhqEoSpfvngzDsCwrCMI5k2L1geM4SZL0emk0TevvTVJlMBh0+T5JCDEajWF/n1QU\nhWWjICdAbZH+DYuLi3O73Yqi1MQ7l8tVk9hUu3fvLigoeOmll9Rhj/Hjx//www9r164dM2aM\negLHcS+99FLtp5SVlTVK+Y2Hoqi4uDhd3jLCMIzBYBAEQZdXZzQaWZb1+XxaFxJ+ZrOZZdlg\nMKjLiGCz2YLBoC7/2LDb7TRNe71eRVG0riX8nE6nLt9JCCFGo1GSpPBeHcdxOv48Qa8i/eaJ\n7OxsQRDy8/PVh263u6ioqH379rXPURRFUZTafzrrcvwDAAAA4NIiPdg5nc4+ffq88847BQUF\nxcXFs2bNysrKUteoW7Zs2ffff08IadeuncPh+PDDD71ebygUWrRokc/n6969u9a1AwAAADSq\nSP8olhAyderUuXPnPvvss5IkdezY8emnn1Y/lt2xY4fb7R4zZoy6uN38+fNzcnIkSWrVqtX0\n6dOTkpK0LhwAAACgUVG6nEVxWXqdY1dZWal1IeHHMIzD4eB5XpczY/Q9x85qtXo8Hsyxiy52\nu53juPLycl3+dnA6nRUVFVpX0SDi4+MFQTh/1Yj64DjObreHsUNoBJH+USwAAAAA1BGCHQAA\nAIBOINgBAAAA6ASCHQAAAIBOINgBAAAA6ASCHQAAAIBOINgBAAAA6ASCHQAAAIBOINgBAAAA\n6ASCHQAAAIBOINgBAAAA6ASCHQAAAIBOINgBAAAA6ASCHQAAAIBOINgBAAAA6ASCHQAAAIBO\nINgBAAAA6ASCHQAAAIBOINgBAAAA6ASCHQAAAIBOINgBAAAA6ASCHQAAAIBOINgBAAAA6ASC\nHQAAAIBOINgBAAAA6ASCHQAAAIBOINgBAAAA6ASCHQAAAIBOINgBAAAA6ASCHQAAAIBOINgB\nAAAA6ASCHQAAAIBOINgBAAAA6ASCHQAAAIBOINgBAAAA6ASrdQHaoChK6xLCTL0i/V1XbXq9\nOoqi9HppRNdXp+NLI/r970Z0fWkk3Fen738rvaIURdG6Bg2Ioqh1CeHHMIwkSVpXEX4URTEM\noyiKXq+OoihZlrUuJPxomqZpWpIkXb7JMAwjy7JeL42iKF2+SRJCWJbV8aWF/X1SlmWDwRDG\nDqERNNERu6qqKq1LCDOKouLi4vR3XYQQhmEcDkcoFPJ4PFrXEn5Go5FlWZ/Pp3Uh4Wc2m61W\nq9/v53le61rCz2azBYNBQRC0LiT87HY7x3Eul0uXsdXpdOryfZIQEh8fL4qiy+UKY58cxyHY\nRR3MsQMAAADQCQQ7AAAAAJ1AsAMAAADQCQQ7AAAAAJ1AsAMAAADQCQQ7AAAAAJ1AsAMAAADQ\nCQQ7AAAAAJ1AsAMAAADQCQQ7AAAAAJ1AsAMAAADQCQS78KD8PsO6VXRVhdaFAAAAQNPFal1A\n1KP4oPHXZeze3ZQk0sFA8IYRWlcEAAAATRRG7OpLMRiZo4WUJBJC2F3bqUBA64oAAACgiUKw\nqzeKEq7rVd0UBW73b9qWAwAAAE0Wgl0YCJ2vVcxmtW34bTORJG3rAQAAgKYJwS4MFI4TOl+r\ntimPhzuwX9t6AAAAoGlCsAuPULdehGHUNrdlg7bFAAAAQNOEYBceis0mZLdT28zJ40xxkbb1\nAAAAQBOEYBc2Qo8+NW3D1o0aVgIAAABNE4Jd2EgtkqWUlmqbPZhLV1VqWw8AAAA0NQh24SR0\n713dUhTut82a1gIAAABNDoJdOAmt28pxDrXN7d5OBYPa1gMAAABNCoJdWNG00K2n2qRCIW73\ndm3LAQAAgCYFwS7MhM7XKkaT2jZs24TFigEAAKDRINiFmWIwCF1qFit2cwdzta0HAAAAmg4E\nu/ALXduD0NX/sFisGAAAABoNgl34Kfa4M4sVnyjBYsUAAADQOBDsGkSoZt0TQgyb12tYCQAA\nADQdCHYNQk5OPbNYcf4BuuyUtvUAAABAU4Bg11BCPftWtxTFsA07jAEAAECDQ7BrKGJWGzm+\nudpm9+6ifF5t6wEAAADdQ7BrMBRVM9OOkiQDdhgDAACABoZg14DEDl0Ua4za5nZso0IhbesB\nAAAAfUOwa0AKw4RqdhgLBrDDGAAAADQoBLuGJVzb/cwOY1s2YIcxAAAAaDis1gVcntfrnTt3\n7q5duwRBaNu2bU5OTkJCwvmnLV269L///W95eXlKSsqdd97Zo0ePxi/1fIrRJHTuati6kRBC\nedxs3j6xQ2etiwIAAAB9ioIRu9dff720tHT69OmvvPKKxWKZMWOGLMvnnLN8+fIvv/zyvvvu\nmzNnztChQ9977z2/369JtecLde9NGEZtGzavI4qibT0AAACgV5Ee7MrKyrZs2TJlypSMjIzk\n5OScnJzi4uLdu3efc9qXX3551113de/ePSEh4aabbpo7d67FYtGk4PMptlixbUe1zZwqZQoP\na1sPAAAA6FWkB7uDBw9yHJeRkaE+jImJSU1NzcvLq31OeXn5iRMnCCFTp06dMGHCo48+mpub\nq0GtFxfq1ZdQlNo2bt2gbTEAAACgV5E+x87tdttsNup0KiKE2O12l8tV+5zy8nJCyC+//PL4\n44/b7fYvvvjiueeemzNnjt1uV0/geb5fv34150+cOPGhhx5qlPJPi48XstvKB3IJIUzh4WZ8\ngDq94Vi4Xye+IbqNBEaj0Wg0al1FQzGbzVqX0FBsNpvNZtO6igah4x9IQkizZs20LqGh6Ph9\nkuO48F6dKIph7A0aR6QHO0JI7VR3Cbfeemtqaioh5O677165cuXWrVtvuOGGmh7at29fc2ZC\nQoIGP6z9BpMD1eOIwqoV9B9uD/srMAwj6fGuW4qiGIZRFEWvV0dR1PnTRnWApmmapiVJUvQ4\nr5RhGFmW9XppFEXp9Tc6y7I6vrSwv0/q8q1J9yI92MXFxbndbkVRauKdy+VyOBy1z3E6nYQQ\nq9WqPmQYxul0VlZW1pxgMBg++eST2k8pKytr2LrPF59gSWjBlJ4ghCi7t7t69VPscWHsnqKo\nuLi4qqqqMPYZIRiGcTgcoVDI4/FoXUv4GY1GlmV9Pp/WhYSf2Wy2Wq1+v5/nea1rCT+bzRYM\nBgVB0LqQ8LPb7RzHuVwuXcZWp9Opy/dJQkh8fLwoiud8olVPHMcZDIYwdgiNINLn2GVnZwuC\nkJ+frz50u91FRUW1h98IIU6n0+Fw1MyrC4VCp06dSkxMbOxaL0fo2be6JcvGrRs1rQUAAAB0\nKNKDndPp7NOnzzvvvFNQUFBcXDxr1qysrKwOHToQQpYtW/b9998TQmiaHjNmzBdffLFjx46y\nsrL//Oc/JpMpQtaxq01o20E+PUrH7vqN8utwkAYAAAA0FOkfxRJCpk6dOnfu3GeffVaSpI4d\nOz799NPqx7I7duxwu91jxowhhPz+97/3+/2vvfaa1+tt27bt888/bzKZtC78PDQd6tnXtGwp\nIYQSRcO2TfyA67WuCQAAAPSD0uUsisvSYI4dIYQQSpKsc9+kvB5CiGI0+qb8RQlTAFXn2NWe\nWagb6hw7nucxxy66qHPsPB4P5thFF3WOXXl5uS5/OzidzoqKCq2raBDx8fGCIIR9jl3N+hIQ\nLSL9o1idURgmdF1PtU3xPLdjq7b1AAAAgJ4g2DU24dqexFy9K4Zh2yZK1OFf/AAAAKAJBLvG\npnAc37W72qb8PnbXdm3rAQAAAN1AsNNA6LqeCle9MpBxywaix3V3AQAAoPEh2GnBbBG6XKs2\nKbeL3b9H23IAAABAHxDstBHq0YcwjNo2blpH9Hj3GQAAADQyBDttKLZYoUMXtU1XlLEHc7Wt\nBwAAAHQAwU4zod79CV3972/YsAaDdgAAAFBPCHaakeMcQnY7tc2UnmCOHNa2HgAAAIh2CHZa\nEvoMIBSlto2b1mlbDAAAAEQ7BDstSc0TxYwstc0cLaSLi7StBwAAAKIagp3GQr0H1LSNG9Zo\nWAkAAABEOwQ7jUkpLaWWaWqbLTjEHC/Wth4AAACIXgh22uP7DKxpGzBoBwAAAFcLwU57UlqG\nlNpKbbP5B5gTJdrWAwAAAFEKwS4ihPqcmWln2LRWw0oAAAAgeiHYRQQxPUtKaam22YN5zKmT\n2tYDAAAA0QjBLlKEevevbikKh5l2AAAAcOUQ7CKFmJkttUhW29yB/UxZqbb1AAAAQNRBsIsg\nZ2baKQq3ETPtAAAA4Mog2EUQMauNlJiktrm8fXRFmbb1AAAAQHRBsIskFCXUzLSTZSMG7QAA\nAOBKINhFFiG7ndQ8QW2z+/fQleXa1gMAAABRBMEuwlCUULN7rCwbNq7TtBoAAACIJgh2EUdo\n20GOb662uX27aFeVtvUAAABAtECwizwUFao1086wfpWm1QAAAEDUQLCLRELbjnKzeLXN7duN\nmXYAAABQFwh2EYmmQ30HVbdl2bButabVAAAAQHRAsItQQtsOUvNEtc3l7mFOYSMKAAAAuAwE\nu0hFUaG+A6vbisJhph0AAABcDoJd5BKz253ZPfZgLlN6Utt6AAAAIMIh2EWwswftDOt+1bIY\nAAAAiHgIdhFNzGojJ6eqbfZQHl1SrG09AAAAEMkQ7CJdsOb2WEKM63/VrA4AAACIeAh2kU7K\nyJJapqlttiCfOXZE23oAAAAgYiHYRQF+wPU1bSPWtAMAAICLoBRF0boGDUTdVYvvvSPnH1Db\n7L0P0VnZ559DUbr9blIURaLwu1ZH+v7G4dKiDv67RamG+MaJoshxXBg7hEag2x/xSysrK9O6\nhCvDlByzLPhQbUspLf1/mnTOCRRFxcXFVVZWNnppDY5hGIfDwfO8x+PRupbwMxqNLMv6fD6t\nCwk/s9lstVo9Hg/P81rXEn42my0YDAqCoHUh4We32zmOKy8v1+VvB6fTWVFRoXUVDSI+Pl4Q\nBJfLFcY+OY6z2+1h7BAaAT6KjQ5ScqqY0VptM8VFbEG+tvUAAABABEKwixqh/oMJRaltw+rl\nRI9/TAMAAEB9INhFDalFspjdTm0zpSe43L3a1gMAAACRBsEumvADrid09bfMsGYFkSRt6wEA\nAICIgmAXTWRnM6HjNWqbdlVxu37Tth4AAACIKAh2UYbvP1hhq28+N65bRYVC2tYDAAAAkQPB\nLsooMTahWw+1TQX8hm0bta0HAAAAIgeCXfQJ9eqvmM1qm9u8nvLrcAk0AAAAuAoIdtFHMZlC\n3fuobSoUMmxap209AAAAECEQ7KKS0L23YotV24btW2hXlbb1AAAAQCRAsItKCsvyfQZUP5Ak\n4/pVmpYDAAAAEQHBLloJna+Vm8WrbXbvLrr0hLb1AAAAgOYQ7KIWTYf6Da5uK4ph7a8a1gIA\nAACRAMEuiglt2kstktU2eyhPOVKgbT0AAACgrTAEO7/ff/z4cbUdCATmzZs3c+bMw4cP179n\nuAyK4gdcX/NIXvodURQNywEAAABt1TfY5ebmZmRkzJ8/nxAiiuLAgQMnTZr06KOPduvWbfv2\n7eGoEC5FSs+UMrLUtlJ0hMvbp209AAAAoKH6BrunnnoqMTFxwoQJhJAvvvhi69at77777qFD\nhzp27Pivf/0rHBXCZQQHDyN09ffRsOoXShK1rQcAAAC0Ut9gt3bt2ieeeCIrK4sQsmjRok6d\nOt1///1ZWVkPPvjgpk2bwlEhXIYc31zoeI3apt0ubttmbesBAAAArdQ32FVVVSUlJRFCJEn6\n9ddfR40apR5v3rz5yZMn61sd1A0/8HrFYFDbhg2rsckYAABA01TfYJeYmKjeJ7FixYrKysoR\nI0aox4uKipo1a1bf6qBuFItV6NFXbVOhkHHDGm3rAQAAAE2w9Xz+sGHDnn766UOHDn3++edZ\nWVkDBw4khJSWlr7xxhv9+vULR4VQJ0Kvfsa9O5WqSkIIt2Nr6Jrr5PjmWhcFAAAAjaq+I3b/\n/Oc/09PTX3rpJZ/P9+mnnzIMQwiZOnXqkSNHnnnmmXBUCHWisCx1Q/VwKZFl45oVmpYDAAAA\nGqhvsEtKStqwYYPL5SopKendu7d68NFHH83Ly+vSpUu9y4MrQHfrISUmqW32UB5TiKUEAQAA\nmpbwLFDs8/k4jiOnFyhetWqVz4f5+42Oovghv6t5ZFy1DOsVAwAANClYoFhXpJbpYlYbtc2U\nnmT37tK2HgAAAGhMWKC4XoLB4Msvv9ytW7ekpKT+/ft//vnnitaDZPzg3xGGUdumtSsoQdC2\nHgAAAGg09b0rdu3atbNmzTpngWJCyIMPPvjEE0+EocDINm3atG82byF3TyEpKXn790195hmX\ny5WTk6NhSbKzmdClG7d9CyGE8ngMW9bzfQdpWA8AAAA0GixQfPW2bNnyzeIl5NVZZPAQkt2G\njL2ZPPnM888/7/V6tS2M7zdIMZrUNrdpPeWq0rYeAAAAaBxYoPjq7dmzh2Rnk4TEM4d69uIJ\nycvL064oQghRzJZQ7/5qmxIF46pftK0HAAAAGgcWKL56ZrOZnHPzL88TQbBarRpVdEboul7c\n7h10RRkhhMvbJxTkSxlZWhcFAAAADQsLFF+9wYMHW0tPkpXLzxya/2F2VlabNm20K+o0hgnW\nrFdMiOnXn4kkaVgOAAAANIL6jtipCxS73W6z2awuZUcIefTRR994443ExMRLPzfatWjR4tVX\nX/3LX/4SWvYTSUkl+/Y6jpfMWbiQpsOwOmD9SemZYuu27KE8Qghddsqwc1uoW0+tiwIAAIAG\nVN9gpxIEYc2aNSUlJTRNp6am9u3b12azhaXnCDd+/PiuXbsuXLiwpKQke/y422+/3el0al3U\nGfz1w5mCfEoSCSGGdauE9p0Us0XrogAAAKCh1DfYybL8+OOPv/nmm0Kt9dKsVuv06dMfe+yx\nenYeFVq3bh2xC7vI9rhQj97GjWsJIVQwYFyzIjhstNZFAQAAQEOpb7CbOXPmzJkzb7nlltGj\nRyclJcmyXFxcvGjRoscffzwxMfHOO+8MS5Vw1YQ+Awz7dlNuFyGE27Vd6NJNapGsdVEAAADQ\nIKh67pTQoUOHkSNHzpw585zj991339atW7dt21afzhtOWVmZ1iWEGUVRcXFxlZWV53+J27/H\ntHiR2pZTWvr+OJFQVONWVy8MwzgcDp7nPR6P1rWEn9FoZFlWl3srm81mq9Xq8Xh4nte6lvCz\n2WzBYFDQ484udrud47jy8nLN99FpCE6ns6KiQusqGkR8fLwgCC6XK4x9chxnt9vD2CE0gvpO\n8z98+PCNN954/vGbbrpp//799exc5fV6X3vttYkTJ95+++0zZswoLS29xMnLly8fO3bsxo0b\nw/LSV2SbP9D4L1oXQvtOUss0tU0XF7H7dmtbDwAAADSQ+gY7lmX9fv/5xwVBYE7vWFpPr7/+\nemlp6fTp01955RWLxTJjxgxZli94ZlVV1fz58w0GQ1he94qs9/lHHj56a+GxY6FI/As+eMNI\ncvpeXdOvyyg9jqAAAABAfYPdtdde+9prr4VCodoHg8Hgu+++271793p2TggpKyvbsmXLlClT\nMjIykpOTc3JyiouLd+++8JjTnDlzBg8ebLE09o2fAVmZVnxCIWSF1zcwv3BueaUcYZ9gyM0T\nhGuuU9uU32fYsFrbegAAAKAh1PfmiSeffHL06NHZ2dmjRo1KSUlRFKWoqGjJkiUnTpz46aef\n6l/fwYMHOY7LyMhQH8bExKSmpubl5V1zzTXnnLlhw4b8/Pxp06b9+uuv9X/dK7Lc4z1yeqDO\nI8lPHS/90eOdldwizcA1ciWXEOw3iMvdSwJ+Qohh2yax4zVS8wStiwIAAIBwqm+wGzVq1KJF\ni5588sk5c+bUHOzcufN77703dOjQenZOCHG73Tabjao12d9ut58/OdTr9c6ZM+eRRx4xmUzn\ndxIKhSZMmFDzcNy4cbfffnv9a6txh8PR2um892B+7ulpdmu8/gGHCp9plfK31GSmse5UUG8y\nuOiXHQ55+Gj5268IIUSWrSt+ZO6bGkV3URgMhktdXdSiKIqiKE3mDzQ09b+t1Wpt/EH0RkDT\nNMdxury9QF1iPS4uTutCGgRN07p8J1GxLBveq7vYxCeIZGFYoPjmm2+++eabS0pKiouLKYpq\n2bJlePecoOoQPj744INu3bp17dr1YifUvqGS5/mwbw7RLy5223XXTC8smnWsRFIUQkhAlv9e\nWLS4smpudlYHayP9Yrv0ddG9+orbt8hHCgghytFCZdsmpmffxims/iiKipAtPRqCji9NTa5a\nVxF+6kXp+NJ0/DOp40sL+/skgl00Cs/OE4SQ5OTk5OTwL5AWFxfndrsVRal5A3W5XOf8RbJj\nx47ffvvt7bffvlgnBoNhxYoVtY800HIn/2eP+R3X6i8lJ3KD1XcnrHd5uv228y/xzmnNmxmu\n5HdAZWXl+++/v2/fPqfTOXr06CFDhlz6/Essd1IbPWS49ZP31H1jxR/+50pKVSzWulelCSx3\nEqXU5U68Xi+WO4ku6nInFRUVuhyPxHInVwTLnUSjqwx27dq1q8tpubm5V9d/jezsbEEQ8vPz\nW7duTQhxu91FRUXt27evfc6yZct8Pl9OTo760Ov1zpo1q2vXrk8++WQ9X/0qdLOYVmSlzS6r\n+Pep8pCsEEJCsvJKafnCKvdrKS36123orrCwcPjw4W3MxqHpLU8cK5z0+eeT77//mWeeqX95\ncvOEULeehi0bCCFUIGD69ZfAqJvq3y0AAABEgqsMdvHx8eGt42KcTmefPn3eeeedqVOnGgyG\n999/Pysrq0OHDoSQZcuWBYPBMWPG5OTkTJo0qeYpjzzyyJ133tmrV6/GqfB8HEVNbd7sBlvM\nI8UntgeC6sGCkDCuoOguZ9wzic1tzGWGyqdNmzY6JfE/I4eqQ3w513YZOPvd4cOH9+zZs/7l\nhfoPZg/sp11VhBB2706mUxepVUb9uwUAAADNXWWwW7t2bXjruISpU6fOnTv32WeflSSpY8eO\nTz/9tPqx7I4dO9xu95gxY2w2m81mqzmfoiibzRYbG9toFV5QR5Pxh8xW71VUvXiyzC/LhBCZ\nkI8qqn70eF9KShgVa7vYE30+3/r162dPvr3mg9tOzZsNy0hbtmxZWIKdwnL870aZF36mPjT9\nvNQ/KUcJ06KDAAAAoKGwzbFrOBaLZdq0aecff+yxxy54/scff9zAFdUVQ1E5zRw3xdqeOF66\n1F09P+y4IN51tGSYLealpISWF1oPJRQKKYpiZs/61lg47pzFAutDzGgttm7LHsiFw28AACAA\nSURBVMojhNCV5YbN6/k+A8LVOQAAAGhFtzcHRY4kjp3fKnl2alKzWqNiP3u8/Q8VvltWIZ43\nPdnhcGRmZn61/2DNkYpA8JfCo9ddd10YqwreMELhqpfY4DaspivKw9g5AAAAaALBrpGMj4td\n3ybjVoe95gNWvyxPP3FqaP6RLedtMvvyyy/PWLvxqVXrVh4p+nxf3rAvFnXs2Wv06NFhrEeJ\ntYf6DVLblCSZVvwYxs4BAABAEwh2jcfJMG+ntPguo1Vbk7Hm4N4gf+Phow8eO1EhSTUHBw0a\ntPDbb7eZY+9Yvvalg0dG3DVp/vz5YV97KXRdr5rNJ5iCfC53b3j7BwAAgEYWBXPsdKaP1bwy\nK212WcXLpeW8ohBCFEK+qnIt83ofbd7sHqeDpgghpHfv3l9//XXDlkLTwd/daP18HlEUQojx\nlx/EtAzFrMNNAgAAAJoIjNhpQF0PZXV2+uCYM4sDV4rSU8dLxxQc3RtsvNVc5ZSWQpduapsK\n+I3L8YEsAABAFEOw00ymwfB1euqnaSnJ3Jlx083+wPWHCh88dqJClC7x3DDiBw1VYqsXFuf2\n72EP1HdNaQAAANAKgp3GhttiVrdOv8cZx5zecEwm5Ksq14BDhV9VuRphQx/FaAz+7saah6Zf\nllLBc2/mAAAAgKiAYKc9O8O8mJz4S1ZaD4up5mCpKD547MTYw0f3NPwns2Jma7FjF7VN+bzG\nlcsa+hUBAACgISDYRYpOJuOSzLQ3U5Pi2TPL3W30B4bmH3m05GTte2YbQnDIcMVSPeGP27OD\nLchv0JcDAACAhoBgF0EoQv4YF7sxO+PeZmc+mZUUZX5FVc8DBW+eKg/JDfXZrGI2B4efWSfP\n9PNiKnwbXQAAAEDjQLCLOHaG+VdS4s+ZrXpazDUHXZL0z5NlQw8fWe31NdDriq3bCm3aq23K\n7TKuXt5ALwQAAAANBMEuQnUxmxZntpqTmpRU657Z/UF+XOGxSUUlhSGhIV6UHza6Zh07bsdW\npvBwQ7wKAAAANBAEu8hFETIuLnZjdsa05k4jVbMVGVns8vQ7VDD9xClXuCfeKWZz8Pphpx8o\npp8XU0KDJEgAAABoCAh2kc5C008lNt/UJuMPcfaagyFZebesosfBq5l4V1hYuGDBgnnz5u3Z\ns+f8r4oduoiZ2WqbdlUZ1qyoR+0AAADQqBDsokMKx72T2mJhemr7WvvMVorSP0+WDckv/MVT\n14l3r7/+er9+/aa9O/uxeR8PGTbskUceUZRzc2Fw2I2KsXrhFcNvm5mjBWG5BAAAAGhoCHbR\nZFCMdWVW2qvJibWXRDnAh/545Nj4gqKdPv+ln75y5coXXp0ZevV18p8PyNuzyUeffPrDj++/\n//45pym2WH7ImQ9kzT/8jwoGw3odAAAA0CAQ7KIMQ1F3OeM2Z2dObd6s9sS7X72+Hr/tevDY\niaKL31fx2WefkbE3kc7VaxGTlFQy8e4FCxacf6bQuWvtO2RN2EMWAAAgGiDYRSUbQz+TGK9O\nvKsJd+peZL0PFfyt5GT5he6rKC8vJwmJZx1KTCwrK7vgS/DDRivWGLXN7tvF5e4NX/kAAADQ\nIBDsopg68W5JZlr3WivehWTl44qq3gcK3imr4M+eP5eZmUn27j6riz27s7KyLti5YjYHh53Z\nQ9a4bAnldoWzegAAAAg3BLuo18NiWprZ6qNWKdnmM/GuSpKePXGq98GCz6vc0ul498ADD1i3\nbCbzPyQeDwkGydLF5MvPH3300Yv1LLZuK3S5Vm1TwaD5p8XkvDstAAAAIHIg2EWuvLy8b7/9\ndvXq1X7/Ze6KoAgZY7ftuq7Lv5MSat9XcSwkTD12fOChwsVur0JIZmbmggULWq9dTcaOJCOH\nJn780dy33howYMAleuavHyE7nGqbKczndmyt/3UBAABAA2Evfwo0ulAo9OCDD367eDFJSSVV\nlUkWy9tvvz1w4MBLP4ujqLubOW5z2N8vr3y9rMIjyerxA3xo0tHi9kbDo4nxY/v127Bhw7Fj\nxwRBSEtLo+nLJHuF44KjbrZ8Po/IMiHE+OsvUlqm7GwWlssEAACA8MKIXSSaMWPGtzt2ko8/\nJ/M+JYu+Pz76pnvuuef48eN1ea6Fpqc2b7YhO2OSM46rddvsfj40+WjJzQVFW/yB1NTUjIyM\ny6Y6lZScGurZV21TomBavIiEe8cLAAAACAsEu4gjCMLHH39Mpv2NJCURQghNkz/9uTI59Ztv\nvql7J4ks+3Jy4qbsjDudcUyteLfO5x91+Oj4wmO/+a9gaTq+7yApoYXaZk4eN2xcU/fnAgAA\nQKNBsIs4brc7EAiQ1JZnHW3Vqo4jdrW1NHAzkxNXtk4fERtT+/gqr2/E4SN/PlK8O8jXqSOG\nCd54s8JUf3Bv3LiWKSq80mIAAACgoSHYRRy73W6z2cihg2cOKQo5dDAtLe3qOmxvNHzSKuWH\nzFb9rZYzXRLyk8d7w6HCiUdL9tUh3snxCaFBN5x+IJuX/JcKBK6uHgAAAGggCHYRh2XZ+++/\nn7w+kxzII4QQPkhmv93C4x4/fnx9uu1uMf83o+Wi9JY9ay16pxCyxO0Zcqjw7qPFl413oW49\nxdZt1Tbl8ZiW/BernwAAAEQUBLtI9Ne//nXK2DHsg/eRsaPI6BHtdu/85JNPnE5n/XseEGNZ\nktlqcWarvrVG72RCvnd7Bx8qvP1I8aXm3lFUcMRYJdauPmILDhm2bap/SQAAABAulNIkB10u\nto9WRCkvL8/Ly3M4HG3atGEY5tInUxQVFxdXWVlZ9/5XeX0vnCzbHjg3yfW0mJ9IiB8QY7ng\ns5hjRyxffqKufkIYxnfbXXJyat1f9CowDONwOHie93g8DfpCmjAajSzL+nw+rQsJP7PZbLVa\nPR4Pz9dtKmdUsdlswWBQEC66NXP0stvtHMeVl5fr8reD0+msqKjQuooGER8fLwiCyxXOLYI4\njrPb7WHsEBoBRuwiV7Nmzfr27du+ffvLprqrMyjG+lNW2ietUrqYTbWPb/YHfl9YNK6waJ3v\nAgsjS6lpfO/TaxpLknnJfyn+Cm6wBQAAgIaDYNekUYSMiI1ZnpW2MD219oazhJDVXv/NBUU3\n5B/5stIlnf2He6jvQKlVhtqmqyqNPy1uvIoBAADg4hDsgBBCBsVYf8hs9XV6ah/rWfFuVyD4\nUPGJQflHvqh0CTXxjqICo25WTm9Ny+Xt43Zvb+SCAQAA4HwIdnDG4Bjr/zJaLc5sNcx21rp3\neUH+4eITXfMOv1xa5pZkQohiswVvvIWcXvrYuOwH5lSpBhUDAABALQh2cK5eFvOCtJSfMtNG\n2221fz5KRfGV0vIeBw//6+SpUlEUM1qHuvVUv0RJoul/X1N6nCMPAAAQRRDsmhy/379ly5Z1\n69Zd+uapbhbTRy2T12Vn/MlhN9BnNiWrEKVZpyquzTv8l+ITO3oPlBKT1ON0RbnxZ0y2AwAA\n0BKCXdPy3XffdevW7Q8333T3bbd16dJl9uzZlz6/tdHwRkqLHW2yHktoZq91c25IUT6rdA08\nfPT6PkMXp6YrFEUI4XL3Gn7b3LAXAAAAABfXRNexkyRJ6xLCj2GYS1/X9u3bBwwY8Prgfnd1\n6UAR8kvh0T9++8P7n3wybty4uvRfKYqzS06+e/zkiVDonC919rgeKsy7teSoiSLM5Aeo9Myr\nv4wLYRhGURRZXTxPXyiKoihKr5dG07Qsy7p8k6FpWlEUvV4aRVG6fJMkdXifjF4N8T4pyzLH\ncWHsEBpBEw125eXlWpcQZhRF2e32qqqqS5zz8MMPG/bs/M/IG2qOvLb5t288wZ9++qnuLxRS\nlK8rXXPKK/eftwVZfIifXJQ/5dTxuD/eqcTYrqj+S6BpWl2g2Ov1hqvPyGEwGDiO0+UCxSaT\nyWq1er1eXS5QHBMTw/O8Lhcojo2N5TiuoqJCl78dHA7HFS3kHkWaNWsmCILb7Q5jnxzHxcbG\nhrFDaASs1gVoQ5dvWORy13Xs2LGbEuJrH+mSEP/G/o1X9K/BEfInh/1PDvsmf+DNUxXLPN6a\nJ5cZjP/O6vBKZvvhO/dM7tRxUGzYsp1Kx981vV4a0fXV6fjSiK6vTq/XpQrv1en730qvMMeu\nCUlKSsotP2svnf1lFcnJyVfXm3rz7K+t02+LizVQZ+6ukCnqh1jH+KMlv8s/8kWVO4j3BQAA\ngMaCYNeETJo06dM9+xfmHlQfbig+/q/1m++999769NnBZHwrNWln26xnEuNT6LN+nHYEgg8f\nO94x99DfSk7mnfe5LQAAAIRdE/0otmnq3r37K7Nef+Cpp/62fLWJZY8HgtOmTZswYUL9e45n\nmanNm90f7/x5966PK1wr4hNrvuSW5I8rqj6pqBoYY73TaR9li2FrDe8BAABAGCHYNS233Xbb\niBEjtm/fHgqFunbtmpiYePnn1IEoivPmzVuwYEFJSckHo4c917bdO+nZ/23Rkj89hqcQssrr\nW+X1pXDcnx32PznsyRx+9gAAAMIMv1ybnLi4uCFDhoS3z6eeeurDxYvJHRNJass/5e77Nf/A\nPFf5K/t3fNQy4/2Mdkc5Q82ZxYLw79KyV0+V3xBjvdNpHxpjZTCABwAAECYIdlBf+/bt+/Dj\nT8j7H5G0dEJIoOu1t61dvf5UYXNCHs/f/2h+7rK+gz9ombXE45VO30ghKcrPHu/PHm8iy97q\nsN/psKcZsFQSAABAfeHmCaiv7du3k6wsNdWpCvoNGL9kmUxRhBCaKMPXr/zYdXJTdsbDzZ3x\nLFP7uSdF8c1T5T0PHJ5QeOybKjePW2gBAADqAcEO6stgMJBg8KxDkrju6LGCdp1rDhiX/ZBR\ndvIfic13tsn6oFXy4Bhr7Z88mZBfvb6cY8c75uY/VnLyN//ZvQEAAEDdINhBffXv399cepKs\nW3Pm0FdfpiQkOEeMFrp2Vw9Qkmj59ivK7TLQ1NhY29fpqZvbZE5r7kxkz5oM4JKkeRVVww8f\nGXCo8N2yilJRbMwLAQAAiHbMs88+q3UNGvD7/VqXEGYURZlMpmBQg7Eum82WkJDw49//To4e\nIQWHyRefmZf99NFHH6WlpYnpmWxxEe2qIoRQQogpOiJ26kJohhASxzADY6xTmjm6mI0BWTki\nCLU3OCwTpV+9/v+UV231ByiKah8bS8ty6Lw9anWAZVmapnW5MxXHcQaDIRQK6XJrTqPRKIqi\nLjf5NZlMDMMEAgGtC2kQZrNZr5dmsVhkWQ7vDn4Mw5hMpjB2CI2gie4VW1ZWpnUJYUZRVFxc\nnIZ7IO7evfvzzz8vKSlp3br1xIkTU1NTq78Q8Fs//YCuqi5MaNM+OHY8Oe9O2FJR/KrK/UWV\n+4JLGdsY5iZn3C1Wc3+rldbXTbRGo5FlWV3uFWs2m61Wq8fj0eVesTabLRgM6jKR2+12juPK\ny8t1+dvB6XRWVFRc/rwoFB8fLwiCy+UKY58cx9nt9jB2CI0AwU4nNA92l8CUlZoXfEidHm8L\nDbie793/Yidv9Qe+qHL/1+V2SxcYC0limVvi7DfF2rpZdPJHJIJdlEKwi1IIdlcEwS4aYY4d\nNDgpPiF44y01o3SGtSu53L0XO7m7xfxqcuLedq3fa5ncW5HJ2dPsjovSu2UVww8fuS7v8PMn\ny3ZjpzIAAIBaEOygMYit24b6n14VWVGMS79ljh29xPkmirrZbgv+dSpZ8MkFTzgqCG+cKr/+\nUGHvgwUvnizbc4UJT5blL7/88oEHHrj77rvfffddTeYmAgAAhB2CHTQSvlc/sdM1apuSJPO3\nX9IV5Zc43+/379ixg9ww9KyjVed+1pzPh147VT7kUOF1eYefOV66wReQLvf5kSzLf/7znx/6\nxz++ptnv45zTP5o3ZMgQt9t9xZcEAAAQYRDsoLFQVGDYaCk9s/pRIGBeuIDyX3RuGUVRFEWR\nc+46fPft8b/8+GC8s+V5O1UcFYQ55ZVjC452zM2fVnziZ483eJGEt2DBgmU7dpIPPyE5D5K7\n7yXvzztkjZkxY0a9rg4AACACINhBI2KYwNgJUnyC+oh2VZm/+ZwSLzz93Gw2d+/enXz37ZlD\npaVkw7pxnTo+26L5b20y17ROfyyh2fl7kZVL0oJK1+1HirP3HRxfeGxueeWx0FkvsXz5cjJy\nFKmZEcwwZPytv/zyS5guEgAAQDPYKxYalWI0Bsb/ybrgA8rjIYQwJ0qMS7694AIohJCZM2eO\nGDHCX3qC9OhFqqrId4smjBw5dGj1h7PtTMZ2JuOjzeO3BQJL3d6lbu/hsxe6CyrKKq9vldf3\n1PHS9kbDsFjbUJu1h9nE8zwxGM56JZNRl4vkgY7t379/586dMTExffv2dTqdWpcDAJECI3YQ\nBqFQ6M033+zZs2fLli0HDRr05ZdfXmKhBMUWG7jlNoWrjlbcgf3G1csveGb79u3Xrl17T7u2\nfTetv7H0+FvPPff222+fcw5NkR4W8/QWzTe1ydjaJvOFpISeFvP5IXE/H3rjVPmYw0cz9x86\nlPMQMZtJ7VVzf1nWvXv3K75sAC2Ionj//fcPvOGGh998a9Lfn+rRo8c333yjdVEAECkwYgdh\n8Pjjj69fsviZfj2z+3fferz0H489WllZmZOTc7HzpcSk4OhbzN99rU6hM2xeL8fahWt7nH9m\ny5YtX375ZYfDwfO8x+O5dBlpBm5KM8eUZo5jIeFnj/dnj2+dz3/OTDu/LBc2iye/n0AIIcEA\ncbvJmtXWnduf+9//ruLCARrfa6+9tnDDRjJ/AUlKJoS4f/l52rRpHTp0aN++vdalAYD2sECx\nTmi4QPGuXbtGDRv22923ZzmqZ60tKzg67rsf9u/fHxsbe4knGn7bYlz+Q/UDmg6OGSe0ucBv\nJoZh6hjszhdUlE0+/08e7w8e3zkz7c6RZuAGxVgHxVgGWCwOlrnSF7pqWKA4Smm4QHHHjh1L\nH36E9B9w5tD0px/o1OG5554LS/9YoDhKYYFiUGHEDupr165dnRPia1IdIWRoRisjIbm5uT17\n9rzEE0PdelCuSsPWjYQQIsumxYvkW26TMrLCWJuJogbFWAfFWP+VRPbzoeUe7yqvf+N5w3iE\nkCMh4eOKqo8rqhiK6mQy9rNa+lrNPcxm5xWGvFAotH79+pKSkvT09N69e9M0ZjtAOMmyXFZW\nRpKTzzqaknLy5EmNKgKAyIJgB/VlMpk8Z995wIsSL0lms/myz+UH/47yuLm8fYQQIknm7xcG\nbr1TSkxqiDrbGw3tjc6H4p3qMN5qX2CV17crEDwn4kmKsjMQ3BkIvltGCCFpBq6XxdLLYupp\nMbczGS/9Evv27bv77rvzy8pIUgopOto1u/W8efNSUlIa4nKgaaJpumXLlkdy95PMWn8C5e7P\nuOF67YoCgAiC4QSor4EDBx4Lhr7OPVhz5NVNW1ukpHTo0OHyT6ao4I23iOnVv6Ionjd//eml\nFy6uP3UY75nE+F+y0va2az0nNekOhz3znPtkTzsSEr6qcv2t5OSAQ4Wd8/LvPlr8blnFJn/g\n/DE/nucnT56c37Ez+fpbMnsu+WrRDltsTk6OLj/PAg098sgjZM67ZPMmIsskECBzZzuPFN51\n111a1wUAEQEjdlBfCQkJr7766uS//OWr/QfaOOO2HD+5vdL95ZdfMkzdPsRkmOAtf7B89Sld\nXEQIoQIBy9ef+v44UYltjIkdzVlmXFzsuLhYQshxQVzr86/z+df5/IUXmpB3QhC/F7zfu72E\nEI6iOpqM11nM15lN3cymTKNh7dq1h8rKyMPTCMsSQojFQh57YuMtY/Ly8tq1a9cI1wJNxO23\n315eXj7zuWf8okgEsW2b7FmfftqiRQut6wKAiICbJ3RCw5snVAcOHPjqq6+Ki4uzsrLuuOOO\nxMTEK3o6FQhYPvuIrqj+vsjNE/y33aWYzKR+N09ctRJB3Oj3b/YHN/j8uUFevtz5sQzdwu06\nsG4tGTbyrC/cMmbh++8NGjToYk/EzRNRSsObJ1SBQCAvL89ut6elpYV3KidunohSuHkCVAh2\nOqF5sKs/yuO2fvYR5a5+V5KTU/1/uEPhOE2CXW1uSd4SCGzy+Tf5gzsCQb982Zh3mtdHXn91\n0Usv9ktLoy+wADMhCHZRS/Ng13AQ7KIUgh2oEOx0QgfBjhBCnyq1fDGfCgbUh2JWm8BNExiD\nQdtgV5uoKLl8aKs/sC0Q3OYPHOJDdfn/Y6HpjiZDZ7O5k8nYwWhoZzJaTw+xINhFKQS7KIVg\nd0UQ7KIR5thBBJGbJwR+f5v5q0/VDWTZ/AOmJf8VbpqgdV1nsBTVyWTsZDJOJIQQUiVJ2wP8\njkBwRyC4IxAoEcQLPssvy1v8wS3+oPqQJqSVgetkNrU3GrrExFxjsyYoCnOhTdUAAACuCEbs\ndEIfI3Yq9vBB87df1Wz5JXW8xnLH3XwoFAkjdpdWKoo7AsF1p8q3erxHDIaTUl0/tDVSVBuj\noa3J2M5oaGcytjMaWxm4qA56PM+vW7eutLQ0OTm5T58+HMdpXVGYYcQuSmHE7opgxC4aYcQO\nIo6YmR0c/XvT99+oG44xe3eKCz8jY8ZpXdflJbDsMFvMMFuM+rBcknYHgrsCwT1BfneQP8yH\nLhb0eEXZHeR3B898ZGmh6WyjIdtoaGs0tjZwbU3GdAPHRcmo3p49eyZOnHjE6yUpLcnRI20T\nEz755JOMjAyt6wIA0D+M2OmEnkbsVOyeneYf/0dqfj579fMMuJ5ESbK5IL8s5wZDe3l+XyC4\nnw/t4/lKUar70zmKyjBwWUZDlsGQaTRkGrgsg6EFF3F/m/E8P2jQoPwuXckDDxOWJTxPZr7c\n9dTJn376SU/7cGDELkphxO6KYMQuGkXcbwUAldjpmiBRTD9+X53tNq0ziiJ//XCt67p6Fpru\nZjF1s5jI6e3XSgTxkCzvD4b2eL37g/wBng/IF/1VKijKAT50gD9rkw8rTacbuFYGriXHpRm4\nVI5tZTCkcmxcHRcRbAAbNmzIP1VWneoIIUYjmfa3HTffuGfPni5dumhVFQBAE4FgB5FL6NQ1\nUOVybFilPjRs26QYjKH+gzUtKpySOTbDaBzpZH2+GEKIrJCjgpAb5HN5/iAvHOD5g3zId8nV\nVXyyvDfI7w2ee9tpDE2nGLgWLJvEsUksk8iyKRyXyLGJLBvPMobzBj5FUWTZ8LwblJWVkfh4\nUrs3i4XY406dOhWW/hsCz/OzZ89esWKFz+fr1q3bX//616SkBtnXDgCgoSHYQeQ6evTo8Htz\nnrm2433XVo/0GDesphia7zNQ28IaCE2RdAOXbuBGkOpZegohx0LCoZCQx/OH+FBeIFggiCfF\nC997W5tXlvOCfB658DojcQzTnGXiWSYmFDq0ZUvx/n1SRUW60zHxllv6d+rkZBgny5iu9lPv\n9PR0UnyMuFyk5hOc48dJeXlWVtYln6cZURTHjRu36cRJMvZmYjbvWrv624EDV6xY0bJly4Cs\n8IrslmVBVryyTAjxyLKkKCIhUkgQBMEbEvjLfV4ZyzDqKoYsIeoyN3aGoQgx07SRokw0ZaSo\nGJpmo3maAQBEjiiYY+f1eufOnbtr1y5BENq2bZuTk5OQkHDOORUVFR9++OHOnTtDoVBmZuak\nSZPatGlziT4xxy4qjB8/PqXs5Ac3/u6c33ihbj3564dH9Xy7GnVcx27p0qUvvvjigQMHLBbL\n0LFj//TY4y5b7OFQ6BAfOhISjgrCSUEM7/9kI0XFMYyDZew0HccwcSwTR9OxDG1nmFiGsVGU\nnWFiGTqOYWw0HcucySWKotx6660ryyvJXx8lrdJI/iHyykvju3SePXt2WAusk5CieCXZI8te\nWfbJsk9WPLLkkarbXll2S9KuAwd/O5xPrutBaj6/DgZYmhEvsn1ww7EzDEOIjaHVzBfHMAaK\nmCk6lqFNNG2h6ViastCMhaZsDB1D02aKttBUHMNYaNpMUzHhmMK4ZMmSNWvW+Hy+Dh06TJw4\n0Ww217/PiII5dlcEc+yiURQEu+eff97r9d53331Go/Gzzz4rLCx88803z5mF/de//tVgMEyZ\nMsVsNn/22Wfbt29///33TSbTxfpEsIt8PM+3atVqy8TbOsY3O/+rQtsO/I23KNrNJAuXugS7\nn3/++fa7J5O77yG9ehO3m3w6v73HvWzZMqPRWHNOSFGKQkKRIBQJYlEoVCxIx0XhhCAWC+IV\nbJVRD2aaiqUZG0PHMrRJkgv37ik5dIgEg1Qg0LV11i3DhzvNZjND0wqxMTQhxELT538ibKVp\njqJEpXp4jBASUBRelgkhskI8ihwSpdVbtx47fpyyWrPatLUlJgZlOagoLkkKyora4BXFJ8lu\nWfbKshjx72/hFcvQFpo2U1Qsw8TQtJmmLBQdxzJmijLTtI2mLDRtpmkbQ1so2kRTNpo2UZSJ\npm0MzRHq79P+8sXixWToMGKNIRvWpUnizz//7HQ6tb6scEKwuyIIdtEo0oNdWVnZ5MmTZ82a\nlZmZSQjxer133HHHs88+e80119Sc4/F43n777T//+c8tW7YkhJw6dWry5MkzZ87Mzs6+RLeN\nUHxj0l+w8/l86enp+6bcmRl34bcVqWVa4OZblYvH96hQl2DXq1evwyNHk/F/qH4sCGTyXS89\n+MDkyZPr8hIeSS4RhOOiWCqK5aJ8QhTLRKlMFLcUFHhibER3QzJQL4pyZiy8pNjBcZ0z0hmK\nslE0R1PW00HQSlMsIXaGYSnKxtBGijJRlJrL7QzDUcRK0xfM7ppDsLsiCHbRKNLn2B08eJDj\nuJoVsGJiYlJTU/Py8moHO5vN9uSTT9Y8LC8vp2k6Pj6+sWuFsLJarW3btv1q/4En+vRQj1QG\n+RfXb3np+v7qaC1TdMTy+Uf+cX9SYvX8vsPz/OHDh0nvPmcOcRy5rvu+ffvq2IONodsyxrbE\neM7x+//9wkKKIQ88fObQvr1xa1Y9Mn16hSRXSVKVJLkkuUqSKk836nsx0fOdAQAAIABJREFU\nkYejKFYQApUVpFk8qfkcYPfuVoo0csgQI03baMpAUTE0baAoC0MTQmJpmiLEERPDCIIoioQQ\nlrrwx6B+WQ6d/stZUohHlgghHkmWKRKU5aCsqGOTvEKCiqKe7JYkkRCPJPtlOSjLblkOygqv\nKI33j187iiWnVBKy2uuvT392hmEJiWFoC0UZadp++vNlG0MbaTqGpi00ZaSoWJo20ZSJpu00\nbaJpE0XZGcZIUepI8MW2WgaA80V6sHO73Tabjar1XmO32y/xF4nH43nrrbduvvlmh8NRczAU\nCk2bNq3m4fDhw0eNGtVABWuIpmmd/Wn1zjvv3Dh8eFWQ/11GWqnfP2vzb806dqb/NJF8/RkR\nQoQQuuxUzGcf0XfdS1oka13sVaJpmqKoS9yRKsuy0Wjk3e6zjrpc8Znp9fx2/+EPf1h4991k\n7C0kNZUQQoJB8uasO4b97smsi64kXCWKbkl2iWKVKLllqUoUXaLkrm5LLlF0S7JbEqtEyStJ\nXkmuEsM88++CYlnGrE5BYxgTTccwTAxNxzCMlaHtLGujaStDxzBMLMvE0ozatjGMnWFiGMZA\nU7Isjxw5cmVuHhl7E7FYyaqVzYuOrtq8OSUl5RIvyjCMLMuN+YmHX5L9suSRZI8k+WXZJ0lV\nkuSXZJ8keSTJLcnqQZcoeWXZL0s+Sa4UxYCsqCc0Wp3ncEkSIaS8fgUYaMpKM7EMbaZpC8PE\nsYyZZsw0FceyFpq2MLSNpm0MY2aYGIaOpRkLQ1to+sxXa83ZoChKw/fJw4cPf/DBBwUFBenp\n6RMnTrz0XPCrwLJseK9ObpSJHBBekR7sCCFUnQfzjx079s9//rNr16533XVX7eOKomzevLnm\nYYcOHfS3wZFKZ9d1ww03rFyzZsaMGV+s3uh0On8/JeeJJ54wWq2yPU6YP5f4/YQQ4nHLH8zm\n7rqXzojQmy7r4tIr944bN+6zD98j/3qZqNP59+4h69ZM+Nfz9fx2T5gwIWfFijn3TiT9BxKT\niWza2DMj/aWXXrpEt805rvkVvopPkryS7JEklygqhFSJIiEkIMtBWVaU6ocX5Di99rKBoq0M\nLUnSyKFDlcefJMm18tZ/3p1kNn744YdXWNS5fvrpp9mzZy9ZsiQQCPQYPOj//u//zr9D63yN\nvN6ynSN2Qq56FRaPJAUk2StJbkkKyrJXktyiFFIUtyiq345fNmz45bftZPjIMyOXx4piCclu\n394tShJRKgVRVBRNMmJIVkKyWHn528EvKpZlrDRjYeg4llVDv5VmHBxrpWkrw8QwtINlrUx1\n7new7LZ169YuWxZyu3p37DhlyhSLxVL/q1i6dOm4ceOC13Yj2W3Ips1vvfXWZ5999vvf/77+\nPYdCoXnz5m3ZssVqtY4YMWLEiBH171Ml1uEefIg0kT7HbtOmTa+88srXX39dE+8efvjhQYMG\njR8//pwzd+7c+fLLL//xj38cPXr0OV9SFKX2NqNGo9Hr9TZo2Y1P/TO0qqpK60LCj6Zph8PB\n83zt7xpdXmZeuIByVdWcFOozMNR3YNTdKluXOXYVFRVjx47Nrawi3a4jLhfZvOnpJ/6v9iB0\nfaxdu3b58uWBQKB79+633HILE777UUwmk9Vq9Xq9PH/hVVeuVL9+/fIGX09uu736sSiQeya9\nMOXe++67Lyz9X5GYmBie5y+788R333330UcfFRUVpaen33vvvWH8jRt2PM8PGzZsL82QCbeR\nGCtZs9r0w5Iffvihc+fO55wZUhS/LPtlRVAUtyyLiuKWpJBC/LKkHnRJckiRfbISkGVeUdyy\nfKqy6vDx415J4iwWY7NmCscFZcUt1Xk3ZU1RwWAzi8XGMrEMY6NpK01baTqGoe0MbaXpGJq2\n0nQsQ9todaiYttKUnWFsNM3UejsKBAJdu3Yt//Nd5ObTSe7HpfY572zbti0uLq4+5Xk8nlGj\nRu13uUmv3iQYJKtW3jFu3KxZs+rTZw2O42JjY8PSFTSaSA92FRUVkyZNmjlzZuvWrQkhbrf7\nzjvvfOGFFzp27Fj7tH379j3//PN/+9vfrrvuurp0i5snogjDMGqwq53OCSGU12NeuIA5VVpz\nRMxqExg5lpjD8Ld1o6njcieCICxatGjXrl1xcXEjRow4/3dtBDKbzVar1ePxhCvYrVy58g93\n3EEmTiZ9+hKPh3z6cduqimXLlmmyJEddthR7/fXXX3jjDXLrH0lGJsk/RL784oWn/j5lypRG\nK/JKVVZWvvzyy8uXL/d6vV27dn3iiSfCslnIwoUL/5+9+46Pssj/AD7zlO0l2fSeEEJvSZAi\n0gIISrH7Q0BE1AMb551wiB6CoB4iCqJYQbEhKiIcdqQfvUPo6b1ne32emd8fCzGEkLopu/m+\nX/e61+6T2dmZhGw+zjPlyWfnoDG3o07xKCMd/fnHh+++e9999yGEnIRaKTGLxImoSSRWQu2E\nmCixisThXuxMqYMivSjaCbUR0UiolYh2Qo2EmAWhwmKl7Xj1j5zB7uSnZVnRaEw9eQLdMvC6\n//hcs/q5hybflpTkx7LuLWzUDCtv5IzCuXPnfn7iJHrrHeQeay8sQLMe+2z16hvHOJoAFk94\no/Ye7BBCy5YtKy4unjNnjkQiWbt2rdFoXLFiBcZ4+/btdrt94sSJTqfzmWeeSUlJGT16dNWr\nVCoVbHfiG24W7BBC2GGX//cHNiu96grVaG0T7hUjolq3jU3XwGDnjTwe7BBCv//+++uvv37p\n0iWZTDZ27NjFixe31RER9Qa7goKC/v37u1asQn2urfQ6dkTy0gtnzpwJCKhlB5/2w7Nnxer1\n+sTERPM/56GRo65e2rVD9fabJ0+ebOZI1SOPPPKL1Y4WLbn63GhESxf98+mnB48YYSTESqhV\nFM2EmAixEWolxCASCyEujjU4nAZRtBJqJcTc/uaQudfiaK9OHLw6EKhmGS3LqhlcdVHLMmqW\n1TDMuNtuK5v1JBpYbX3Ve+88wKD333+/+Y2BYOeNvGCO3Zw5cz7++OPFixeLotizZ89///vf\n7tuyp06dMhqNEydOvHDhQlFR0YYNGzZs2FD1qlmzZo0fP77tWg1aA5XKrPdPkZw4It3zJxJF\nhBA2GhQbP3cMGuqNt2VBvcaOHTt27FiHwyGRSBo++7ZNnDhxwhUY9FeqQwj1H+BUq0+dOjVq\n1Kibv87XHD9+3CyR/JXqEEIjR5nXrD527Fj1/xRvgr1796LXlv31XKNBsXF5v/4yYkJdn/w3\nbndSPeQZRbLyww/3sRwaU+1YaqMRnzwx8s47rZRaCDES4t7jut5DR5pGoNS9Jr2hL/j0i5pX\nlCpbRfs9wQ+0NC8IdgqFotbpRPPmzXM/6Nu373//+9/WbRRoNzB2Jg8Ug0PlP23GZhNCCBEi\nPbCHLcyzj7+HetVtWdBA1Xdmbrc4jkPi9RPPKUWC4MFZjF5BEAR046Jvlmv+rHxRFFGNbybL\nErGeWY830rKstlo1l/w0+9a8j4aNQFX/zL7bmHgh9duna07ldO9W4x4INF871+TqU5G4BwuN\nomi+9jSvslIvikipRLgll90IAjq4v++DD7TgW4D2zQuCHQD1EqNiLI/8TfbzFu7abVkuM135\n6Qf2kWOE7r1h6A60vgEDBijMZuu+PWjo8KuX/vxDQ2kD5wH7jMTERIle7zx5HCVe6/jJExJ9\nZVJSUjNrHjRo0K5ffkY9r803tVrQnt2D581tZrXTp0//+uuvU+f9A02eglQqtP9/0q0/vr51\n640lOYz9WNavwUmdkOiNGzeuXbs2My8vskuXe6ZOGzlpkgWhqlPvTKJoINT9wESISSRmQvSi\naBKJmRInqW+A0OFAZ8+g7zfGE/GJJ55obMeBz/CCOXYtAebYeZE65tjVRKnk8H7p/t2o2rwZ\nMTrWPmY80V03qyk3N3fx4sV79uxxOp3JyckLFy5s/p+ZpoE5dl6qIYsnNm7c+Ow//4luH4fi\nOqG0K2jH9rUffHDXXXe1WiObxrNz7BBCa9asWfzmCvTgZNS5M0pLQ99tXDxv7tNPP93MatPT\n00ePHm1OvgUNHYYsFvTjD4NCQ7Zs2VL3mGhDTp6oqKhYvnz5H3/8YTQaExMT58+f379//2a2\ntvkclJrEq6OABvf0QZGYKDWJ5HJ+/v9OnarIzPDb9F1KSspLL70UGhrqkTeFOXbeCIKdj4Bg\n91f5/Fz5th+w6a8dfSnLOgcMcQ2+jbIcQkiv148cObK/Qvp0cl85x226eOXDsxd+//33Hj16\ntFQfbg6CnZdqSLBDCJ08efLzzz/Pzs6Oi4ubOXNmr169Wqd5zeHxYIcQ+umnnz777LPMzEz3\n98FTE6BzcnJWrFhx6tQplUo1ZsyYJ598so41c25wpFijQLDzRhDsfAQEu+qwwy75327JqWPV\nh+6I1s8xZrwQF//aa68d/v7bHVPuY67don3uzz2XtAHfffed51tfHwh2XqqBwc4btUSwaz8g\n2DUKBDtv1Ko7pwPQOqhU5hg1zjp1phjy114YjEEv3/S1fOv3xiuXx3eOY6pNvJuU0OnMmTNt\n0VIAAADAkyDYAZ8lhoZbpz3mGDWOVltEyV2+sKZn/NhOMdVL6u0OpVLZ6g0EAAAAPAyCHfBp\nDONMGmB57Gmh518b6GOEegcFVj21uFwrDh+HXQ8BAAD4AAh2wPdRpcp2593WB6aKwTVXihGE\n/sjIju6csGDBgjZpGwAAAOBBsI8d6CjE2HhrbDyblSHdu4MtLnRfZBC6p2vnexASf9zoSh7o\nSuiGGPivHQAAAN4Kgh3oWMTYTtaYOP7KRcmBPUxpSdV1Nj+Xzc+VarSuvsnO3v2oUtWGjQQA\nAACaBoId6HgwdnXp7kroxl86Lzmwhyn/a+8bbDRI9u2UHNjjSujm6pskRsbAAB4AAAAvAsEO\ndFQYu7r1dHXtwWWm8SePcpnpqGrXLlHkL57jL56jSpWra3ehWy8xPBLOJQMAAND+QbADHRvG\nQqcEoVMCY9Dzp47xZ09im+2vL1rMkhNHJSeOUo3W1bWH0K2nGBpeR2VOp/PDDz/88ssvCwoK\n4uLiZs2aNXXqVAbG/AAAALQWCHYAIOQ+l2L4aOdtI9gL56SnjzEF+dW/io0GydGDkqMHqdZP\niI0XOnUWYzpRnq9RyYsvvrhny4+LbhvUZdjAU8Uli//9Unl5+XPPPdeK/QAAANChQbAD4C+U\n5YRefYVefZmyUu7Sef7iOabiutPnsEHPnz7Onz5OWZZExQhxnYVOnYkuECF04cKFDV9+eWLm\n1ASdH0IoOTS4i87/zuXLp0+frtPp2qY/AAAAOhgIdgDUggQGOQOHO4cMZ0uLuYvnuAupjEFf\nvQAWRTYrg83KkO76g2r9hKgYa0HxyJhod6pzGxoVoebY8+fP33bbba3eAwAAAB0RBDsA6iIG\nhYhBIY6hKWxhPnflIpt+hS0rqVEGG/S8QT8CoREPTKx+3SmKdkGQy+Wt11wAAAAdGwQ7ABpE\nDIsQwyLQsFHYamEz0riMK1xWBnbY63iJUxS/vv+uAaIDFReKwaGwrhYAAEBLg2AHQONQhdI9\nDw+JIpuXw2VlsLlZbHEhIqRGSZVEckdUONrzJ0KISmViRCSJiBYio0hYBGXhVw8AAIDnwV8X\nAJqKZcWYODEmDiGEXS4mP5fLyRTSr0jLStgbymKHnctIQxlpEoQQw4hBIWJEFImMRgldkVrT\n6k0HAADgmyDYAeABlOfF2E5ibCc0bJTNYWfzctj8XDYvhykqwKJYszQhbHEhW1yIThxBGNOg\nEGlUjBgdK0bGUJmsLZoPAADAR0CwA8DDqFQmxHcR4rsghLAoMEWFbF42m5/H5udiu+2G0hSX\nFElKitDxw4hhxOBQMTpWjI4VI6MpL6kqZbfbv/rqq9TUVH9//3Hjxg0cOLA1ewQAAMBbQLAD\noAVRlhMjosSIKPdTxqBncrO5glw2K6PG/ikIIUQIW1TAFhWgIwcQw4hhEe6AWEzRHXfcITeb\nRsVGldns93/4wZPPznnxxRdbuzMAAADaPQh2ALQeovUjWj+hV1+EEDYa2LwcaWE+k5OJykpv\nKErY/Fw2P1e6d4fM6Vqe1HNCfCeWwQih0yWJI997d+TIkYMHD279LgAAAGjPINgB0DaoRiv0\n6M0m9uc4zlpUxOZkcjlZbE4mYzTUKBku4e9KiL/6KoT6Bgc92D3h119/hWAHAACgBgh2ALQ9\nqlYLPfsIPfsghBiDns3O5DKvsJkZ2OWsUdK9Fd67t6dccBH+zEmhcxeqULZ6ewEAALRTEOwA\naF+I1o/0SXT1ScSiyORkcRmXS/btiVQqqpfhGaaPlEG/b0PbGTEsQuyUIMTFwx7IAAAAINgB\n0E5RlhXj4sW4+FOc4r6nnnx9xJBBEaEKnr8uu12biifZt5MqlGKnzkJcZ1dMHJIrblYtAAAA\nHwbBDoD2bvjw4XTN+4uXLz+95Zf40JDnx4+7r0c3WUEeFoXqxbDVwqWe5lJPyxiGhIa5ouPE\n6DgSEUU5+DUHAICOAj7xAfACI0aMGDFiRNVTASGLy8llpLFXLvFZ6chmva40IUxBvrQgHx36\nH2U5Eh4pxsQK0XFiaDhibzwUAwAAgO+AYAeAV6K8xNW1h6trDzshTFEhl5nGZ6UxRTWPrMWi\nwOZmsblZErSb8jyJiBIjooWoaBIW6R7J27179+7du202W3Jy8r333svB8B4AAHgz+BAHwMsx\nDAmPcIZHOIcMRzYrn5XBZaaz2RnYbKpRELtcbFYGm5UhQQixrBgStv1K+oY/dwbKZQxCyzZ9\n/8knn2zdulWhgPl5AADgrSDYAeBD5ApX916u7r2Qe9uUrAwuP4fNycSmmiEPiSJbkDdOKR13\n1x1XLxCy5vjpL5a9PvuVpbC6FgAAvBQEOwB8E9H6kb5Jrr5JiFK2rITNzmRzs9n8HGy74bxa\nhBBCLMPMuSURIUTXrBDDIkh4pBAWQcIiqFTWug0HAADQdBDsAPB1GItBIWJQCOo/CFHKlJey\neTlsfq7x9MkAvpZPAGyzcRlpKCNNghDCmAQEiWHhYniUGBZBAoNgMA8AANozCHYAdCQYk8Bg\nEhjs6td/1bkrF3/84du772TqyGqUMmUlTFkJf/YUQohKJCQ0QgiPIOGRYlhEvYdelJeXSyQS\nz/YAAABAHTCltK3b0AZcLldbN8HzOI4TBKH+ct4GY8xxHCFEFMW2bovnMQyDMW6TrhkMhv79\n+/eRsH/v30/B8z+nZx4rLf/oxQVhopPmZNfcQqVW/joUFYujYnB0DKq2l4rFYlmyZMnatWtN\nJpO/v/8zzzwzf/58H0t4LMsSQnzy85PjOIyxT35IIt/9nEQI8TxPKfVs7wghUqnUgxWCVtBB\ng11lZWVbN8HDMMYajcZgqHl+vA9gGEar1TqdTovF0tZt8TyJRMKyrO0m895aWm5u7uLFi3fu\n3Gm325OTk19++eUBAwa4v4TNJjYvh8nLYYoKmMJ8VG/0ZFkSFEIio8WQsBc+/Hjv9u3LU4Z2\nD/Q/VVw2d8fe2yc/9Prrr7d4f1qRUql0OBw+GRFUKhXP83q93if/Omi1Wp/8nEQI+fv7C4Jg\nunGlVDOwLKvRaDxYIWgFHTTYlZWVtXUTPAxj7Ofn53uBFSHEsqy/v7/D4fDsB1Y7IZVKOY5r\n88wqiiJ7872LscvJFBWyBXlsYT5bkIct5norFAjhGMb9OLW0bMDn3544cSIiIsJjLW5rarXa\nbrf75LCWVqvleb68vNwn/zrodLqKioq2bkWLCAwMdLlcno2tPM9rtVoPVghaAcyxAwCgOlId\nQojyEjEqRoyKcT/FRgNXmM8U5LEFeUxxUY2TzdyqUh1CqFdQ4O//dzfatZ27bagYGk5lcs82\nHgAAQBUIdgCAxqEarUujRV17IISQKDLFRVxhHlOQxxXkYWPtowVDoyJQYQ76/muEMfHXkbBI\nISychEeKgcFwyhkAAHgQBDsAQDOwrPvcC5Q8ECGEzSYhI23TyrfujI4IV9W2ZpZSpqKcqSjn\nzp1GCFGOI8GhYmi4GBJGQsNJQCBspwIAAM0BwQ4A4DFUpWb7JEY+/mTSjBldFdKx8XEqnuse\nEjIyPo5zOm4sjwWBLchjC/KuvpyXkJBrOS84lOgCULVbum4lJSXnz5/38/Pr0aOHj620BQCA\n5oNgBwDwsCFDhhw+fPjXX3/Nz88PjIrqOWGCTa1mKiuYwjyusIApzGdLimpdZotdTjYvh83L\ncT+lHE+Dg8XgMDE4lISECrrAxa+99sknn/hLeJPDGRgW9s477wwdOrR1OwcAAO0arIr1EbAq\n1ku1k1WxLUEulyuVSpPJ5HDUHKvDooCLCrmiAqYwny0qYPSVqAEfRBTjjAq9v0yqk8tESj86\neeaVo6d3794dGRnZMj2oC6yK9VKwKrZRYFWsN4IROwBAa6MsRyOinBFR7qfYbmeKC9niAqao\nkC0qYAz6Wl+FKY33v/o3hsX4qaS+03v3KN/wmSwxWQwMIoHBYmAQkitaqQ8AANAuQbADALQx\nKpOJMXFiTJz7KbbZmJIitqSIKS5iSwqZygpESK0vVPG8ClF06hhfVZVSRYJCxMAgEhBIAoJI\nQGDDd1cRRVEQBNhnHwDg1SDYAQDaFyqXX5fzBBcuKWZLija9u/rOmEidXFbHa7HFzFrMbFb6\nX7UpVSQwiAQEiQGBRBdAdIFUpa7xqqysrIULF+7cuVMUxe7du7/88ssjR470eL8AAKAVQLAD\nALRrlONpeCQJj8zsnTTo3dU/3j+xZ2AApehIQVGJw3F7n95Sq/lmQ3qoKuplZ/41qieVEV0A\nDQgUdQHEP9DAS/7vgQeT5JJdk+9R8fyWK+nTpzz0/Y9bBg0a1DodBAAAD4JgBwDwDs8++2xB\nQcHA9Z9HadQGu4PXaletWuUcPdolCkx5GS4tYctKmbJitrwMGw11rMbADjtbmI8K890ff3KE\nzj4wgb22r8r8gP6hSsWaZf8ZtGVrq3QLAAA8CVbF+ghYFeulOuaq2ObIy8s7e/asRqNJSkqS\ny2ufP4ddTqa8DJeVshVlTFkpU17KGPQNWXhbHeUlRBdA/HXEP4DoAqi/jvjrqmbswapYLwWr\nYhsFVsV6IxixAwB4k8jIyHr3N6G8RAwNR6HhVafYYkFgKsqZijJcXsZUlDEVZUx5ea2n3FbB\nLidbXMgWF15Xs1xOdYHEX4dCwliNlqg1xD+A3nyf5MrKyq1bt+bm5sbExNx9990ajaaB3QQA\ngKaBYAcA8H2U48TgEDE4pNolypiMTEVZ2sEDx37+6YHuCaoGnGOBbTacn8vk56LU0zxC7nl7\nVKG8Orbnp6NVD3j+8OHD06dPj+SYHoEBO0rKli1b9vXXXycmJrZUJwEAAIIdAKCDwphotESj\njY2N/+JKZuR774+Ni9UppDkG0y09e86bOUNiMjKVFUxlObbb66nJamGtlqoDM9yISqVOz/pl\n4ph+IcEIIYrQkn2H/va3v+3fvx9OQgMAtByYY+cjYI6dl4I5du3E8ePHd+7cabFYkpKSJkyY\nwFQ7oxbbrExFOVNZzlRW4IpyprKCqazAQlNm1xWYLfKISFV0LPH3p3464q8jWn/aznbOgzl2\nXgrm2AE3GLEDAACUnJycnJxc65eoXCFGKMRr52S4qSlxFhaQ0hKmspzRVzKV5biyAtd2AG51\n4SolMlSis9f9BxiVy4mfjmj9iJ8/9fMnWj+q9ScqNWLZumsrKipSKpVqdc1t+QDwOpMnT/7p\np5/MZnNbN8QXQLADAIDG02iJROoKr7aMg1LGZMQV5Yy+gqmssObmlF4419nfD2Ncd03YZmNt\n+Wxh/nVXGYaqNUSjpVo/ovUTNX5U60e1fkSlRgyzcePGpUuXlpSUIISGDBnyxhtvdO3a1fN9\nBKD9OXXqVGJiok8OJ3sKBDsAAPAEjIlGizRaEXVCCLEIvfbss6lbvnln7IjuOl2R1Xq8sLhf\nly49Q0OwobLesT1ECDboWYMe5WZfd51hrCzXOyt7z93jQlVKi8v1derFl554fN0Pm7VBQS3W\nNwDai3379rV1E9o7CHYAANAili9f/uabb969fr3JZNJqtY899tidzz9vkUgQpdhoYPSVjKGS\n0euxvoIx6BlDJbbZ6q+UEAVxDooIcz+Tc9zfb0n8O0Jo/QdULidqDVVriVZL1Rqq1hCNH1Gp\naQPu6rqZzeZVq1bt3r3bZDL17dt33rx5CQkJzfgGAFA7SunSpUs/+eST0tLShISERYsW1Siw\ncePGt99+OzU1leO4Ll26zJ07d/LkyQihcePG/f777wghjHFycvKxY8fqKNxhweIJHwGLJ7wU\nLJ7wUo3aoLi8vDwgIKDeYthuZwyVjEGPDXrGoMeGSsZowPpKLNS13179MKZKFdVoRZWaqjVU\no6VqDVFriFpDlSp0bZmIy+WaMGECzc99JrmfWirZdiXjh4zsP/74w8du8sLiiUZpocUTy5cv\nnz9//tSpU2fMmFFRUbF06VKXy5WXl+eeY/ftt99Onjz5nnvueeyxxxBC77333m+//fbTTz+N\nHz/+ypUr8+bN27p169GjR5VKZffu3eso7PFmewsYsQMAgJbVkFSHEKIymSgLE0PCalzHVgvW\n61mTARv0jMm4e8uPg8OCVHyD90yhFJtN2GxibvzS1cynISp1ek7evWrZs9Pul7IcQmhSQifF\n9t0LFizYvHlzQ98IgAaglL7zzju9evX66quv3FeGDh0aExNTtQ1QRkZGSkrKxo0b3VeGDh0a\nEBDwzTffjB8/PiEhITAwECHUv3//egu3Qd/ah1p+0wEAALQfVKEk4RGurj2cA261jxr3s19w\nytc/lF+7b3umpHTezn05MfGu7r3EiCiq0SKmwR/slGKziSnI5y5f7Gc3zx2Y7E51bm+NGvZ2\n5yj55o2yP36WHtjLnz3FZaSxZSUNumV8A0JISUkJIaQJrwW+JDeMwE2bAAAgAElEQVQ3t6Cg\nICUlpepKWFhYVVBDCC1YsGDHjh1VOU+j0YSGhubk5NSsqPGFOwgYsQMAAG/y0ksvTbtwoefH\nXw6KCNM7HCdKyxcvXuz/4NS/tlEmBFssjMnAGA3YZMQmI2MyYJOJMRqw1dLwM3M5hukdFIDS\nL9/4JcqyVKWmKjVRqqhKTZUqolIjlYoo1VSppApl9cI2m+2NN9749NNPbTabQqGYOXPmv/71\nr5ud89tYlNK8vDyVSuXv7++RCkFLKyoqQggFXb/WJzw8/MyZM+7HRqNxxYoVP/74Y05Ojnua\niiiKMTExtdbWqMIdBAQ7AADwJjKZbNOmTXv27Dl58qRWq3135MjY2NjrSjAMVatFtVoMv+FQ\nXVFkLGZsMjJG/bXMZ8ImI2MyNirzYVHEBj0y6GtflMGyVKEgSjVVqqhSuet/B4LPpe6bfHeE\nWn25onLupu/nl5evXr26sR2/0TfffLNkyRL3nOn+/fuvWLGiZ8+eza8WtKhaZ/aL1daJT5w4\ncf/+/fPnzx83bpyfnx/GeOzYsTerrVGFOwgIdgAA4H2GDx8+fPjwRr+MZa/uyXL9fssIISoI\nLzz9VNHpU5N7dAlSyEutdoVCPvqW/lKHHZtNqN79WaoTRWwysddWO03SyCcNvsX9eGB46L7p\nD9oFkV3zFqP1o3IFVSioQkWVSiJXIIWSKlVELkcKBWXr+fP0888/L3j++XdvHzEhoZPJ4Vx+\n6NiDDz64Z88e9xws0G65x+rc43ZVsrKy3A/S0tL27t37xBNPvPbaa+4rgiBUVFTExcXdWFWj\nCnccEOwAAAAgzHHLPvxo06ZN23btsllsPXv2feKJJ1xarXvdL7ZaGLMZm43YbMImE2M2XV2Q\nYTE3aqjPTcaxyGpB1roWg1OJhMoVSKkicgWVy6lcQeUKqlBeeyz/aOXKxUMHTenZDSGkkUhW\njRlx7psf1q5d+8ILLzT9uwBaXmxsbGBg4G+//UYIcZ/dd/ny5dOnTysUCoSQe6V5ZORfg80f\nfPCB3W6vGtJz7/gtCALHcfUW7phguxMfAdudeCnY7sRLNWq7E+/S6LNiCcFWC2MxY7MJW8yM\n2YytFvdjbDFTk5FtrQUTZ0pK83jZ6IkTiVSG5HIqU1CZjMrkRCZDMjnCGDV4u5P09PSq/fxG\njBhR7/Eh7YEXbXfy8ssvL1269N577506dWpJScmyZcsCAwMvXrxoNptdLld8fDwh5P333w8I\nCPjxxx+PHz+OEDp+/PjWrVsHDBiwfPnyJUuWvPLKKz179pw0aVLdhZVKZX1t8UEQ7HwEBDsv\nBcHOS0GwayCn0zlm6NDpMeF/vyURI0QR2pWdWyqQe8aM5hx2ZDFjiwW7nM1/o3pRqYxKpaxK\nLXAclcmpVEZlMiSVEanU/YDK5FQipVLpZxs2vLT01f7BgX5SycH8wl63DNiwYYNMJmt+GwoK\nCr7++uucnJyoqKiHHnooKqrmDfHm8KJgJ4riv//97/Xr11dUVHTt2nXJkiU7duz4+OOP3Z8V\nx44dmzNnzunTp9Vq9d133718+fK9e/c++uijoigeOnRIoVBMmjQpNTW1U6dOFy9erLtwly5d\nPN749g+CnY+AYOelINh5KQh2DXfixIlp06YFELFPcOCZkrJyhv3qq6+SkpKqCmBBQFYLNpsZ\nmwXbbNhmxRYztlmxzcbYLMhiwTYrdrZG+LuRQMm5knJeF5DQqxeSyahUhiQSKpFSiQRJpEQi\nRVIp4iW06uLND/nYu3fvww8/PDAooHdQwIXyin2FJevWrbv99ts91VRKKc/zQjO3s75eCwU7\n0KJgjh0AAIAWlJSUdOjQoW3btuXk5NwaHT1p0iS1Wl29AOU4pNFSjbaOW7ZYFJHNythtyGpl\nbFZktVCLeft//+soK4310yh5XspxETp/madv+3KY6RsShBBCl8436AUsS3kJkkopx1GOR3I5\n5XjKsiLPF3+/6ff7JtwSFuIuuDMrd8Nby4dHhiu0WsRxVCJBDEulUsSwVNLg3acRQght27Zt\n0aJFubm5GOPBgwcvW7ase/fujesn8CEwYucjYMTOS8GInZeCEbt24vDhw8ePH1er1cOHD4+O\njkaUIruNsdux3Ybtdmy3IpuNcdiR3Y7tduywS0TBZTIyDgey29pqFLBB3AGRZSnHIZ6nLIc5\njvI8xQyVSBDGSCpFCFFekpOfv2XLlqGREd0D/UustrePnPi5qGz37t0eWR0MI3beCIKdj4Bg\n56Ug2HkpCHZe6rrFE4RghwM7HdhuQ3Y747Ajh33f9u25J44/2qdH1YKJEovVTlFUcBByOpp7\nbm/LowiN+eaH/vc9+NJLLzW/Ngh23ghuxQIAAOiQGIbK5VQuR1o/hJB7h4yukbGzv9hwIL/w\nhcH9/WXSbVcy5+7c+97Hn1w9e5QQ7HRghwM7HMjlxC4ndjiQw4FdTuxyIfeXXC7qcjJOB3a5\nqNOJ3Q8EF9MqA4QYoZExUccv13JeCOggINgBAAAAV/n7+3/33XcvvPBC77VfUUrDwsLeWLnq\nrxPlGYbK5FTWlPPQXn/99f9+9tnCoQP6BAVl6PXrTp8bNW7cYzNmYIeDCgIWBOx0uAcREaXY\nYUOEIqcDE4JdTkQIcjgQQthuQwhhpwNRhFxOXNuGbUVmi190fNO/BcDLeUGwM5vNH3/88Zkz\nZ1wuV9euXWfPnh0cHNyEMgAAAEC9unTpsnnzZovFYrFYPPinZP78+SEhIa+uXZv9266oqKhH\nH31s6uOPC1xz/wq//tprB77b+ON9E3RyOULoSEHR1+cufvXyEk80GXglL5hj9+qrr5rN5lmz\nZkml0g0bNmRlZa1evdq9XXWjylQHc+y8CMyx81Iwx85LdaA5dj7B6XROmzbt5IEDQ6LCLS7X\ngcKSuXPn/uMf//BI5TDHzhu19xG7srKyo0ePrly50n302+zZsx9++OGzZ8/27du3UWUAAAAA\n3yORSL777rvdu3dfunRJKpUuHTSoW7dubd0o0Jbae7C7cuUKz/NVB/qqVKrIyMhLly5VD20N\nKQMAAAD4qhEjRtx///0eP3kCeKP2HuyMRqNara5+Tp9Wq63xD7feMoIgLF++vOrp4MGDBw8e\n3JKtbhsMw6hUqrZuhee5f7Icx/lk71iWxRj7atcQQjKZjOf5tm6L53EcJ5fLpVJpWzfE89w/\nOF89ZNNXf93cWJb14d6BBmrvwQ5d+7venDKiKG7evLnqqUajGTlypAda1v545DTD9ollWfbm\nZ/V4O67ZE6jbLZ7nfTLYoWsByFf58IeJD3eNYRjP9s6zB5S5tdAcd49syOwb2vufEz8/P6PR\nSCmtim4Gg8Hf379RZSQSydatW6ueqtVq31tkgDFWq9VGo7GtG+J5DMNotVqn0+mTKwwkEgnL\nsjabra0b4nlSqVShUFgsFmd73t+/qZRKpcPhaIk/e21OpVLxPK/X631y8cSN93x8hr+/vyAI\nnl1kxrKsRqPxYIWgFbT3YJeQkOByudLT0zt37owQMhqNubm5NU7Bq7cMxjgiIqL6S3xyVSxC\nSKxtTyPfQCn1yd4RQhiG8cmuuWMBIcRXe+erXXMTRdEngx2Cz8nGqGNzCdButfefmU6nGzx4\n8Jo1azIzM/Pz81euXBkfH9+jRw+E0Pbt27dt21Z3GQAAAACAjqO9BzuE0Jw5c2JiYhYvXjx/\n/nyJRPLvf//bPTp16tSpI0eO1F0GAAAAAKDj8IINiluCT96KhQ2KvRFsUOylYINiL+V7GxRX\nCQwM9Ph2Jy2xQTEsnmhpXjBiBwAAAAAAGgKCHQAAAACAj4BgBwAAAADwF0EQMMZ//vlnkwu0\nIQh2AAAAAPBlO3fuPHbsWMPLsyy7a9eu5OTkJhdoQ+19HzsAAAAAdChGo3HLli3Z2dlRUVGT\nJk3S6XTNrPDtt9+eMGFC//79G1geYzxixIjmFGhDHXRVLAAAAABaX72rYk+fPv3QQw8FUbFP\ncNDF8opsp/D555/Xe8J7HatiU1JSdu/eLZFIevbseeTIEY7jPvnkk9dee23EiBGfffZZamrq\nP//5z2PHjhFCBg4cuGbNms6dOwuCwPP89u3bU1JSWJbdsGHD+vXrc3NzLRbLkiVLHnnkkXoL\nuDsyffr0y5cv9+jRY8WKFSkpKadPn+7Tp08TvmmNAiN2AAAAAGht0n070Q1DS6IoXvjqqy9H\n3TY8OtK9G+3B/MLTH703xGqo9dRp55ARtL5Tm3fu3BkbG/vCCy/Mnj0bIcSy7EcfffTDDz8k\nJCQghO6///6BAwfm5uaKojhz5sxHHnlk//79Va9lGIZl2bfeeuuXX34JDg5et27dU089df/9\n90ul0roLyOXyiRMnDhs2bN++fVlZWTNnzkStdZIHBDsAAAAAtDbJkQOIkBuvP9Gtc/WngyPC\nBkeEoRNHaq3EOfA2VF+wu9Hdd9+dlJTkfnzw4EH3wdYIoSlTpkyePPnGO5kPP/xwcHAwQmjU\nqFFWqzUrK6tr1651FzAYDLm5uUuXLtVoNH369Hnqqacee+yxxrazaSDYAQAAAKADcZ8s73by\n5MlXX331/PnzCCGHw+FyuW48bzc6Otr9QCaTIYRsNlu9BXJycliWjY2NdV9vzWUWsCoWAAAA\nAB1I1Y3UtLS0O++8c8yYMVlZWUVFRevXr6+1fL2HlN5YgFLKcVzVdbbxw4pNBiN2AAAAAGht\n5qefr/X6kiVL/rdt65Kht/YODrhUrl+072C3ocPefPPNWgtTiaQ5bTh27JggCHPnznVP4Dt0\n6FBzaqsuLCzM4XAUFBSEh4cjhI4fP+6pmusFwQ4AAAAArY3K5LVen7/4FV6jnbp2rcFgUKlU\nM2bM+Ne//nWzwg2kUCjS0tL0er2fn1/167GxsaIoHjp0aMCAAZs3bz5w4ABCqCqNNcett94a\nGBj42muvrVixIjMz86OPPmpmhQ0Ht2IBAAAA0F5IJJIXXnghLS3t4sWLGRkZixYtksubleoQ\nQrNmzXr//fd79+5d4/qgQYPmzZt31113hYeH79ixY8uWLcnJyX379s3KymrmO0okkk2bNu3d\nuzcoKGjWrFlLly5FrbUqFvaxAwAAAEArqXcfu6apYx+7tiIIAiFEIpEghA4ePHjrrbcaDAaN\nRtPS79tBb8WaTKa2boLnSaVSh8PR1q3wPIyxTCYTRdHpdLZ1WzyPZVmGYVwuV1s3xPM4juN5\n3ul03rjEzAfwPC+KIqltswZvJ5FIWJa9cd2fb5DJZHa7va1b0SLkcjkhxLN/BViWde8DAhqL\nUtq9e/fbbrtt5cqVNpvtlVdeGTZsWCukOtRhg53vBSCMsUKh8L1+IYRYllWpVKIo+mTvpFIp\nxtgnu8YwDMdxNpvNJ3snkUgEQfDJRC6TyTiOczqdPnk/R6lU+uQ/SISQWq12uVye7V2tewKD\nhsAY//DDD//4xz+ioqJkMtmwYcM++eST1nnrDhrsAAAAAABaTp8+fXbs2NH67wuLJwAAAAAA\nfAQEOwAAAAAAHwHBDgAAAADAR0CwAwAAAADwERDsAAAAAAB8BAQ7AAAAAAAfAcEOAAAAAMBH\nQLADAAAAAPAREOwAAAAAAHxE+zp5Ij8/f+XKlWlpaVu2bKm1gNls/vjjj8+cOeNyubp27Tp7\n9uzg4OA6rgMAAAAAdBztaMRu3759L774YmRkZB1lVq1aVVJSsmjRojfffFOhUCxZssR9CPfN\nrgMAAAAAdBztKNi5XK4VK1YMGjToZgXKysqOHj36t7/9LS4uLjw8fPbs2fn5+WfPnr3Z9dZs\nPAAAAJ+Rnp7+6aefrlq1ateuXR6sdu/evQ8//PCwYcOmTZvmwVNECwsL582bl5ycPHr06FWr\nVjkcDk/VDLxRO7oVm5KSghBKT0+/WYErV67wPB8XF+d+qlKpIiMjL126ZLVaa73et29f9xVC\nyKVLl6rqCQgIkEgkLdWNNoIxxhhzXDv6gXoKwzAIIV/tHcuyDMP4ZNfcPziWZX2ydxhjlmUp\npW3dEM/DGCOEOI7zyd4hhOr9B/nhhx8uXrw4KVDnJ5O+/9aKPgMHbdy4USaTNfN9169f/9K/\n5s1O7PN/naIulJc/Pv3hFxe/8uSTTzaz2tzc3GHDht0a4De7S2eLy/XRhx/s2LFj27ZtHvm9\nc/8WA+/iTR+4RqNRrVa7P3TctFqtwWDQarW1Xq966nK5Hn744aqnM2bMeOaZZ1qnza3Mz8+v\nrZvQUiQSie/F8SpSqbStm9BSFAqFQqFo61a0CB/+B4kQ0mq1bd2EllL35+Thw4dfWfjvLfdN\nHBkThRCqsNnv/G7LsmXLVq1a1dA3cLmQ4KJOFxIF5HQgUaROp6myctdHH/z50H1JoVfnf0/v\n3f2rn7fSHl3UEh4hhAQBuZwIIeQSqOBCCCFRRM5rY28OOxWvzS9yOZEgVL2brqQk/dGHlPzV\nv+bTenW75bNvvvvuu6eeeqqhDb45odobAW/hTcEOXftPyYZfd2NZ9pFHHql6mpSUZLPZPNyy\ndkAmk9nt9rZuhedhjGUymSiKTqezrdviee4RO5fL1dYN8TyO43iedzqdoii2dVs8TyKRCILg\nk3N5pVIpwzA++SGJ6v6cJAQ7Hdu+/OLp5H7uVIcQ0slln46//dsTR+x//IIcdndoQ3Y7EgQs\nuJDTSQUBO+xIFKnDgUUB3eR3WYbQd5PGVr/S2d9v8ZAB6MCeZv56BHJs9adqieTB7l127Njx\n6KOPNq/iq3xyxL0OgiDwPP/rr7+OHj2a5/nt27ePHj26eoGsrKy4uLizZ8/26tWrgbXdWEmL\n8qYfmJ+fn9FopJRWxTiDweDv73+z61Uv5Dju2WefrV5VWVlZqzW7dWCMJRKJxWJp64Z4Hsuy\nMplMEASf7J1UKuU4zie7JpfLeZ53OBw+OeOHYRi73e6riZxhGKvV6sW3YkUROx3YYccOB7LZ\nGKcDOR3Y4cBOh8AwokGP7HbsdGKXEzmd2GHHTgdyurAoIIQWKlk0/NbqlfUI1L0SqEM7fqv1\nrfAND9ocoZQQ4pFPFZ7n5XJ58+vxRizL7tq1q2pOV6Ps3LlTo9H079+/OZU0mTcFu4SEBJfL\nlZ6e3rlzZ4SQ0WjMzc3t3r17WFhYrdfbur0AAAAQQujnn3/+9NNPc3JyYmJiHn300fHjxze2\nBux0IruNsduR3cbYbchux3Yrstvzrlwxl5epWDZEo1YwDHbYkcOOb34DkSDEN68vLYeyHOJ5\nhBBiGFr1QHJ1ngbmuKsXEaIYV10/duwYNhkHhYe6n+odjm8vXH7uwSmt23YPO3/+/Lp163Jy\nciIjI6dPn56YmNj6bcAYjxgxommvffvttydMmNC/f//mVNJk7SjYVVZWiqJoMpnQtRE1lUol\nk8m2b99ut9snTpyo0+kGDx68Zs2aOXPmSCSStWvXxsfH9+jRA2Nc6/W27hAAAAC0Zs2alf95\nfc4tib0Te6aWlv991t+yX3zp6gwwQrDdhq1WbLdiqw3brIzNiuw2bLNiux3brNhuwzab+15n\nrZXHI4QwQoQgfUXrdIdKZYhlKc9TiQQxLJLJKMNQiRRzPOVYyksQyyKJlGJMpVKEGSSVIoyp\nRLprz5533l19e6fYBD+/1LLy7y9cfnLev6ZMnYIwQ5sxy1bX/9aUlJQ+KsU9XeJNTte606mx\nfftNmzbNg11uZT/99NOsWbOcw0eiHr1RVuZX48e/+/bbkydPbnKFgwYNSk5OXrNmjfvp7t27\nR40alZOTU1lZ+c9//vPYsWOEkIEDB65Zs8Y9PORW/S7qqVOnZs2alZqaGh8fv2DBgqoyqamp\nN9aQkpKye/fuP//885NPPjl8+HBVJcXFxc8999yePXv0en1iYuLy5cuHDBlCCGFZdsOGDevX\nr8/NzbVYLEuWLKk+eawJcPsZbH/88cdLSkpqXJk0adKbb75pNBqXLl2KELJarR9//PHJkydF\nUezZs+fs2bPdt1xvdv1mfPJWrJ+fX2VlZVs3xPNYlvX393c4HO7Q72N8+1asUqk0mUw+eStW\nrVb76q1YrVbL83x5eXlz/zoQgm3WyrzcZ2Y88p9ht/YI1Lkvl1ltaXpDcvdunNOB22ImH+U4\nJJFSiZRKpUgqpbyESiRIIqFSOZLwlOOLKvVfff/9qXPnLE4Xq1LNePyJcRMnUqkUcTxt3oSz\nI0eOrFu3Ljs7OyoqasaMGUOGDPFIj8rKylavXp2amiqTyUaOHDljxgye98y4JM/zHl9GU/X3\n98GsXHLDHWxRFA8dOiRERKLAwKuX9Ho2K3PAgAG1Llf6MjpCzmCEUGBV+RusXr162bJleXl5\n7kW+Tz311OXLl//8889u3boNHDjw/fffF0Vx5syZhYWF+/fvv3GOXUpKSnx8/LBhw95///3y\n8vJHHnlk9+7d7jl2tdaAEIqNjX3hhRdmz55dPR0OGjTIz8/viy++UKlUCxcuXLt2bXp6emBg\nIMdx/fr1++WXX4KDg9etWzdnzpySkhKlUtnk73A7CnatCYKdF4Fg56Ug2HmphgY7SrHVwlit\n2GxCFjNjNWOzGVutjMWMbRZssWCbFbXu35fzZRUWlbrfwIFUJnfnNiqVIamUSqVIIqNSKZVI\n/cPCKvT6htRmNpstFktISEhLN9tTAgMDXS5X9R0hmq9Fg13YuctCs/+FZHRPULMMqjPYFRcX\nR0RE7Nq1a+jQoaIohoeHv/HGGzNmzKisrJRKpe5l+5s3b548ebLD4RBFsUawUygUQ4YMSU9P\n79SpE0Joy5Yt99xzjzvY1VoDxvjGYBcQEJCUlHT+/Hn3PDGbzRYUFPTBBx88/PDDHMe99dZb\nf//739G1lRmpqak9e/Zs8vekHd2KBQAA0LaOHz++f/9+q9XarVu3iRMmcHYbYzZh9/8sFsZs\nwhYzNpsYswnbrKjFFgVTiYTK5FSuQAoFkcmRTE5kciSTuf+fyuRUJku8dci3k8YlhgRVverb\n85cuhUZ+snBCXVU3eGM2lUqlUqma0wvQToSEhKSkpGzatGno0KG7d+82mUz33XcfQujkyZOv\nvvrq+fPnEUIOh8PlctW6hD83NxdjHBMT436akJBQ9aVaa6h1HXF6ejrDMN26dXM/lcvlMTEx\nWVlZ7qfR0dHuB+7tEpu5Jh2CHQAAeBlBEDZv3nzmzBmVSnX77bcnJSU1uSrscGCT0R3d9v20\nLevM6dtDggMUMuWpSvXl02ydO0k1jU0QLlcauiYlcxoNkcmRQknkcipXUIXCHeaoTI5Ytt56\ntJFRf2RmVwU7QunO7NzRI8d4vMGghUTzvIhqjtgRQvLy8qi/DlXNO3Q5UXl5RHh4rYGJadi/\n0ClTpixcuHDVqlXffvvtXXfdpVar09LS7rzzzkWLFv3yyy8ymWzr1q133313ra9133Oo2naj\nam+/htdQK0JI1R5edW/Z1lgQ7AAAwJsYjcZJkyYZcrJTYqOKHc5Jq1Y9/fe/V5/QXRMh2GLB\nJiNjMTEmEzabGLMRm4zYbMYmA652N/l2FqHE3s1pG1UoqVJJ5UqiVFGFAimURKnad+LEslXv\nDI4Mi9KoTxaVbDh36Z333ut0//3NvI29cOHCR6ZMUfL8pIRORodzxeFjRZxk5syZzasVtJ7D\nXeJqvf7Jvl0vPvYa+r/JqHMXlJ2Fvvn6haefen70iOa817333vvkk08ePHhw8+bNX3zxBULo\n2LFjgiDMnTvXPR/x0KFDN3ttZGQkpTQ7O9t9wNWFCxfc1xteA0IoISGBEHL+/Hn3PVaLxZKd\nnV198M+DINgBAIA3efnll/0Mlf974mE5xyGEThWXpry7evhtt93Wtw82GRmjHptM2GRk3DdM\nTQZssXjqnillOapSUZWaKFVUpUJKNVGpqEJJlSqiVFG5otaRtkG9+y3um7R+/fqDWVmxvRN/\neXu1R7b1Gjly5Adr17766qtzd+zleX7YsGGbPnvdh0/f6TieeOKJyMjItWvXZmz/PTo6+tG3\n37rrrruaWadGoxk/fvzLL7/MMMztt9+OEIqNjXUv1BgwYMDmzZsPHDiAECooKAgPD6/x2sGD\nBwcEBLzyyisrV64sLS2tWl17sxqio6MVCkVaWpper6+6m9+3b99bb7113rx5X375pVQqnT9/\nvlqtbtQIX8NBsAMAAC9BKTabi44efnfMCPm121L9QoIyn5ypObQLH/LkcfUIoRKr7cOTZ+e9\n+po7zFGlmjZ1r9p+/fo14kiuBhs/fvz48eONRqNMJvPtE946mjvuuOOOO+7wbJ1Tp0699957\nn332Wfct3UGDBs2bN++uu+7CGN9zzz1btmwZM2ZM3759jx49WuOFcrn8559/fuqpp8LDwxMS\nEpYvX37HHXcQQm5Ww8mTJ2fNmrVgwYJvv/02MzOzqp5vvvlmzpw5PXr0IIQMGDBg3759Go3G\ns310g1WxPgJWxXopWBXrpVp0VSwWRWzUY4OeMRqxUc8aDdigx0YDYzHfbDu3RqFSKVVrqEpN\nVWpRpaYqNVVrNmz7acs3G368byJ3bXnBaweObDM7tm/f3vx3bD90Ol1FRSvteNfKvG5VrGfV\nsSq2o4EROwAAaCOUYpORMegZgx7rK1mDHusrGIMeW8zNrRljqlASd3rTaIlSRdQaqlZTpZpq\ntLS2Tc7ueDx8+dffTPvvb88PTNZIJFuvpL956NjGTT80tyUAgNYFwQ4AAFqeKDJGA6OvYCor\ncWW5+wFj1DdnBI4iJIgk02DIsjluu3M8qwugag1Ra4hKTZWqhiwsrU6tVm/evHnRokW3b9rm\ndDq7dev2+dcbPLWDLgCg1UCwAwAAj6KUMRpwRTmqKLv4v33W3OwImTRao27y1iFUIiEaP6r1\nu5rbNJqjV9Lf/OjjfadOsxLJmDFjFi9eLEZENP8ebXR09GeffaZWqymlFoulY07UAcDbQbAD\nAICmw2YTU1nBVJYzlRXuB7iyAl8bh0tCCFXbQbduVColWozKnUcAACAASURBVD/q50/UWqr1\nIxot1foRtfbGJQuJPfpsuOsep9PJ87xnd8BCCDEMw/O8T877BKAjgGAHAAANgu02prICV5Yz\nFeXIbJKUFEsryrHL2fiKMFVriJ+O+PsTrR/10xGtn6j1Q3JFo6qBdaAAgBtBsAMAAGQ0Gk+e\nPGm1Wvv06RMREYFEkdFXMhVlTEU5U1nOVJQzFeXYZq3+koYeTVXNrF//fOAfcwfdOZ42cgIc\nAAA0EAQ7AICXEQSh1sOFmuy3zZu/fmdlV6WsW0BA9jZVYEx0IMc0YVNfqlQRfx3xDyA63amc\n/IWvv/77Q/dW3SgllP73Ssbd/jpIdQCAlgPBDgDgNXbs2PH6669fuHBBoVCMGzdu4cKFISEh\nja0EGw1sRRlTVsqUlzHlpbSk+AGX84EJ158xWm+qkyuIv4746YhOR/wD3HmOVrs3GtXdlPrS\nwnWnUh/v18t95b3jp3mNtn///o1tMAAANBwEOwCAd9i9e/eMaVNfvHXAHdPu19sdbxw8+MAD\nD/zxxx8ymayOV2GjgS0vZUqLmfIypqyUqSjDzsbNiqMsS3UBon8A9Q+4GuN0AargEGedGxSr\n1erVq1c/9thj29IyegYGnC4pPVBc9sUXX9TdWgB8Huwk3NIg2AEAvMPLL7/80q0D5w1Kdj8d\nEB46YP03X3755RNPPFFVBtttTGkxU1rClpUwpSVMeRl22Bv7RkaH8/tLadOe+wfRBRJdAFFr\nENOECXVo7Nix+/fv37BhQ25ubuKwlLemTYuIiGhCPQAA0HAQ7AAAXkAQhIsXL44fPKXqipRl\nx8ZGl144z186j0uK2NIStrQYGxtznhLLEn/d2aKSjIyMe7rEV13+/uLlVRl5DyYPbH6zY2Ji\nFixY0Px6AACggSDYAQC8AMuyMpnMeP2xs6+OuE3CMui/mxpSA2U5EhBAdIE0KIToAsTAIKL1\nRyxL09MfS0nJNZqeTu7LYvy/3PyFew++/J9lLdMPAABoWRDsAADtmCiy5aVMYT5bVHBy1oxI\n7rpbohL25ndIGYb46cSgYBoYTAKDxKBgovWv9Y5qfHz8unXrnn/++cX7Dso4zkLoc889N3Xq\nVI93BQAAWgEEOwBAe0IpU1nBFOWzhQVccSEuKsSi4P5KrKSuzyuqUJLgEDEoRAwKoUEhJCCw\n4buKjB49+siRI+fPnzebzb169fL3929uLwAAoI1AsAMAtDHscjKFBVxBHlOQxxXkoev3Aa4V\nRcimUPIxcSQ4hASHikEhVKlqThukUmliYmJzagAAgPYAgh0AoA1gs4nLy2Hzcpj8XLaspP59\n4xhGDAgkIWEkJEwMCSNBIVQiaf6x9wAA4GMg2AEAPM9ut//5558lJSXh4eFDhgzheR65w1x+\nLpudwebnMuVliNK6K6FKlRgaLoaEiRFRJDKKcnyrtB0AALwYBDsAgIedPXv2kUceESsr4/21\nVkEY3avHc3dN9KsswyZT3S+kMpkYFknCI8XwCDEknMrlrdNgAADwGRDsAACe5HA4Fjz7zKLe\n3ab27IarzknNyay9NMYkIFAMixAjosWwCBIQiP56DQAAgEaDYAcA8ASblc/NZnOy0IXUPeNH\n1VWSYcTgUDEyWoyKESKikFzRWk0EAADfB8EOANBE2Olk87LZ7Ew2J5MtLXHPmat1HpxAiFGt\nVfbuS6JixPAoKpG0clMBAKCDgGAHAGgELAhMcSGbl8PlZLK52Uisf2VqqdXad+3Xv+/bFxsb\n2/INBACADg2CHQAd2uXLl/ft22e1Wvv37z948ODaC4kiW1TAZWewOVlMQR6uM8yRwKCfz186\ndvHylJ7dEnTa0yVlT/22Y9TEiZDqAACgFUCwA6DjWrVq1ZtvvnlLcKCC51YuWzZ09Oh169Zx\n3NWPBcagZ7My2OwMLisDO+x11EOVKiEyWozpJMTFU422T0XFNwsW9Pv0K4wQwnjq1KlLlixp\njf4AAECHB8EOgA5q7969b7/xxh//d/egiDCEUJHZMvqbzetXvv3k7aPY7EwuJxPbbHW8nKrV\nYnScEB0nRMVQrV/1L+l0uo8++ui9994rKysLCgqqSooAAABaGnzgAtBBff/999N7d3enOoRQ\nqEq57+EH/JEd/fHzzV5C5QoxPFKMiBJjO4nBoXVvTaLRaMLCwkwmk8Ph8HDTAQAA3EQHDXZs\ng08H9xYYY4yx7/ULIcQwDELIh3vXNl2jNMhhv6tbl+rX/GWyWgpKpSQqVoyJI7GdSGBwVZir\nt8UYY4QQwzA++YPDGPtq19xYlqX1HQ3ipXz4p+bxDxMM+0p6Ieyrv7p1c7lcbd0Ez+M4ThCE\ntm6F52GMOY4jhIgNWIDpddzBrtW6Ri0WnH6JXLqA0y5Ri+Wm5TgeR8egTgmoU2ccGY0Ypgnv\n5c49oiiSes+B9UIsyxJCfPLzk+M4jLFPfkgi3/2cRAjxPE8p9WzvCCFSqdSDFYJW0EFH7AwG\nQ1s3wcMwxn5+fr7XL4QQy7L+/v4ul8tU34FU3kgqlXIcZ6kjY3kCW1rMpV3mMi4zhQXuLFJr\nHjlXVi7r1Td86HAxMvqvg1mb+m2Xy+VKpdJqtfrkrVi1Wm23230y/Wi1Wp7njUajT8ZWnU7n\nk5+TCKHAwEBBEDzbO57nIdh5nQ4a7ADwfaLI5uVwaZe4tEuM8aaf9ZVO169X0v/Myj3vcD27\n4MVJkyb55mgGAAB0DBDsAPAp2OXiMq6wVy5xmWnYfpNlrQxDwiKEuM5Cp85ccOgwo/EWmy00\nNLR1WwoAAMDzINgB4Auw4OLSr7AXz3EZaVio/f4glSvETp2FTgmumLjqJ7RqtVqtVttaLQUA\nANCCINgB4MWu5rlL57n0KzfLc0QXIHTuJnTuIoZH1r1BCQAAAG8HwQ4AL0QIm5MpOX+WvXwB\n1zp/n2HEsAihc1choSvxD2j19gEAAGgbEOwA8CZsWQmXepq/kIrNtS1WZRgxItrVtbvQtQdV\nKFu9dQAAANoYBDsAvIBQWXHhu2+iK0ojudq2lIM8BwAAACEEwQ6A9gzbbdyVi+j0CWVB3q0Y\noxtSHQmPcHbvLXTtQZWqNmkhAACAdgWCHQDtDhYELv0ydyGVzbiC3YdSXL/oIcdgFPskBo8e\nR3Qwfw4AAMBfINgB0F5gp5PLuMJevsBlpGGX8+YF6cK9BwNY5SsPTm29xgEAAPAGEOwAaGs2\nK596irt8kc3KwGIt5z7YBVGgRMVfO+MLYT+Z1Gw2t2YbAQAAeAUIdgC0DcZo4NIu8xmXcXam\njJDaSjBidJyre6+RTz3zYEjAPwYkuS/bBXFHVu6sKdNbtbkAAAC8AQQ7AFoRpWxxIZt2mUu7\nxJYW116GYcSIKKFLd9e1JRHzFy1+dNo0kdJxnWLLbbZlB4/JIiKnTJnSqi0HAADgDSDYAdDi\nsCiyOZlc2mUu/RI21bb/HEKIZYXoWKFLd6Fz1xpblowaNWrdF1/85z//Wbz/O5VKdccdd6xZ\nuFAikbRG0wEAAHgVCHYAtBRss7GZV7i0y1xmGnbWvhiC8hKU0NUe11nslEBlsptVNWbMmDFj\nxrhcLv6vmXYAAABATRDsAPAwbDTwVy5yaZfZvGxU6+Q5hKhaLXTqIiR0ZTt34WRywWJpSM2Q\n6gAAANQNgh0AnsEY9Nyl89zlC2xRAaK01jJiUIjQuYvYuasYEubemo7lIKsBAADwGAh2ADQL\nU1nOX7rAXr7AFhfepAQjRsYInbsInbsSrV/rtg4AAEDHAsEOgKbAVgt/IZU7d+Zmec4mCL9n\n5kSPvaPLnZOoXN7KzQMAANAxQbADoBGwIHBXLnLnz3BZGbXOn3MRwmMGYSTnuDyjac7LS05O\nvAfWrwIAAGgdNc8UBwDUii3Ik/26Vfn+W7KfNnMZaTVTnVyRptE9+dsOnmHQtWNdZyf2tlRW\nnj59uvVbCwAAoGOCETsA6oJdLu7CWf7kUbaklv2EqVQqJHRzde8tRsfu2bTpWGFJ9a9yDCNh\nGedNNjoBAAAAPA6CHQC1YyrK+ZNH+XNnsMN+w9cYIbaT0KOPkNCNcld/iRITEy+WV5wtLesd\nFOi+8ntGtpWiXr16tWazAQAAdGQQ7AC4HqVcZprk2CE2J+vGXUvEkDChZx9X9141DodACCUk\nJDwxe/bELz6fP6h/twD/40UlKw4dX7RokVarba2mAwAA6Ogg2AFwDaVcxhXJgb1sUUHNr7Cs\n0LmrK3mgGBFVRwWLFi2Kj4///Msv806di4uLe/uDDyZOnNiSLQYAAACuA8EOAIQI4S6ekx7e\nz5SV1PyKn87VL9nVq19DtixhGGb69OnTp09vmVYCAAAA9YBgBzo2UeTPn5Uc+h+jr7juOsZC\nXGdX0gAhtpP7iAgAAACg/YNgBzouNitDtuuPmqN0GAudEpxDhoshYW3ULgAAAKCJINiBjogp\nLZHt/oPNyrj+KiN07+0YNIToAtuoXQAAAECzQLADHQu22SQH9khOHau+wzBlGLF7L8fgocQ/\noA3bBsD/s3ef8VFUawPAz8yZ2d5TCQkkAYTQCVKlKlWaglRBuCCaF8UuAvdeERTLRa8o5KKI\noEhTAUV6E5EuCtI7AUJC2m6yvUx7P0yyhNBCdpPZbJ7/B39nJrNnnzGw+3DmnOcAAECAILED\nNQbHyY4elh34nfDcUpdu19Xr0w//vWz9c9GQ1QEAAKjmYEsxUCPgnGz10oXyXdvKZHUIoW51\n4+NINGPGDEkCAwAAAIIIRuxAuOM42f7d8j/2l372avf5tDKZ2CYQerZF07Q9eySKDwAAAAia\nEErsHA7HwoULjx8/zjBMw4YN09LSoqOjy1yTk5OzZMmS06dPe73e1q1bp6WliWX9X3rppStX\nrvgvUygUP/zwQ1UGD0ITLsiTb/wZ5+X4zwgUtTY770rGldfbpfpPQj0TAAAA4SGEEru5c+c6\nHI4ZM2bI5fIVK1bMmjXr888/J8mbD4sZhnnnnXfi4+M//PBDlmUXLVr00Ucfvf/++wghh8Px\n3HPPtW/fXryy9KtADcVx8kP7ZAf3II67ea5OkqfvwIvLli//ZVNaajM1TYvnFx871alTJ4kC\nBQAAAIImVBK7goKCw4cPf/rpp0lJSQihtLS0MWPGnDhxokWLFv5rMjIysrOzZ8+eHRERgRB6\n+eWXx48ff/Xq1bp169rt9tjY2MhIqFIBEBKrmWxeh3Nv+M8INO3t8hjTqg0iiGefffbnn3/u\n8t2Pz7ZsqqDw6rMXjjncv82cKWHAAAAAQFCESmJ34cIFmqbFrA4hpNFo4uPjz507VzqxYxgG\nISQrmRplNBoxxhcvXoyLi/N6vQcOHFi2bJndbq9fv/4zzzxTu3btqr8LEAroMyfkWzYQLOM/\nw9dOcPcd6C9lIpPJfvnllwULFvz4229ut61t78fnv/IK/KsAAABAGAiVxM5ms2m1WqLUXCe9\nXm+1Wktfk5ycrNPpVqxYMWHCBISQOIvObre7XC6DwcCy7KRJkxBCK1eunDZt2oIFC9RqtfhC\nn8/Xp08ffz8jR4589tlnq+CmqhhBEOJYZliSy+X+nP6uOI7btI7bt/vmGZrGvfrJOnVT3DaN\n7r333gt2jBWnUCikDqGyaDQajUYjdRTBRxDE/f9AVk/i57DJZJI6kEoR3p+TNE0H9+5Ylg1i\nb6BqhEpih0o+Te5BqVROnTp13rx5W7ZskcvlAwcOjI6Oxhjr9fqlS5f6L5syZcrYsWP379/f\ns2dP/0mtVutvy+VyvtQCybCBMQ7L+0IIYYwFQbj33QkOO7/iG6H0ZhLxdfDQp4moaF4QkCBU\nepQVQhAEQRBh+YsTb00QBCFU/+cHgiTJML61cP0ziWr85ySoCUIlsTMYDDabTRAEf3pntVqN\nRmOZy5o2bfrll186nU65XI4QWr16dVRUVJlrlEplVFRUQUGB/4xMJlu3bl3pa0r/NDwQBGEw\nGAoLC6UOJPgwxkaj0efz2e32u16Te0O57kfCWuQ/w7RI9TzWF2GMQvv/iVwupyjK6XRKHUjw\nKZVKtVrtdDq9Xq/UsQSfVqv1eDzi/JAwo9fraZouKioKy7TVZDKF5eckQigyMpJl2TJPugJE\n07RYegJUI6GyerRBgwYMw1y6dEk8tNlsmZmZKSkppa/hOG7Pnj2FhYVqtZqiqKNHjwqC0Lhx\n46tXr86fP98/YuzxePLz82NjY6v6HoBEqFPHlSuW+LM6AWNP7wGeXv0RxtIGBgAAAFSxUBmx\nM5lMHTp0SE9Pf+mll2Qy2aJFi+rVq9e4cWOE0Pbt2z0ez4ABAzDGa9as2bt378SJE3Nzc9PT\n03v16qXT6QiCOHDgAMuyI0aM4Dhu6dKlGo2mY8eOUt8TqHw8r9i5hf77T/8JQatzDxrK1YKl\nMwAAAGoiInQG210u18KFC48ePcpxXJMmTdLS0sRHsXPmzLHZbO+++y5CKDs7Oz09/fz58wqF\nomvXruPGjaMoCiF0+fLlJUuWiEtrGzZsOHHixJiYmHu8FzyKrUbER7Fer7fMo1iC4xQb1lDn\nz/rPcAl13QOfElTqKo+x4sL+UazdbodHsdWL+CjWbDaHzrdDEJlMJovFInUUlSIyMpJhGHgU\nC0IosatKkNhVF4cPH/74449Pnz5tNBr79OnzyiuvqFQqhBDBMMp1P+CMS/4rb06qq1Ygsaum\nILELBSzLrl279tixYyqVqlevXm3atLnvSyCxeyCQ2FVHoTLHDoDb7d+//8kBA5rbCxd1afdW\nvTo7l383evRonueR26X8funNrI4kPX0HwqQ6AGoUh8PRq1evF2bOXHg9e+7fxx5/4omZ1aHM\n+NWrV3fv3p2RkSF1ICBshcocOwBuN2XKlGkd20ztUPyv8N7JdVstXr5l9Y9PuQpxfp54UsDY\n238w81DK3bsBAIShd9555wSP0NIVSK5ACKGMy/NfeL5Lly7du3eXOrQ7KygomDx58o6dO5HB\niIqKunXtMm/evCCu8wv18VVQVWDEDoQop9N57ty54SkP+c8YFfKnGzd69PLZm1kdTbsHj4Cs\nDoAaaP369WjcP4qzOoRQUjLq0euXX34JvOfCwsJp06a1bt26YcOGw4YNO3LkSOB9CoIwadKk\nHeZC9ONPaO0vaO2639ze55577kHLzlk47ozXt8PuXF5onZNnfj079+mrWd0vXml89mLPYycD\njxOEARixAyGKoiiSJF231j1/o32qERdXOhQUStfgEXztBCmiA+Fm165dv/76q9PpTE1NHT58\nOE3TUkcE7sPhcCCN9pZTOp3Dcddql+Xk8/mGDBlyQkDo2TSk1e7av2//wIG//PJLampqIN2e\nOXNm15696MefkMGAEEIGI/r3jANDnvjrr7/KTA108Hw2w+ax7I2S/+awbA5T3PDdfeJjltcX\nSIQgbEBiB0KUXC7v0qXLJ4eOfN2vp5jKcQJvLNl6S9BqXU+N5iPLlqcGoALeeOONb3/4AXXp\nhpTK7/4z56uvvtqwYUPp7WpACGrSpMnRA/tRo5IBe45Dhw42HTE8wG6XLl16orAQLfoWyeUI\nIdSylVdGT5s2bevWrYF0m5mZiSIiirM6kVqDhjz1tcO17kZePstlM0w+x91gWFdFt46AxA6I\n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" }, "metadata": { "image/png": { @@ -15829,18 +15959,18 @@ "\n", "plot(my_history)" ], - "id": "16234cff-9298-4b95-a43e-d8474f4a2507" + "id": "4513ef65-be2b-4306-b936-d17ac3a2ab1b" }, { "cell_type": "code", - "execution_count": 404, + "execution_count": 367, "metadata": { - "id": "c2014194-df6e-4afc-9d89-a4b1acace3fd", - "outputId": "742538eb-5689-4042-f8e3-d025a5fb718f", "colab": { "base_uri": "https://localhost:8080/", - "height": 225 - } + "height": 233 + }, + "id": "193c05db-b490-471e-af56-8763deac5b39", + "outputId": "17af62a5-7813-47c0-d27a-937f3007c8c7" }, "outputs": [ { @@ -15849,16 +15979,16 @@ "text/plain": [ " y_test\n", "y_ 0 1 2 3 4 5 6 7 8 9\n", - " 0 951 0 8 1 0 9 5 1 4 5\n", - " 1 0 1116 1 0 5 1 3 11 3 9\n", - " 2 2 2 951 9 6 0 2 13 3 1\n", - " 3 1 5 23 970 2 47 0 14 30 14\n", - " 4 3 1 10 1 936 9 8 10 10 48\n", - " 5 1 0 0 8 0 787 10 1 9 4\n", - " 6 13 4 7 2 15 17 924 1 12 1\n", - " 7 2 1 10 6 0 1 1 963 8 20\n", - " 8 5 5 21 7 5 13 5 1 890 8\n", - " 9 2 1 1 6 13 8 0 13 5 899" + " 0 954 0 4 0 1 8 8 1 2 3\n", + " 1 0 1122 4 2 2 3 3 12 2 6\n", + " 2 3 3 951 9 5 2 2 16 8 3\n", + " 3 4 0 13 949 1 19 3 5 13 7\n", + " 4 1 0 11 0 931 3 10 7 6 33\n", + " 5 2 1 3 9 0 822 17 2 8 7\n", + " 6 14 3 9 0 13 10 908 0 5 1\n", + " 7 1 2 13 9 1 4 2 969 12 26\n", + " 8 1 4 23 24 4 16 5 2 915 12\n", + " 9 0 0 1 8 24 5 0 14 3 911" ] }, "metadata": {} @@ -15869,40 +15999,40 @@ "y_ <- apply(tmp, 1, which.max) - 1\n", "table(y_, y_test)" ], - "id": "c2014194-df6e-4afc-9d89-a4b1acace3fd" + "id": "193c05db-b490-471e-af56-8763deac5b39" }, { "cell_type": "code", - "execution_count": 405, + "execution_count": 368, "metadata": { - "id": "377c4696-96f9-493d-9c04-428abf962a96" + "id": "d3367189-c3b4-422d-80ad-08224443440a" }, "outputs": [], "source": [], - "id": "377c4696-96f9-493d-9c04-428abf962a96" + "id": "d3367189-c3b4-422d-80ad-08224443440a" }, { "cell_type": "code", - "execution_count": 406, + "execution_count": 369, "metadata": { - "id": "b734bd17-2cc2-4f3e-ad5a-07c7bd02af31", - "outputId": "81ee88d6-5b46-41b8-ce45-8ee0cd1eec6e", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "f16da2a1-68fb-40be-8701-8317d1359221", + "outputId": "b2a89b52-e8c6-4ea5-efdf-53d8abf2723d" }, "outputs": [ { "output_type": "display_data", "data": { "text/html": [ - "0.9387" + "0.9432" ], - "text/markdown": "0.9387", - "text/latex": "0.9387", + "text/markdown": "0.9432", + "text/latex": "0.9432", "text/plain": [ - "[1] 0.939" + "[1] 0.943" ] }, "metadata": {} @@ -15911,18 +16041,18 @@ "source": [ "mean(y_ == y_test)" ], - "id": "b734bd17-2cc2-4f3e-ad5a-07c7bd02af31" + "id": "f16da2a1-68fb-40be-8701-8317d1359221" }, { "cell_type": "code", - "execution_count": 407, + "execution_count": 370, "metadata": { - "id": "2182a4a7-cf2d-40ef-a9af-590bff996b7e", - "outputId": "6ea4aa5e-046a-402c-cfce-d2be7e43de4a", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "493883d1-7426-4662-adbf-8de53aa9373b", + "outputId": "5cdf2f2f-c52c-4e1d-9166-8cf0247c16d3" }, "outputs": [ { @@ -15934,13 +16064,13 @@ ".dl-inline>dt, .dl-inline>dd {float: none; width: auto; display: inline-block}\n", ".dl-inline>dt::after {content: \":\\0020\"; padding-right: .5ex}\n", ".dl-inline>dt:not(:first-of-type) {padding-left: .5ex}\n", - "
loss
0.22294782102108
accuracy
0.938700020313263
\n" + "
loss
0.204719439148903
accuracy
0.943199992179871
\n" ], - "text/markdown": "loss\n: 0.22294782102108accuracy\n: 0.938700020313263\n\n", - "text/latex": "\\begin{description*}\n\\item[loss] 0.22294782102108\n\\item[accuracy] 0.938700020313263\n\\end{description*}\n", + "text/markdown": "loss\n: 0.204719439148903accuracy\n: 0.943199992179871\n\n", + "text/latex": "\\begin{description*}\n\\item[loss] 0.204719439148903\n\\item[accuracy] 0.943199992179871\n\\end{description*}\n", "text/plain": [ " loss accuracy \n", - " 0.223 0.939 " + " 0.205 0.943 " ] }, "metadata": {} @@ -15950,30 +16080,30 @@ "my_model %>%\n", " evaluate(x = x_test, y = y_test)" ], - "id": "2182a4a7-cf2d-40ef-a9af-590bff996b7e" + "id": "493883d1-7426-4662-adbf-8de53aa9373b" }, { "cell_type": "code", - "execution_count": 408, + "execution_count": 371, "metadata": { - "id": "018d13e9-d9ca-4088-98ba-67a7734763ca" + "id": "40f627cb-dd69-4324-82a5-442001ed1c12" }, "outputs": [], "source": [ "x_train2d <- x_train %>% array_reshape(c(-1, 28, 28, 1))\n", "x_test2d <- x_test %>% array_reshape(c(-1, 28, 28, 1))" ], - "id": "018d13e9-d9ca-4088-98ba-67a7734763ca" + "id": "40f627cb-dd69-4324-82a5-442001ed1c12" }, { "cell_type": "code", - "execution_count": 409, + "execution_count": 372, "metadata": { - "id": "f61fdf0b-17df-4f69-8865-7902e8130226", - "outputId": "df586efd-b5a4-4cbf-c17a-bf0ec4b3badb", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "b8989289-9810-4d92-b22e-170e8fd94dcf", + "outputId": "5855424a-22fa-43ee-8d6e-6b1d766a0cb5" }, "outputs": [ { @@ -16017,18 +16147,18 @@ "my_cb <- callback_early_stopping(patience = 5,\n", " restore_best_weights = TRUE)" ], - "id": "f61fdf0b-17df-4f69-8865-7902e8130226" + "id": "b8989289-9810-4d92-b22e-170e8fd94dcf" }, { "cell_type": "code", - "execution_count": 410, + "execution_count": 373, "metadata": { - "id": "d50d6e18-60ed-4d25-96ca-bae451703883", - "outputId": "43672643-9fb3-4620-d3aa-e718e00e51cb", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "92d64806-286c-442d-882b-a6705f3caffa", + "outputId": "e2381705-f4f7-4af7-9b8b-1918e51ece0b" }, "outputs": [ { @@ -16037,7 +16167,7 @@ "text/plain": [ "plot without title" ], - "image/png": "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" + "image/png": "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\n1uVyqV2I8oxGI8uyXq/X5/OpXYvyrFar1+vleV7tQpRns9lomnY6nZr8pR4fH6/JTxJCiF6v\nF0VR2avjOE6rEV/D0Msaod59990LL7wwOzs7Ly/vnnvu6ezsHN5x/BfMONaSJN03OxSrDwAA\nACIPgt2IiKL4yiuvXHbZZePHj7/66qs3bdqkyGE3bNjw2yVLflWQXX77zzde/YOOHdtvuOEG\nv98/jEMJBaOCvXTsgTLK5VSkQgAAAIhACHYj8sADDyx94k9751zcft/92+dd8tM77li3bt0I\njylJ0ooVKx6/+KI7J59XFB87IzP93Wvm99bXvfvuu8M5HEX5z59+rCmKOqwwBgAAoF0IdsNX\nXl7+ytq1ZM3TZME15IILySXfJ2vXLf/d7z0jW8Krp6enra3t+/k5wS0mjp2dlXHw4MHhHVAY\nN0GyWOU2t2c35fOOpDwAAACIWAh2w/fNN9+QUcUkuz+BUYTExbuefOa/FZUjOazJZGIYpttz\nQvzq9nisVuvwDigxjD+4wpjPx5XvHUl5AAAAELEQ7IZPp9OR7z7ul5F5H2fc4R5+p53BYPj+\n97//v1+W+vrXAdvc0PTZkdb58+cP+5j8pGmS/tiTTbqvd2CFMQAAAE1CsBu+WbNm6ZsaydeD\n71rrJeTHdU3re+3DPvKf/vSnKoqd+Lc37vjPf6/+578XvPeflStXjh07dtgHlPR6PrjCmMPO\n9k9uBwAAAFpyjs5jp4isrKyVK1cuf2ApufR7JCODtLVT114nZecQQvyS9Msjrbvdnj+mJbNn\nMAvdIElJSVu2bNmwYcP+/funJiY+9IMfjB49eoTV+s+frvt2l9xXp/+6VBg3gZx9YQAAABDJ\nEOxG5Pbbb580adL69etbGuqKioquGz96RYDe4jw22ezrR3ub/P6XstJjz37mfZ1Od/311ytY\nqmS1CqPHswf2EULozg62rkbIL1Tw+AAAAKA6BLuRmjp16tSpU4Mv10vSg22dr3T3yC8/d7p/\nUNu4NjujSK9TqcDjfNNK2INlRJIIIfodXyHYAQAAaAzusVMYS1F/TEtek56io48NdNb4/N+r\nafjIrv7MwIGkZKHg2HKxdHMT01inbj0AAACgLAS7kFgYH/vPnKyE/hFYZyBwc2Pz051HVV95\n0T9jdvDWOn3pV+oWAwAAAMpCsAuVErNxU0HOeINefhkg5Pftnbc2tTgDARWrEniokZ0AACAA\nSURBVFPShNx8uc001jNHGlUsBgAAAJSFYBdCWTruw/zsq2KOTyz8QZ/jB7WNNb7hrPqqFF/J\n7GBbtwOddgAAANqBYBdaJpr+W3b6wymJTP8AaKXXd2lNwwd9DrVKCmRkiVm5cputq2HaWtSq\nBAAAAJSFYBdyFCFLkhLW5WTGscdvubu1qWV1e5coqXPTna9kVrCtw512AAAAWoFgFybzLKZN\n+Tnj+m+5kwh5srP7+obmbjVW9xJz8sSMLLnN1hxm2lvDXwMAAAAoDsEufHJ03Ef5OdfYYoJb\nvnC6Lqlu+HoEC8sOm396f6edJHE7t4W/AAAAAFAcgl1YGWnqr1lpA2e5a+b5H9Y1PdvZHeZK\nhPxCMSVNbnOHD9HdXWEuAAAAABSHYKeChfGx7+dmp3PHlv0QJGlVe9ftTS0OMawzofhLjnfa\n6bZvCeepAQAAIBQQ7NQxzWT4rCB3tsUU3PKvPsclNfVlHm/YahAKi8WkFLnNVR5kujrCdmoA\nAAAIBQQ71SSyzD9zsx5OSQx+D+r8/OW1jS9194TpWVmK8s+Yc6wtSbptX4TntAAAABAiCHZq\nkmdCeTs3M5k9Nizrl6QHWztuamzuDcvTskJRsZiWIbfZqkqmtTkMJwUAAIAQQbBT3xyLeVNB\nznSTMbjlI7vz4ur63W5PS0uL2+0O4bkHddrhTjsAAIBohmAXEdI59r28rHuT4oPfjyZeuKKq\nbuKap3Lz82+44YbGxlAt6irkF4qZ2XKbra1mjjSE6EQAAAAQagh2kYKlqAdTktbnZCb2L1BB\nGIbccrv04Sf/NZpvuOEGjydU0935Zs4JtvXbvgzRWQAAACDUEOwiyzyr+fP8bG7fnuOb9Aby\n698eHj/h7bffDtFJxew8MTtXbjONdUxjfYhOBAAAACGFYBdxdE4n/+slxOU6voki5Jf3vpCU\nFronKnyzLg629V9tDtFZAAAAIKQQ7CKOxWLhWJYcaRq0vTY75+Kahm2ukDxLIaZnCnmFcptp\nOcLWVYfiLAAAABBSCHYRR6fTLViwgLz4HHG7Bn2pyc9fU9e0oq3TJw1/qrumpqZ33nnnzTff\nrKysHLjdf9FcQh1b6Ez35WYyglMAAACAKhDsItHq1aunMDT56XXkwaVk8e26R1dYRUH+UoCQ\nF7qOXlbTsG9Ya1Q8//zzJSUld/1pzb1/+etF8+YtXbpU6g9wYmq6UFQst5mONvZQuSLXAgAA\nAGHDql0AnITNZvvoo48+++yzAwcOxMfHX3rppVxyyq+b2z5xOOUdDnl9P6htXJIY/z9JCTqa\nOsPDbtmyZeXq1WT1E2TyFEIIaah/5b4lxcXFt956q7yDb9YlbPVhEggQQgxbv3AVj5UY/IQA\nAABEDfTYRSiapi+77LJ777134cKF6enpSSzzRk7GcxmpFvrYt0yQpCc7uy+pbdh7xl13b775\nJpl/1bFURwjJySU33bp27drgDoH4BP68SXKb6uvlvt2t2PUAAABA6CHYRZOfxNm+KMwtMR9f\no6LC67u8tnF1e5c/cPpb4rq6ukhq2gmb0tI6OzsHbvDNnCtxnNzW7dhKhWzyPAAAAFAcgl2U\nydFx/8rLXpOeYj6x6+6iqrov++xDvzc3N5ccOnjCpoMH8vPzB26QzBb/1Olym/J6dLu2KVY6\nAAAAhBiCXfShCFkYHzuo667W77+07OADre2uQOBUb/zFL35h2rGdvLmWeDyE58mnH5N1b/76\n178etBt/4UzJZJbb3De7qL7eUFwFAAAAKA7BLlrl6rj3c7MfS0sx9XfdBQh5ubt3VnX9Z87B\n86TIioqKXnrpJds768mV3yOXX2p46k+rV66cN2/eoN0kTucrmSW3KVEwbNsSuqsAAAAABSHY\nRTGaInckxH5VlDvPag5ubPLz19cfWXyktUMQBu3v9Xp///vfFxr1j1w0/XczL5ydlrJmzZr2\n9vbvHpmfeH4gLl5uswfLmI620F0FAAAAKAXBLuplc9zbOZnPZaYlcMenJnm31z6jqv7Vo70D\nn6l48cUXma6OzT/7f0tLpv5m+vn/vvaqkriYRx555CQHZRh/cJExSdJt+SyklwAAAACKQLDT\niOvjbOVTJl4Xawtu6RPF+1vaL6tt2NM/H0ppaen1Y4v1DBPcZ+H4MaWlpSc9ID9qTCA9Q26z\n9TVsbVXIagcAAABlINhpR7KOez4z9a2czOz++UoIIWUe7xW1jQ+1dtjFAE3T4okLhYmSRNOn\n+BmgKO/c7wUXGdN//ikRxZDVDgAAAApAsNOay6zmrUV5v0pK4PozmSBJf+3uKamqs137k7X7\nK5x+Xt4ekKS/7imfM2fOqQ4lZmTxxWPlNn20W/ftrlAXDwAAACOBYKdBRpp6KCXxq8Lc2RZT\ncGOHIGwoHtv6zAuTtu15Ysc3z+zeM+eNf1YHyMMPPzzEoXxzLzs+X/H2LZTLGdrSAQAAYAQQ\n7DSrQK/7Z27WMxmpCQNuqnNlZrU8vuavV137vs4y+6c/++KLL+Li4oY4iGSN8U+bIbcpv1+/\n7YuQ1gwAAAAjEUFLvDudzpdeeqmsrIzn+eLi4sWLFycnJw/a5+jRo6+88sq+ffv8fn9+fv4t\nt9wyatQoQsiSJUvq6+uDuxkMhrfffjucxUcmipCfxtmuiLH8saP71aO98g12AUKOnD/NecH0\n+ckJRqv1tAfhL5ypO7BPnqaYK9vDT5gipqaHvHQAAAA4e5QknX6N0fD43e9+53Q677zzTr1e\n/9Zbb9XX1z/77LODbu2/7777dDrdokWLjEbjW2+9tWfPnr/97W8Gg+HWW2+95pprpk8/thYW\nTdPx8fFDnKurqyuEV6IGiqJiY2N7enpOtcMBr29pS/tO9wlrvxbodQ+kJF4Vc5p4xx3ab/hg\ng9wWM7LcN9wcfKgiDBiGiYuL8/l8DocjbCcNG71ez7Ksy3XyOaWjmtFoNJvNDofD5/OpXYvy\nrFar1+vleV7tQpRns9k4juvu7o6c3w4Kio+PP3r0qNpVhERiYiLP8319fQoek+M4m812+v0g\nkkTKUGxXV9fu3bsXLVqUl5eXnp6+ePHi5ubm8vLygfs4HI6kpKS77747Pz8/LS1t4cKFdru9\nqalJ/lJqampiv6FT3blpnEG/MT/7+czU1AHT3dX4/Lc1tvyk/kiFd6hfvfzocWJmttxmmpu4\nw4dCWysAAAAMS6QMxVZVVXEcl5eXJ7+0WCyZmZmVlZUTJ04M7mO1WpcvXx582d3dTdO0/DeK\nz+crLS194403HA5HYWHhwoULMzIygnsGAoHNmzcHX+bm5qakpIT+msKNoii9Xj/0Pj9PSf5x\nUuKato7n2rs8/avKbna6ttS4f54Q90B6SuqAqVIGkr4/n7zyIpEkQoh+y3/pMePJKfZUnNxr\nS9P0aa8uGrEsyzCMVi+NEMKF6+ckzGia5jjulLMFRTOKoggher1ekz12Z/I5Gb0U/5zU5E+4\n5kVKsLPb7VarlRowwGez2YboUnY4HH/+858XLFgQFxfX19cXGxsrCMJdd91FCFm3bt3y5ctf\nfPFFs/nYQls8zy9btiz43ptvvvmee+4J2aWoyXoG98xZCXncZluSm/NAbcMb7R3yJ7coSX/v\nOvp2T+8vM9IfyM6MYZnvvG20cP6F4tc7CCFUX69x93b2+/MVr38IHMdpNSIQQnQ6ndolhIrB\nYDAYDGpXERIa/oEkhFgsFrVLCJUz+ZyMUgzDKHt1wneWpoTIFynBjvT/mXgmjhw5smrVqkmT\nJt10002EEJvN9vrrrwe/ev/99990003bt2+/7LLL5C0syz7wwAPBHYqLi51OrU3bQVGU0Wh0\nu91nuH8sIS9kpf08LmZ5U8s3rmPvcouBPzYeea21fWl6yk2J8dyg78iseWz5XsrnJYSIWz7z\njR4nJSQpehEnR9O0yWQSBMHr9YbhdGEm99hp8i40juP0er3X69Xk7waDwcDzvKjFWbuNRiPD\nMC6XS5M9dmazWZO3tBJCLBaLKIoej+f0u54xiqLkrneIIpHyDYuNjbXb7ZIkBeNdX1/fSWfi\n2Ldv3+OPP37DDTfMn3/yHiOj0ZiUlDTw8QiGYa655pqB+2jy4QmDwXC20Wcyy3yUl/Ven/13\nbZ1N/LHfvm08/+uGI8+2ti9PSbo6xkoH0x3LcRfNNXz2MSGEiCK1cYPnJwvD8BQFwzAmk0kU\nRU0GO3nAS5OXJo95yXdKqF2L8jiO8/v9mnx4Qq/XMwzj9Xo1GexMJpMm/7kRQiwWSyAQUPbq\ntN0trVWRMnxeVFTE83xNTY38Un4qYsyYMYN2O3jw4B//+Mf77rtvYKpraGh47rnngr0CXq+3\ns7MzNTU1PJVHO4qQa2wxO4ry16SnDJzxrs7PL2pqmVNT/2/78WdR+cnTxLRjNy8yTQ1cxYFw\nlwsAAACnFinBLj4+vqSk5Pnnn6+rq2tubn7qqacKCgrGjh1LCNm0adPGjRsJIX6//+mnn77q\nqqtycnK6+nm93vj4+NLS0ueee66trU1+r8VimTFjhtrXFE10NLUwPra0KG9xQpx+QCdchdd3\nW2PLD2sbt8vDtRTlu/Ry0n87rX7zJ5RG//YFAACIRhE0j53b7X7ppZf27NkjiuK4ceMWL14s\nD8U+8cQTdrt91apV+/bt++76V3feeeeVV15ZW1v76quvyo/WFhcX33HHHUM/96rJodih57E7\nc0f8/OMdXW/3OcQTfzbmWMzLkhOmmoyGTf/h9n4tb/RPmea75PKRn3QImMcuSmEeuyiFeeyi\nFOaxA1kEBbtwQrA7rUqvb3VH93/sjkE/H5dZzctiY2a8+bdj68ZSlPtntwbHZ0MBwS5KIdhF\nKQS7KIVgB7JIGYqFSFNs0P89O/2j/Ox5VvPA7ZscrkubWhfMvny3LYEQQiRJ/9+PSP+UeAAA\nAKAiBDsYyvkm49s5mRvzs2eYTcGNEiGfEHrWjEuvnjp7V2wC09ai6x+ZBQAAABUh2MHpTTcZ\n/5WX9c/czAtMxoHbP0lKm11y6ZXT5uwsL6PtSvb/AwAAwDAg2MGZmmMxf5if/XbO4Hj3WWLq\n986fNb+iepPdqcFbcgAAAKIHgh2cnXlW84f52f/MzZx+YrwrNVl+2th8cXX9v77zOC0AAACE\nB4IdDMcci3ljfvZ7eVmzuBNWld3v9d3e1HJhVd3L3b0uPFEBAAAQXgh2MHwXmU0bigs/O9py\nZUcLNaCXrsHPP9DaPqmy9nftXW28BtcJBQAAiEwIdjBSE2dc9E51+a5tn1zX2sgMiHe9ovhM\nZ/f5VbWLmlp2upVclxoAAABOCsEORkpiuaMz553n6Ht9b+n+LR/eUn1QJ4rBr/oD0nt9jvm1\njXOr618/2uvG+CwAAEDIINjBSEmSdNvqP35UU08IyfO4Xqwqf+XV52ccKEvl2IG7HfD6/qel\nfUJl7bLWjnKvBpciAAAAUB2CHYzUrl27tm7ePC31+OK8/y8jZeKrf/003vZ8Zur5Jz482yeK\n/9fdc3F1/SU1Da909/QN6NsDAACAEUKwg5GqrKwcl5SQaD4hwP1h7syefd9eF2v7OD97U0HO\nDbExBooauEOZx7u0tWN8Rc2dTa3/dbiEsM+Q4vf7Dxw48O2332pynVYAADg3IdjBSMXGxna4\n3INymZ5hJlbup3w+Qsgko+HZzLR9xQUrU5OK9LqBu3klaUOf/YaGIxMqax5s7djr8Yan5k2b\nNk2bNm3upZd+/6qrzjvvvL/97W/hOS8AAEBIIdjBSM2ePdvJ6Z7a9a38UurvezO4nfpPNgZ3\ni2eZuxPjtxflfZCffX1sjIk+4WevUxBf6u65rKahpKruD+1dh0J5E15lZeVtt93WsuDH5KNN\n5KP/OpY9tHzVqg8++CB0ZwQAAAgPBDsYqdjY2BdffPHxvQcu/Pv6G//98SXr3u3xHYtlXOVB\nbt+3g/a/0GT8c2ba/uKCJzNSLzAZqRO/Wu3zr+nsnl1df1F1/RMd3ZUhSHgvv/yyZ8ZMcu1P\nCMsRiiIzZpKbbn3mmWcUPxEAAECYsaffBeB05s6du2PHjg8++KClpWVufj49cTz5YAORJEKI\n/rOPA2kZYnLKoLdYGfrncbafx9maef7dXvtbvfYan3/gDpVe3+Ne3+MdXTk63dXJCQtibeMk\nQg+KgcPS2NhIiseesKloVOM/3lLg0AAAAKpCjx0ow2w2p6WlpaWlpaenk1Fj/NNK5O2UKBjf\nfYvu6z3VGzM4bklSwo6ivI/ys+9IiB00SQohpMHvf/ZI68X7KyYerrm/pf0zp8s7sictUlJS\nyJGmEzY1H0lJGRw9AQAAog567EABe/fuvfXWW5vcbpKaThrrJ+bnr33ttYLmJqa5iRBCOR3G\nt9e6f3qLZLYMcZCpJuNUk/F3qSk73Z5/2R0b+xwdwgnLkbXxwqtHe1892mukqTkW82UW82VW\nS9p3guBpLVy4cP2CBeTCEnLRLEIIqakmr/zt1geWn+1xAAAAIg0lhX2aiUjQ1dWldgkKoygq\nNja2p6cn/Kd2u92zZs1qvHAGufMXhGGIx0Mee3SmFPjXm2+Y3nwl2FcnJiV7rr9JMhiHPlqQ\nKEk73Z4P7c6PHM4mP3+q3cYZ9BdbzRdbzBcYjbozHqldu3btww8/7IqJITq9rrXl1ltvffTR\nRylKiYHes6TX61mW1eSUK0aj0Ww2OxwOn0+D81FbrVav18vzp/zJjF42m43juO7ubk3+doiP\njz969KjaVYREYmIiz/N9fX0KHpPjOJvNpuABIQwQ7DRCxWD3n//856b/+Q35x7sk+KBrXx/5\n0Q9Lt28blZRoevMVyuWUNwfSM9zX/VzidKc81skwDFPHcu+2d77X2XXoxPvwBjLT9CyLaY7Z\nNMdiHjSpykl1dXXt3r3b5/NNnjw5JyfnrEpSEIJdlEKwi1IIdmcFwS4aYSgWRqqrq4ukpJCB\n05fYbMRs6uzsLCwsdF97o+kfr1EeDyGEbmk2vvcPz49/KjHMWZ1iitUyTsf9Otba5Oc3OZyf\nOFzbXG7fib91XIHAx3bnx3YnISSdY2ebTXMt5lkWUzJ78h/yxMTEyy+//GwvFgAAIJIh2MFI\n5ebmkoZ64nYRk/nYpsYGyuXKy8sjhASSkt0/ut70zhsUzxNCmIY6w7/e8f7wmrPtt5Nl6bhb\nE+JuTYhzBwJbnO7NTtdnDmcTLwzarYUX1vfa1/faCSHFBv0ss+kis3GGyRTHnl2gBAAAiC54\nKhZGaubMmReOG0ce+V/S1koIIVWHyaMrfvrTn6ampso7BDKyPFdfR/p76diaw8a3XqUc9pGc\n1ETTl8dYnkhP+ba4oLQo7/dpyRdbzIaT3SRX6fX9rbvn5saW0RXVF1fXP9Ta8ZHd2Ys1agEA\nQItwj51GqHiPHSGkra3tN7/5zSeffEI4jhbFG2+8cdWqVSaTaeA+3OFDhg82kP5EJVmsnmuu\nF1PSTntwhmHi4uJ8Pp/D4Rh6T58k7XJ5vnS5v3C6yjzewKn3pAkZa9DPMJtKzKYLTIZTDdeG\nAe6xi1K4xy5K4R67s4J77KIRgp1GqBvsZF1dXc3NzXl5eTExMSfdgamvMW58l/IeWxBWYljf\nFVfzo8cNccxAIPDf//63pqYmNjZ25syZ2dnZZ1hMjyBuc3u2utxfOV2HT/3IhSxPx11oNk0z\nGiYZDWMMem4Ej8dWVVWtX7++paUlNzf35z//eXp6+tD7I9hFKQS7KIVgd1YQ7KIRgp1GREKw\nOxN0V4fx3XW0vf+jh6L8M+f6LpxJ6JPcFWC326+77rpvamrI2PGkr9dQU/2HP/zhZz/72dme\ntF0QtjrdW13ubS533alnTpHpaGqMXj/BoJ9oNIw1GEbpOdsZP+rx/vvv33333f6pF5CcHHK4\n0nTo4Pr160tKSoZ4C4JdlEKwi1IIdmcFwS4aIdhpRLQEO0II5XaZ3n+bbj6+9oOYmu79wVWB\npORBe95zzz3/OFRBVj9+7LGM7VsNq1Zu2rRp9OjRwz57Ky9sdbm3u9ylbk/N6XryZOkcW2zQ\nj9brCnW6fL0uT8elc9x3+/S6u7unTZvmWPJrcun3jm16c236fzbu3r1bpzvlkyJnFey6urpi\nYmKGOFpEQbCLUgh2UQrBDmR4KhbCTTKZ3T9ZaPh4I3uwTN7CtLWY177snzrdN3Nu8BkLQRDe\ne+898vRzxx+2nXGRd/KU999/f9myZcM+exrHXhsbc21sDCGkUxB3utw73Z5dHk+Zxyec4tdY\nCy+08MLnjuPZy0BR+Xpdvl6XxbHZHJej02VzbPn27Q6L9XiqI4T85IaWta+VlZVNnTp12AXL\n1q9f/9hjj7W2trIsO2/evNWrV6s49x4AAEQsBDtQgcQwniuu1iUl6bZ+QcmPU4iibuc2pq7G\nd/lVYnIqIcTtdvv9fhIff8I7ExIrKyuVKiOJZebbrPNtVkKIOxAo9/rKPL59Xm+Zx3vY5xdP\n3V3hlaSDXt9B74kdUXmjyF//74QtLEvOm9Di8wckcsaLYpzE+++//8ulS8ndS8iFJYK9b9Pr\nr9Zcd93mzZvNZvPp3wwAAOcSDMVqRBQNxQ5E9x41fPRv5kjj8U0UJeQX+WfNc8fEZmZmkqUP\nkB9ccexLgkBuv3luXu4777wT6sI8AanC56vw+Su9vkNe32G//8jpbs4bAkdRqSyTwXFZOi6D\n4zI4NoPjsjg2W8fFGY2nHYqdMmVK0//7CblqwbHXokjuuOV3t9165513DrukMMBQbJTCUGyU\nwlAsyNBjB2oKxMa7f7JQ981O3dbPKUEghBBJYmsOs3XVVEFxYVxs9fPPEoYhF0wnvT3k1f+z\ntbXmzpsbhsKMNDXZaJhsNAS3uAKBGp+/1s/X+v21fr7W52v0C+3C4LmRT4qXpCZeaOKFHW7P\noC8lsmy2XpfB0Ll6XZ5Ol6fjBt3D5/V6m5qayJQBg7kMQyZNVrDnEgAANAPBDtRG0/5pJULh\nKMPHG4933QUCxqpD+26/sfRIy5/+sfbjx1YxFHVxbtZ+jj3//PNVKdNM0xOMhgkDoh4hxCdJ\nDX6+0c83+P1HeKHR59vT3NIqSYI15qTP+X5XlyB0CcK3J27UU1SBXlek1xXr9UU6Vj96jK+3\nh2RmHt+juzsuK2PkFwUAABqDoViNiNKh2BNIEltdqdv2BdPZMegrDr+/vtf+wBfbepNS/v3v\nf7PqzSd8hvwBqU0UWnihyc8383wLLzTzQpPf3yKIfcNb9EIUCU0RiiaEkMpD+geXffTOO+ed\nd56yZSsLQ7FRCkOxUQpDsSBDsNMILQQ7mSRxhw/ptn9Jdw2Od7xE/IWj6PETxfxCieVUqW7k\nnIHAET/fxAtNfn8TLzSLgUa/v97r6z6bwEcRUqjXnW80TDMZp5mMxXr9SB7OCBEEuyiFYBel\nEOxAFuk9H3DOoSi+eCw/agxXcYDbXcq0twa/wlGEqzlMag5LLCfmF/CFo8WCIslgVLHYYbDQ\n9GiDfrRBT4iZDJjHzi4G6vz+Oj9f5+drfb5qP3/Y57OLJ18XTSKkyuev8vnX99oJIVaGnmY0\nzjAbZ5hNk40GdgQrZwAAQFRDsIOIRFH8mPH8mPFMe6uubA9bsZ/0L0RGCKEEnj1cwR6uIAwj\npmcKuQVifqGYlEKiOdDEMPREo2HiiffwtfFCpc9X5ecPeLzlXt8hr89/sk4UhxjY7HRtdroI\nIWaavsBkmGk2zbGYJxgMEdiTBwAAoYOhWI3QzlDsdzAME2c2+b7ZJe7ewbQcIaf4iZVMZjGv\nUMgrEHILJGPUdOOd1coTgiRV+fkyt2evx/u1x7vfe8pJlWVxLHORyTjHYp5jMefqwj14jaHY\nKIWh2CiFoViQoccOooFOT6Zc4C4aQzkdbHUlV1XBNNaTwAnDlJTbxR7Yxx7YRyhKTEkT8grE\nvEIxLeMMn06NCixFjdHrxuh1P4mzEUI8AWmvx7vb7d7l9u5we777WEaPIG60OzfanYSQXB03\nz2KeazHNMputjHb+n5yzDh06VFZWZrFYSkpK4gfN4w0A5zAEO4gmksXKT5rKT5pKeTxMbRVb\nW8U11BGP+8SdJKathWlrIaVfEaOJLygSikaLuQVSxD9Le7aMNFViNpaYjYQQUZIOeH3b3Z5t\nLnep6yQhr97Pv3q099WjvSxFTTUa5lnN8yzmiRirjUKCICxZsuSd994neXnE6bC53Y8//vg1\n11yjdl0AEBG09qsOzhGS0SiMmyCMm+ANBOi2Vq6+mq2rodtaBnXjEY+b27+P279P4jghr1As\nHisUjZYYpqen509/+tOWLVu8Xu/UqVOXLVuWm5urzpUohKEoeZq9xQlxoiTt8/i+dLm/dLl2\nujyDbssTJGmH27PD7Vnd3hXPMHMspoutlrlmUyqHT4Po8OSTT76zvZS89gZJzyCE9G365Fe/\n+tWYMWPGjBmjdmkAoD7cY6cRGr/HLi7O5/M5HI6h96R4P9NYz9YcZutqKPvJbzSRDAZvwaib\nnvtrV2vLnZPPM7DMhorqj5rbNm/enJOTE4LyT+Os7rEbBk9A2uFyf+Fyf+5wHvL5h9hzjEE/\nx2yaZzWXmExGJfrxcI9diIwbN67jl78mF806vmnFQ3eNH/vII48ocnzcYxelcI8dyPA3OmiH\nxOmEglFCwShCCNPZwdQcZqsqmPbWgc9bUF6v8UDZ2/NKJCJRhCKEXF1UcMuHn/7v//7va6+9\nplrpIWOkqXlW8zyr+ZHUpDZe+MLl3uxwbnG6j35nrPaQ13fI6/tLd4+OoqaZjLMspllm02Sj\ngYvmZ421JxAIdHV1kfT0E7ZmZLS3t6tUEQBEFgQ70CYxKVlMSvZPv4iy97HVlVxVJXOkYeBA\nrZzqZDefN/bGz7aqUWZYpXLs9bEx18fGBCSyz+v93On6V3PrIZqRTny+xC9J21zubS73Hwgx\n0/R0k3Gm2TTdbJpo0Os0fUeew+Hwer1JSUlqFzIUmqazsrIaKitIfsHxjC9LvgAAIABJREFU\nrRWH8i65eNjHdAcCzbzQLggtPN/KCz3dvc+OKlSgVgBQwzk6FOsdMCmaZuj1ek2OeVEUpdfr\nRVEc6bCX00Ht+Zp8u5scHTwQL0rSu7UN1z71HElKHtEpzh7DMBRFCYIQ5vMSQurq6qZPn26/\n7qfk2usIxxGvlww5TYyRpqdazDOtlulW81SLOeF0D6MwDMNxHM/z4vBWUQuj8vLye++9d/v2\n7YSQrKys1atX//jHPx76LRzHiaIYCJx8Bukgv9//xRdf1NfX5+fnz507V5HV8P7+97//Yuky\n8tD/kvOnEZ+PvPFa/Mf/2b17d/qgbrx+oiR1CUKHn2/jhQ6e7xCEVp+/QxCa/f5OXmj2887v\nfINaZkyLO92lRSmtfk4SQgwGQyAQ8PuHuuNieIdV9oAQaudosFP2LoQIYbVaT3sXWjSiadpq\ntfI873a7T7/3aUnSpy/9Rdrx1VWFBYPHGCkqkJsvTp4mFo0mDKPAuc4Ax3EMw6jyl8by5ctf\n3FdOfv+H45s+3JjpdEy98xdfOV3dp8uauXrdFJNxisk42WQcazDEsYP/j+l0OqPR6Ha7FbwR\nTZKkTz/9tKyszGazXXLJJQUFBad/z+l0dnZedNFF7dMuJDf8jJhM5Mst5IU///PNNy+99NIh\n3mU0GnmeHzqRV1RU3HjjjdVd3SQjkxxpHJ2W9uabbypS81NPPfXEE0+4BYFIpGDSxPt//1jG\n2LGdvNAlCN2CeFQUuwShnRe6RbGLF7oF4Ww/5Tckx89NS6U1NFVQkFY/JwkhNptNEARlb9hl\nGMZisSh4QAiDczTY4eGJKHLmD0+coUAgcP3113eUl//p4osuSE81f2fmXsli9U+YzE+YIllj\nFDnjEEL98MQQbrzxxk8ys8mNNx3fVF5mfXBpbW2tRMhBr+8rl/srp7vU7XacYmWzgVJYdrRB\nP1qvG23Q53Bcto4riLHGWiwKPjzhdruvu+66nYcqyPjxxOnUVRx65JFHbr/99hEe9rHHHntq\n8+fkqT8fX7nkzbUTdpV+9tlnQ7zrtA9P+P3+Sy65pKKgiPzqPsJxxOcjTz4+oa31008/ZU73\nZ0NAIr2i2BsQe4VAb0DsFcUeQewRAz2iKP/XKwa6eaGD97tICAbHAwGy/Lfx1VUPP/zwjTfe\nqPzxVYWHJ84KHp6IRrjHDs45NE2vW7fuH//4x18///yv1U0/nzD++zFG9mh3cAfK6dBv/1K/\nY6uQWyCMnygUjpIYDf5LSUpKIq2tJ2xqbUlOTiaEUISMM+jHGfTy5CkHff4dLs8Ol3un29N+\nij6qdkFodwpbnMcTKkNRmXpdJsemMUwCw6SwbDLLJHJsIsPEsYyNpm1n2S26cuXKnX0O8uY/\niMVCCPF/8/XKB5dOnTp10qRJZ3vtA1VVVZFJU05Yj27K+YffGOmTNLt3765oOkKefZFwHCGE\n6PXkvqVlKx98vmx/Sm6uKxBwBAL2gGQXRUcg4BADjoDYJwbsgUCfKJ5JkiaEkBGkugSGSebY\nVJZJ4bhUlk1mWbPbueKee3oLisiCa8gjvz+67atfP/BAbGzs/Pnzh30WAAg/9NhpBHrsRkSS\n2Ppabs9utq568Ex4hEgGg1A8jh8/UUzPVPzMKvbY7d69+4oFC8gjvyPTZxBCyJEj5H+WPHL3\n3XfdddcQ76r389+4PXs83j0eb7nX6wkM/wOEJiSWYawMbaVpI02ZaMZG00aG1lOUjqJMNE0T\nydo/GmhimJUPPOC7agHJHjArzQf/npOactVVVw19ImcgMMTaax988MEer4/MmnN8U11tzM7S\nX/3qV4QQiRD7idfYK4qEEI7jXLzgFoQAkRwBiRDiCgR4SXKIAZFIjkDA6+fdKg1lMhQVz9CJ\nLJvIMsksm8AwiSybyrGJDJPMMsksm8gy333YefXq1U9u/pw8+ezxjLvhneJPP966VVPPFaHH\n7qygxy4aIdhpBIKdIih7H7fvG135Xsrl/O5XA7ZYYcx4oXicmJwyxEHq6uqam5tzc3MzM08f\nBFUMdoSQV199dcWKFZ7kFGI0kprqn1133ZNPPnnmd1YJklTp8+/3eCv9/kNeX6XP3+TX4Nqp\nkYMiJI5l4hj5PzqeZeMZOp5hE1kmnqETWDaeYRJYJn5Yd4jecccd75tjyO2Ljm+qOszetah1\nULdulEOwOysIdtFIgwNMAMMmxdj8sy72z5jDVVey5XvZhtqBHXh0X69ux1bdjq2B+AS+eJxY\nPFY88SnaI0eO/PKXv9y2dWuCydjl9syfP/+pp56KjY0N+3WcqVv+P3v3HR5VlTYA/Jzbpmcm\nlZA6CUkggRBCC6CgggKiNAsirDSl6IorCCorKFIsFFGxLG1FURFXRde2fghSpUsJnYSEFBLS\np5dbzvfHQAikk0kmM3l/j4/PzMm5Z95Lkpk3p06efP/99x84cMBisfTo0aNTp06NupzB2DVi\nW1lilqTjJaV/m/uiZfhI1On6QQgOO5LBwrqasRi7+iy1NK2jKT+K0tK0lqa1NKWlKN31YWt/\nhtZRtD9DN99+M4GBgSg376aiq1cDAwOb7QUBAM0CEjsAqqFpvmMS3zEJW8zsudPMqRN0UWHV\nr1NlpbL9u9H+3ZKfVojrKHRIECOjBUKmTp0aWlGa++xTQUpFjtE08cffZs2a9cknn3jqPhoi\nNDR01KhR7mpNTVGmo0csRw6huS/fKGVYNHLYZ5u/Ck9OviqI5aJgEEm5KFSIYoUomSTJJpEK\nUbRJkpUQs2sos6GTzDxDTVEsRRFClBRmMWYwVlMUQkhLUxTCfhRFY6ShaeR07N+56+LxY0gQ\nsNWa1qXLlHGPh2g0aorS0rSKojQ0JW81+z8/+uijG0aMQIMGo95pCCFUWoLWr3n88cc9HRcA\noHEgsQOgVkSldvZIc/ZIo68WMGdPsefP3HJSGWU0cH8d4v46RBSKKxpdot3y7oNDXMtso/w0\nm0YMTfjXxqysrJiYGA/dgQfYbDakUN5URNOIZuQWc1dF4/rtKq7vr2a4nuf9+OOPH3/8cVFF\nBaVQdO/e/dlnn71lvLsyx6qRH0Xddh6loSi6ysUNPVJs0hNlZQ/k5ORER0f7+/vf5mu3iB49\nery1aNFrr/7TEa1HKjU6e3rYwIEvvviip+MCADQOzLHzETDHriUQQhfkM+dOs+fPYHODgon8\nYP3Hn2266667aqvg2Tl2zSEjI6PvnXei9RuR/no6m36Smf3cyZMn3XWoQ1FRkUajUdS5nXJz\n8+BZsc0qNzf38OHDdrs9Pj6+V69eng7H/WCOXaPAHDtvBD12ADQYxmJYhBgW4bhnMH0lj7l4\njrl4jqqoNZmWCHnz7js7Szy22YhHs5CWFBcXN3XKlHUvzUGTn0R6Pbp4EX2yYc6cOW48qsu1\nJwtoDpGRkV26dGFZtrS0tG3+2Q+At4MeOx8BPXaeQhUXsZkX6Ivn6KsFqLbfJozFdu3F6Fgh\nSi9FRJEq50r5Xo8dQojn+Q0bNnz66ae5ubmxsbFTp04dP368jx1j4Ks9dgghrVbrw4kd9Ng1\nCvTYeSNI7HwEJHYeh62Wkv37Lvz0Q+8Ana7KQtFbEJqRIiKFqBghKkYKbS9TKHwvsXNRKBQq\nlcqNJ0+0KpDYeSlI7BoFEjtvBEOxALgHUaoCBw3uddfAv44edWSc7yxjw22W6t14WBToy1n0\n5SwZQkQmI1ExuEM8HRouBgWjVrNAEgAAgJeCxA4Ad2IYpldaGkpLQwhZEUI2K3s5i87OZC5n\n3bKiFiGEHQ588Ry6eE6JEFEohSi9GB0jRsVI/gEeCB0AAID3g8QOgOakUPKdOvOdOiOEqPJS\nV18dk5uNbbZbKmKblT1/hj1/BiFE/LRCVIwQHSPqY4lS5YGwAQAAeCdI7ABoIZJ/oOQfyHfr\niQihiwrpy1l0Thadl4OrzdPCRgN76jh76jjCWAwMFvWxYnSsGBlNXMfJAwAAALWAxA6AFuda\nJNuuPerdT8YwzNUC4fwZ+nIWXZCPrm/Jew0hdEkRXVKEjhwQCEk3mNJtDmVyt/smTKJu6zxQ\nAAAAvg0SOwA8iqZRlN4RGIz63YUFnsrNYXKy6Zwsuqiw6jG1CCEG41SdX6oOoZJ80/LF8qQu\nMCEPAADALSCxA6C1IAwrxnQQYzoghLDNxuRm05ez6OxLVMWtuzNoaApVmZAnRun5SL0UpZf8\nYGMCAABo0yCxA6A1IgoFn5DIJyTyPN8vKXH7uIfC1eoaa2KjgTl1gjl1ArmSvIhoITJajIiU\n/ANh/xQAAGhrILEDoFUjhFw2GCvsjqqJXUZZud5fx1TL27DRwJw5yZw5iRBCCqUQFiGGR4jh\nUVJoWNXjLiqVlZUtX758x44ddru9e/fu8+bNS0hIaM67AQAA0LwgsQOgVeM4rmfPnp+cOL1i\n0ABXSbHVds+X3654//3hXZOvDddWm5CHEEI2K5N5gcm8gBBCNC0Gt5PCIoT2YVL7CNe0PJvN\nNmLEiCCLaUmPFBXLfnc+Y/Dgwb///ntcXFyL3iEAAAD3gcQOgNZu5cqVQ4YMKbLahsREl9rt\nHx090b3/gPtHjBQxvjYhz+Gg83PpvMt07mX6asGtS2sRQqJIF16hC69c2y5FoRRC2x/PybtX\nLXvjwUEymkYIDYmNpn/bMX/+/K+++qpl7w8AAIDbQGIHQGuXmJi4a9euVatWvXPypL+//9QX\nX5o8eTKuMg5LZDIhNk6IjUMIYZ6nruQx+blUfi5dkIdrPKfVZmWyMvsj1H/QXVWLn+nedfxv\nO5v3ZgAAADQn7JPHPNerpKTE0yG4GcZYp9OVl5d7OhD3o2na39/f4XCYTCZPx+J+MpmMYRiL\nxdIsrUsSXVpC5ecwBfnUlXyqvBQ14PedqNRiu1AxJJS0ay+GhEpa3e0twlAoFCqVymQyOWpM\nLr2cRqOx2+18tc2lfYBWq2VZtrS01Cc/HQICAsrKbl1m7huCgoJ4njcYbj26sClYltVqYa29\nl4EeOwB8F0WJwSFicAjfrSdCCNttdMEVuiCPKrhCF17B1pqzSWwxM5cymEsZrqdEJpOCQqSQ\nUDGknRQSKgWF1LgOAwAAQGsAb9AAtBVErhBiOggxHa49N1SsWfCKsrhwcEx0uEajYGo+yuLa\nBL783Gvz8yhK8g8Qg9tJIe2k4FAxOIRo/KpftXXr1k2bNuXl5en1+qlTp953333Nc08AAABu\nQi9cuNDTMXiA1Wr1dAhuhjGWy+V2u93TgbgfRVEKhUIURafT6elY3I9hGIqiPDOiJ5f3GDos\nAzOfns/8+mppWVRMwn1DcFAwYVjsdFY/wfYaQrDNSpcUM5ez2LPp3JED3LFDzKVM6uoVymzG\nkoTkihWrVi1buHB8RLtxsVGcsWL+R//S+Punpqa27O01L5lMJgiCVH0xsveTy+U0TdtsNk8H\n0iwUCoWv3ppSqZQkyb0zH2ialsvlbmwQtACYY+cjYI6dl2reOXZNgC1m+mohXVSIrxbQRVcp\nQ3lD5uchhBDGl8oqdAp5gFzmKvhfZvbYn7elp6frdLpmjLhlwRw7LwVz7BqlxebYjR079qef\nfjKbzS3wWj4PhmIBADUgKnXlSluEEOadVHERVVRIF12lS4pw0VXM19KBSkis/02fBEM76HeN\nHY22fs0ldxWDgqWgEKLWNHf8AACfdPz48dTUVJ/8q8NdILEDANSPsJwYFiGGRVzroSKEMlTQ\nRYW4+CpdUkQVXaUMFXV06aWEBKGSQvRH4bWr5QopMEgKDJaCgsWAICkgkPhp4QA0AEC99uzZ\n4+kQWjtI7AAAjYexpPOXdP4oIfFaAe/ExUV0cZEzJ/vU9m09Q9txNFXr1Xaba0FGZQlhWcmV\n4QUGSwGBkn+gFBBAGLb6tU6nMzMzU61WR0ZGuv22AAAtgBCyePHidevWFRcXx8fHv/baa7dU\n+Oqrr955551Tp04xDJOQkDBnzpyxY8cihIYOHfrbb78hhDDGPXr0OHLkSB2V2yxI7AAAbkBY\njoRFSGEROKX7CYP1/jlzZvbslhbe3ikKIsGDuyXreGcNR2Jch3mevlpAXy2oUoSJxk/yD5D8\nAyWdv+QfIAUEfvjlV2+vWOGw2QRJSk5OXrVqVUpKSkvcHgDAfZYvX/7aa6+NHz9+0qRJZWVl\nr7/+etXpqlu2bHn88cdHjx7tSvg++OCDxx9/XKPRPPDAA6tXr547d+4PP/xw+PBhlUpVd2VP\n3Z3HweIJHwGLJ7xUq1080URHjhzZvHlzbm6uXq+fNGlSUlISEkWqvJQuLcElxVRpMV1aTJWX\n1ZHq1UgkxCmIcpZxCuK27Mv/zSl47b33tTExhOWa6UZqA4snvBQsnmiU5lg8QQiJiIgICAhI\nT093lRQUFERHR3Mc51o88eabb/7++++//vorx3EIIaPRGBgY+Nhjj33++ecIoaeeemrDhg2V\nP5x1V26bILHzEZDYeSlfTexQQ06eEEWqvIwuK6HKSnFpMVVaQpWV1romo05EqSI6f1Grk7Q6\novOXtDqi9Zc0foiqdTj4Fn/99dfOnTstFktqauqwYcOo+i6ExM5LQWLXKM2R2OXk5ERHRz/3\n3HPvvfdeZWG/fv1OnjxZ26rYyMjImJiY3bt3o2qJXd2V2yYYigUAeAhNS0HBUlBw1TJsMlHl\nJVRZKVVeRpWWUOVllLEC1bddHLZasNVCXcm7qZSiJLWGaP0lrZZodaKfjuh0kkZLqiV8S5Ys\n+dcHH9wXE6Xm2Jc2rP9Xl+RvvvkGtu8CoDkUFhYihIKDb/rFDwsLO3nypOux0WhcsWLF1q1b\nc3JyXH/0iqIYHR1dY2uNqtxGQGIHAGhFiEYjajRiVMyNIlGkjAaqvOytuS88mZgQpW3wVimS\nRBkNyGigc28upyii1kh+rmxPe66gMOuXnw5NerxjoD9CyOh0Dtn83dKlSxcvXuymewIA3FBj\nZ5tYZVbG8OHD9+3b99JLLw0dOlSn02GMhwwZUltrjarcRkBiBwBo3Wha8g+Q/AOsKT1GfvnF\nT2NGhmvUCKGfM7PXp59Z9eqCMLkcV5RRhgrKUI4bcviKJGGjgTYaUF4Og1AKQl+PHlb5RT+O\n+/6REf/Lvcwd2iepNcRPRzR+RK0hdM1HrtXL6XRevXo1NDSUZWtY5AtAW+Pqq3P121XKzs52\nPcjIyNi9e/fUqVOXLl3qKhEEoaysLCYmBlXTqMptByR2AADv8PLLL2dlZXVZt6lrSFC53VHA\nC8uWLQsc8kDVGXzYbqMMFZShArv+X1FOmQy4ohwLQsNfqJ1KObFTHNq1vWohUaokteZakqfW\noOAQipPRKpWkVBGlqsZ2TCbTokWLvvjiC57nOY6bOHHi/PnzlUrl7dw8AL5Cr9cHBQX973//\nkyTJNZn1woULJ06ccP1quOatRkREVNb/+OOP7XZ7ZZcexhghJAgCwzD1Vm6bILEDAHgHjuM+\n+eST48ePnzhxQqfT3XHHHUFBQbfUIXKFKFeI7drfUo6tFlxRQZsM2FBBGQ3YaKCMFdhQgRt8\nADG2WmirBRXd6GbgELq2FpemiVJFNH6SUkVUakmlJkolUWs+fn916dHDfzw+umOA/8mikn98\n/91LJtPq1atv9x/gJkaj8fz58xqNJi4ujmHgnRx4DYqinn766cWLFz/66KPjx48vKip66623\nunfvfu7cOYRQXFxcZGTk2rVru3XrFhgYuHXr1qNHj959991Hjx79448/evfuHRYWhhB64403\nOnfuPGLEiLoru7ZEaWtgVayPgFWxXqpNr4ptBbDdbs7Pe/UfM/sH6gbHRisZ1uR0EILC/DTY\n3e+NDlHYkZ3XZ9AgVUg7olRJCiVSKiW5AimVRKEiMlnDm1q5cuW7775LiYJTlKL0+vfee69P\nnz7uihNWxXopb1kVixASRXH+/PkbN24sKyvr2LHjokWLtm/fvnbtWtd7xZEjR5577rkTJ05o\nNJpRo0YtW7Zs9+7dkydPFkXxwIEDSqVyxIgRp06dio2NPXfuXN2VExIS3B586weJnY+AxM5L\nQWLXGly6dGnBggU7d+7keT4xMfHVV18ddM892GKmjAbKbMImIzYasNlEmU2U2YTNpsZuv9cg\nNE3kCqJQELmi8gGSKyS5HMkVkkyOFAoilxOZ4rOvv37j1QWbhg+5JzrSLojLDxz56OzFP/74\nIzw83C2BsCzrdDopivLJTwdI7BqlmRI70KwgsfMRkNh5KUjsWg9BEARBaMguJ9hqUUuSs7RY\nMhookwlbLdhkpKwWbDYhixk3//weXhJZ6sZijt25+YqIyJS0PojjCCcjnAxxnCSTI45DLEs4\nmcRxmGVrPKKtqvPnz7/88sv79u0jhERGRr766qujRo1q5ltpaZDYNQokdt4IZmYAAABCCDEM\n08DJakSpQhqN5B9Q4wbF2G7DFotgqHh9zgv3BPs/GBeLESKE5BhNNMOE63S3twlzVVWzOoTQ\ngMhwhCR06M/6I5fLEc0QhiEyOWZowskIzRCGQTKZw+k8+u13L4T6b3n2SVEiP1y89I9nnlar\n1ffee28TowUAtCTosfMR0GPnpaDHzks15OSJY8eOTZgwQeWwdQoMOF1cKmj8vvjii6SkJCwI\nyGqhbFZssyKrlbLbkM1K2WzIZqXsdmS1UA47slkbvrCjmaw8+NcXxeW7du3ybBjuBT12jQI9\ndt6oFfXYmc3mtWvXnjx5kuf5jh07zpgxIyQkpIF1GnItAAC0pNTU1AMHDvz66685OTkjY2KG\nDh2qUCgQQoRhkJ9W9Kvv81KSsN2G7XZks1IOB3bYkN1OORxH9u65cvb0kNgYDccihIwOh12U\ngjRqyt1DwPdERyz885B72wQANLdW1GO3ZMkSs9k8ffp0mUz25ZdfZmdnv//++1S1k39qrNOQ\na6uCHjsvAj12Xgp67JqJKIqzZs36ZsuW+ACd0eG0MOyKFStGjBiBJAk7HNjpwA4Hcjowz2Pn\ntQeId2KHA/FOLIjIYceCgEUB2e1IFLHTgQUBiaJoszIYV32hXzKzp+8+cObMmZa/x+YDPXaN\nAj123qi19NiVlJQcPnx41apVrg2jZ8yY8cQTT6Snp6ekpNRbJzw8vN5rAQDAN9A0/f7778+c\nOfPkyZMajaZ37946nQ4hhCiKKBREobi9Zg8ePPjoqFG/jh3VJ6w9QqjMZl+4Z/+jj45xY+QA\ngBbQWhK7ixcvsixbeQyIWq2OiIg4f/581eSstjpWq7XeawEAwJfEx8fHx8e7scG0tLQ58+YN\nfvvtPqHBfhy3L+9Kcu+0f/7zn258CQBAC2gtiZ3RaNRoNLjKQIBWq72lS7m2Olqttu5rnU7n\n888/X/l0yJAhw4bdOBrSZ1AU5ZN95q7vrK+OCFAUhTH2yZMDXHMhlEplQzYQ8To0TdM03Xqm\nsrjFggULHn300e3bt5vN5hmpqYMHD/Z0RO6HMfbJdxIXhmHce3eSJLmxNdAyWtHHCb55ekej\n6tR9LSHk0KEbU4CTkpJ89TRuX70vhBBFUXVMmvR2PnxrrgTI01E0C5/8riUnJycnJ3s6iubl\nw++TGGP33p3QmEOWQSvRWhI7nU5nNBoJIZUpmsFg8Pf3b0ideq+VyWRHjhyp2hQsnvAisHjC\nS8HiCS8FR4p5KVg8AVxaS2IXHx/P83xmZmZcXBxCyGg05ubmJiYmNqRO+/bt670WAAAAAB7X\nTB0rQUFBzdGsN2otQwkBAQF9+/b98MMPs7Ky8vPzV61a1aFDh6SkJITQtm3bfvzxxzrq1HEt\nAAAAAEDb0Yr2sbNarWvXrj127Jgoip07d54xY4ZrOHX58uVGo3Hx4sV11KmtvDYwFOtFYCjW\nS8FQrJeCoVgv5S1DsdBj19xaUWLXkiCx8yKQ2HkpSOy8FCR2XgoSu+Zo1hu1lqFYAAAAAADQ\nRJDYAQAAAAD4CEjsAAAAAAB8BCR2AAAAAAA+AhI7AAAAAIAbBEHAGP/++++3XcGDILEDAAAA\ngC/bsWPHLQdQ1Y2m6T/++KNHjx63XcGDWsvJEwAAAAAACCGj0fj9999fvnw5MjJyxIgRAQEB\nTWzwnXfeefDBB3v27NnA+hjju+++uykVPKiN7mMHAAAAgJZX7z52J06cePzxx4OJ2DUk+Fxp\n2WWn8Omnn/bt27fuq+rYx27gwIE7d+7kOK5z586HDh1iGGbdunVLly69++67P/nkk1OnTs2e\nPfvIkSOSJKWlpX344YdxcXGCILAsu23btoEDB9I0/eWXX27cuDE3N9disSxatGjixIn1VnDd\nyIQJEy5cuJCUlLRixYqBAweeOHGia9eut/GP1ijQYwcAAACAlibbswNV61oSRfHs559vGnTn\nXVERGCGE0P78ghNrPrjDamBZtnojzjvuJjRd9wvt2LFDr9e//PLLM2bMQAjRNL1mzZpvv/02\nPj4eIfTII4+kpaXl5uaKojhlypSJEyfu27ev8lqKomiaXrly5S+//BISErJhw4ZnnnnmkUce\nkclkdVdQKBTDhw8fMGDAnj17srOzp0yZ4qp8u/9ajQCJHQAAAABaGnfoTyRJ1cundoqr+rRv\nePu+4e3RX4dqbMSZdieqL7GrbtSoUd27d3c93r9/v0wmUyqVCKFx48aNHTu2+kjmE088ERIS\nghAaNGiQ1WrNzs7u2LFj3RUMBkNubu7ixYv9/Py6du36zDPPPPnkk42N8/ZAYgcAAACANiQu\n7kbueOzYsSVLlpw5cwYh5HA4eJ4XRfGW+lFRUa4HcrkcIWSz2eqtkJOTQ9O0Xq93lbfkMgtY\nFQsAAACANqRyIDUjI2PYsGH33XdfdnZ2YWHhxo0ba6yPMa67weoVCCEMw1SW043vVrxt0GMH\nAAAAgJZm/vsLNZYvWrRo748/LOrfLzkk8HxpxWt79nfqP2D58uU1ViYc15QYjhw5IgjCnDlz\nXBP4Dhw40JTWqmrfvr3D4bhy5UpYWBhC6OjRo+5quV6Q2AEAAACiHdizAAAgAElEQVSgpRG5\nosbylxa+zvppx69fbzAY1Gr1pEmTXnzxxdoqN5BSqczIyKioqNDpdFXL9Xq9KIoHDhzo3bv3\nd9999+effyKEKrOxpujXr19QUNDSpUtXrFiRlZW1Zs2aJjbYcDAUCwAAAIDWguO4l19+OSMj\n49y5c5cuXXrttdcUiiZldQih6dOnf/TRR8nJybeU9+nTZ+7cuSNHjgwLC9u+ffv333/fo0eP\nlJSU7OzsJr4ix3HffPPN7t27g4ODp0+fvnjxYtRSq2JhHzsAAAAAtJB697G7PXXsY+cpgiBI\nksRxHEJo//79/fr1MxgMfn5+zf26bXQo1mQyeToE95PJZA6Hw9NRuB/GWC6Xi6LodDo9HYv7\n0TRNURTP854OxP0YhmFZ1ul0Vl9i5gNYlhVFUappswZvx3EcTdPV1/35BrlcbrfbPR1Fs1Ao\nFJIkufdTgKZp1z4goLEIIYmJiXfeeeeqVatsNtvrr78+YMCAFsjqUJtN7HwvAcIYK5VK37sv\nhBBN02q1WhRFn7w7mUyGMfbJW6MoimEYm83mk3fHcZwgCD6ZkcvlcoZhnE6nT47nqFQqn/yB\nRAhpNBqe5917dzXuCQwaAmP87bffzpo1KzIyUi6XDxgwYN26dS3z0m00sQMAAAAAaD5du3bd\nvn17y78uLJ4AAAAAAPARkNgBAAAAAPgISOwAAAAAAHwEJHYAAAAAAD4CEjsAAAAAAB8BiR0A\nAAAAgI+AxA4AAAAAwEdAYgcAAAAA4CO8Y4Pi/Pz8VatWZWRkfP/99zVWMJvNa9euPXnyJM/z\nHTt2nDFjRkhISAsHCQAAAADgWV7QY7dnz55//vOfERERddR59913i4qKXnvtteXLlyuVykWL\nFvnkGY4AAAAAAHXwgsSO5/kVK1b06dOntgolJSWHDx+eNm1aTExMWFjYjBkz8vPz09PTWzJI\nAAAAAACP84LEbuDAgcHBwXVUuHjxIsuyMTExrqdqtToiIuL8+fMtEh0AAPiIkpKSWbNm6fV6\nrVY7evToo0ePejoiAECjecccu7oZjUaNRoMxrizRarUGg6HyqSiKn3/+eeXT5OTkjh07tmiI\nzQ9jjDFWKBSeDsT9XN9ZmqZ98u4YhqEoyidvjWVZhBDHcRTlBX9ANhZN0zKZjGF84S3UxWaz\nPfTQQyEW00f9emg47qeMrFGjRv322289evTwdGju5Kvvky5ufzOp+sEKvIWPvCvV/cMnCMLq\n1asrn06aNKl79+7NH5QHqFQqT4fQXBiG8aUP0Vu4ciCfJJPJZDKZp6NoFp79gTx06NBff/2l\n1WrvuuuusLCw22zFZkOIECePROHLf29IEByfjxnJUhRC6I6IMAqjefPm7du3z51xtwI+/D5J\n07R7704QBDe2BlqGL3xS6nQ6o9FICKlM7wwGg7+/f2UFlmXfeuutyqd6vd5kMrV0lM1PpVJZ\nLBZPR+F+FEWpVCqe5+12u6djcT+GYWiadjgcng7E/TiOk8lkdrud53lPx+J+crmc53lRFOuu\nRgg5e/Zsbm5udHR0p06d3PDCgsBbLC/Pev7Y3r3JIUGEkP++uWTKxAn9evbCDjsSBMQ7sdOJ\nRBE57EgSsdOJBIE4nVgUEe/EkuhK43C1b8oEhCaMfqBqyaiEuA++/sHH3i3VarXZbPZ0FM1C\no9GIomi1Wt3YJkVRPvwXdY0EQWBZ9tdff7333ntZlt22bdu9995btUJ2dnZMTEx6enqXLl0a\n2Fr1RpqVL3zD4uPjeZ7PzMyMi4tDCBmNxtzc3MTExMoKFEXd8m9aUlLS0lE2M4yxUqn0yfzA\n9TeoJEk+eXcuPnlrFEXJZDKe533y7jiO43m+7pw1Pz//6aefPnzwYDuV8qrFekf//h999FHV\nnZiwKCC7Hdts2OnAdjt22JDDgR127HBgu+uxAzsdyOnATid2ODDvRKLIIbQ6NgzFjrnxSkX5\n6Jf8OiLBtTyum9nplMvlPvbtU6lUPnZHlTQajdvfJ314MKFeNE3/8ccfKSkpt3Htjh07/Pz8\nevbs2ZRGbpsXJHbl5eWiKLr+anQlZGq1Wi6Xb9u2zW63Dx8+PCAgoG/fvh9++OFzzz3Hcdz6\n9es7dOiQlJTk6cABAG2SJGGblZjNH8594QEW/fSPaSqWtfLC/vyCq6ve1ndNxnY7ttuQzYbF\n1jvOxUvSsgNH77//fk8HAtqiM2fObNiwIScnJyIiYsKECampqS0fA8b47rvvvr1r33nnnQcf\nfLBnz55NaeS2eUFiN3fu3KKiItfjKVOmIISeeuqpESNGHD9+3Gg0Dh8+HCH03HPPrV27duHC\nhaIodu7cef78+TDlEwCf5HQ6MzMz1Wp1ZGSkRwLANhu2WlBpMV1ags0mZLVQFgu2WrDNev0/\nm6vm6tQbf14qWWaQPhIhhPJymj9ETGRyRFGEZRHLEZpGHIdomrAcoSjEsoimCc0glkUYE06G\nECIsi2jmP//5z58H9vdoF3LFZP7mfIYUELh28eJmjxaAm/3000/Tp0933nUPSkpG2VmfP/DA\n6nfeGTt27G032KdPnx49enz44Yeupzt37hw0aFBOTk55efns2bOPHDkiSVJaWtqHH37oGvdz\nqTqKevz48enTp586dapDhw7z5s2rrHPq1KnqLQwcOHDnzp2///77unXrDh48WNnI1atXn3/+\n+V27dlVUVKSmpi5btuyOO+6QJImm6S+//HLjxo25ubkWi2XRokUTJ0687ZtFXpHYrV+/vsby\nuXPnVj5WKpXPP/98S0UEAPCMDz74YMWKFQ6bTZCk5OTkVatWuWuMY8eOHdu3b7darT1SU8c+\n+KDMYcMWMzabsMVCmU3YYsYWM2UxY6sFXZ9X16xjVIRhECcjnIzIZEgmJzIZ4jjCckQm+2j9\nhj4B2j7h7a/VROjvv+3oOGTYk9Onu+ogmr69Fx2V0t1vx45du3ZZrdYnRz0yfvx4X134AlqD\nMdm5UrWpAaIoHjBYhC++RkFB14qmzng+O+vLC5c4jqveyKaocAVVTz/OuHHj3nrrrdWrV7tW\n6H/99df33HNPeHj4oEGD0tLScnNzRVGcMmXKxIkTa1wqJEnS6NGjBwwYsGPHjtLS0qpZ1yOP\nPFK9hR07duj1+pdffnnGjBlVV5+MHDlSp9MdP35crVYvWLBg2LBhmZmZQUFBNE2vXLnyl19+\nCQkJ2bBhwzPPPPPII480ZRGMFyR2AACAEPr8889XL3t707D77ouJMjmdS/cdGjdu3K5du4Iq\nPwAaDNtt2GyizCZsNlNGw/5t/ycvLHghKMA/UKUuzKI2fNAc8ROEcg3GgMgohb+/JFcguYLI\nFUQmI3IFksslmRzJ5UQmJzIZkcnrSM40haWjZs9eM2zQ/bF6s5N/c//h/+Zf3TVxEvHTNj3I\ngQMHjh49mmXZ0tJSQkjTGwSgNnssNqHGn7GUbjc91enEbqn7nTxy1jClVSCk3omjjz322OzZ\ns/ft29e/f39RFL/99tu3334bIbR//36ZTKZUKhFC48aNGzt2bI0/8wcOHMjOzt6+fbtKpVKp\nVP/4xz927tzp+lKNLdQ4YHjs2LGDBw+eOXPGNct2yZIla9as+fXXX5944gmE0BNPPOEqHzRo\nkNVqzc7O7ty5c903VQdI7AAA3uGdd955+547h3XQI4QC5PIVgwYc/eKbTZs2zZo1q8b62GKm\nTEZsNlFGIzabKJMRmwzYbMYmIxZu+oS4S8mh2OjbDozQDFIqJaWKKFVIqZQUSqRQCnLFkpXv\nyIxls3v30HBcmc3+5C/bjKHhWxcvtzZtosiYMWMqKiqmvv225ftfRUK6dOmyefNmOB0bgNq0\na9du4MCB33zzTf/+/Xfu3GkymR5++GGE0LFjx5YsWXLmzBmEkMPhqG2de25uLsY4OvraW0R8\nfHzll2psocZ1xJmZmRRFVS6NVygU0dHR2dnZrqdRUVGuB3K5HCFkuz6d4/ZAYgcA8AI8z+fm\n5vYaPKCyBCOUFhZ6NTuLLi7CxgpsNFAmE2UyYmMFNhmx2YTr24ukgQjNILVaUqmJSk3UGqJU\nSkqVPCjYwXICxxGVhtQ0QoQQ+tsbb02fPn3l6vURGnWeydyrT59//etfbpn+O23atMmTJ1+6\ndEmtVoeHhze9QQBaXhTLiujWHjJJkvLy8oh/AKqcBsA7UWlpeFhYjQlTfcOw14wbN27BggXv\nvvvuli1bRo4cqdFoMjIyhg0b9tprr/3yyy9yufyHH34YNWpUjde6FhpX/uZWjq42vIUaSZLk\ndDpdj927KgASOwCAF+CcjkEd452iVLVwYf8+CoZBG//VxMZFQugqb6y5RuMbB4+tXLuOqDVE\nrSbyGrbyl2s0xG6X6tzuJDIy8ueffz59+nROTo5er3fvUn2WZX3vBB3QphxMiKmxfN2eP/75\n5FL02FgUl4AuZ6PNX7z892deuPfuprzWQw899PTTT+/fv/+777777LPPEEJHjhwRBGHOnDmu\nLV0OHDhQ27URERGEkMuXL7tOLj179qyrvOEtIITi4+MlSTpz5oxrjNVisVy+fLlq558bQWIH\nAGhFMM9ThnJcUU5VlFOGClxRRhkqsKECC8LPI4feUlnRmK1TiUxONH6SWkPUakmjJWo10fgR\nteZfX27+ev36PRPGsNePPvvw6MlzcpWoj3XD7WDcpUuXhmxkCgBwmTp1akRExPr16y9t+y0q\nKmryOytHjhzZxDb9/PweeOCBV199laKowYMHI4T0er0oigcOHOjdu/d33333559/IoSuXLlS\n/RyXvn37BgYGvv7666tWrSouLq5cXVtbC1FRUUqlMiMjo6KiQq1WuyqnpKT069dv7ty5mzZt\nkslkL730kkajaVQPX8NBYgcA8AzsdFLlpVR5GVVRjl0PysuwtUmnpxC5QlJriJ+WaPyIxk/U\n+BG1hmj8iJ8fYWseMB03bfqGLV8//O1Pz/dO1XDs1vOZH5888/PPPzclDABAU9x///1u30Nx\n/PjxDz300MyZM11Dun369Jk7d+7IkSMxxqNHj/7+++/vu+++lJSUw4cP33KhQqH4+eefn3nm\nmbCwsPj4+GXLlt1///2SJNXWwrFjx6ZPnz5v3rwtW7ZkZWVVtrN58+bnnnsuKSlJkqTevXvv\n2bPHz8/PvffogtvmuiefPHlCp9OVl5d7OhD3o2na39/f4XD42NFGLq6D5H3yLDiFQqFSqUwm\nk8PhQIRQRgNVWkKVFlPlZVR5KVVWis23+Q2VELKxHB0QyAQFi3464udHNFpJ40e02tqyt7oV\nFhYuXbp027ZtNpstNTX1lVde6dWrV92XaDQaXz0tTavV+vCq2ICAgLKyMk9H0SyCgoJ4njcY\nDG5sk2VZrdYNq62raqbP39tYHe+roMcOAOBukkRVlDuuFhjz89RWs9KVxt3GaeIUJak1ROsv\nabVEqxP9dETnL/lpiVqDKEpCyF1ZVWho6OrVq93UGAAAeBIkdgCAphFFqqyULiuhSotxSTFV\nWkKVlWBJQgg1fIdNwjCSLoD4B0g6f0nnL2n9ib+/pNHe9l67AADQNkFiBwBoBCzwVGkJLi2h\nS4upshKqpJiqKEeSVP+VlWha8tNJAYHX/vMPkHQBRK1BcAwgAAA0GSR2AIBaYd5JlRRTpcVU\nacm1B0YDauTUK7sgbj1/ceDYcX6xcVJQsKTzR9fXnwIAAHAvSOwAANeJIl1agouv0qXFVHHR\nbaRxRC4vIfjP9NMjE27sFSJn6Fd27X/niScHJXRqhqABAADcAIkdAF6jrKxMrVbXeBL27cEW\nsyXjQtHJ42qLuT2F5GYTasxpDUShlIKCpcBgKTBYDAiUgoKJWrP/jz+eWbH6gTg9c71bzsLz\nZXYbrFkDAIAWAIkdAF5gy5Ytb775Zn5+PsMwgwYNeuONNyrPFmwUqqKcvlpAXS2grhbSRYXY\nalEj1K5h1xK1RgoKFgOCpKBgKTBICgwhihqOZOjXr59faOi8nfvevPsOhqIcoviPbbsSkjon\nJyffRsAAAAAaBRI7AFq7H374Yd7s2csG3jlk5OBSm/2NfYfGjBmzfft2lar+VafYZKIL8ujC\nAvpqAVV4BdsberY0Uaml4BAxMFgKChYDg0lgMJHLG3KhTCZbv379pEmTtq75NCHA/3RJqaZ9\n2Oeff0LBvDoAAGh+sEGxj4ANir1UQzYo7tGjx5yOsdNSr/V48ZKUtnHz+FkvTJs2rXplLIpU\n4RX6Sh51JY8pyMcmY8ODuVhW8Z/cK8+/+bYYFIwUykbdyC1sNtvevXsLCwvDwsL69+/vxuHj\nVgI2KPZSsEFxozTHBsWguUGPHQCtmt1uz8nJGTjkrsoSlqLuioo4d+5cZQl2OOgruVReDpOX\nQxVcwWL9WwETjeZofiFvNvYNa19ZWGKzrfrz0MzI6KaHrVAoRowYcePkCQAAAC0CEjsAWjWO\n4+RyeZHFGuevqyy8arHGBvgz2Zn05Ww6J4suKqx3Jzmi1oihYVJoe7FdmBjanihVG+fNKzl0\nrO+oG4nd0cKi6Gg3ZHUAAAA8BRI7AFo1iqJGjx49f/euHx4ZruE4hNClCsOzPbv1kSPqP1/U\ncSFhWaldezEsUgwLF9uHE7XmlgpPPfXUoM2bVx78a2bPFJam/5eZvWjPgRUffNCMNwMAAKCZ\nQWIHQGv35iv/XPdS+Y7LuQOjIzUcF6vTxuq0NW4vR9QaISJKDI+UIqLEoJC69wHu0KHDJ598\n8sILLyzcs5+lKczJXl6wYPTo0c12HwAAAJodJHYAtEZYEKjcy8zlS3R2pqakeEHn+NpqEj+t\nEKUXIvVSZLSk1dVWrUb33HPPwYMHL168aLPZOnXq1JBltgAAAFozSOwAaDUIoYuL6OxM5nIW\nlXcZC7WugSAKhRAVI0bHiNExki6gKa/JsmxSUlJTWgAAANB6QGIHgKcZDeyZU/TlS0z2JWyz\n1lqNosT24WJMnBDTQWzXHmHcgiECAADwDpDYAeABmHfSOdl09iU2JwuXFNex86+k1YkxcUJ0\nrBitJ7IGbREMAACgzYLEDoCWQghdVMhkZdJZGXRBfh2nshKZXIzSC/pYUR/bxJFWAAAAbQok\ndgA0L2yz0VkZzKUMJjuz/pFWfQdBHyuGhtW9oBUAAACoESR2ADQDQujiq8ylDObSRaogv47d\ng0lgMIqLt4dHiZF64nPnbgEAAGhhkNgB4D6iSOdksxnnmczzuPaTbYlCIUTHivoOQnQMFxzC\nMIxQ51mxAAAAQANBYgdAU2GeZzIv0BfPMVmZ2GGvuRJFiaFhYkwcr+8ghbaHkVYAAADNARI7\nAG4TFgU6+xJ7/gx94RzmnTXWEViOxMYJsfFiXAKRK1o4QgAAAG0NJHYANJIkMVkZzJl0JvMC\n5vnaahGE/vXXyQ+z8vbs3csw8IsGAACgJcDnDQANRZUUsWfS2fTj2FrDlDiC0Oni0i7Bga6n\nGKHJXTvP27k3PT09NTW1ZSMFAADQRkFiB0A9sN3Gnj7JnDxGlxTV8GWKEiOi+I5J/zl97sNP\nvzowcWzlV+QMrWI5s9nccrECAABo2yCxA6BW1JU87sRR5tzpGo5txVgMj+Q7dRYSEolKjRCK\npbgzJWWXDcZorZ+ryuGCwgqns1OnTi0cNgAAgDYLEjsAboVFgTmdzh47RBddrf5VSRcgdO7K\nd0mR/LRVy7t27Trq4YdHfvPj0rv6dQz0/6uw6J879z333HPBwcEtFTgAAIC2DhI7AG7ANht3\n7DB77HD1WXSE44TELnznFDEsAmFc4+UrV65cuXLl1M8+Kysra9++/Yw5c6dNm9b8UQPgNjzP\nnz592m63h4aGqtVqT4cDAGg0SOxAW1RQULB06dKdO3c6HI6ePXvOnz8/Oaw9d+QAc+p49VFX\nMaQd362nkJhc78kQcrn8lVdeeeWVV2w2m0IBm5sAL7N3795Zs2Zl5+YihlVQePbs2c8//7yn\ngwIANA4kdqDNMRqNw4cPT6TxugFpcprZm5ef++6ytI5xmJCq1QjNCImdnSk9pLCIxr4EZHXA\n6+Tm5k6cONH48KNo7HjEcbYjh5cuXhgSEjJu3DhPhwYAaARI7ECb89FHH4U4Hd/+7REaY4TQ\ngKhwhBCqktURhcKZ2otP7UWUKk8F6dV4nl+zZs1nn32Wl5en1+unTp06ceJECg7baN02btxo\nTExCEyZfe96zF5o247333oPEDgDvAokdaHNOnDgxtVsXuqZ5cpJ/oLNnmtClG4EthZtgwYIF\nG37+BU1+CsXEXLxw/sW33iopKZk7d66n4wJ1ycnJQfEdbypK6JiTk+OhcAAAtwk+vUBbQgiT\nnflmR32y6tah0vMVxuiJT/LxnWpbGAEa6MKFCxs2bkQbPkXReoQQik9Aev3Kfzw7ceLEkJCQ\nJjZeVla2Zs2a9PR0jUZz//33jxw5EsP3y03atWuHzl+8qSgvNzQ01EPhAABuEyR2oE3AosCc\nPcUdPkCVFN2S1UmIvLZ7vyG5+9KERE+F50tOnTqFIqOuZXUunZNFrfb06dNNTOzy8vLuvffe\n0rBw1KcfMpm+mzPn999//+CDD5oYcN0sksQTQggySpKrxCxJAiFKTDmdzjKHU0I3BvGtEuER\nqbEdiSCjKDb8dRmM1bQbBq/VFEU3oBqFcM9x4z/5+9+dB/ajPn0RQijnMlrz8eRpU5seAwCg\nJUFiB3wcXXyVOfkXe+YUtttu+VKu0bQzJ+/NPw8rwiN+fuUVj4TncZmZmXv27LHZbD179uzV\nq1fTG1QoFMhy82YxoojsdpVKhRBySsQsSSZJMkmSWZLMomQlkk2UHITYCHFIkoMgOyEIIYKI\nQZSqNrNj557S15egpGTk6qSbOGXLkUNZh/6qrVdJQVMCIbxUc6ZlkSTX+mcnkawSQddzOCch\nNomIiJhufvU2gEKrP772cP48dHD/hHHjnn32WY+GBABoNExIze96vq2kpMTTIbgZxlin05WX\nl3s6EPejadrf39/hcJhMpoZfhe125twpNv04XXil2tewoI/dI9FbDh91bXfy+OOPsyzrzqAb\nTCaTMQxjsdRw+GwLeO+995YtW+aM74gUcnT61IODBq1bt45pwvxCgtDF0rKhEyaYHn0M9ex9\nrfTKFc5ubd8psUwU21625JWWFxcMiI6KjY31dCDuFxAQUFZW5ukomkVQUBDP8waDwY1tsiyr\n1WrrrwdaE0jsfAQkdtdIEp2TzZ05SZ8/iwW+eltCp86OXv2k4KZO9nIXDyZ2e/fuHT12LFr2\nDuqaghBCJcXo+ZkvP/G3F154oYEtmCXpnN1xweG85OQzHY5LTv6Sw2lvk28pPuZs7+7BNqtP\nfjpAYtcokNh5IxiKBT6BEPpKHnsmnTl/GttuHXJFCEkBgXxyKt8lBXYwqbRlyxY0dNi1rA4h\nFBSMpjy1+bNP6kjs8pz8cZv9tMNx1u48ZbfnOPnm/uT3oynq2sgrMpvNAkUhmeza1whBFotS\noeDq2zi6Eoexgrqx2IJCyI+m7Xb7xTOnpZBQFBjoehl05FDvpKSuiYlKikLXpqkRCmO/6zu2\nyCmsUyp5nhdFkUZIffNOLizGKooSRXHmzJkX/HToiYlILkdWK/r0310EftWqVU1c8PHQQw8Z\nJ05BXZJvFH2x6YGw0MmTJ9d+Ua1MEpFunheoVCrDZZzTZm1KkAAAT4HEDng3bDSwZ0+x6ceo\n8hr+Cic0I8Ql8F27i9ExsNz1FuXl5Sgi6qai4JBbOjPKBfGIzX7cZj9msx232YuFRkz/d/Gj\nqWCGCaBpf5oOoKkAhtHRtJqiVBRW05SWolQUxWKspigGYw1NUdcTo+pNpaen33///Y57B6O+\n/ZDRiL75um+7kK1bt9J0Q5YH1GrevHnns7LR/IXXnqvVyOEofnnum4cO1XGVRqOx2+08X61X\n+LqDBw9e2LEdfftfJJcjhJBSiSZMOjV6OH7m6ZSUlNquqhchxPzXUfT0zVPfzGbFmdN3qd3z\nR4tWq2VputQtbQEAWhwkdsArYd7JnD3NnjpOX8lD1QeMMBYjo/mkrkJCJyKTeyJALxAXF/fb\nwcPob1WKThyLT0g4Z3ccsdkPWaxHbPYMh7OBfXKBNB0rY+M4LkYmC2PoMJaN1qg76rSS1epw\nONwScHJy8rZt25YvX358zUc6nW7oww/NnDmziVkdQqiwsBBF3pzgRkdfuVJtamYjFRQUoOCQ\na1mdi0qNAoMKCgqakthhjGNjYzNOHEexHa4VEYLST8SPGN60eAEAPgISO+Bl6JIi9vhR5sxJ\nXFO6IAWH8InJfGIX4gfzQuoxffr0zZs3l33wHnp8PFKqUHYWiku4MP6J/hnZ9V7rz9CdZbJE\nOZcklyfJZB1krLZagqWQy1Q03YgFLw2QmJj473//261NooiICHT6zE1FFy9GR0e7odnCQmQ2\nI7X6WlFFOSopiYqKqvO6+s2bN+/JmTORWo3uuBOZTOjzz9qXlU6aNKmJzQIAfAMkdsBLiCJz\nJp07foTOz63+RaJS84ldhM4pYki7lg/NG9kJueSnffA/332XmWlWq5FMjhKTEELmWuoHMHSK\nXJaqUHRTyFMU8jDWd946Jk+evGngQMvXX6GHH0U0jY79hdateXbpkiY227179349uv+5ZCF6\n6Z/IPwCVlqA3Fg8c0D8pKamJLY8YMeJdk2nJkiUlbyxGCKWlpS3fsiUgIKCJzQIAfAOsivUR\nPrwqlkFEc/GcsPN3VHHr3RGaEeI7Cp1TBH0s8s6jSFtyVaxZkg5b7X9aLPsttmN2u7OWDd5c\nGIw7y2W9lIqeCnlPpSKaa/R2MAqFQqVSmUwmdw3FNp/t27e/8MIL+cXFSCaX885Zs2bNnj27\n7kvqnWOHECosLJw5c+bOXbuRTocqyu+79973338/KCjILTETQvLy8jQajU6nc0uDlbRaLcuy\npaWlPvnpAKtiGwVWxXoj3/mzG/gezPPsiaPcoT8Fy60dSbGWjnsAACAASURBVJJ/IN+tB985\nhShuPRwMVFUmiIestj+t1gMWW7rdIdT5Ua2mqF5KeR+VMk2pSFXIld6ZK9+GQYMGHTp06OzZ\nsxaLpXPnzu76JAsNDf3Pf/6TnZ2dnZ0dGxvb9EHYqjDGkZGRbmwQAOAbILEDrZIkcccOc/t3\n37p3CU3zcR35bj3ESD2scq3NZSd/0Go9aLUftNou2B1197oEMXQflbKvUpGmVHSRy+i2+q/K\ncVxT1jTUQa/X6/X65mgZAACqg8QOtDp0brZ8+/+o4qKqhU5R/OTkaUfvOyaPeMRTgbVaVkk6\nbrMfttqO2uxHrLZ6NyVpzzL9VMo+SkVfpSJBLmujqRwAAPgiSOxAK4LNJvnu7cyZ9Ko7mBCC\nMEYcTaeEBA99++1ud92dmprqwSAbwmw2qyvXQjYDOyGnbPYTrv/sjgsOZ91jrAihaI7tq1Tc\noVb1USr0jZ8wBwAAwCtAYgdaB0K4owe5vX/gKrPR7YJocDjaqZSup33C2w+N1f/yyy+tNrGz\nWq3Lli3btGmT0WgMCgqaMWPG3//+96YcveoiEJLt5M86nOfsjnN2xzmH45KTrzeToxDqJJf1\nUyl7KxV9lIr2PrSOFQAAQG3gvR54HrZa5L98z2RlVi20R8d2f2Xhr4+NqlroL5ebzbXtyOF5\ns2bN+u7YcfTKayg6uuTC+SUfrjYajQsWLGjg5TwhRYJwhRcLBeGy03nZyWc7+WynM58X+Iat\nT9TQVHeFoodC3kup6K1U+NFtZfUDAAAAF0jsgIfROdmKn7di842NbCWdv2PgEKFDgvD2qp8y\nsv7e49qUdisv/HE5d9aT0zwUaT1OnDjx3Y8/os+3oJAQhBBqF4pC2n3wzLTp06eHhIQghEyi\nVCaKpYJYLomlglAmSkWCUCqRMlEscDgLeaFYEKRGviiLcaJcliKXpSoVPZWKBI5ts6sfAAAA\nIEjsgLucOnXqq6++unLlSocOHSZNmhQeHl7/NZLE/blLdmDvjRl1FOXo05/vcyehaYTQ0qVL\np0+Z7BTFwbHRRRbrm/sP62JiH3mk1S2eKBXFEl74MScXjX7kWlbn0rGT9MG/hhQUO8qMFaLU\nwF63uvnRVEcZlyiXd5XLUhTyJLmMg0wOAADAdbBBsY/w7AbFmzdvnjNnjrP/ABQeic6fVZw8\nsWXLlr59+9ZxCbbZFN9vofNyKkuIn9b2wGjx5mPpf/3112XLlp07d87Pz2/YsGHz588PDAxs\nrtuonVWSLjv5PF4oFIQCns9z8kWCWCgIJYJYKor1Tne7PSzGESyjl3F6lo1mmPLjf5nST4az\n7ODBgzt16tQcr+heXrRB8W1oyAbFXgo2KPZSsEExcIHEzkd4MLErLCxMS0uzzluA7ux/reiL\nTRH/+/nw4cO1rRvAJqPymy+pkhsbmghxHW1DhyOFsnplmqbVarUkSSaTe88drZlISLaTP+Nw\nXnA4sp38JYcz28kXCUIzvZyKotpxbCCFQxg2jKXbM2woy0SwbDjHhDEMgzFCyGAwjBo16lTh\nVZTSDRmN3Ilj8+fPf/rpp5spJHeBxM5LQWLnpSCxAy5tdChWJpN5OgT3wxh75L4OHDhgDQ65\nkdUhhMaMzfv03xcvXuzWrVv1+ri8jNnyGS6//t5K0+Jd90p9+8tqGVIsLCw8dOiQVquNj4/n\nOM7t8Tsk6YTNfsRiPWm1nbbZz9sddqmxU91qYrPSJnN8u5AwjTqAZgJYJoCh/Wk6gGECGDqA\nZkJYJoihNRxH03Tdqc+CBQtO0Qz6fDOSyRFCzhPHX31x9oABA7p37+6GOJuNK61nWd/cWoWi\nKJZlKV88nANjjBCSyWQ+mdh56n2yZVAU5d6788mfcJ/XRhM7n/ywwRh75L4EQUBy+U1FDIMY\nRhCE6vHgK3lo0wZkvX40qkJJ/jaFioiq8c1DEIQ5c+asWbcO+fsjs7lDRMTatWv79evX9JiL\neGGvybTfaD5ktpyw2hyNzOQUFBXOcaEcE8Kw7Tg2iGHasUwwxwbQDDFU7P3l59JLlzrGxY0Z\nM6beP3Zpmq77GydJ0tatW9GKVa6sDiGEUrqhfnf88MMPaWlpjQq7hbk+Emia9nQgzYKiKIZh\nfPJjz3VTTd+mp9Xyyfd/F099CoBWxWd/devWmrfMuD2u32eP3FdiYiLKzEQ5l1FU9LWiA/vl\nhMTExNwSD52Trfh+C77eO0VUatuYv4m6AFRL2MuXL1/z3/+itf9GHeKQIGR+9smYMWN2794d\nUnWBQoMVCcKfFts+i/VPi/WCw9mQSxQU1rNsjEwWw7F6jg1n2XCWCWWZgDqSFX9d6vjxlc/q\n/Y7IZDKGYSwWS20V7Ha73W5HWv+bSnX+paWlrfzHWKFQsCxrt9thKNa7aLVaiqIsFotP9thx\nHNfKf3Fum1wuF0XRvXfHsqz8lr/bQavXRhM74EadO3ee/MTfPpk7G02YhCKj0JnT6IvPFi5c\neMvRC0xWhmLrFiReO+1KCgyyPjKe+NXaoSVJ0po1a9C8+ahDHEIIMQyaMrX0r6NbtmyZOXNm\nA2OzSNKfFtsus2W3xXrWXk96IcO4o1yWJJd1lHGdZbKOcllYK9jUVy6X6/X67MMHUUTEtSKB\nR8f+Spwx3aNxAQAAaI08/7kFfMAbb7wRFxf3xRdf5Ofnx8XFPf3uuyNHjqxagb5aIP/hm8qs\nTmwfbn348RqXSlQymUwGgwHFxN5UGtshLy+v7mAIQqftjt9N5h1myxGrve5NRvQc21Op6KGQ\n91QqOstlbKvcOmThwoWTZsxAFIXS+iCDAX32SYKMG1+lXxAAAABwgcQOuAHDMNOmTZs2reat\ngylDheKbLzF/bfRT1HewjXoUsfUsg9BoNBqNxnQ5G4W0u1F6OTssJbnG+iZR2mWx/m4ybzdb\nCvlaF7FihDrJZXeolP1Uyr5KRRDjBTPAHnjggXWrV7/55puX3l3JcdzQoUNf//ADhULh6bgA\nAAC0OpDYgWZmsyq++QJfXy0hhobZRo0hDZjeS1HUk08++e77q9DSt1FUNBJFtPlz/9ycMWPG\nVK2Wz/O/Gc3/M1v2WaxOqdbOuViOu0utHKBW9VUpAr1wOv+oUaNGjRplNpvlcrkPz2oHAADQ\nRPAJAZoRFgTFd19RZaWup5JWZ3v48YZkdS4vvvhiUVHRl1MmoJB2yGSM0One37Chffv2CKFz\ndsdPRvOvJnO6zV5bNhdA0wPUyrvVqgEqZSTnCyvFbpm2CAAAANwCEjvQbAiR/7yVvnJtShxR\nKGyPjidKVcMbYFn2vffee/HFF7OzszUaTUJCQjbCy4pK/ms0n699JURHuWyIRj1ApbhDpWRa\n5Zw5AAAAoJlAYgeai2z3dubCWddjwrK2h8dJ/rdzGlhUVBQXn/BFQeHUnIJLzpq3KVFQ+B61\neohGdZ9GHewN0+YAAACA5gCJHWgWTFYmd3j/tScUZR/+sNg+vLGN5PP8VoPpO4Mp3WavsUIQ\nQw/VqIf6qe9Sq+SN75wrKytzOByusV0AAADAB0BiB9wPW8zyX75H1/cZsQ8cInRIaPjldkL+\nz2TeUm7cbraINW1WEkDT92rUI7TqgWrV7W1QcvTo0blz56anpyOEwsPDFy9ePHz48NtoBwAA\nAGhVILED7kaI/H8/Vi6D5RMS+dReDblOImivxbKlwvST0WSt6YyvdgwzUqsZodX0UiioJsyd\ny8vLGzt2bMXgoejVRUgmy/9jx5Snn/5Op+vfv3/9FwMAAACtGCR2wD0kSUpPTy8oKOgnOTSX\nLroKiZ/WMfjBeq8t5IWvKwyflRsuO2s4oElL0yOCAkf5+/WjKbcshvjoo48qEpPQ089eez5i\nFCore+uttyCxAwAA4O0gsQNukJGRMX369POnT98XEzVy5P3ItVEcRdkefIjUvo8uT8g2k/nz\ncsMOs7X6kCuH8WA/9Rit331aTWhgoMPhMJlM7ooWde12U1FKt4wfv3dL4wAAAIAHQWIHmsrp\ndE6ZMiWVIn88N1VVZY86Z7+7xPDIGi8pEoSvyg3/LjPk13SGeke5bIxWMz5A59pJmKYo9wYc\nEBCASopvKiouDggIcO+rAAAAAC0PEjvQVLt37y65nP3x05Nl1I19Rnbn5AeFRd2S1hGE9pqt\n/y4r/5/JIlTrogti6Md02nH+2gRZPaeNNdFjjz327YQJaNB9KDEJIYSKi9DGDY9NmdysLwoA\nAAC0AEjsQFPl5+fH6rSym8/peu7/di4bNykyOtr11CaRrysMa0vLLzhu3YiOQugutfKJAP8h\nahXXlDURDXbPPfe89I9/rHr+WWenRMTJ0KmTI4cMmTlzZgu8NAAAANCsILEDTRUeHl5gsRJC\n8PWVDSVW2/mysoiICITQFV74d1nFZ+UV5YJ4y4XBDD3eXzvBX9fy533NmTNnxIgRe/futdls\nvRct7NWrQet2AQAAgFYOEjvQVAMGDHht8MDKrM4mCGN/+OWBBx8sDQpelHvlZ6OZrzbqmqZU\nTAnUPajRtEwXXY0SEhISEhqxux4AAADQ+kFiB5pKUVYyLjbKtR2xycmn/vuLduOfEJ6YeF/m\n5VtrUvhRnfbJAF2SXOaJSAEAAAAfB4kdaBpJkv32EyYEISRg/H6PvvLRTxyVCHLctNy1PctM\nCdBN8NcFwEGuAAAAQLOBxA40CXf4z/9v774Do6jz/49/ZmdLssmmJyQhIQRCCUVABEEBCyKi\nJ6j3/dnRExVziuUrcoB6wHFnwXKiiAURy3nq3X3lULEAdhDxwBNp0kKAFEJI77uzs/P7Y8IS\nERHY3cxm8nz89d7PTmbfk3XCyymfkctK3RbL6xndnuzRb6/dIXw/OfE6MDLi9qSE38REn9qz\nvwAAwIkj2OHUWWqqlf+sfaFrr/ndeh1w/GQiYkmI86OjpiQnjIhyGtUeAAAdDcEOp6heVV/7\n7rsFZ4+rsP9k2jmbJF0eGzMlOSE3xNPRAQCAoxDscNLqVN/iyurny8qqUjJaj0dI0vXxsXck\nJWS0+fQlAABAEOxwUupU30uVVS9UVFV5VSGOXDMXLUk3JcX/PjEhmXsjAAAwDsEOJ6TB53up\nouq5lkh3RLzi+X1zw01Dh8TJRDoAAAxGsMOvaNa0Vyurnz5UUf6zSHfn3p13HCySb5yskeoA\nAAgDBDv8IkXT3qiqeepQxQHF23o8XvXetefHO/buivEqzRddqkRG/tIaAABAWyLY4Rg0IZbV\n1D1y8FCB5yfzDLtkyx2q597P3ovxKkIINTVd6TfQoB4BAMDRCHY42ud1DX8pK9/U1Nx60Gmx\n3JoYP8UVlfHq85JXEUIISXJfME4w7TAAAGGDYIcjfmhqnnvw0Ff1ja0HHZL0u4S4u5MTk62y\n49OPpIZ6fVwZeIaa1tmINgEAwLER7CCEECWK98lDFX+vqlG1Iw8EswjxmxjX7LTkLjabEEI+\nVGbf+J3+luaMco8415BWAQDALyHYdXS1qu/p8soXyyvd2k+e8XpxjOv+lMReEQ7/iOOzFcLn\n02v3ORdoEdwzAQBAeCHYdVxeTXu9snpeWUWl+pN5TM50Rs5OTR7i/Elus+7aLu8v0GtfeobS\n97S2axQAAJwYgl0H9UV9w6zSQz82u1sPdnfY/9gp6ZIY19FLq6rjy09aaklqPncM90wAABCG\nCHYdToFH+Uvpofdq61oPxlvlKYnxeUkJ9mMlNvt331qqKvXam9tf7ZzZFo0CAICTRLDrQOp9\nvifLKhZVVnl8Ry6ns0vSbUnx9yQlxsiWY/6U1NRoX7dGrzWrtXnkeW3RKwAAOHkEuw5BE+Lf\nNbWzSw+V/vQZEhfHuOakJmfbbcf5WceaLyR3y5x2nqFnazGxIWwUAAAEgGBnfrvdnvtLyz6v\na2g92MNh/3NayujoqOP/rKX8kG3Tf/Vac7mUoWeFqksAABAwgp2Z1am+R8vKl1RWe1tNZZJg\nlWekJN0QHyufwA0QEV+s9E9x0jxqtGY73rE9AABgrGNfVgUTWFFXPyp/76KKKn+qswhxZVzs\n513STy/c9/1339XX1x9/Ddb8nXJBvl6raZ29uf1D2zEAAAgMR+xMaJ9HmV5y8NP6n5x7PcMZ\n+WhaStFnn144fXpNRbnNImt2+wMPPHDLLbccey0+n+Orz1pqSXKfP5YpTgAACHMEO1Px+LSF\nFVV/LStvbn3uVZZnpyZfEx+7bevWvLy8x0YOu3lgP1mSPthdcOPsWenp6RdffPHPV2XbtslS\nXqbXSs9cNT2jjbYBAACcKk7Fmsf39Q3jCvY/fPCQP9VJQlwZF7u2Z/a18bGSEC+++OL/y8me\nPKi/fnXdJTnZ04cNefbZZ3++Kkn1Or7+suWFLHtGnd9WGwEAAE4dwc4M6n2+mSUHz/x+86am\nZv9gboRjebcuCzNSE2VZHykqKhrQKbn1Dw5KTd63b9/PV2jb8K1UW6PXyoDBvriEkPUOAACC\nhlOx7d6quoZpJQeLFcU/EmmRpiUn5SXF2356VVxqaurO3dtbj+yoqEpPTz9qhVJzs339Wr3W\nbHb3sBGhaRwAAAQZR+zasRpVnVpy8Np9Ra1T3fCoyM+6d70zOcH2s3sdfve7372+edt7u/bo\nL9cfOPjQ1/+5+eabj1rM/u0aqalJrz1DhmtR0SHbAgAAEEwcsWuvPqytm1ZSVuY98iSJRJt1\nTkrSVfGxv3Tz6tChQx+a99ik2bPjP/3KIcv7Gxpvv/32q6++uvUyUl2d7b/r9VqLdCpnDAvV\nBgAAgGAj2LU/lao6s6RsaU1t68HfxsUs6NXD1vArU9PdcMMNdrv93Xffdbvd151/fl5e3lEL\nONZ8Lnlbjv+5zxqlORxB7BwAAIQUwa6dWV5TN+3AwXKv6h9Js1mfTE+9MCY6zm6rajjOjwpN\n0yZNmrT8y6/EueeJmPjVL7z47rvvvv/++xEREfoClspy27ZNeu2LjVMGDA7ZdgAAgODjGrt2\no0ZV7ygqvamwpHWquyYuZnVO1zGuX3nkq+7NN99c/s034pW/iXuniTvvFq/9fWND46OPPupf\nwPHVZ/4HiHlGni8O304LAADaBYJd+/BFfcM5u/f9s7rGP9LZZnu7a8YzGWmxJxy/Pv74Y/Gb\nCSIxseW1wyGuvvajjz7SX8mlJdbdO/Ra7ZSm9O4btO4BAECb4FRsuGvyaX86eGhJRZXWavDa\n+Ng/p6bEyCeXy5uamoTT+ZOhqKimwzfA2td8IQ7PbOwZeR4PEAMAoN3hiF1Y29jUfH7+3pdb\npbpkq/y3Lp2f7px6sqlOCDFgwACx+kv/yVYhhPjyi4EDBwr9cN3efH3M1znTm50TcO8AAKCt\nccQuTPk0saC8Yl5ZhdLqqa+/iYl+ovORJ0mcrDvvvHPp0qVFsx4Ql10hbDbx2SdRX30x+9NP\nhRCO1Z/5D9c1n31uwO0DAAADcMQuHBUryhV7C/9ysNyf6mJl+bmMtFe6dD7lVCeEiIuLe//9\n9/8nrVPSvIdiZz9wQWP9hx9+2L17d7m4UN7bMmux2jlTzcoOwjYAAIA2xxG7sPNebd3U4oPV\n6pFbX8+Kci7snJphtwW+8oyMjOeff/6oQcfqz/21e+R5gX8KAAAwBMEujLg17U+lZS9VVPtH\nrJL0v8kJU5MT5ZDdyiDvK5AL9+q12rWbmtk1RB8EAABCjWAXLrY3u28tOrC92e0f6e6wP5+R\nNigyIqSf61j7pb92Dx8V0s8CAAAhRbALC69XVj9woKy51X0S18XHPpyW4rSE9iJIa0G+XLRf\nr73ZOWpGl5B+HAAACCmCncFqVd+9JaXv1tT5R2Jky5PpqZfFumpqajbs2pWYmJiVlWUJTcJz\nrP2ipZIkz4hzQ/ERAACgzRDsjLSl2T1pf3GBR/GPDIyMWJSZnmWV586d++KLL3oki/C4+/fr\n98wzz/Tr1y+4ny4X5FtKivXa272nmpoe3PUDAIA21g6CXX19/aJFizZt2qQoSq9evfLy8lJS\nUo5aprS09JVXXtm2bZvb7R48eHBeXl5sbKwh3Z641yur7z9Q5j58+lUS4vakhAc6Jdkkaf78\n+Qv+8Q/xxHzR/zTR2LB50QvXX3/9F198ERcXF8QGHOtWt1SS5DmLq+sAAGj32sE8dvPnzy8r\nK5s9e/bjjz/udDrnzp3ra/3sBCEURZkzZ46qqo8++ujjjz9eX18/b948o7o9EQ0+3++LDkwt\nOehPdQmy/FbXjDmpyTZJUlX12WefFffcJ/qfJoQQzihx1/8WR0T+61//CmIPcklRq6vruqud\n0oK4cgAAYIhwD3bl5eXr16+fPHlydnZ2enp6Xl5ecXHx5s2bWy9TUFBQUlLy+9//vnPnzllZ\nWXffffeWLVv27dtnVM/Ht6PZfWH+vv+rrvWPDHFGfJ7TdXR0lP6yurq6pqZG9Ox15GcsFtGz\n1969e4PYRuubYT3DRgZxzQAAwCjhfip2165dNpstO7vlWQjR0dEZGRk7duwYMGCAfxlFUYQQ\ndrtdfxkfHy/L8u7du7OysvQRTdPq6o7cneBwOCSDnnD/YW3dlKIDtWrLEUdJiFuT4ud0SrFb\njvQTGxsbERHRXFIsEhOP/GRxUdrQM47Ttv7WCW6XfPDAkUdNdMn2ZXQx5tdxkoz61kJKOszo\nRkLFxFtn4k0TJt3ddCbeNBHsrTP378qswj3Y1dbWulyu1v9txcbG1tTUtF6mW7duMTExb775\n5s033yyE+Oc//ymEaJ3kPB7P+eef73/5u9/9bsqUKSFv/ae8mvaH/L1PFZX4R+Kt1ld695iQ\nlPDzhW+55ZZnn/6reOQxkZwiNE2886+4/ftuvvnmxNZR71h+dQGdsnyp7/BZ4IiLLnGe2E8Z\ny+FwOBwOo7sIlYiI0M5WaKDo6Ojo6GijuwgJE/8HKYRISDjGnyZzOMG/k+2RzWYL7tZ5vd4g\nrg1tI9yDnTiB/2OIjIycMWPGggULPv74Y4fDMX78+JSUFLnVM1UlSRo6dKj/ZWZmpn6QLyiq\nq6tXrFhRXFzcs2fPiy66yGo9xq/0gMdz3Y78NbVHsuag6Kh/9M7p6nAcs5OHHnpo//79711/\ntcjqKqqqOsmWl15/PTU19fhtW63WE9oJy0p9P27RSymzi9olWw3ebyMUJEmyWq0+n09t9Zg1\n07BYLJIkmXXTZFlWVfWoi2LNQZZln8+ntZp70jSsVqskSUH8IxlWTvTvZDtks9k0TQvu1vl8\nvmP+o4ZwFu5fWFxcXG1traZp/nhXU1MTHx9/1GL9+vV78cUXGxoa9P+H/r//+7/k5GT/u3a7\n/bnnnmu9fHl5eVDaW7t27S233HLI7hDpnUX+rt4pKW+++WZmZmbrZf7T2DRpf8nBVjvbtfGx\nj6V3cjQ31zQ3/9KaX3755a1bt27evDkxMXHYsGEul+uo45RHkSQpLi7u+MvoIlZ+aDv8r1Hj\n0LO9J/AjxpJlOT4+XlGU1kdhTcPhcFit1oaGBqMbCb7IyMioqKjGxka32/3rS7c3LperubnZ\nlOknNjbWZrPpf3iN7iX4EhISTuTvZHuUlJTk9XqDu3U2m83cR6ZNKdyDXY8ePRRFyc/Pz8nJ\nEULU1tYWFhbm5ua2XkZV1bVr1/br108PfOvXr9c0rU+fPqHuraamZvLkyYd+M0FMvFFIknC7\ntz/60O233/7+++/7l3m9snpmaZnH1/L30S5Js1OTJyceHUyPqW/fvn379g1uz5bqStvOH/Va\nTenkzc4J7voBAICBwv2u2ISEhOHDhy9cuLCgoKC4uPipp57q3r27HtpWrVqlRyhZlt95550X\nXnihvLx869atCxcuvPDCC2NiYkLd2+eff37QIrekOiGEwyHumbru228LCgqEEB5N+9/i0qkl\nB/2pLtNu+6BblxNMdSFi/2a1OHxeTBk+SnBhLAAAJhJosGuDMxF33XVXVlbWnDlzpk+fbrfb\nH3zwQf207MaNG//zn//oy/zhD3+or6///e9//+ijj44YMeLWW28NdVdCiIqKCpGc/JNsFBsr\nHI7y8vIDindCQeEbVUcOiZ/nivqkW9bASCOvkZdqa2yHr67zJSYpPXob2AwAAAi6QE/Fpqen\n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" }, "metadata": { "image/png": { @@ -16059,18 +16189,18 @@ "\n", "plot(my_history)" ], - "id": "d50d6e18-60ed-4d25-96ca-bae451703883" + "id": "92d64806-286c-442d-882b-a6705f3caffa" }, { "cell_type": "code", - "execution_count": 411, + "execution_count": 374, "metadata": { - "id": "f4fa7eac-8937-4bfd-a108-199d5caf1786", - "outputId": "27c39ced-9b16-4a3a-e07b-8f74c3bc4524", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "0a2a2ccf-59fa-4eb5-9eb5-dc36e0437421", + "outputId": "fb4bc2fb-2e04-4c00-d15e-343773d3803f" }, "outputs": [ { @@ -16082,13 +16212,13 @@ ".dl-inline>dt, .dl-inline>dd {float: none; width: auto; display: inline-block}\n", ".dl-inline>dt::after {content: \":\\0020\"; padding-right: .5ex}\n", ".dl-inline>dt:not(:first-of-type) {padding-left: .5ex}\n", - "
loss
0.152891755104065
accuracy
0.96289998292923
\n" + "
loss
0.123617917299271
accuracy
0.964800000190735
\n" ], - "text/markdown": "loss\n: 0.152891755104065accuracy\n: 0.96289998292923\n\n", - "text/latex": "\\begin{description*}\n\\item[loss] 0.152891755104065\n\\item[accuracy] 0.96289998292923\n\\end{description*}\n", + "text/markdown": "loss\n: 0.123617917299271accuracy\n: 0.964800000190735\n\n", + "text/latex": "\\begin{description*}\n\\item[loss] 0.123617917299271\n\\item[accuracy] 0.964800000190735\n\\end{description*}\n", "text/plain": [ " loss accuracy \n", - " 0.153 0.963 " + " 0.124 0.965 " ] }, "metadata": {} @@ -16098,13 +16228,13 @@ "my_model %>%\n", " evaluate(x = x_test2d, y = y_test)" ], - "id": "f4fa7eac-8937-4bfd-a108-199d5caf1786" + "id": "0a2a2ccf-59fa-4eb5-9eb5-dc36e0437421" }, { "cell_type": "code", - "execution_count": 412, + "execution_count": 375, "metadata": { - "id": "7d8294f2-eb4c-4eaa-a24c-167288cd3dc7" + "id": "caf1f1d8-3dad-4609-82da-956436ee334f" }, "outputs": [], "source": [ @@ -16128,18 +16258,18 @@ "my_cb <- callback_early_stopping(patience = 5,\n", " restore_best_weights = TRUE)" ], - "id": "7d8294f2-eb4c-4eaa-a24c-167288cd3dc7" + "id": "caf1f1d8-3dad-4609-82da-956436ee334f" }, { "cell_type": "code", - "execution_count": 413, + "execution_count": 376, "metadata": { - "id": "a320c3e2-34a9-4c31-bd0f-5e2f3c400222", - "outputId": "a6735040-8b70-440c-9918-e16908b8630b", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "df9e3f56-5212-4c35-8e92-46bf4c106729", + "outputId": "14b7946e-d3bd-4c7c-cf59-9ebd450729fd" }, "outputs": [ { @@ -16148,7 +16278,7 @@ "text/plain": [ "plot without title" ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAIAAAByhViMAAAACXBIWXMAABJ0AAASdAHeZh94\nAAAgAElEQVR4nOzdd3wUdf4/8M9nytZsNrukEBJKEiD0jhQpggJKUe/Ur54N22FOPY7zFMVy\ncHDK3Ql3WFC/nD8LeqjoWb/YULoECD1IDwRCgPTsbrJt2u+PSULoJbOZ3cnr+fDh4zOT2dn3\nh00mr8x85jNUURQCAAAAALGP0bsAAAAAANAGgh0AAACAQSDYAQAAABgEgh0AAACAQSDYAQAA\nABgEgh0AAACAQSDYAQAAABgEgh0AAACAQXB6F6CPqqoqvUvQnsPh8Pl8elehPYZhHA6HIAh+\nv1/vWrTH8zzLssFgUO9CtGcymaxWq9/vFwRB71q0Z7VaBUEQRVHvQrRnt9s5jvN6vYacvt6o\nx0lCiNPpFEWxtrZWw31yHOdwODTcITSDFhrsJEnSuwSNUUoppcbrl4phGGLET40QwnEcMWjX\nCCEMwyiKYsjeUUplWTZq1xiGkSTJkMFO7ZreVUQEwzCa/xZQj70QW/CZAQAAABgEgh0AAACA\nQSDYAQAAABgEgh0AAACAQSDYAQAAABgEgh0AAACAQSDYAQAAABgEgh0AAACAQSDYAQAAABgE\ngh0AAACAQUTXI8WKi4v/9a9/HTx48IsvvjjnBjU1NYsWLdq5c6cgCNnZ2Tk5OcnJyRdYDwAA\nANByRNEZu7Vr1z7zzDPp6ekX2GbBggWlpaUzZ8586aWXbDbb7NmzZVm+wPrm4fF49u7da8jn\nuAMAAEAMiaJgJwjCvHnzBg8efL4NysvL8/LypkyZkpGR0aZNm5ycnOLi4vz8/POtb4aaS0pK\n7rvvvo4dOw4fPjwzM/O5554LhULN8L4AAAAAZ4uiS7GjR48mhBQUFJxvgwMHDvA8n5GRoS7G\nxcWlp6fv27fP7/efc33v3r0jWrAkSQ8++GBcyfGdD92dmeDcfKLk4U+XSpI0d+7ciL4vAAAA\nwDlFUbC7KK/X63A4KKUNa5xOp8fjcTqd51zfsBgOh6dNm9awOG7cuPHjxze9nuXLlx/YsWNv\nzuR4k4kQMjgtdfGkcUPefnvWrFm6jPBjGMbpdDb/+0aa+snyPG/I3jEMQynluFj6SbxEDMMQ\nQmw2m8Vi0bsW7bEsy7Ksoih6F6I99bsxPj5e70IiglJqyCOJiuM4bXvXnIOaQCsx9uukcXq7\nlPUqRVE2bdrUsNitWzee55tezOHDh7sludVUp+qdnGRl2aNHj6alpTV9/1dAk35FJ4Zh1KBg\nSAbumhqA9K4iIgz8qRFDH0wM3DVKqba9E0VRw71B84ilYJeQkOD1ehVFaYhxHo/H5XKdb33D\nC00m04oVKxoWzWZzRUVF0+uxWCzHvDUKIQ2hstwf8AuCyWTSZP+XRf0ztLq6upnftxkwDONy\nuUKhUE1Njd61aM9sNnMcV1tbq3ch2rNYLHa7vaamxpADT+Pi4kKhkCAIeheivfj4eJ7nKysr\nDXk+0uVyVVVV6V1FRLRq1UoQBK/Xq+E+eZ436rlbA4ulYNepUydBEAoKCjp27EgI8Xq9RUVF\nXbt2TU1NPef6hhdSSs/41vT5fE2vZ9SoUc/b7HPWbXju6kEMpX5BfOyHlUOvvrp9+/Z6HRAN\neSBuYMjeKfX0LiRSDNw7A3eNGLp3Ru2XStveGfvfyqiiKNhVVVVJkqRGrvLyckJIXFycxWJZ\nvnx5MBicNGmS2+0eMmTIwoULp06dajKZ3nrrraysrG7dulFKz7k+0gXHx8f/+9//fuihhz7Y\ntTfT5dxVVpGSkfmfhQsj/b4AAAAA50SjJ48/9NBDpaWlZ6y58cYbX3rpJa/XO2fOHEKI3+9f\ntGjRtm3bJEnq3r17Tk6Oesn1fOvPRw2OmqipqVm5cuXx48c7dux4zTXX6DWciFKakJBgyEsM\nLMuql2I1Oc8abQx8KdZqtdrtdp/PZ8hLsQ6HIxgMGvJSrNPp5Hm+oqIien47aMjtdldWVupd\nRUQkJiYKgtD4xsGmM+pda8YWRcGuOWkY7KIEgl2MQrCLUQh2MQrB7rIg2MUiI9/VBQAAANCi\nINgBAAAAGASCHQAAAIBBINgBAAAAGASCHQAAAIBBINgBAAAAGASCHQAAAIBBINgBAAAAGASC\nHQAAAIBBINgBAAAAGASCHQAAAIBBINgBAAAAGASCHQAAAIBBINgBAAAAGASCHQAAAIBBINgB\nAAAAGASCHQAAAIBBINgBAAAAGASCHQAAAIBBINgBAAAAGASCHQAAAIBBINgBAAAAGASCHQAA\nAIBBINgBAAAAGASCHQAAAIBBINgBAAAAGASCHQAAAIBBINgBAAAAGASCHQAAAIBBINgBAAAA\nGASCHQAAAIBBINgBAAAAGASCHQAAAIBBINgBAAAAGASCHQAAAIBBINgBAAAAGASCHQAAAIBB\nINgBAAAAGASndwH6sNvtepegPYZhDNkvSikhhOM4Q/aOZVmjfnAcxxFCzGaz2jAYjuMsFovJ\nZNK7EO2xLEsIsdlsehcSEZRSQ/64qViWNXDv4BIZ8IB7KURR1LsE7SmKYsh+MQxDCJFl2ZC9\nUxmya8b+4DiOkyRJkiS9C9Eez/MMw0iSpCiK3rVEhCG/IVWa/xZQf4ohtrTQYBcKhfQuQWOU\nUpvNZrx+kfq/QWVZNmTvVIbsGsMwZrNZEARD9s5kMgmCIAiC3oVoz2KxEEJCoZAhg53dbjfk\nNyQhxOFwaH6c5Hlew71B80AYBwAAADAIBDsAAAAAg0CwAwAAADAIBDsAAAAAg0CwAwAAADAI\nBDsAAAAAg0CwAwAAADAIBDsAAAAAg0CwAwAAADAIBDsAAAAAg0CwAwAAADAIBDsAAAAAg0Cw\nAwAAADAIBDsAAAAAg0CwAwAAADAIBDsAAAAAg0CwAwAAADAIBDsAAAAAg0CwAwAAADAIBDsA\nAAAAg0CwAwAAADAIBDsAAAAAg0CwAwAAADAIBDsAAAAAg0CwAwAAADAIBDsAAAAAg0CwAwAA\nADAIBDsAAAAAg0CwAwAAADAIBDsAAAAAg0CwAwAAADAIBDsAAAAAg0CwAwAAADAIBDsAAAAA\ng0CwAwAAADAIBDsAAAAAg0CwAwAAADAIBDsAAAAAg+D0LuCUmpqaRYsW7dy5UxCE7OzsnJyc\n5OTkxhvk5+c/++yzZ7zq4YcfnjBhwtSpUwsLCxtWWiyWpUuXNkPNAAAAANEjioLdggULampq\nZs6caTablyxZMnv27FdeeYVhTp1T7NKly9tvv92wWFpaOmvWrF69ehFCampqpkyZMnjwYPVL\njV8FAAAA0EJESwAqLy/Py8ubMmVKRkZGmzZtcnJyiouL8/PzG2/D83xiIx9++OGvfvWrtm3b\nEkJ8Pl/r1q0bvuR2u3XqBwAAAIBuouWM3YEDB3iez8jIUBfj4uLS09P37dvXu3fvc26/du3a\nEydOzJw5kxAiCEIoFMrNzf3ggw98Pl/Hjh3vvffetLS0ho1lWd68eXPDYmpqanx8fCR7owNK\nKaWU53m9C9Geev6VYRhD9o5lWaN2Tf3gWJY1au84LlqOn9qilBJCeJ5XFEXvWrRn1OOkSvPe\nsSyr4d6geUTLgcnr9TocDvWAonI6nR6P55wby7K8ZMmSO+64Qz2w+v3+hIQEURQfeeQRQsiH\nH344Y8aMN954w263q9sLgqB+SXXfffc99thjEeyMfpxOp94lRArP8wbundls1ruESLHZbHqX\nECkGzgeEEOP99dvAwEcSjuO07Z0oihruDZpHtAQ7Uv9n4qX4+eefg8HgqFGj1EWn07l48eKG\nr06fPn3y5Mnr168fM2aMuoZl2cmTJzds0K9fv0AgoFHVUcRisQSDQb2r0B6l1GKxSJIUDof1\nrkV76hk7QRD0LkR7HMfxPB8OhyVJ0rsW7ZlMJlEUZVnWuxDtmc1mhmEMeZAkxj1OEkKsVqss\ny6FQSNvdGvXMtIFFyweWkJDg9XoVRWmIdx6Px+VynXPjlStXDh069HyniK1Wa1JSUnl5ecMa\njuN+//vfN96m8VeNgVJqMplqa2v1LkR7LMtaLBZRFA3ZO7PZzHGcIbtmtVp5ng+FQpr/pokG\nDMMEg0GjJnKGYfx+vyEvxZrNZkP+uBFCrFarJEna9o7neavVquEOoRlEy80TnTp1EgShoKBA\nXfR6vUVFRV27dj17y9ra2m3btl111VUNa44cOfLaa681nDEOBoNlZWWtW7duhrIBAAAAoke0\nnLFzu91DhgxZuHDh1KlTTSbTW2+9lZWV1a1bN0LI8uXLg8HgpEmT1C0PHjwoSVJqamrj1+bm\n5oqieMcdd0iStHjx4ri4uKFDh+rTEwAAAACdRMsZO0LI1KlT27dvP2vWrKeeespkMj333HPq\nZdnt27dv2rSpYbOqqipKaeMJTRwOx5w5cyoqKqZNm/b0009LkjR37lwDj0YHAAAAOCdqyFEU\nF2XIMXYJCQlVVVV6F6I9lmVdLlcoFPL5fHrXoj1jj7Gz2+0+n8+QY+wcDodRx9g5nU6e5ysq\nKgz528HtdldWVupdRUQkJiYKgnC+2SSujLGnIzCqKDpjBwAAAABNgWCnDaa4yPLdV2xZid6F\nAAAAQMsVLTdPxC7qr7V9/D5TXkoIIRwvXXeD3hUBAABAC4Uzdk2l2OxEqZuklNudT0UDjrkB\nAACAmIBgpwGhRx+1QUNBdt8efYsBAACAFgvBTgNCz75K/WMwTDu36lsMAAAAtFgIdhpQrFYx\nq7PaZo8dZSqMNpcKAAAAxAQEO22Ivfs1tPld23WsBAAAAFosBDttiO0zFWeC2ubzt1FJ0rce\nAAAAaIEQ7DRC6albKAIBrmC/vuUAAABAC4Rgp5lwzz6Eqfv35HbgFgoAAABobgh2mlEc8WKH\nTLXNHTlEPdX61gMAAAAtDYKdloSe9bdQKApuoQAAAIBmhmCnJbFjZyXOobZN+duJLOtbDwAA\nALQoCHaaYhihe2+1SX1ervCQvuUAAABAi4JgpzGhdz9Cqdrm83ELBQAAADQfBDuNyc4EqW17\ntc0d3E9rfPrWAwAAAC0Hgp32hF5961qyzP+yQ9daAAAAoAVBsNOe2LmbYrWqbX7HVqIo+tYD\nAAAALQSCnfYUlhW69lTbjKeaLSrUtRwAAABoKRDsIkLo1a+hzW/fomMlAAAA0HIg2EWEnJQs\npbVV2/zBfbiFAgAAAJoBgl2khHv3r2tJkmkXbqEAAACAiEOwixSpS3fFalPb/I4teAoFAAAA\nRBqCXaQoLCv0qH8KhdfDFRboWw8AAAAYHoJdBAl9Bpx6CgVuoQAAAIAIQ7CLIDnBJbXPUNvc\noQPUU61vPQAAAGBsCHaRJTTcQqEofP52XWsBAAAAg0OwiyyhY7YS51Dbpp1biSTpWw8AAAAY\nGIJdhDFMuGcftUlra/iC/fqWAwAAAAaGYBdxQq9+hKn7d+Z3bNW3GAAAADAwBLuIU+KdYkZH\ntc0eOcRUVehbDwAAABgVgl1zEHrXPzpWUXDSDgAAACIEwa45iJmd5Hin2jbt2kElUd96AAAA\nwJAQ7JoFpWLDvCcBP7tvt67VAAAAgDEh2DWTcM8+hGXVtglPoQAAAIAIQLBrJoo9TuiYrbbZ\n4iK2vFTfegAAAMB4OL0L0Aetf4RrcxL7DuDrL8LyW/PkcRM13LnaI1361WyM2jtKqVG7Rgzd\nOwN3jRj3x40YumtE694Z+9/KqKiiKHrXoANR1Of2BemVf5CSk4QQwpvY6X8mNpuGO2dZVjLi\nky0opSzLKopi1N5RSmVZ1rsQ7TEMwzCMJEmGPMiwLCvLslG7RinV6yAZaRzHGbhrmh8nZVk2\nmUwa7hCaQQs9Y1ddXa3L+/I9+1pKviWEECHsX78mPGCwVnumlCYkJOjVr4hiWdblcoXDYZ/P\np3ct2jObzRzH1dbW6l2I9qxWq91u9/v9oVBI71q053A4gsGgIAh6F6I9p9PJ87zH4zFkbHW7\n3YY8ThJCEhMTRVH0eDwa7pPneQS7mIMxds1K7NFbMVvUNr8tjxjxuAkAAAB6QbBrVgpvErr3\nUttMdRVXWKBvPQAAAGAkCHbNTeh3Fakfjspv3aRvMQAAAGAkCHbNTXa5pQ6Zaps7XIBHxwIA\nAIBWEOx0EO47sK6lKDwmKwYAAACNINjpQMzsJDsT1Da/azs14o11AAAA0PwQ7PRAqdBnQF0z\nGOR279S3HAAAADAGBDt9CL36Khyvtk1bMe8JAAAAaADBTh+KxSp27aG2mfJS9thRfesBAAAA\nA0Cw043Q/6qGNuY9AQAAgKZDsNONlJQipbVV2/zBfdTn1bceAAAAiHUIdnoS+tWftJNlfgfm\nPQEAAIAmQbDTk9Cpi+JwqG3T9i1UEvWtBwAAAGIagp2uWFbo1U9t0oCf3fOLvuUAAABATEOw\n01m4d3/CsmrbtGWjvsUAAABATEOw05lijxO7dFfbbOlJtqhQ13IAAAAghiHY6S/cf1BD27QZ\nJ+0AAADgCiHY6U9KSZXS26ltrmA/U1mhbz0AAAAQoxDsokJ4wOC6lqLw2zBZMQAAAFwJBLuo\nIHbMlhNcapvP30GDQX3rAQAAgFiEYBcdKG2YrJgKYT5/m77lAAAAQCxCsIsWQs++itmitk3b\n8ogs61sPAAAAxBwEu2ihmExCzz5qm3qq+QN79a0HAAAAYg6CXRQJ97uKMHWfCL95g77FAAAA\nQMzRINj5/f4TJ06o7UAg8O67786fP//QoUNN33NLozgThI7Zaps9fow5XqxvPQAAABBbmhrs\n9u7dm5GR8d577xFCRFEcMWLE/fff/8QTT/Tr12/bNtwBcNmEhnlPCDFtwUk7AAAAuAxNDXbP\nPvtsSkrKbbfdRgj56KOPNm/e/Prrrx88eLB79+4vvviiFhW2LFJaWyk1TW3z+/dQr0ffegAA\nACCGNDXYrVu37umnn87KyiKEfPbZZz169Pjd736XlZX16KOPbtyIp2NdCaF/3bwnRJZN2zfr\nWgsAAADEkqYGu+rq6tTUVEKIJEmrVq0aP368uj4pKamkpKSp1bVIQuduSrxTbfM7tlIhrG89\nAAAAECuaGuxSUlLU+yRWrFhRVVV1/fXXq+uLiopatWrV1OpaJpYN9+mvNmkwwOVv17ccAAAA\niBVcE18/duzY55577uDBgx9++GFWVtaIESMIIaWlpS+//PLVV1+tRYUtkdCrvyl3LRUEQohp\n8wahz4CGaVAAAAAAzqepcWHOnDkdOnT429/+Vltb+8EHH7AsSwiZOnXqkSNHnn/+eS0qbIkU\nq7VhsmLGU83v36NvPQAAABATmhrsUlNTc3NzPR7P8ePHBw+um6rjiSee2LdvX69evZpcXssl\nDBx6arLiDeuIouhbDwAAAEQ/bSYorq2t5Xme1E9QvHr16tra2qbvuSWT451Cdje1zZaVsEcO\n61sPAAAARD9MUBy9hEFXE0rVtnlzrr7FAAAAQPTDBMXRS0pKkdpnqm32cAFbelLfegAAACDK\nYYLiqBYaeOoJY3weTtoBAADAhWCC4qgmdciSUlLVNr/3F8ZTrW89AAAAEM2aOo+dOkHxqFGj\nmj5BcU1NzaJFi3bu3CkIQnZ2dk5OTnJy8hnbTJ06tbCwsGHRYrEsXbr0El8bo4SBg9n/+5wQ\nQmSZ37IxNHqc3hUBAABAlIqiCYoXLFhQU1Mzc+ZMs9m8ZMmS2bNnv/LKK8zpE/PW1NRMmTKl\nYV6Vhq9eymtjlJDd3bRuFVNdRQjhd2wNDxmhWK16FwUAAADRKFomKC4vL8/Ly5syZUpGRkab\nNm1ycnKKi4vz8/PP2Mzn87Vu3TqxntvtvvTXxiqGEfoPUptUFEzb8/QtBwAAAKJWtExQfODA\nAZ7nMzIy1MW4uLj09PR9+/Y13kYQhFAolJubO23atAcffHDu3LnFxcWX+NqYJvTq23CWjt+a\nR0VR33oAAAAgOjX1UqxKEIS1a9ceP36cYZj09PShQ4c6HI7L2oPX63U4HLR+2jZCiNPp9Hg8\njbfx+/0JCQmiKD7yyCOEkA8//HDGjBlvvPHGRV8bDocffPDBhsVJkyb9+te/vtw+6ksePFxZ\n+QMhhPpr4w/tp1cNPXsbhmESEhKavbSIUz9Zk8lk1N5RStX5vQ1GHQths9msRhw8wLIsx3GK\nER8Jo154cTqdehcSEUY9Tqo4jtO2d7Isa7g3aB5NDXayLE+fPv2VV14RBKFhpd1unzlz5pNP\nPnlZu2qczM7J6XQuXry4YXH69OmTJ09ev379RV+rKMqePacetzpo0CCO0ybRNhtl2MjwupVE\nEAghytqV/OBh5FwjCGOuX5eOUmrg3hljPOg5qSnBkAzcNWLog4mBu6b5cVLEBaIY1NTvgPnz\n58+fP/9Xv/rVxIkTU1NTZVkuLi7+7LPPpk+fnpKScu+9917ifhISErxer6IoDRHN4/G4XK4L\nvMRqtSYlJZWXl2dmZl74tWazefPmzY1fW15efhmdjA6W7r357ZsJIUplhWfDz0Lnro2/SilN\nSEioqqrSqboIYlnW5XKFQiGfz6d3Ldozm80cxxnyEXxWq9Vut/t8vlAopHct2nM4HMFgsPEf\ntIbhdDp5nq+oqDDk+Ui3211ZWal3FRGRmJgoCMIZV7qaiOd5o567NbCmnid45513Hn/88c8+\n++yBBx644YYbJkyYMGXKlO+++27KlCkvv/zype+nU6dOgiAUFBSoi16vt6ioqGvX07LLkSNH\nXnvttYY/IILBYFlZWevWrS/ltQYQHji44Swdn7uWGPGYCwAAAE3R1GB36NChCRMmnL3+pptu\nanz186LcbveQIUMWLlx4+PDh4uLif/3rX1lZWd26dSOELF++/Ouvv1a3yc3Nfe21106ePKlu\nExcXN3To0Au81kjkBHfDWTq29CR3uEDfegAAACDaNDXYcRzn9/vPXi8IwuUOQJk6dWr79u1n\nzZr11FNPmUym5557Tr20un379k2bNhFCHA7HnDlzKioqpk2b9vTTT0uSNHfuXLPZfIHXGkx4\nyHBS3y9z7hp9iwEAAIBoQ5s4imL48OE8z3/33Xcmk6lhZTAYvOmmm8Lh8MqVK5tcYUTE4hg7\nlfXzj7mDdTO5+G+/R2pXN8kLxtjFKIyxi1EYYxejMMbusmCMXSxq6s0TM2bMmDhxYqdOncaP\nH5+WlqYoSlFR0bJly06ePPn9999rUiI0Fh46givYrw6wM+eu89cHOwAAAICmBrvx48d/9tln\nM2bMePPNNxtW9uzZ89///vd1113XxJ3D2aSUVKlDJnu4gBDCHj3MFhdJaW31LgoAAACiggYT\n3tx8880333zz8ePHi4uLKaVt27ZNSUlp+m7hfEKDh9nq75wwbVgXuOU3+tYDAAAAUUKzmQzb\ntGnTpk0brfYGFyClt5fS27HHjhJCuEMH2JITUkqq3kUBAACA/q4w2HXp0uVSNtu7d++V7R8u\nLDxkuPWT/6htfsM66abb9K0HAAAAosEVBrvExERt64DLInbIklq3YU8eJ4TwB/aGy0qVZFz+\nBgAAaOmuMNitW7dO2zrgcoUHD7N+sZQQQhTFnLc+OOFXelcEAAAAOjPso8cNT+yYLSUmq21u\nzy6mypgzMwEAAMClQ7CLWZQKg4fVtWWZ3/SzrtUAAACA/hDsYpiQ3U12tVLb/K4dSrUBHzsB\nAAAAlw7BLpYxTHjw1XVtSVLWrNC1GgAAANAZgl1sE7r2VJwJalvevIF6tXxKIAAAAMQWBLsY\nx7KhhpF2omjeiJF2AAAALReCXcwTuveW60/a8fnbGE+1vvUAAACAXhDsYh/LhoeOqGtLkmnD\nWl2rAQAAAN0g2BmB0K2X7D51eyxTVaFvPQAAAKALBDtDYJjwkPqTdrJs2oDnggAAALRECHYG\nIXbtQesfF8vvzmcqcdIOAACgxUGwMwqGYUaNrWvLsjkXI+0AAABaHAQ746C9+kpJ9U+P3buL\nqSjXtx4AAABoZgh2BkKp0Hik3frVulYDAAAAzQ3BzlCEzl2lpPqRdvt2s2Wl+tYDAAAAzQnB\nzlgoDQ8dWddWFB4n7QAAAFoSBDujETtlSympaps/sJctK9G3HgAAAGg2CHaGQ2n46lMn7Uxr\nVuhaDQAAADQfBDsDEjM7yW3S1TZ36AB77Ii+9QAAAEDzQLAzIkqDI69tWDKv+pEoio7lAAAA\nQPNAsDMmKb29mJGlttkTxdyBffrWAwAAAM0Awc6wwiPHEErVtnntT0SW9a0HAAAAIg3BzrCk\npGShaw+1zVRW8L/s0LceAAAAiDQEOyMLDx+tsKzaNq9bRUVB33oAAAAgohDsjEyOdwq9+6lt\nWuPjt27Stx4AAACIKAQ7gwsPHamYzWrbtPFnGgjoWw8AAABEDoKdwSlWmzBgsNqmwaBp03p9\n6wEAAIDIQbAzvvDAIYo9Tm3zWzZSr0ffegAAACBCEOyMT+FNocHD1DaVRPP6NfrWAwAAABGC\nYNciCL37ywlutc3/soMpL9O3HgAAAIgEBLuWgWXDw66pa8uyec1PehYDAAAAkcHpXYA+4uLi\n9C5BewzDXKhfAwYpWzbSE8WEEK5gf1zJcZLVufmKawJKKSGE4zhDfmosy1JKjdo1QojFYuF5\nXu9atMdxnNVqNdffcm4k6gdnt9v1LiQijPrjpmJZ1sC9g0vUQoNdKBTSuwTtmUymC/eLXneD\n+YP/RxSFEEK+/Sr04KOEiYFTtgzDmM1mWZYN+anxPM+yrCG7ZjKZeJ4XBEEQDDgzNsMwgiCI\noqh3IdrjOI5hmHA4rKjHCmO56HEydlksFs2Pk2z9FPcQQ1posDPebxpKqaIoF+lX6zZspy7c\n/j2EEFpWSrZsFPoMaKb6mkA9ssiybLxPjRDCMAyl1JBd4ziOECJJkiF7Z7FYRFE0ZNfUPCcI\ngiGDHTHi8b/BxX8LQAsQAydsQEOha8Y0esjYSsxXDAAAYCQIdi2L7EwQ+tfPVxwImDau07ce\nAAAA0BCCXYsTHjK8Yb5i09ZNTFWFvvUAAACAVhDsWhzFZApdfU3dgiSZV/2oZ1VfHJIAACAA\nSURBVDUAAACgHQS7lkjo1VdKSVXb3MF9bGGBvvUAAACAJhDsWiRKQ9eMaViyrFxOZFnHcgAA\nAEATCHYtlNSug9ipi9pmykv5/O361gMAAABNh2DXcoVGjT1t6pNQUN96AAAAoIkQ7Fou2Zkg\n9LtKbVN/rWn9Gn3rAQAAgCZCsGvRwkOGK1ab2jZt3cSWl+pbDwAAADQFgl2LppgtoRGj6xZk\n2fzDMmLQhwgBAAC0BAh2LZ3Qs6+c1lZts8VF/C879K0HAAAArhiCXYtHaXDsBMLUfSdYVv2I\nB8gCAADEKAS7qFZZWSkIQqTfRUpMDvcdWLcQ8JvX/hTpdwQAAIBIQLCLUu+//36PHj2ys7Pb\nt29///33FxcXR/TtwsNGKQ6H2uZ3bmOKiyL6dgAAABAJCHbR6KOPPpo9Y8YL/XsWPvLA2jtv\nkffsuvPOO0OhUOTeUTGZQiPrn0WhKJYfluFZFAAAADEHwS7qKIoye/bs+deOuLtH19Zx9j4p\nSUtuGh88XvzJJ59E9H2Frj3EjI5qmy0vNW3Li+jbAQAAgOYQ7KJOVVVVWVnZ6A5tG9ZYOHZY\n2zZ79+6N9FuHrr1eYTm1bVq3kvp8kX5HAAAA0BCCXdSx2+0cx5XU+huvLKn1u1yuSL+17HKH\nrxqitmk4bF71Q6TfEQAAADSEYBd1zGbzxIkTn1n1s18Q1TXLDh5efbxk4sSJzfDuwuDhsjNB\nbfN7f2ELDzXDmwIAAIAmEOyi0d///veSuPju/15815ffXrvkv3cuWz537tzs7OxmeGuF40LX\n3dCwaFm+jIoRn28FAAAANMHpXQCcg9vt/umnn7799ttdu3b1c7tfHjeuffv2zfbuYmYnsXNX\nbv8eQghTXWVauzI0amyzvTsAAABcMQS7ptq9e/fSpUtPnDiRlZU1efLklJQUTXbLsuzEiROb\n5/Lr2YLX3WA/WkiDAUKIactGsXNXKa3tRV8FAAAA+sKl2CZZsmTJmDFjFv6y+zOL7aUfVwwe\nPHjLli16F6UBxR4XuqbRtHbffU0lUdeKAAAA4OJwxu7KHT9+/Omnnw7/+S/k6uHqmpp33srJ\nydm4cSPDxHxiFnr24fb+whUWEEKYynI+d2142Ci9iwIAAIALifn8oaM1a9YEUts0pDpCCLnz\n7sKion379ulXlJaCYycoJpPaNm/8mS05oW89AAAAcGEIdlcuEAgQq+20VSYz4bhAIKBTRRpT\nnAnh4dfWLciy+duviCTpWhEAAABcCILdlevTpw85sI8cLz61KvdnK8N06dJFv6I0Fu47QEpv\np7bZshJTXq6+9QAAAMAFINhdub59+/7mllvIE38kP3xHftlFPvmYzP3rrFmzbDbbxV8cKygN\nXj9J4eqfM7Z+NVNepm9FAAAAcD4Idk0yb9685x96sOMnH9mmP9775zWL/vnPBx54QO+iNCa7\nWoWHjlTbVJKs339NZFnfkgAAAOCccFdsk5hMpqlTp06dOlXvQiIrPHAIt2+3evMEc/yYaVte\nuP8gvYsCAACAM+GMHVwChgndcBNhWXXJtOYnXJAFAACIQgh2cEmkpOTQoKvVNhVFyzdf4A5Z\nAACAaINgB5cqPGSE3CZNbbMlJ8zrV+tbDwAAAJwBwQ4uGcMEJvxK4eumLDZt/JktOqJvRQAA\nANAYgh1cBjnBHRpZP2Wxoli+/ZKGQrpWBAAAAKcg2MHlEfoMEDM7qW3GU21e8Z2+9QAAAEAD\nBDu4TJQGb7hRsdnVJX7XDn7fbn0rAgAAAFUUzWNXU1OzaNGinTt3CoKQnZ2dk5OTnJx8xjaV\nlZVvv/32jh07wuFwZmbm/fff37lzZ0LI1KlTCwsLGzazWCxLly5tzuJbFMVmD46baP38Y3XR\nvHyZmN5OscfpWxUAAABEUbBbsGBBTU3NzJkzzWbzkiVLZs+e/corrzDMaecU//rXv5pMpr/8\n5S9Wq1Xd5q233rJYLDU1NVOmTBk8eLC62RmvagaSorxZUXW3y+msn+zN2MSO2UKPPvyu7YQQ\nGghYv/nSf+udhFK96wIAAGjRouVSbHl5eV5e3pQpUzIyMtq0aZOTk1NcXJyfn994G5/Pl5SU\n9Oijj2ZmZqampt57771er7eoqEj9UuvWrRPrud3uZq7/42rvrJNlAw8cfqWsIqwozfzuughd\ne73sTFDbbGEBvy1P33oAAAAgWs7YHThwgOf5jIwMdTEuLi49PX3fvn29e/du2MbhcMyYMaNh\nsaKigmGYxMREQRBCoVBubu4HH3zg8/k6dux47733pqWlNWwpy/LmzZsbFlNTU+Pj4zUsPqgo\n/yitIIRUidKckvJ3qjzPpabc7k5ozvNXlFJKKc/zzfeWPC/ceKv5P2+rj461rP6J6ZAlp7TW\n/H3U868MwzRr75oLy7JG7Zr6wbEsa9TecVy0HD+1RSklhPA8rxjxb9TmPk42L817x7aMa1AG\nEy0HJq/X63A4aKNreU6n0+PxnG97n8/36quv3nzzzS6Xy+PxJCQkiKL4yCOPEEI+/PDDGTNm\nvPHGG3Z73QB/QRDUL6nuu+++xx57TMPi9/tqwo0Wj4WFnCPH3q3yvJTVYZhTywR5UU6nsznf\njjh7iddcJ634gRBCRMH85VLT1OnEbI7EW/E839y9a0bmyPyjRQObzaZ3CZFi4HxACNH2r9+o\nYuAjCcdx2vZOFEUN9wbNI1qCHan/M/FSHDt2bM6cOX369Jk8eTIhxOl0Ll68uOGr06dPnzx5\n8vr168eMGaOu4Tju97//fcMGPXv2rK2t1a5w0o2hO3t2nX+iZGFJWUCW1ZUbvL7h2/InuRJm\nprXuYrVo+HbnRCm1WCyBQCDSb3SmoSPZA/to0RFCiFJeFvhosXzrndq+A6XUZrOJohgy4px5\nHMcxDBMOhy++aazhed5kMoVCIUP+bjCbzaIoSkZ8sJ7FYmFZ1u/3G/KMnc1m8/v9elcREXa7\nXZKkYDCo4T4ppUY9M21g0fKBJSQkeL1eRVEa4p3H43G5XGdvuWPHjn/84x+/+c1vJk6ceM5d\nWa3WpKSk8vLyhjUsy6oRsEHjr2qCI+SpVgl3x9v/VlqxtMoj16//uqr6m2rP/zgd05MT000R\n/PueUmo2m3UIdoTQCb+yv/e/NBAghDC788MbfhZ699Nw/yzL2mw2SZJ06V2kmc1mjuMM2TVC\niMlkCofDRk3koVBIEAS9C9GeyWRiWTYQCBgy2FmtVqP+uNntdlmWte2dsU9LG1W03DzRqVMn\nQRAKCgrURfWuiK5du56x2e7du//+978//vjjjVPdkSNHXnvttYazAsFgsKysrHVr7Qd7XVQa\nz7+a1npNxw5jHafm/pAU5cNq76CDh/90vKRMNODf94ojPjj+Vw23xJp/+o4tPalvSQAAAC1T\ntAQ7t9s9ZMiQhQsXHj58uLi4+F//+ldWVla3bt0IIcuXL//6668JIeFweMGCBTfeeGP79u3L\n6wWDQbfbnZub+9prr508eVJ9bVxc3NChQ/XqS7bF/J/2aUs7tO1pOTVwKiwriyurBx04NL+s\nolaWL/DyWCRmdgwPqJtrhkqi5atP8agxAACA5kej52S73+9ftGjRtm3bJEnq3r17Tk6Oein2\npZde8nq9c+bM2bFjx/PPP3/Gqx5++OEJEyYcOnTonXfeUW+tzc7O/u1vf5uSknKB99L8Uuw5\nKYR87fW9cLL80OkjqNws+2iia0qi26LdxG+U0oSEhKqqKq12eNlk2fbRe2xxkbokdOkenHSL\nJjtmWdblcoVCIZ/Pp8kOo4p6KVbbQZ9Rwmq12u12n89nyEuxDocjGAwa8lKs0+nkeb6ioiJ6\nfjtoyO12V1ZW6l1FRKhzRFzgpsMrYOy71owqioJdc2qeYKcSFOWDKs/80oqS04eQt+a5aYnu\ne1wJJkaDeKd/sCOEej1xi/9NAnUDk4PXTxJ69m36bhHsYhSCXYxCsItRCHagipZLsQbGU3q/\nOyGvc+bzKYkJjeYEOimIT58overA4UUVVcaY01iJdwbG33RqsN3yb9myEn1LAgAAaFEQ7JqJ\nlaFTk1rldc6YluS2N3riWbEgPHuidNiBwx9XecTYj3diZqdw/0Fqu36wnZb33gMAAMAFINg1\nqwSWfTYlaWvnzKlJrRoPsDscFh4rPjlo/+HFldWxHu9CI66VUuse+8FUVliWfUFivEcAAACx\nAsFOB26OfT4lMa9z5oOtXI0H2B0VhD8dLxly4PCSKo8Qu2GIZQOTblGsVnWJK9hvWr9G34oA\nAABaCAQ73bTmub+lJm/smHGvO4FvdPauMCz8ofjk4P2HP4jZeKc4EwI33krqrzibc9fw+/fo\nWxIAAEBLgGCns3QTP79NysbOmfe4nGecvftj8clBBw6/VVEVjMF4J7XLCI24tm5BUczffsmU\nl+laEQAAgPEh2EWFtjz3z7TWGzpmTHafNvtJUViYcaK0376CV8oqfJIG0xrX1NS88MIL48aN\nGz169PTp00tKInjXanjgELFHb7VNw2Hrl0txIwUAAEBEIdhFkbYmfl6blE2dMn7bKsHc6OJs\nmSjNKSnvta/gmRMlpU14nnowGBw/fvzaj5Y8lJQwrW3r46tXXHPNNRHNdsExE6SUVLXNVFZY\nvvkSN1IAAABEDoJd1Enj+RdTUzZ1zpzSymVtdPauRpb/XVE9cP/h506UHgtfybSob7zxBlte\nuuKuWx/o3f2uHl2+vPXGIa74v/zlL9rVfiaF4wI33XbqRoqD+8y5ayP3dgAAAC0cgl2UasNz\nL6Qmb8/OejK5VeNpjf2y/L8VVf33H7rrSPFW/+Vd2czNzb2jW7a50d7u7dE1NzdXs6LPRXEm\nBCb8uuFGCtP61VzB/oi+IwAAQIuFYBfV3Cw7PTlxW3bmC6nJrXmuYb1MyA++mnGHjkw4dPR7\nX80lXt1kGEY6/UqopCgME/HvASkjKzR8VN2ColiWfc6Wl0b6TQEAAFogBLsYEMcwU1q5NnXK\nnNsmpa2Jb/ylTf7A3UeKRx8s/KTaG5YvEvBGjhz5fv6emvrLuLKi/O+2/JEjR0aq7kbCA4cK\nXbqrbRoKWT/9DzXig18BAAD0RQ35mOeLKi8v17uEKyQrZHlNzb/KKrf4A2d8KcXE35sQ/1Ar\nl7vRxdbGBEG46aabqg4emNyzm4llPt178CTH//TTTy6XK/KFEyoI1g/fZUtOqItymzT/7ZMV\njrvwqwghLMu6XK5QKOQzYhY0m80cx9XW1updiPasVqvdbvf5fKFQSO9atOdwOILBoCBcyWjX\nKOd0Onmer6ioMORvB7fbXVlZqXcVEZGYmCgIgsfj0XCfPM87nU4NdwjNAGfsYgxDyThH3HeZ\n7T7tkD4qzkYbfakkLLxUWtF7b8HjxSf3Bs/xq5Tn+S+++GLy439axVuXScyIO+9atWpV86Q6\nQojC84FbfqPE1x0jmOPF5mWf4yZZAAAADeGMXZTavn37/Pnzd+/e7Xa7J02alJOTYzKZzt5s\ndzC0sLzqc4/3jGdUUEJGxtmntHJdG2dn6Nmv0w1betK65F0qhNXF0OBh4eGjL/ISnLGLTThj\nF6Nwxi5G4YwdqHDGLhpt2LBhzPjx31lsRx9+ZPu1Y+e88+4DDzxwzoNsN4t5YXrr7dmZ01MS\nE/lTw+8UQlbV1N555NhVBw69UlZRKUnNWP6FSMmtg42fNrZhHb9zq74lAQAAGAaCXTT605/+\nRO65j/zhcTJ0GJl4I3n19e83bPjmm2/Ot30yx01PTjw0sO/8NinZFnPjLx0JC3NKynvvLfhD\n8cmdgah48IOY2fHU08YIsfz4LXv0sI71AAAAGAaCXdSprq7ev38/GTvu1KoEFxk4KC8v78Iv\ntLHMve6EtR07LO3QdnScvfEF2KCiLKnyXFtwZPyho59Ue0N6X2EJDxwi9BlQtyBJ1q8+Zaoq\ndK0IAADACBDsog7HcZRScsbYHVHgef48rzgNJWRUnO3jDukbO2dOTWrl4k67QzbPH3jk2Ilu\new/+6XjJ7nPdYNFsgqPHSR2y1DYNBKz//ZD6DTjODAAAoDkh2EWduLi4gQMHkk+XnlpVdJRs\nyB01atT5X3QOGSb++ZTEbZ0z57VJ6Wo+7cYLryQvrqweebBw4qGjS6s9+pzAY9nApFvkVonq\nElNVaf3vhw03VQAAAMAVQLCLRgsWLIhf+RN5Yhr5aAl5/TXyyJSH7r576NChV7ArO8NMdies\n6ZTxVUa7m5wOnp52i+xGf+DRYyd77C145kTJrmY/gadYLIFb7lRsdnWRPXnc+uUnJGru8wAA\nAIg5CHbRqFOnTrm5uVOvHjr6wN5bFfG9hQvnzp3bxH0OsVvfattmR3bW8ymJHU5/fEW1JP27\nonrUwcJhBwtfKasoF5svWsnOhMDt9ygWi7rIHi6wfPMFJrcDAAC4MpjHziAopQkJCVVVVZey\nsayQNbW1iyurv6+pPftBZCaGjo2z/8blHB1n5+jlTYIXDofPOd/ehbFHC62f/ofWn6sT+g4M\nXnfDqa9iHrvYhHnsYhTmsYtRmMcOVDhj1xIxlFwTZ3+7Xdr2zlnPpyRmnh7FwrLyf96au44U\n99536PkTpTsuYZKUQCDwwgsvdO3aNS0trX///m+99ZYsy5dej9SuQ2j8zaQ+RPLb8kybfr6s\nHgEAAAAh5OJP6gQDS+LYqUmtfp/UapM/sKTK85XHV9MokJWK4psVVW9WVHU2m25NcN6aEN+W\nP/c3zLRp0/asXvXmyKEdXc4tJ0qffeGvXq/38ccfv/RKhC7dSTBgWV43V595zQrFZhd69GlK\n7wAAAFoaBDsglJBBNusgm3VuavJXHt9H1d71tf7G12D2h8IvlpTNLSm7yma9NSH+RqfDzZ6a\nRWXr1q3ffPVl/kP3tI13EEK6tHK3czrGz5t3//33X9aDaIU+Axif17RhHSGEKIrlh2WKLU7M\n7KhRLwEAAIwPl2LhFBvD3OFyfpHRNq9z5pPJrTJOv8dCIWSjP/Dk8ZLuewv+58ixJVWeakki\nhPzyyy89k5LUVKca3jbNSun+/fsvt4DQsFFCz751C5Jk+XIpe7TQ6/Vu3LixoKDgsi7vAgAA\ntEAIdnAO7U389OTETZ0zv81s91ArVyv2tFmORUVZ6av9Q/HJ7vsK7jxyLD81rYI5bQO/IAZE\nMS4u7rLfmNLg2AliVue6JVFkP1p8zzUjBo8c2b1Hj9GjR+/cubMJ3QIAADA43BVrEJd1V+zl\nkhRlXa1/abVvmddXe87TZoLQtbjowYDnthNHk0PBGSvXLauuWbduHcNcyV8OVBSsn/yHPXZU\nXfRQdsKQUZt5C/l//07N/XnVqlVut7sp3YkquCs2RuGu2BiFu2IvC+6KjUU4YwcXx1I6Ms6+\nML31L12y3kxPvSE+znTGNCg8v6dD5hNd+3YYOdGV1nlRp+4v/u+iK0t1hBCF4wO33iWlt1MX\nnYr0f3mr+4lh8tgfTjjiP/744yZ2BwAAwKgQ7FocRVGOHj1aUFAgiuLlvtbOMLckxC9ul7an\nS8fX0lpf57CbmNMSnsKywV59/b/NuZ3yNxw6uqCsYu8VPdBC4fmS68ZvOVmqLiYIwld5q7vV\nekl2l8LCwivYIQAAQEuAYNeyrF27dtCgQf379x88ZGivXr0+/fTTK9tPPMvc7nJ+2D59V+es\nFxMc/JY8cvolWpmQzf7ACyXlww8WDth/6NkTpWtqaoXLubJjc7e69avvt3NmdTExHPp+46ou\n1ZWtW7e+spoBAAAMD8GuBTl48OA999xzeNR1ZNn35NvlZQ/89nfTpq1evbop+3RxbPKWPOGf\n88j5L7weCQuLKqpuKTzWdW/BlKLjS6s9l/LUMpZlb7z99omfL9tjrXuYbFI4+E3PTnfecH1T\nCgYAADAwBLsW5I033qi9ajC5ZzKx2YnZTK4fT+64a/78+U3crdfrJWePrl3xk4OceX7OI0mf\ne3yPHjvZfe/BsQVH/l5avsUfkM5/Gu/5558fnJU1/uU3Cmr86po2cfas1T+wZSVNrBkAAMCQ\nEOxakMOHD5Nu3U9b1b37oUOHmrjbLl26kEOHSEWjG41/2cXNnbMxNenLjLaPJLozz3p6rEzI\ntkBwXmnF9YeOdttbkHPsxMdVnpKzxvyxLOt2u0s83ts/+bLIW/egWOr1WJe8wx060MSyAQAA\njAdPnmhBEhMTScnJ01adPJmUlNTE3Q4cOHDimOv+7+knye8eJentyJ5fyOuvTp06NalVqyRC\nhtptf2mddDAU/s5X8723Ji8QPOMUXaUk/bfa+99qLyGkq8U80m67xmEfYrPaGGbevHnrvvpy\n8/13dkt0i4riCYWcZjMhhIbD1s8/Do0aG+53VROLBwAAMBIEuxbkzjvv/Pzuu8nwEaRXH0II\nKTpK3nv77iefbPqeX3311TZz534463mfz5eYmPi73/3ukUceabxBR7PpMbP7sUR3tSStrvH/\n6KtZUeMvPesU3Z5gaE8w9GZFlYnSgVbLZm/NX+69q6OVJ4rMUeo0m/dWVHZp5SaEEFk2//Qd\nU14avG78BYb3AQAAtCgtdILiCE3kqyNKaXx8/EWnpnzllVfmzp0bateecBw5eOC+u+6aP38+\nPWNSuibweDyXOJulQshOf+BHX+2Pvpot/oB4/u9DuyQNqSobUVk6srJsyX8/v2fY0AGmUw+6\nkDKywjf/j2K2aFC9HkwmE8uygUBA70K0ZzabbTZbbW1tOBzWu5aLEwTh4MGDfr8/Ozv7Uh6a\nYrfbQ6HQFcwZFP3i4uJ4nq+urjbkbwen06ntFL7Rw+VyiaLo8/k03CfLsvHx8RruEJpBCw12\nhjwcsywrSRe/27SwsHDNmjXhcHjIkCHdu3e/6PbNwCtKKz2eH6u9P1Z5DgaDF9iSDQYzQsH/\nsZqu2rl5UHWFSwgTQkjrVOaeh2iCq5nK1RSllFJqyMfgMgzDMIwkSdF/kFmxYsXDDz9cWFRE\nOM7OcX/+858ff/zxC7+EZVlZlqO/a1eAZVlKqSEPkoQQjuMM3DVFUS7lt8Clk2XZdNYgaYhy\nLTTY4ZFiUasoLKyq9a/y1a6r9Vde8AhFFSW71ndVdfmQ6oq+IX9G/yFMj57NVqdW8Egx3R05\ncmTUqFG+239DbruD8DzZtJH8ddbr//jHbbfddoFX4ZFiMQqPFLsseKRYLMIYO4gubU38PSbn\nPS4nIaTAH/jjB//ZEBZp//6y48zLAQqle+Pi98bFL07PJIRwitJx645eLnfv+LjeVksPi9l+\nwbF3paWlmzZtCofDffv2zcjIiFyPIMq9/fbbvp69yF331i0PGkweevjll1++cLADAIhOCHYQ\nvbJs1q+mPHTy5MnCI0fLOHLE1SovFN7sD5x91wUhRKR0r8myt9a/tNZPCGEIaWfis83mbIs5\n28xnm82dzWZr/QPQ3n333ZkzZ7Y28Tae219ZPfmBB1544QVNxhquXLny/fffP3HiRPv27R9+\n+OG+ffs2fZ/Q4OjRo//85z/z8/OdTue4ceMeeOABnuebvk/SOfu0VdnZR95c2MTdApxTOBw+\nduxYeno6LnFChCDYQbRLS0vr0aNHKBRqGBR8VBA21Qa2BIKb/IHdwdA5b7yQCSkMC4Vh4Xtf\njbqGEtKW57PMvK26+vvNW++ffE9SdZW19GSaxTJjyX+ysrIefPDBJpb6xhtv/PnFF8mkm8k1\n127ev++/Eya89cYbN910UxN3C6r9+/ePHTu2dsBV5IaJxOdbu/D1VatWLVmypImJPCUlhRwp\nOm1VURGeXAeaq62tnT179uLFi0VRZFn2zjvvnDVrFm5NAM1hjJ1BGGaM3dlYlnW5XI2DXWN+\nWc4PhnadPLG7sHC71b7HHi9c1uwnskzKy+Iqylmv96GJE9NNfBrHpZv4tibecplx4dixY4MG\nDQr/bR7p269u1Q/fO19/ZefOnTab7Xyvwhi7S3fzzTf/nJhMpv2pbtnjIQ/c8+aLL95yyy1N\n2W1+fv4NN9wQmj6DjL6OEEKOFJInH//LY4+eMWXPGTDGLkbpOMbu0UcfXbplK/njE6RjJ1J4\nmCyYP7Fj1jvvvKPV/jHGDlQ4YwexzcYwg2zWQZmZtF070/rV5MefdtkdO5yunY6EPY74PXEJ\nJSbzhV7PMCQ5pSY5hRAyv6yi8VfcHJvCca05NoXnUzk2mePSeD6R4xI5Npljzx7At3HjxnBq\nm1OpjhBy3RjPy/N37tw5ePBgrfrbYkmStHHjRvL6olOrnE4yfOTPP//cxGDXs2fP+fPnP/PM\nM95FbxKrlRwruv+ee3JycppaceQFAgGe5zmupR/GQ6EQx3Esy158U/0UFBQs/fRT8sHHJDWV\nEEKyu5C/zv2/O27Lz8/v2TP27vqCaNbSjwhgGArHhUZcy3bM7vPtl/2KTj0nrZI37U5qvat7\n793JrQ+ExYKQcDQUupQ5jStFqVKU9pznqxZKE3kuheNasaybZdwcV+xOJCOvOW0jSgllDHna\no/nVXW894x9TURgtpqe+/fbbx4wZs2nTJr/f36dPn8zMzKbvM6KWLVv2wgsvHDhwwGQyXXfd\ndXPmzGnXrp3eRV1IOBxevXr1kSNHOnToMGLECK2Gl/3444+zZ8/et2+fyWS69tprZ8+eHbX/\nDgUFBSQxqS7VqVolkrS0gwcPItiBthDswFCkNun+yQ/zuWtMmzdSUSCEuIXwsONHhx0/qtjs\n4UFXC737j7/1tk1Dh5EJk069LBikiqJYrZf+RkFFORYWjoUbXYlLak3uf+i0jSgl//3yt3ab\n+2Chk2ESODaBZeMZJp5lnCzrZNl4hrYyC63MJlNYUNez2k0WfekkSZIkKcqHcjMMM3To0DVf\nfUGeeKpuVVUlWbN6+LyXNNm/2+2+/vrrNdlVpK1YseK+hx8mDz1M/vJCuKbmmw8W777llhUr\nVjgcDr1LO7f9+/ffe++9BZVVpG1bUlTUsZX7vffe69y5cxN3u27dut9MX9vwWwAAIABJREFU\nnkwmP0Cefi7o9y/78D+7fv3rlStXRue/g8vlIl4PCYdJww+aJJHKSrfbrWtdYEAYY2cQLXaM\n3fnQgJ/fmmfasoGePsBL4bjtgfBf9x/64fEZp0bjvfP/Bu3b/f4XXxaL4rGwUCSIxYJQIorF\nglAmSscF0d9cEwjb62Ofg6H14Y+p/z/jZNk4lolj6v5zskwcw3BNyIKHDh16/vnnV69eLYpi\n9+7dZ82aNXz4cK36ovkYu4KCgjFjxvh69CRDhxGPh3z1+fgBA959993LvXnCI0kKIYJC1I+1\nVpYFRSGEVEsSIUQipEaWCSGyQrz1Myl6JFkhdYdKr6wohJhMJlEUg6Lov/xDqI1SU6MTjZSQ\neOZUF2ws2xCxnWxd1OcJtdVv82ROzuG+/cm4G+o2kiTy7NNPTrhhypQphJAmfksQrcfYiaI4\nevToPR0yyR+fIDxPBIEsmN/1cMGKFSuaeBH5uuuu29FvALn3/rplWSa/++0zt97yxz/+8QKv\n0muMnSiKo0aN2tu5C/n9NMJxRJbJm69nbN64du1as/mCw0UuGcbYgQrBziAQ7M6J+mtNeRv4\nbXlUOPOpVqWS/Elqu49S2+XlbSavv/r5xx8PGzbsfPupkeXjglgqiiWCWCFJ5aJYKkrlolQh\nSWWiWCFKNfo9OsJEqY1hTJRaGWqm1MowJkpsDEsIYShx0LoAwVEax5521TIUCn399dd+l4tk\nZhGWIyeOswcPjB07Nikp6coqYQlxNBrnxHFcstWiPneLEupkL/uaaVhRGkdqidCTXu+WLVtK\nS0tZmy09M7NTp04SITWSTAgRiOKXFUJIQJZDikII8UmyRBRZUXyyQggJynKwJR3uGELi6z8O\nM6WWRtkxnmGYRuGPpcTBnPbBUUob7gthiNL4q+dkZqj1PNfES0tLv/vhBzJuPGn4BpBk8tkn\nt958c5s2bchZufYMF/jOeeqpp8Tb7ySN719e8ePAoP/C4yPj4uKoP8CQSH0nCArxK+c+Ghw7\nduzVV18tFwSSnELKy9yUPvbYY+3bt697oazUXsJh5IwfClUoFMrLy6s8ciT7wL6RI0feeuut\nmgxRIAh2sQnBziAQ7C6ABgKmvFx+2yZ6roeWHvHVBtpntB85Skprd1lXYxsLy0q1LC397vsX\nX1vYr2OGKzmlQJIPE2b0TTdZEpM8slwlSR5J8kiyeroIAEBjNT6y5APy/bfjBw++gjPZ54Rg\nF4sQ7AwCwe6iaCDA79nF78lnjh87zxZUbpUopbcX09pK6e2U+Ms7nJWXlw8cOHDhqKtv71o3\neGj+xq2v7T+0efPmM4aveSXZI0k+WfZIsp9haohS5g/4ZMUjSV5J8kiyV5Y9ktTw/7DcEn9I\nY4uVoWZ67nMksizLsqw+ORexHiKuqpI8dN9rs2fffvvtTd8Zgl0sws0T0FIoVmu438Bwv4FM\ndSW/exe3J5+prDh9C4UpL2PKy/jtm9XtZVcr2Z0ou92Kq5XsbiW73Ap73h+Z9evXJ3NsQ6oj\nhEwd2OeF9Rt37tw5YMCAxlvGs0x8/dWlS5nHLiDLf5o587/f/yC73YTjHMnJ9z/6WHKHDjWy\nXCPJXlmWFMUnyTIlPkmWFMUny+T0SzZBWQmd9Sec3+8PU0IaTwcjikwodAUzpvplOdzsfyKa\nGGqjDCGEJUS9yqxelSaEWCi1MAwhxMFQhlCW1l0jtlJqZhhCiJOhhBALw6izFcaxdePSnAxD\nCGEpddRfyUqov5rpYE9d3LIyTGJ8/EXnsSsrK3v88ce/++47YrWSQODGG2+cN2+ey+VqvE1Q\nUYL1H5OsEF99WyKKT5LP2EZWiE+Rg8HgvHnzDtfUkvYdSChEjh8fNW6sOpBAHf9HCAnLcsPg\nv1pZFur/NggTJdDo74SzL08Hg8GampowpdRstl7sBLZXli/wsZ/zoiFEnMtNxoxbsWKFJsEO\nYhGCHbQ4coI7NHREaOgI9uRxbnc+d3Af46k+ezMaCLCBY2zj03uUKlabYrMpVptssxObXbba\nFJuNWCwKy7mrKoakpTbeA88wFpYLBoNNLHjurFmffPIpmTWH9OhJwmHfe2+/eePELVu2NPHp\nCN9///3dUx4mr/8vad+BEEL8teQPj/1u3NhZs2Y1ZbeSJE2aNCnPYiNPPkUc8aSqgiz457CU\nlAULFjTerEaWz35kSMK5piI7Y3zYObeJQoqiPPLII6s8PvLRpySlNTle/NXfXwxPnfr+++83\n3sxCqaVRj9zkEnoX77j1b3OXLVu2bdu2+Pj4Mbc80r17d01qnj9//t/mzSd9+pI4O9m+bUjX\nrkuXLrVYLE3cbXV19TPPPPPpp58qDENl+dZbb33xxRdt8c7zjUX7/+zdZ3wUVdcA8HNndma2\npidASEgChFCkhY70LlUQqQqIIOCrgAiIoKIUCyAWRBREEVSKUnwULEDoEOmEDgESQk/fPvW+\nHyYJAULaLiS73P8Hf7vD3bt3MOye3HIOAEgYCt9wph55URRl9+7dFy5c0Ol0TZs2jYmJebCl\nWVaUfDvqfHx8zGZzIT0fO3Zs7oIFMPFNCA4BAFAU+H5pq6CgiRMnFnmnhfCl6RKtjPrQRW9K\n1VMUgyA2NtYy/V2oky9nCsuKdmvJx0h4CbIU6yXIUqwrkMWiuZZMX0+hryVTaan3J0tzEUVh\ndVaM4zAA5rRAUaDVYorCDEtrtUirFWgGdHpFqwWdHmu1WKfHRhPOPTMYGhoqzngP2ra/2+fr\n4/pGV1+6dGlB71cC77zzzrc//ADNWoBWC4cPNasRvX79ehfP6MXHx/caOBB+3QR59TYyMmBA\n3727dhX4veuhiqw8cezYsS69esG6DZC3pp+eDoOe2x0XV6tWrcc0ypLYt2/fswMHwsIvoXYd\nAACrFSaNf6V9u7lz57ql/+zs7JSUlPDw8LJd2ivyVOyUKVNWpGXAm1PvXko4oX97SnJy8iMf\nXKkMHDgwTme4mwaI5+GVkbNHj3JLkm2yFOuJyIwdQQA2mcRaT4m1ngJ1ou76VerWDSo9jcpM\npzIykCy51LuiIKcDAMDpeNiv7AVGUthgxH7+Tr3h7WaNrgT4Xsm8c0lvusnpAABqxJw+leDS\nqAAAYM6cOX369ImLi3M4HI0GD+zRo4frh+lSUlKgYiXIX0UtIAD8A65du+ZNgV2RkpOToWIl\nyL9TMzAQgoKTk5PLZ2C3adMm6Ng5J6oDAKMRXh69fv7H7grsfH19PSJEcDgcoLu3BqDBwPO8\nLMvls7jF3LlzO3bsaBdFaNMWHA5Y/1tdX5+RI0eW9biIMkMCO4K4B9bppOoxUD03BMEYmbOp\nzHQqM4PKzEB2G2W3gc1GOezIYYdHuYUI2azIZtUDTG/ZBK5dhGsXASCLYc4ZfM/oaXOtaDrp\nkhIUgo0upWNt0qRJkyZN3DRkAIBKlSrB7dvA85A382fOhqxMNbfFk6NChQqQmnrP34PdDhnp\nLi6gPzrZ2dlw7/4/8A8ofNXSK9WvX3/tkm9g1Ct3Mwnv2lG3bt3yGdUBQPXq1bdv3/7JJ5+c\nWL5Ur9e379ThjTfeKOf5xolHiizFegmyFFs2HHbKYUeiCDyPZAkJAggCSCISBCTLIImAAfEO\nAABBBEVGoogUGXhencZDigKiiHinK4u/mNMqfv6Kf4Di54/9AxQ/f8UvoPjR3l9//RUXF+d0\nOmNjY4cOHer694Eoil27dj0ZUgEmTQW9Hixm+HBOa4Zev369W/IvlBNFLsWKoti5c+fTlcNh\n0hTgOHA6Yd5HsdmZf/31l7tyjLnXp59++vHv/4OvvrlbcO+Xn546sHfHjh1lOi43K3Ipluf5\nLl26nGFYGDwUDEbYt5fb+NvGjRvd+/vPo0ASFBMqEth5CRLYeSj1VKw9PQ05HWB3ULwDHHbK\n6UTmbCo7C2VlUNlZqOSVG7BGg338sI+vYvLBPj6yjx/28cEmH2zywRomr9m4ceO2/fFH/1rR\nRob5I/EyWzF08+bNrldkunLlyujRo0+cOw8VKsCtmy0aNVq6dGm5nakqnSIDOwBITEwcOXLk\n2ZQUqBwG167VrRq1YsWKclvMNCsrq127dtdr1YGhL4LeAHt3w9Il61atat++fdEv9hzFqTyR\nnp7+0Ucf/fvvv2azuUGDBtOnT2/atOnjGZ4rSGBHqEhg5yVIYOehipPuBBz2zEuJf678EdJS\nawUF1K9UIQArkFvtqqQwx2GjCRtMyZmZf+/cPaROjJ+WAwBRVp7ftKVi67bz57uh+qqiKKdP\nnz5//nzt2rVr1arlTXN1quIEdgAgSVJ8fHxKSkpERESzZs3K7XKeKjExcfr06Xv27JEkqWrV\nqu+++27Pnj3LelBuVlYlxR4Djw7sBg0a9Oeff1qt5DCvG5DAzkuQwM5DFSuwe5AsU5npdHoa\nlZ6KMtKpzAwqKzPniIZrREXR+PoqOgM25OZzMRiw3oj1eqw3KHoDGAyFJPNTWSyWOXPm/Pzz\nzzzP63S60aNHT5061V0FMcuJYgZ2nkir1QqCgDH2ym8HEtiVSDkM7I4fP96wYUOv/OF0F3J4\ngiA8EE0rQSFKUEj+a8jhoLIyqKxMKisDZWVRVjMyZ6Ps7BKd6mUoCiwWutAYGrMsNpjUUA8b\njNhgUAxGbDAqegM2msBgnDBhQsrB+C3P9awZ6J9wJ23iz6ssFsu8efNKebPE48VxnNFoTE9P\nL7opQTx2e/bsKeshlHcksCMIL4F1OllXWa5U+b7ryG6jzNnIbKasZmS1UlYLslmQ1SKkp2lL\n9VsvEgQkpEPmQ7/4l0ZVMsYMYCgKMLSPCP93UL/x/+5IO340uGo1MBixC8uRoiiuX78+ISHB\nx8ena9euDRs2LHVXBEGUFYzx7Nmzly1blpqaGh0dPXPmzPsarFmzZuHChadOndJoNDVq1Jg8\nefKgQYMAoFu3bv/88w8AIIQaNWp0+PDhQho/sUhgRxBeDusNst4AFe/PNmKz2bp37hzLaUY3\neMrEsqfT0i9lW14a8HwgxyKbFTnsyGZDfGnKZvhrc1ddEQBABYN+bd8esPXPnPFoddhgwHqD\nYvTBej3oDYrekDP/p9NhvQFzBZc6yMrK6t27t/3G9fYRYZecfK/PP5/w5ptTpkwpxQgJgihD\n8+fPnzlz5tChQ0eMGJGRkfHBBx/k39Wwdu3awYMH9+3bVw34vvrqq8GDB5tMph49eixatGjK\nlCm///77oUOHDAZD4Y3L6u7KHAnsCOIJZTAY1m3c+OGHHw7avsNutzdq1GjGe7P09erl36mH\nZBnsdsphQzZrTvY+m5Wy28FuQzYr5bAhu72kxziQ04GcDkhPe+jEHU1jrQ7r9Virwzod1uqw\n3oC1un9+W98vwPRW9xdZmgKA47dT2y9c2Lp16+bNm5fyr4AgiMcOY/zFF1889dRTP/30k3ql\ndevWERERebmWLl++3KFDhzVr1qhXWrduHRgYuHr16h49ekRHRwcFBQFAXgHuQhqXwb2VD+Tw\nhJcghyc8VCkPT5QrDjtlsyK7DVmtlN0mZWZs27ixfoBvpK/Po35njLEdQOfnj7U64DjMabH6\nX5YFlsWcDjgOsxxm2dwHHLBsgWvBSUlJu3fvdjgcsbGxxclY5sWHJ3x9fRmGSU9P98pvB3J4\nokQexeGJq1evRkREjB8//osvvsi72LJly4SEhIcdnggPD4+Kitq9ezcAjBo1avny5YX8cOZv\n/GQiM3YEQbhGp1fuLcFk9A1qNXx4EFZiAvwvZ2cFBIV8MXdORIAfZbcjq4Wy25DNhmwWZLMh\nh92V5MwIIQMAZGdBdlYJXkbTmGExx2GWRSyHGSbx+o2TJ06E0hpJUfb/9UdS1aoDXxxG6/WY\nZbGGAZbFHIc1DDDMw5aJC4QxXrt27Q8//KCmOxk9enTfvn3dlfnFbDafP3/eaDRGR0drNG77\nJL906dKhQ4dsNltMTEyrVq3c1S1B5Ll16xYABAcH578YGhqakJBTJtFsNi9YsGDjxo1Xr15V\nf+mVZTkiIqLA3krU+AlBAjuCINysadOm8fHxW7duvXXrVo/Klbt166bT6Qo+mqsoyGGnHHaw\n2ymbFTkc4LBRdjs47JRDzdXsAIcdSa6V672PLCPZkT87TAxATO1769hu2/KwV2OGBYYBjmM5\nLaPRYIbBLAcchxkWMwywnBoyAsutXr9h42+/jqsVE1kz6uSd1LcnTLh27dr48eNdv4MFCxZ8\n/vnnGkXhZTk8IuKLL75o0aKF690uWbJkzpw5scGBPiz70Y2bjVu1XrlyJSlORbhXgZNtcr4d\nHb169dq3b99bb73VrVs3Pz8/hFDXrl0f1luJGj8hSGBHEIT7+fr6vvjiiwaDwWKx8IVUzqAo\nbDDKBiMAFLJTD0kSOOyH9+yeP/O90Q3qNqlUUZDl/27exFpdv2e605KIeCfwTsTziOddLNFW\nJCQKIApgtxVZF2wkBSMHPKs+bh0W+mps/czs27qvF1JaLWZY0Goxy4KGxYwGa3WgYXJiRJbB\nNINZFrMs0jCY4zDDAE3nTRauWLFi+aIvf3+2e7uIMKckz48/PGzYsJ07d1aufP+B6BI5dOjQ\nh7M++KN/77ZVwgAg1e7otmbjxx9//N5777nSLUHcR52rU+ft8iQlJakPEhMTd+/ePXr06Llz\n56pXJEnKyMiIiop6sKsSNX5ykMCOIIjyDms0YPJp1L3nyww358MPz/7xj16v79q168z3ZgoF\nVSpDvBMEAQkC8DwSeCrnKY9EEQQe8TwSBBAFJArgdN5MTvIB7PNY8if7azmwWcFWyvT6mNYA\nwzyXkTF89DAfjgUArYZ+t1Wz1lUqm3/6vmqTpqDRAMthisKcFtM0YhjMsJiiQKsFmsYshzUa\n9QE8UK/2t99+e75mDTWqA4BgvW5WmxZj16xxS2B35MiRH374Qd1c9dJLL8XGxrreJ+GhIiMj\ng4KC/v77b0VR1LrJFy5cOHHihF6vBwB132pYWFhe+yVLljidzrwpPXUzgyRJGo2myMZPJhLY\nEQThMTp37ty5c2dBEApfH8ScFjht3qxd4Z/xX82de3zjb38P7Jt3ZfmJ09stjmVLvkaCQAk8\nFgQkiYjnQRSQKKrhIIOxwjux04kEHgkCqA0eMSRLIEuhet1919tVCQPAcOS/EvRFUZjlgKax\nRqM+GKen2eaN8jeJrVhhZHQUc/ww0DSwHNZoMK3BLIdoCmt1GCFgWWCYIiuRrF279s0JE154\nqtbzwQGnz57q3b37p198MXDgwBKM9uEyMjLOnj1rNBpr1apFVo09AkVR48aNmz179vPPPz90\n6NA7d+58/PHHsbGx586dA4Dq1auHh4cvXbq0QYMGgYGBGzduPHLkSLt27Y4cObJjx46mTZuG\nhoYCwIcfflinTp3evXsX3lhNifKkIadivQQ5FeuhvOFU7EPodLqil2LLgdu3b7dt23ZQZNjk\nZo0MLPO/C5cmbN21dMWKLl26FPKqAk/F3g3+BN6aljZlwvixdWu2CK2k/unZ9PSE9Ow+3Z9h\nJFGdMgRByHmJh08wYIYFmsYcB4jCHIdoCrMcRhRmWVFWfv19U6vQitX8/dTGJ+6k/XjmwvSZ\nM42+vmqwCBoNqMvNDJsTLwLC2qLPqXzyySdffvmlkabsohhUsdLChQvbt29f+EuKeSo2OTl5\n586dFoulQYMG7jpEoijKzz//vGzZsuTk5CpVqrz00kvDhw93Y/lgTzkVCwCyLL/zzjsrVqzI\nyMiIiYmZNWvW9u3bly5dqn5WHD58ePz48SdOnDCZTM8+++y8efN279790ksvybIcHx+v1+t7\n9+596tSpqlWrnjt3rvDGNWrUcPvgyz8S2HkJEth5KBLYlQcnTpyYPHny8ePHASAkJGTmzJkD\nBgwo/CXFSXeycePG11577dlqkbWCAk7eSfvzytXly5d369atgKaKggQe1KlBUQTeiSQZiQII\nPEgSEgQQeKQoiHciSTp/5kxWytXYCiE6RgMAFkGQFOxjMtLemHsFc1pACBgGUxRoNFjDAEKg\n1QJA0s1bZ0+fbhZaIVivxxgO37p94NadgS8O8wsIUGNEAFBb5oSPAKDT+fj4ZNvswDAAgNX1\nd1qDGSb/m3733Xfvv/9+vQB/fy33342bsS2fXrVqlevFjufNm/fj14vfadm0XkjQ2fSM2XsP\n9hsx4sGiC6WGMWYYRnLrSaPHViuWcCMS2HkJEth5KBLYlR8ZGRlWqzU8PLw4GUmKmcfu7Nmz\nK1euVNOdjBgxIjo62vVxyrI8adKkX9esqe7vZxYEu4b59NNPe/XqBeopE0kEQVCjQCxJSBSR\nJCJZBt4JsowEASQJyRLieVBk4HkkSUiWgOdBliWrxZqVRSmKD8fSbkrL4kEwywJFy7J8LS21\ngt6gxs2Sohy/neoTElKtenWF5QAAKBpYBgCwhgE10Yy6kVGNFBEFkBNQAoDCcWoBlnSbbcjQ\noUu6tn8qKFD9o9Np6V1Xb/h327YqUVE5YWhp/fHHHzNnzkxJSUEItWjR4uOPP65Vq5YrHeYh\ngZ0nIoGdlyCBnYcigZ2HKvMExYmJiWrN3MaNG/v5+bm3c57ntSwLvBMkCcky4nmQJeB5pMhI\nFEEUQFaQ04EwzplTlEQQRZBlxPMIMDidgDFyOgBj7HTarRYT2f1WPFirzanER9M4Nz1hzrQl\ngLrGnXOR1qgNUlNT9+7bVzc4MNzH55bNtvDg0c230nbu3KlWaHARCew8EQnsvAQJ7DwUCew8\nVJkHdo+O2ytPfPPNN/Nnzx7fpEGjSiGnU9PXnrk49rXXBj/XD8syEgQEGPE8YAw8D4CR0wkA\nSOABYySKIEtIkrEkIqwgQQCAnKhRFK9fTQ7iOHVejciDATqvXt/4uQEzZsxwvTcS2Hki8k+C\nIAiCeITGjh0bFRW1fPny1cfOVqlS5a3PPu/atavrp0VWL1nyzbx5vz/fq25wEAb44cTp9w4c\n3vy/36tVraqGgIjnASsgyyAIAEAJPGBs0GltmVmg5sTBGCkKiAIAqEEkYLhwMuFOclK7KmF5\nS9GpdkeaIMZEVAEAhLHaG0iim/NmuwkCaB8RfuTChbIeCFFmSGBHEARBPFpdu3Z1ez2AMWPG\nXL169ekffgj3MZp5QdbqPv3ii6p1nsIA+N4adyo1lKQCAsRCT8Uam7Ts2a5dt+CAaS0a+2m1\nmxMvT9i664tvvgnr1avA9kgUQJYBAAmCmhn7blETR84DNaY8derUymXLavr5hvuYMpyOK2Zr\nv379alavBmqAiDHinbl9SljOuUgJuRPeogi5oSQSBFByYuPM27dNDMPSdxMT3rLa/KpUK+zv\njvBqZCnWS5ClWA9FlmI9FFmKLSdSUlLUVBexsbEmk6nI9sVJd3L27NmpU6fGx8cDQHBw8Dvv\nvDNkyBB3jXbVqlVqupMhQ4a4pUDC3Llz/1m1cuvgfkF6HQAcvHGr29qNP61d17p1a9c7J0ux\nnqgcBXZWq3Xp0qUJCQmiKMbExIwdOzYkJKSYbYrz2vxIYOdBSGDnoUhg56E8K7ArqWLmsQOA\n7Oxsi8WSv6pB+SQIwgsvvHBs//6nw0Ntorj/5p3Jkye/8cYbbumcBHaeqBwFdnPmzLFarWPG\njOE47pdffklKSvryyy+pe+vePKxNcV6bHwnsPAgJ7DwUCew8FAnsPNHOnTvPnz/PcVzz5s1r\n1qzprm5JYOeJiixj/ZikpaUdOnTolVdeiYqKCg0NHTt27PXr10+ePFmcNsV5LUEQBEF4q3bt\n2s2YMWPChAlujOoID1VeAruLFy8yDJO34cBoNIaFhZ0/f744bYrzWoIgCIIgCK9XXk7Fms1m\nk8mUP+G7r6/vfTXvHtbG19e38NcKgvDyyy/nPe3Vq1e/fv0eyW2UKYqi3J6ntDxQ/8+yLOut\nd4cQYu6taOQd1L0Qer1ep7u/aL0XoGlao9F45WKlWr3UWxfgvPVzUqXRaNx7d4qiuLE31SPa\nCuWWhMzeobwEdpD7/V26NkW+9vr163mPs7Oz3Vh3ufxACHnlfam8++68+NYK2erq0RBCXnxr\n4NU/k158a27/nPTKX128XnkJ7Pz8/MxmM8Y4L0TLzs729/cvTpsiX8uybFxcXP6uyOEJD0IO\nT3go9fCE1Wolhyc8i3p4IiMjwyu/1L318AQABAUFiaJ430qXi8jhCU9UXn7jjI6OFkXx0qVL\n6lOz2ZySknJfGeOHtSnOawmCIAiCILxeeQnsAgICWrRosXjx4itXrly/fv2zzz6rVq1a7dq1\nAWDr1q1//PFHIW0KeS1BEARBEMSToxzlsbPb7UuXLj127Jgsy3Xq1Bk7dqy6nDp//nyz2Tx7\n9uxC2jzs+sOQpVgPQpZiPRTJY+ehSB47D+UpS7Hk8MSjVo4Cu8eJBHYehAR2HooEdh6KBHYe\nigR2j6JbT1RelmIJgiAIgiAIF5HAjiAIgiAI4i5JkhBC27ZtK3WDMkQCO4IgCIIgvFlcXNzh\nw4eL356m6R07djRq1KjUDcpQecljRxAEQRAEAQBms3nTpk3Jycnh4eG9e/cOCAhwscOFCxf2\n7NmzcePGxWyPEGrXrp0rDcrQE3p4giAIgiCIx6/IwxMnTpwYPHhwMJbrhQSfS89IFqQff/yx\nRYsWhb+qkMMTHTp02LlzJ8uyderUOXjwoEajWbZs2dy5c9u1a/fDDz+cOnVq0qRJhw8fVhSl\nWbNmixcvrl69uiRJDMNs3bq1Q4cONE3/8ssvK1asSElJsdlss2bNGj58eJEN1BsZNmzYhQsX\nateuvWDBgg4dOpw4caJevXql+EsrETJjRxAEQRDE48btiYMHppZkWT7700+rOrZqWyVMrSV1\n4PrNE99+9bQ9u8Ca2sLT7XBRVdTi4uIiIyOnTZs2duxYAKBp+ttvv12/fn10dDQA9O/fv1mz\nZikpKbIsjxw5cvjw4fv27ct7LUVRNE1/+umnW7ZsCQkJWb58+avtIzldAAAgAElEQVSvvtq/\nf3+O4wpvoNPpevXq1aZNmz179iQlJY0cORIeV4lFEtgRBEEQBPG4sQf3g6I8eH10zer5n7ao\nXKlF5Upw9GCBnQjNWkHJy+M+++yzsbGx6uMDBw5wHKfX6wFgyJAhgwYNenAl88UXXwwJCQGA\njh072u32pKSkmJiYwhtkZ2enpKTMnj3bx8enXr16r7766ssvv1zScZYOCewIgiAIgniCVK9+\nN3Y8duzYnDlzzpw5AwA8z4uiKMvyfe2rVKmiPtBqtQDgcDiKbHD16lWapiMjI9Xrj/OYBTkV\nSxAEQRDEEyRvITUxMbF79+6dO3dOSkq6devWihUrCmyPECq8wwcbYIw1Gk3edbrk04qlRmbs\nCIIgCIJ43Kz/92aB12fNmrX3j99ntW5ZNyTwfHrWzD0HarZuM3/+/AIbY5Z1ZQyHDx+WJGny\n5MnqBr74+HhXesuvUqVKPM/fuHEjNDQUAI4cOeKunotEAjuCIAiCIB43rNUVeP2t9z9gfHyH\nfvdddna20WgcMWLE1KlTH9a4mPR6fWJiYlZWlp+fX/7rkZGRsizHx8c3bdp0w4YN+/fvB4C8\naMwVLVu2DAoKmjt37oIFC65cufLtt9+62GHxkaVYgiAIgiDKC5Zlp02blpiYeO7cucuXL8+c\nOVOncymqA4AxY8Z8/fXXdevWve968+bNp0yZ0qdPn9DQ0O3bt2/atKlRo0b169dPSkpy8R1Z\nlv3tt992794dHBw8ZsyY2bNnw+M6FUvy2BEEQRAE8ZgUmceudArJY1dWJElSFIVlWQA4cOBA\ny5Yts7OzfXx8HvX7PqFLsRaLpayH4H4cx/E8X9ajcD+EkFarlWVZEISyHov70TRNUZQoimU9\nEPfTaDQMwwiC8OARMy/AMIwsy0pByRo8HcuyNE0/eO7PO2i1WqfTWdajeCR0Op2iKO79FqBp\nWs0DQpQUxrhWrVqtWrX67LPPHA7HBx980KZNm8cQ1cETG9h5XwCEENLr9d53XwBA07TRaJRl\n2SvvjuM4hJBX3hpFURqNxuFweOXdsSwrSZJXRuRarVaj0QiC4JXrOQaDwSt/IAHAZDKJouje\nuyswJzBRHAih9evXv/HGG+Hh4Vqttk2bNsuWLXs8b/2EBnYEQRAEQRCPTr169bZv3/7435cc\nniAIgiAIgvASJLAjCIIgCILwEiSwIwiCIAiC8BKescfu+vXrn332WWJi4qZNmwpsYLValy5d\nmpCQIIpiTEzM2LFj1XK8BEEQBEEQTw4PmLHbs2fP9OnTw8LCCmnz+eef37lzZ+bMmfPnz9fr\n9bNmzfLKNAQEQRAEQRCF8IDAThTFBQsWNG/e/GEN0tLSDh069Morr0RFRYWGho4dO/b69esn\nT558nIMkCIIgCIIocx6wFNuhQwcAuHTp0sMaXLx4kWGYqKgo9anRaAwLCzt//nz9+vXVKxjj\nGzdu5LU3mUw0TT/KIZcBhBAAeN99QW4NFoSQt96dt96a+jNJUZS33p233pqKpmmvzGMHXvo5\nqXL7h4n6r5jwLB4Q2BXJbDabTKb8P3++vr7Z2dl5TwVB6NOnT97TESNGvPbaa491iI+Lv79/\nWQ/hUWFZVi3M4pW0Wm1ZD+FRMRgMBoOhrEfxSHjxDyQA3Fcr3Zt48eekRqNx791JkuTG3ojH\nwxsCOyjqtwqKojp16pT3tHr16t6XeRwhpJZvKuuBuB9CiGVZRVG8Mss/TdMIIa/89KRpWqPR\niKLolRtevbikGMMwFEV534ekimVZr/ycBACO49z+OYkx1mi8JE54cnjD/zA/Pz+z2Ywxzgvv\nsrOz8//WwjDMxx9/nP8lj6gIcRlCCPn5+XllDVyaplmWFUXRK++O4ziNRmOz2cp6IO6n0+k0\nGo3T6fTKEMFkMjmdTq/8ZcPX15eiKKvV6pVLsQEBAV75SQIAHMfJsuzeu2MYxovXE7yVBxye\nKFJ0dLQoinmb8Mxmc0pKSq1atcp2VARBEARBEI+ZBwR2mZmZaWlp6m8haWlpaWlpTqcTALZu\n3frHH38AQEBAQIsWLRYvXnzlyhU14121atVq165dxuMmCIIgiEfv2LFj/fv39/Pzi4iImDBh\nwp07d8p6RERZ8oCl2ClTpuT9mI4cORIARo0a1bt37+PHj5vN5l69egHA+PHjly5d+v7778uy\nXKdOnXfeeYec5SEIgiBKTRAEh8Ph6+tb1gMpwqlTp3r37j36qZrvdu9ol6Qv9u959tlnt23b\nptfry3poRNlAXrmLokjeuscuMzOzrAfifjRN+/v78zzvlTtjvHuPncFgsFgsZI+dZ/H19WUY\nJj093Su/HQICAjIyMgpvc+XKlbfffnvXrl2SJEVGRr777ru9e/d21wAEQbh+/XrlypXddar6\nhf7PNRDsH7RuoT4VFeXplWt7jR4zceJE1ztnGMbtoe0j+v4NCgp6FN16Ig+YsSMIgiCIB509\ne/aTTz45fvy40Wjs1KnTpEmTfHx8XOzTbDb379+/mZ478OLz/lrt5sQrr48do9PpOnfu7Eq3\nSBDsVsuiBQs2bdyopyiW0fTt/sywF140amjAGHgnYEC8AzAgngfAyOkEwOB0AgDF8zmPMUa8\nEzCmBAHnPv69Wf38b8RQVK/qVU+cOOHS38ITTJIkhmH++uuvTp06MQyzdevW/Fk1ACApKSkq\nKurkyZNPPfVUMXt7sJNHigR2BEEQhOc5e/Zsly5dBteo9mWzhlZR/GrDb8/t27d582ZXZsKQ\nLK/54fsaNKzo1Y1GAABjGtYN1ut2fPt19yqVsSwhUUKyBKKIZAmknAdIkrAkIUlCsgSCALKM\nRBFkCYkiKAoSeFAUADACzPbXzR455O77bd5Q+qE+/I/MgqDT6UrdM6GiaXrHjh15lQ5KJC4u\nzsfHp3Hjxq50UmoksCMIgiA8h6IggccYf/nB+1MaNZjxdBP18rPR1abv3Bf/3bcdWz0NGHLC\nKYFHGCNBAEUGUQRZlgD0vDMn/MoJ0WSQJJBEJEkA8CbAm8/3yf+G/WKq9wOA//32+O+1FK6a\nLT+fOrfg1fFlPRCXnDlzZvny5VevXg0LCxs2bFjDhg0f/xgQQu3atSvdaxcuXNizZ8/GjRu7\n0kmpkcCOIAgCACAzM9Nut1euXLmsB1I0QRDWrVuXkJBgMpk6d+5cSCntMpO7UIhyZrAELElI\nFJEiI1HMmd+SRJAkkO7OgSFJxpKYM/UlSWoohkQBKQqIIigyypdb+KdGdfK/IaehP+3UBmyZ\n8M+fhY0LwDMKilEUZjlAgFku5zFFAcdhQJjjACHgOEAU5jheEL7/+RfJYgkzGXelXFt/7mL3\nfs+pxwo91J9//jlmzBihbXuoXReSrvzUo8eihQsHDRpU6g6bN2/eqFGjxYsXq0937tzZsWPH\nq1evZmZmTpo06fDhw4qiNGvWbPHixdWrV897Vf5V1OPHj48ZM+bUqVPVqlV7++2389qcOnXq\nwR46dOiwc+fObdu2LVu27L///svr5Pbt2xMnTty1a1dWVlbDhg3nzZv39NNPK4pC0/Qvv/yy\nYsWKlJQUm802a9as4cOHl/pmgQR2BEEQJ0+enDx58tGjRwGgYsWKM2fO7N+/f1kP6qGysrJ6\n9uwp3r7VKarKbSc/4OuvXx47dubMmS51qihI4K1m8w/ffnv0v3iZ5+vFxAweOCAiJATLMhLF\nnCBM4JGCEe8AWQFRUCOwnEBNEECRkcADVveHPSkwywJFA8tipIZcFHAcUJTCquGXFhBgre7m\nzVs//vLL9JZNNFROljFFUQb//vfEt9+u37SpGqJhgLxwrURjeKFNx59//nnHmTPasKglb81w\ncTvgYzMgKUV5YElZluX4bJv08zrIOwwxeuzEpCu/XLhc4CL7qiqVdVQRSTCGDBny8ccfL1q0\nSK08vm7duvbt21euXLljx47NmjVLSUmRZXnkyJHDhw/ft2/fgy9XFKVv375t2rSJi4tLT0/P\nH3X179//wR7i4uIiIyOnTZs2duzY/FWF+vTp4+fnp24Jfffdd7t3737p0qWgoCCapj/99NMt\nW7aEhIQsX7781Vdf7d+/vyuVGElgRxDEE+3OnTsDBgzoXyV03biXjCzz+4VLb4x/3dfX1y3f\njlardcuWLSkpKZGRkd27dy/1zqecuEpRkCh+Nev91jrms1EvMBQFAFctlg92bL34VK3a1avn\nbroHdQkyZyuYrIAoAMaUwAPO2Y+PnA4AuC8OMwK8rQVomzv/F7/b1fsvN7BWC4Awy9IajaTR\nAKKA5YCmMMtiRAHDAk1hhgWaBobZeyB+y9atET4mmqJO3kk1hYa9/c47rNGINBrMMEBrMMMA\nldu+eHwkaf2iJanbdn3Wqa2GomSMp+/af0KUo7t0k0sYxj2IZdmXXnopKChIFMX8ddLLuT02\nh1Tgyev6De556ucnN2h4QBBBKOAQuoRxoRsOAQAGDhw4adKkffv2tW7dWpbl9evXf/LJJwBw\n4MABjuPUvDBDhgwZNGhQgSfB4+Pjk5KStm/frla+njBhws6dO9U/KrCHArOtHTt27L///jtz\n5kxISAgAzJkz59tvv/3rr79efPFFAHjxxRfV6x07drTb7UlJSXXq1Hmwk2IigR1BEE+0ZcuW\n1dFrP+vUVv0wHl63dprd+dFHH7l6ClISE44enTZxYpAi1Qj032NzHPjhuylvvBEWFIRkGUQB\nBB4pCuKdBcx+ibkb8BVFfZy/508qBUCl9nlPq5hMy3t0gcvn4PI5VwZc5u6Z+lIfMwxoNFjD\nYJpGGgZraExrgGEwTYOGsTocC79arJfFWoEBNkHcfCnpqSZNJr39NiCEOS0AqPNeWHtPMB0Q\nEGAuKt1JkxZtTN17b9u2zWKxdGjYsGvXrgghF6sCazSaZcuWDR069J+lK+sEB55Lz+T1hpUr\nV3IuR3VEkSpUqNChQ4fffvutdevWO3futFgszz33HAAcO3Zszpw5Z86cAQCe50VRlO/9t6ZK\nSUlBCEVERKhPo6Oj8/6owB4KrK576dIliqJq1qypPtXpdBEREUlJSerTKlWqqA/UAm4Oh8OV\n+yWBHUEQT7TExMTW4aH5f8VuHxm26twOKi0VyRIIPEgyJfA528IEHskyCDwgYHiettuRLCNJ\nRGoDnkeSBLKkzoG1BNjd95l73uxo/GO9t0eEpjHDAqPBFJ2z90urBUQpHAcUBSwLFI1ZVg2/\nLl65smrlyo/bt8r7G8YAPdZtmjxrTrOWLTHLAkI5nZQQC/Ba4+bffffdT8eOGU0BPaYM7NOn\nj+ym1PQ1a9bM+w52l1q1au3fv//ff/+9fPlyv8jILl26POE5hKswjAz3z5ApinLt2jXsHwB5\nIa8oQHp65dDQAgOmopZhcwwZMuTdd9/9/PPP165d26dPH5PJlJiY2L1795kzZ27ZskWr1f7+\n++/PPvtsga9VM3HmzcPlra4Wv4cCKYoi5O4ZdW9JBRLYEQThfhcvXly3bt3NmzfDwsKGDh0a\nHh7urp4PHz6ckJDg5+f39NNPV6hQ4b4/RU4HCAKSRCSK4HAg9agjzyOBR5IEooAEASQRBAEJ\nApIl4PlFNaowQsX8ncRWCDk+fCD8sKTwkdCesA0/Z7mQprFGo64hIprGLJuzB1+Nw2gNZpgt\n/25lUm/3qB6V99qEO2kz9h9au2GDuv6osCyiKHUyrPjOZJg3Xbj0SftWeVcQwOXM7FQMiq+f\ni3dnNBrdkob3sdFqtW7Mdezp/qsRVeD1ZXt2TH95LgwcBNVrQHISrP552v+9+mandq68V79+\n/caNG3fgwIENGzasXLkSAA4fPixJ0uTJkxmGAYD4+If+0hUWFoYxTk5OjoqKAoCzZ8+q14vf\nAwBER0crinLmzBl1jdVmsyUnJ+ef/HMjEtgRBOFm//vf/8aNG/dMRHjtoIBjh/5ruXjxqlWr\nSnHmHzmdiHcipwOcTop3Slbrrz+tSk1OqubvxyDq3NbN+tq1Kvj6IoFHggCCgESh6E4fUElD\ng6bMkn5hmoYCZr9Q7tZ7LmdhESFgOYwQMMyl5KuLF3/VMaJKbKWQbCf/27mLVxC9aPFiVm8A\nhsEIAcvCA0uQRbJmWt96/fVDLw0KNRoBQMH4g73xhqfqyxUq3R1tyW+wXr1618yWQzdvNamU\nEz0funk7xWp7zJm9CA8yevTosLCw77777vLWf6pUqfLSwk/79OlT9MsK5ePj06NHj/fee4+i\nqC5dugBAZGSkLMvx8fFNmzbdsGHD/v37AeDGjRuhoaH3vbZFixaBgYEffPDBZ599lpqamne6\n9mE9VKlSRa/XJyYmZmVlGY1GtXH9+vVbtmw5ZcqUVatWcRz31ltvmUymEs3wFR8J7AiCcKeM\njIw33njjm85th9TJWcladPj4//3f/x09ejRvOxFy2JHNhhx2ym4Dh51yOMBhp5y5/7XbEe9E\nTic8sJH5pUpBUClf4SCnHZz2x3JbBcCcFmgaMwxmWaA1oNViWoM1GuC0WKNJy85eumLFxCax\nftqcu75hsQ36fct3P/5YOaqquoespIcfVeGxTbsHhnz00UcJf283GAxdu3Z9/513NBUquLgJ\nrE+fPn/++WfTFWtefKqWiWX/TLx8m2a2fviha71C5cqVJ06a9Nw3S95p2fSp4MCTqelz9x+c\nOHGiR6SVIcrKM88888wzzxTdriSGDh3ar1+/119/XV3Sbd68+ZQpU/r06YMQ6tu376ZNmzp3\n7ly/fv1Dhw7d90KdTrd58+ZXX301NDQ0Ojp63rx5zzzzjKIoD+vh2LFjY8aMefvtt9euXXvl\nypW8flavXj1+/PjatWsritK0adM9e/a4XiilQKRWrJcgtWI9lPfVit2yZcuCyW8eemkwAKjH\n1RSA9WcvdGzZwpemKYcdOexqIv6yoU6AMRpMazCnBY0GGEZhOavTeSM11SZKwZUqhUZVVffs\nA8sCTSsspzbDLIspGjgOGMbo519krdjRo0cnHdj3Wae2TwUHHr+dOnHrrnqdu3z55ZfuuhVZ\nlulin8osDozxpk2bdu7cabPZ6tSpM2rUKJPJ5Hq3iqL8/PPP33//fVJSUmRk5MsvvzxkyBCq\n5Jvq3KI4tWI91KM4FUtqxXoiEth5CRLYeSjPCuyQLOdNrSGHAzkclMMOdnXuzQ42C+VwYJuV\nelyfKjesNhvDRtWsiVkOOC1mWcyywLCY0wLLYobBGga0WqxhMMMAx5UoP0XhTCZTkYGd1Wqd\nPXv2Tz/9JAgCx3EjRoyYMWNGOa/1dPPmzePHj9tstho1atSrV6+sh+N+JLArERLYeSKyFEsQ\nBChWq0bkwa4GbY7cVVFnbhinXnEUZxNb6Q936fSKVgd6vaLVgVanaLWg1WKtTuFyHjz/wosv\nVQ3rX7OG2hwDDN60pdNLL0/sP7TU7/lIGY3GTz75ZM6cObdu3apUqVKBZ/rKlVWrVs2YMcNR\noSIYDHDxQt8ePb7++uvyP2wCAPbt23f+/HmdTtekSZP85ROIJxD5F0sQ3k5RkN1GWczIZkV2\nO2Wzgt2G7DbKZpPMWXxGhoFCtFsP2z/IAYgLCsJanWIwgsGIdXpFr8d6IzYYsE6HdXqs1UFR\nY+jzypjxU6eytKZb1QgzL8zZfzBJxmp6z/KMYRg3Hgp+dE6cOPH222/z774PT7cGALhze+Ob\nE6ovXDh16tSyHhpRGFEUR4wY8e/efVDnKXA62MmTp02b9vrrr5f1uIgyQwI7gvASyOGgzFlU\ndhbKyqQsZmTORjYrZTEju+1he9poAI52w1YnrNNhvQHr9IreAAajxGkPnDy5efee00nJbFDw\ns0OH9h80WHI5dhw8eHB2dvbL8+bZrVYZ4/r1669evTowMND18RMAsGbNGr5125yoDgBCKsAr\n41Z9vYgEduXcggUL/j13HlathoAAABBOJsya8kajRo1atmxZ1kMjygYJ7AjC8yDeidLT6YxU\nKj2dykpHWZlUdjbi3VygE9M0aNXpNO3d/+ZOsOX+V4d1+gezy/pVDGOzrJVCKlWuXLl5q9bu\nSr85duzYl19++fLlyz4+PpUqVSr6BUSxpaWlQYV78vlBxUretx25mLZv3/7PP//YbLZ69eoN\nGzasPO+MXLduHYweq0Z1AAB160HnruvWrSOB3ROLBHYEUa4hUUTZmbZrKQf/+RtlpEcadFVN\nRp1U2J79YnSKsE6fkpGJeWeE793z9ufTM96LP/rDunWKVgc6PWaY0nWv5rETmjaDyKqwZ+9X\nX331008/tW3b1qUx52IYJiYmxi1dPQYnT55cuXJlSkpKRETEiBEjatWqVdYjeqioqCjYeW9x\n2NOnqlatWkbDKUtTpkxZsW4ddOgERtO65d8vW7bsn3/+Kbdzw5mZmRB477mB4ODM2zfLaDhE\n2SOBHUGUGSSJCCsginRmBjjsFM/nHFlwOpDFTJuzUFYWstsAwADQkwII8gMAKE5UR1FYb8A+\nPorBpJhM2GBSjCZsNIHRqOj06hzb9HHjQpMS53Vonfei8xlZh7PMckjFQjoukprHTnhzKnTp\npl5x/rr21VdfzZ/H7gnx22+/jXt9PHToANVrQGLiT506ffvttz179izrcRVs5MiRP/74Y8aS\nr+CFYaDTwb69sOzbyZ9/5pbODx48+P3331+9erVKlSojR45s2rSpW7p9FLZu3bpi3a/w7fcQ\nFgYAMOqV5HfenjZt2rJlywps78TYqSgAoABY5Jw9D3aMhdyL5tzyozzGztwD4xZZkXMfZ+U2\nUAAsSs5FDDhbvruDIku6W8PUgpXcVmBXFGXJMjAY7w4IYzh+rEbbNqX9CyA8Hkl34iVIupPH\nDDkcyG5DDhtltwPPgyQiQcgp5S7wSJSwLCG1gjsAEngsK6DISBCQIoMogSgiWXLLSLDBqPj6\nKX7+iq8f9vVX/PwUHz9s8imy+ObmzZsnjhmzd9iA6v5+AGATxS6rNzTu03fOnDmujGfLli3D\np0yFtevvXlIU6NXtj7Vrmzdv7krP5UqR6U4yMjIaNWpknTQF2nfMufT3Fr9vvz527FheMvpS\nu3r16oIFCxISEkwmU5cuXcaMGcOyrIt9AsCRI0cmTZp05swZoChfk2n69OkjR450vdtffvll\nwpQp8EwPqFoNLl+CvzZ/uWDB4MGDXe85jxpd5YVWVkWRMBYw2BUZALIVBQB4BTsUxWAw3LRY\nFIxlQFZFAQCHIvMYAMAqKxLGCQkJSQhBROTd3h0OlJ2llmk3K4r6nWlR7kZm5YWiQOodWP1z\n0L49u3btCgkJcb1Lku7EE5EZO4J4OIwpixmlp9GZGVRGGsrMQFZLGabYlRFK1hnOsdpzO3fS\n/oGjpr+DAwNLWrszT48ePXYNGdJ0xape1asaWObvS8mVYmJmzJjh4iCdTifctyGJooDTOhwO\nF3v2LIcOHbLq9HejOgDo+kzWksVHjhxxcVX64sWLnTt3tjVpCr37gs0W/8OKnTt3/vrrr66n\n/G3UqNGuXbvMZrPT6QwICHBLopNr6enT5s6FWXOhWYucS+06TPlltalde43BKAAWFWxTFAyQ\nLcsAYFUUGZAabImKYlMwBmxWMABYFFnGOTGchMGmKLIsWzAu8jx1yUQ+UMBUp8M6XbLg2v6H\nx+DObRj8fJMmTeb9+qtborpHhERgjxoJ7AgiH0WhU2/TKcnUjWtURhqVkeGuebWSwlqd4uun\n+PoJesOMBZ8mDR+VVLX6ZYNRQBQAwJ6DtRJOjwx1tSjT5MmTU1JStvz3nyAI0dHRn3zyieub\nxOvXrw/XUuDyJahaLedSwnHGavHKbLeFEEUR7tukiBAwTOE5jYtj2rRptvYd4c3cw6qduux+\nefjatWtLNAeWJcsKBouiAIBZURSMbYoiYuzEmNYbaJPP9WyzoigixjZFAQCbgiUAESs2NcaS\nZRmDANih4LxFQ7UHEWO7giHfCiOs3XDPezdoyDdo+FJ6NqS7I5XuI87UU7aMFKXJvUE9hZjc\nx1qK0uY+phGYKBoA/KOjl965466DSoTnIoEd8eQSBEGSJD3H0bdv0ilJdMpV+kYK4nm3dI4x\nTrU7HAiFRVUFAOC0QKGcWqIMA3ROxXdab6A4zknRoNNhrQ5rtVirU4uQ5g3ymyHD4TU/MOar\nKkhRwcHBLo7QZrP17t37kn8ATH8XtLpTu3f26tXrn3/+cXGDf7Vq1caOHv3NW5NhxEiIjIQL\nF2DlD1OnTi23e88fkYYNG8LtW3D6JNSpm3Pp6GHWYm7QoEGp+8ySZV5RDiQlwwej7l41mWDs\n/60w21JT0y0KFjC2KopDUXgFmxVFzHuKsU1RJAxmWS67gm7llI5CHKIAwERTFMDNmzcFhwP8\n/YGiISONupNav379MD9fBAgAfGiKQggADBRiEAUADICeygmn/HL/5XII6XJzCflQFAL49ddf\n1/7+P+jcBcLC4cZ1WP/bsG5dx48fDwAGitLkxmP5g7kSeRSVJwhPRPbYeQmyx65Ezp49+/67\n7/rcvjGwZvQz1aK0xcnlRlGKjy82mtRUbVivV3R6MBgVvQFYFnPaXfv3vzVhwrGXh2pyV8Sy\neD580Xfbd+4sJFQqTkmxNm3anK1TF/5vfM7zrCwYOezzBfNbdXsmW5atOdMkYMcK3LvJ2oEx\nf++SsY6iudyvjG3btv116DC8OAyo3CpbG36tb7POf/999QbyvmDyf+v40nSR3zmSJK1YseLH\ntWuv3rwZFRU1ePiIrr16qRMJd2dx8u06d1GBX4RahLT3Lk1SCJmoAsZuoqhS5Ge+b4+djLEl\n373wGDsVvGzZsm/XroM+faFyKNy4AXt2DRswsG2P7gBglhUFY3WLvUVRFEBZsqxgbJYVCcCm\nKHZFETDOkmV1zdGOFUF5sj6rDRTFIMQhpKWQBiEjRUFu2GSgKA3A5k0b5dhG4Od/9zX/Hagn\nCsMHDAD1BxWBFiEOIQTgS9MAoEWogr9/dna2D0UhBAxChiR0eKkAACAASURBVILWrzMyMubN\nm/fvv/+azeaGDRu+9dZbjRs3dvF2bt261bBhQ+nzRXcD/cSLMOblQ//9FxkZ6WLnKk8pKUY8\naiSw8xIksCsujM2nT25fOL9njaoBDy8bihkWh1SQ/QOVgADFP1AJCMT+gbjQMqNr1qz5Ye7s\n/cMG5r8Y/tV3S1auKmRP1X2BnYxxuiyny8ptUUyX5AxZSZekxNTUP/buVapEQEAgqDGoTl+i\nm350dBRyPGEBxxOORUhPUaDOQiHQURSHUN5qoImmKAxaitJSiAYw0TQAnD965J9t26BmLfAL\ngNQ7sG/3kP79+3XuDLlBOYeQjqJoACNNQfF+eQCAqlWrWmZ9CA0a3r206ItBLL1o0aJCXlVW\ntWK3bds2+PXx8OvGe64OG/LdzPf69OnjlrcggR2hIkuxxJMCZWcxp44zpxNM2VnDakU/2ABr\ntXLlKnJ4hFS5ilKxUpGnSu8TGRl5ISMzw+m08MI1i7Wqn69dlNIdzvyZwDBAmiSnyfJNUbwj\nSrclKR1DhqJcdzjTZDlNktIluaAoiYJW5TR5AYnqyiF1YdFEIZaijBSlQ4ijKDXk8tPQFIAP\nTWtyVxINFKIQ8qEpADAhikIQbPIxsEx2drYvRQEAi5COQgDgQ9EFzXgWwzNdt7Oa5cuXq+lO\nRo0a1aFDB9dvs0OHDr//uhbqN8jZZpeeBnFbO86f73rPj4JWqwXeCYpyzweLw6HVlvLwE0E8\nDJmx8xJkxq4QKDuL+28fc+o45FsHVCmA9gYE/y4pCStWbth/wJWN2Iqi9OrV62JCQiYGiIwC\no0FfsWLU061b9Ox5XRRvS9INUUqTZOmJ/BdHFEldbVSjKD1CLEX50hQDyEBReirnKQtITyEj\nRfFW655//k5JTDQwTKsGDZ7t0cOk0RhpistdsnSFr68vwzDp6enl/Nvhzp07nTp1uunrB61a\ng9UGf2/p07bNd999V/irymrGzuFwxMbGpg1+Afr1z7n012a/pUsOHz7srikxMmNHqMiMHeHN\nkDmb+28fc/LYgyHdGaPv6soRqytFXNPpIW6b6fadEkV1CoZbkpQiilcF8YYo3pDkFF44OXGy\nw88vb53UDnAa4HS6q9E2S6EAmg6g6UAN7UvTPhTlS1O+NO1D0T4U0tGUOtGiHpSjEPIp3ld7\nlix/+OGHcfHx0KQZ+PrAqZPhWu20OXO1Oi3kS6CqpgQDALuC85/n5BXFUdAXvzo/BAAajcaX\n40AUJEnKf4hPS92z+02HKLZ4f/EY4xUrVvz999+ywQi8MyA4+KVRo2rXrn1fM5uCxXu37uUd\n7cxPArA9ZLqxOMcLOIYxACj3dksDzourWIrSIwQANEImmgLI2e+l7uvK2/XlQ1F07oRZCQT6\nj3tldMle4nVCQkL27t27bNmy48eP6/X6Lh9/1K9fv7Ie1EPpdLrFixcPHz7cefA/qFEDLl1i\nDx/8fOlSEjYRbkdm7LwEmbG7DzJncwf3MwlH7wvpsMG49uyFz/YfOvHB3JyEVeZsGP9/poz0\ny5cvF9hVuixf4YVkQUwSxauCeE0N5iTJLZvZEUAwowmk6WANHaLRBNJ0kIauwDABNKVGcsG0\nxlTSb/2S2LJlS1xcnNPpjI2NfeGFF9yS51al0+kMBoPFYuHddNB40aJFs775BuZ8DNE1QFFg\n7WqfNT/v3LkzPDzcLf2XSJEJij2Xp8zYlU5Zzdiprl69umrVquTk5CpVqgwZMsS9FdvIjB2h\nIoGdlyCBXR4kieyeHcyxQ+jekE7x8xdatBFr1x3ywgvWM6cOpKZD4ybAcnDkcEOD9pqMz5w5\nc1uSLvHCZUG8LAhXeCFJEJNF0eJadggaIITRhDJMBY0mlNEEaehKGk2wRlNBQ4doNJUNei3D\nFH4q1kO5PbCrU6fOnVdfh7bt716a8sabbdtMmzbNLf2XCAnsPFTZBnaPFAnsCBVZiiW8Cn09\nRbvldyrrng9uxddPaNlGrF1P3bbcuHHjzSeO/T3ouU28eMM/UNe92wFaI4RFRJ25aC1t9g0G\nIT9ZSj1/HmrWBJQ7wWazwsjhOzasrxVT7WEvLF3CqieQKIp37ty5vypAVLXr16+X0YgIgiDK\nIxLYEV4CSRK7fxd76ED+Yl/Y109o1Exs0NgM6JyTP8cLF3n+7LP9zzZq1i0g8P5NdcWI6jiE\nwlkmnNGEs2w4owlnmCosG85oQjQaSRTajxt9IToGxr8BLAs2K3w45+no6rViYtx+s08ghmGC\ng4NTk5PuKeJ55XLltq3LbEwEQRDlDwnsCG9A37im3fI7lZmuPhUp6kxA8IlGzU8FVzorCOcS\nk1LEeyuDBRZdrDBIQ0exbATLRLJMJMNEcmwky1R4ePVMlmWXL18+atSo88/1hoqV4Pq1xnXq\nLPn+e9fujLhrzJgxcxYvgsphUK06KAr8utZ0/uzQpd+U9bgIgiDKERLYEZ4NyRK7b5ft+JHD\nBp8TkTUSTH4JPv5nfXwEoAAAinci1Y+mq3JMVZatzrFVWbYqy1Tj2FKkjahZs+aOHTsOHjx4\n7dq1qlWrNm7cmNRtdKPXX3/91q1b3415GQKDwGYL9fX5fPnyMjk5QRAEUW6RwI7wSBmSfMLJ\nJ2RmJiQlndD5J3coQer2ygwTzbHVWSZGy1Xn2BiOC9YUVlKiRBiGefrpp93VG5EfRVEfffTR\n66+/fvr0aR8fn/r167sruaskST/++GNcXJzdbm/YsOFrr70WEBDglp4JgiAeMxLYER7g+vXr\nMscdtdmP2h3HHc4TDv5q3mlE/yIWVYM1dG2ttibH1tRytTmuhrY0U3FE+REaGhoaGurGDhVF\nGTJkyI4zZ6FnL9Dp9+7etWbNmri4uIoVK7rxXQiCIB4PEtgR5ZSC4TzPf7l12x+XLvNVq0Fk\nVHFqfLEI1dJydbTcU1ptTY6to+MKKQhLEACwevXqHadOw/IVYPIBAHju+dT3ZkyfPv17sj+S\nIAgPRAI7ohyxyMphu+OQw3HQ7jxid1gVBaKqQ1T1Ql7iKwkN7dY6oWG1/Xzq6nTVWYYh29qI\nkti9ezd07JQT1an69tv9wXtlNyKCIIjSI4EdUcaui2K8zXHI4Yy32c/xglxUTlS9JMVaMhpl\nZ8ZmZ8RmZVb193P0HYhzq3gRREkp99VlBwCKVkqb0ZAgCKJskcDuSZSdnS1JUmBgYFkN4LIg\nxNsc++2O/Vbb/YlIHkBjXNtqbpqV3iwr3e9yYk+WpiAn+BNr1HL06IsfnoKEIIrUvHnzTV98\nCUOHgT7314Mtf7Zo0aJMB0UQBFFK5BvxyXL06NG33nrr+PHjABAVFTVnzpwuXbo8nre+yAt7\nbfYDNvt+m+O2VEQwF0jTTfTarZ9/trBS4FANGOXc9iwFuVEd37yV0Kr9/UmGCaKEhg8fvn79\n+kOvjYVn+4FOB3t2+Zw4/mFcXFmPiyAIojRIYPcESUlJGTBgQHaXZ2DaO8CwV7ZvHTly5MaN\nG5s0afKI3vGWKB10OHZZ7XFW2zWhiKqaESzTTK9vptc21etitBwCeF0S1vyyZlD/3sDdW5me\npp2de4h1GzyiYRNPFI1Gs379+q+//nr79u02my02NvbNL78ICwsr63ERBEGUBvLKMs9FSktL\nK+shuBlCyM/PLzOzsHy806ZNW372PMz9+O6lb5e0vn51w4YN7hqG1Wp1aHW7rLZdVtteu6Pw\nYE6DUH2dtrle18Kga6LTBTyQTM5sNg8aNOjW+fN/Pt87JtBfvYg5raN3fzmyqrvGXLY4jtNo\nNDabrawH4n46nc5gMFgsFp7ny3os7mcymZxOpygW8euKJ/L19WUYJj093Su/HQICAjIyMopu\n54GCgoJEUczOznZjnwzD+Pr6urFD4jEgM3ZPkIsXL0LD2HsuxcZe2LHN9Z5TzZYpP/20NSNL\nqFcfoqoWsjzKIdRQp21p0Lcw6JrodYZCM5j4+Phs+d/vzmVfB1tzPqowp3UMfFGuUMn1MRME\nQRCE9yGB3RPE19cX0u+dqkxLcyXD/hknH2e1xVlt+7ItSpsOD2vGINRQp21l0Lcy6JsYdNri\n74qTZd3/1pvyojoN4+g3kER1BEEQBPEwJLB7ggwYMOCPMWOgQyeIrgEAkHoHVq4YMOaVEnWS\nJcu7bfbtFluc1XYr70Drg0mAFaUux7b3821l0DfTa/WlKPagKNotmzSXLuQ8Q+hmm04+YREl\n7ocgCIIgnhgksHuCdOvWbeIrr3z+6hioWw8YDSSc6NO167hx44rz2lNOfpvF9q/FctTBF5Jq\nLsph65h2q0Pa7TFz53244ofmMdVKOVaMtVs3M+dOq89EjAfFH9ux6Lv58+cPGDCglH0SBEEQ\nhLcjgV05xfP8r7/+evr06YCAgB49etSuXdst3c6YMaNv37579uzheb7Ze+82a9askMZ2Rdlt\ntW+12rZZrDcenm1Orygofv8nPtqOabeiHDYAsImiMzOj9FtuMdZu+4tJOKY+kxEa0aDl5u6D\nYGfcm2++2bBhw+jo6FL2TBAEQRBejQR25dHt27d79uyZJElQvyGcOff555+/++67Y8eOdUvn\ntWvXLjxMvCFK/1isf5ut+2x2/iGTcxRAPZ22g9HQ0WSIcjpafTovJabackW5brVW8/NLMZur\nx8TExMSUboTs3h3M8cPqY4zQa3Uar68UDgDQroPz7782btw4derU0vVMEARBEN7tCQ3s6PJd\nGH7y5MlJlcPh/dmg0QCAcPzYnGmT27RpU7du3Ye9BCGEEHLlvk46nH9lW/62WE/YHQ9bag3U\naDqYDJ1MxvYmQ1BevQeTcciQIZ989RU83RrqxsD5c+jUuSX/396dB0ZR3/8f/8zOzm6SzeYC\nwhkxEI5wBeQQBKEKiIiAaCtSxVtMv1Lsz6Nqa0Vpa0VtxYN+W0rx/Iq2iiiIHGKrgIKgXEpB\nbkMAMefuJtnd2dn5/TFkSbkEdjezmX0+/vrM7GT2PWx2eOUzM5/P//6voijnUIZ943rH2tVG\nWxfi7rxOL+Y1GNmkRYvKysoE//jOis1mi/KDS1iSJAkhbDabVY/OqodmkGXZksOdiIQ//0cj\n5icTiRHgm6AkDXbp6elml3BKdXV1K1asEHPmiUhy6t0n0LffihUrTj/NkSRJZ3tcIV3/pNrz\nXkXVoorKkkDwVJsVudJG52SNzsoa4HbJJ3zPDx8+/NJLL4npM8SPjj4Yq78874knnrjpppvO\n+hSz/evwiiWRpac2bp1jzxLd65c1TXz9VY8R0xL54ztbFg52NptNCJGSkuJwOH5w4yZHlmWb\nzWbJ6GO324UQLpfL7ELi4hzOk02ILMuxPTomTW6KkjTYxXYIx9iqqKjQNE1kZPzX2ozMsrKy\n05RtDFB8hscV0PV/eWve93iX+2oqQtpJt0m1ScPSXSPTXSPc6W0UuxBC6JrP4zlxy/fff9+X\n0yyS6oQQYtIN+1579dNPP+3Vq9eZ1GOQD5WmvvmqVH8eUXv3S2+VLx59TDidYsBAUVkh/v63\nfKGPHz8+kT++s2X5AYpra2sZoLhpMQYo9ng8loytOTk5VjqBNNS8efNQKBTzAYqdTmcMd4hG\nkKTBLpFlZ2e3adPm4GefirHjj67y+8WXX/S48ooo9+wLh1d4axZXe1f6ampO8XdYC7s8yp0+\nyp3+I7frDAec8/v9x2ZPNyiKcCh+v//Ma7NVVaS+PV+q/28yVNDFP/zyyTZbXV3dU089VVVV\nJYQYOnTok/PnW/ivbQAAokSwSziSJP32t7+97a67RCAg+g8QFRXi5XkXtGt79dVXn9sOvVp4\nudf3nse30us71cMQXVKcl7vTL3e7LkhNtZ3lPRVFRUVi9y5RekC0rZ9ec8PnTk3r2rXrGe5B\nqvGlvvmqVFdrLGrtzvOPu0bYbEKIKVOm3HnnndXV1S6Xy5LXKwEAiCGCXSIaN27c34V48skn\nd/7vC263+8orr/zNb35zts8ieLXwUq9vkcf7kbfmpHlOEqJ3asqYjPQxGe4C57nfBdWzZ88b\nJk587f57xM23ibw8sf0/4qV5Dz/8cMZxV5NPQQoEUt963eY5evkg3LxF3VUTdfnYb6bNZuvQ\noUMgEPB6vedcJAAAyYBgl6DGjRs3bty4YDB4tjee14X1ZV7fO9XeD72+4MnynCxJA9NSx2S4\nr8hwtT2nB1dPNHPmzPy//OX//u//SktLCwoKfvb47890GGFNS333H/KRw8aS7nbXXvNTPTU1\nJlUBAJBsCHYJ7cxTXVDX3yuvfK300FKvr/Zk98/ZJWmIK21cpntMRnpOrK9pOhyOadOmTZs2\n7Wx/MGXlB/L+vUZbdzrrrvmpnnGuwxoDAJD0CHZNm6brq2pqF1R5lnhrqrWTPN+qSNIQV+q4\nzIwr3Ok59sS6R83x+afK5i+Nti7LdRMmai1amlsSAABNGsGuqdpc53+ryvNOtfe70Ekm+5Il\naWh62lUZ7tHu9OwEy3MG+64dzk9WHl2QpMDocVre+WYWBABA00ewa2L2B9W3qj1vV3l2nmw8\nYZsQA9JSJ2S6x2VmNE/IPGewlR1JWbJQ1N8CGBh0sVp4ykk1AADAGSLYNQ3Vmvaex/dGZfX6\nU8z31Ts15fpWLS9z2I8OJpzApBpf2tvzpfpBa9XOhcGLhplbEgAA1pDoISDJhXT9377aN6uq\nP/CcfAi68x3Kj7MyrsnM6JTizMrKqqysbPwiz4qkhdIW/kOqH9xEa9k6cMVVgukIAQCIBYJd\ngvqPPzC/qvrtKu+Rk91C10yWJ2RlXJPp7pfWpEYG0XXn0kW2gweOLqW76yZM1GM05AoAACDY\nJZZqTVtQ7Z1fWb2x7iTzcaVI0uiM9GuzMn+UnmZvgr1czs9WKdu2Gm3dbq+bMFF3n9EgxgAA\n4EwQ7BJCWBeramrmV3kWV3tPvOQqCTEgLfW67MxxGe4M2Rbley1ZsuTjjz9WVbV///4/+clP\n7PZG+h1QvvmP49OPjy5Ikn/MBK1Vm8Z5awAAkgTBzmQHgurrVdVvVHlKguqJr7Z3KNdmZVyb\nlXm+IwbXK3Vdv/3221ctXzahS0G6LD/17sKXXnrp3XffTUlJiX7np2crL3N+8O6xx2CHXBLq\nXBjvNwUAINkQ7Myh6frqmtpXKqqXeH2hE7ronJI0yp1+Y07m0HRXDC+4zp8/f93KD7+89frW\n6S4hxO+HDb709bdmzpw5ffr02L3JSUiBQOrCf0jBo+OzhLr1Cg4cEtd3BAAgORHsGtveoPrP\nqurXKz2l6km66IpSU67NyvhJZkY8RhX+4IMPbi/qYaQ6IUSaYv9/Ay54bMmS+AY7XXcufc9W\nUWYsaS1a+keNiePbAQCQxAh2jUTV9Q+8vpcrqlb5ak8ctqSFXb4uO3NSVmYn55lODnsO6urq\n3P+9/0yno66uLn7vKIRwrlujfPMfo62npPonTNTtPAYLAEBcEOziriSovlpZ9X+VnhMHLrEJ\n8aN01+ScrFFulxL/p1x79er13jtvT+vX21b/Xu/s2N27d+/4vaO8f69jzb+PLkiS/8oJ4cys\n+L0dAABJjmAXL8aDrqe6i66VYr82K/OmnMzzGnEUt5///OeXLFhw3cIlP7ugl1OW3/zPN2/t\n2f/hnL/H6e0kT3XqordEOGwsBodcEsoviNN7AQAAQbCLhwpNe62i6qWKqhL1+C46WZJGpLtu\nysm6ND1NbvSB6LKzsxctWvS73/3u+hX/NoY7ef/95wsK4hK2JC2U+u4/pfrrvKGOnQMXDo7H\nGwEAgAiCXSxtrPPPq6h6p8pz4lh0Le3267MzJ2dntovFwCXnLC8v769//WsjvJFzxRL58EGj\nHc7O8Y9h3jAAAOKOYBcDQV1fUOWZV1F14nQRkhBD0103N9ZddAlC2fKlsnWT0dYVR91V1+rO\nuA+VBwAACHYx4NHC9x78LvjfvXRZsjwpO+PmnKwOjjg+6JqAbN8fca5cenRBkgKjx4Wb55pa\nEQAAyYJgFwPN7fL4TPc/qzzGYmen46acrBuyM9Ns0U7/1eRIITV18QKp/vnfYN8L1S7dzC0J\nAIDkQbCLjVtzst71eC9PT78xJ3NY/QjAScj54VJb2RGjrbVqExg63Nx6AABIKgS72OiXlrq1\nS8ccOfbTRTQhyo5tytaNRlt3pvjH/Vgk9z8IAACNLOmuFcZPkqc6W1Wlc9niyGJg5BWMRQwA\nQCMj2CEWNC31/XekwNGHgtXe/dTCHuZWBABAEiLYIQacn6y0HTxgtMPNcwOXXGZuPQAAJCeC\nHaJl37vL8cU6o60rSt3Ya3Q7924CAGAC/gOO1urVq994441Dhw517NhxypQpcZqhK2FJXk/K\n+++I+jH8AsNHh5u3MLckAACSFj12Ufnzn/884brr3gyon/Ts/eK+b4cNG/bxxx+bXVQj0vXU\nJe9GJoRVu3RTe/Y2tyIAAJIZPXbnbt++fb///e/Fk38SRUfTTPCfb06dOnXjxo325LgW6fjy\nc/nbvUY7nJUTuHycufUAAJDk6LE7d2vWrAm2Pz+S6oQQ4qqrD5eVbd++3byiGo+tvMzxycr6\nBVvdmAl6kk2eBgBAoiHYnbtQKCSO65mTZSFJofoJtawsHE5ZsjAydVhg4JBwm7bmVgQAAAh2\n527AgAFi506xZ/exVR99mJmWVlhYaF5RjcTx6Sfy4YNGW2vZOjjwYnPrAQAAgnvsolFYWFh8\n+21/ue//iet+Ktq1E19tFQvemvnss06n0+zS4kv+7pDz8zVGW5dl/+jxTB0GAEAiINhF5bHH\nHuvWrdv8+fNL33+vU6dOd82ff/HFFu+7kkJqyuIFQtOMxeCwEeEWueaWBAAADAS7qNhstkmT\nJk2aNMnsQhqP898f2irKjbbW7rzgBQPMrQcAAERwjx3Ogrxvj7Jpg9HWnSl1V1wlJMnckgAA\nQATBDmdK8vtTly2KTDLhH365npllbkkAAKAhgh3OVMpHyyRPtdEOdS4Mde9lbj0AAOA4BDuc\nEfu+3favNxttPc3lv2yMufUAAIATEezwwyQ16Fy2OLLov2yMnppmYj0AAOCkCHb4YY5PPrLV\nX4RVu3QLdepqbj0AAOCkCHb4AbaDpY4GT8IGLh1lbj0AAOBUCHY4LU1LXbZIhMPGUuDSy/R0\nt7kVAQCAUyHY4XQca1fbyo4Ybe2889XuRebWAwAAToNgh1OyVZQ51tXPCWtX/KPGMhwxAACJ\njGCHU9D1lKWLJC1kLAUvviSclW1uRQAA4PSawFyxPp9vzpw5W7ZsUVW1S5cuxcXFubnHzzp/\n+PDhF198cdu2bYFAoG/fvsXFxZmZmaZUaxmOjevl0hKjrbVqw5ywAAAkvibQYzdr1qwjR45M\nnz79qaeeSktLmzFjRrj+Xn6DqqqPPvqopmlPPPHEU0895fP5Zs6caVa11iB5qh2rPjq6YLMF\nRl0pbE3gVwUAgCSX6P9bl5WVrV+/fsqUKfn5+W3atCkuLi4tLd26dWvDbfbu3Xvw4MGf/exn\nbdu2bd++/d133/3VV1/t37/frJotIGXFEikYNNqBCwdrua3MrQcAAJyJRL8Uu3PnTkVR8vPz\njcX09PR27drt2LGjqOjY45mqqgohHA6HsZidnS3L8q5du9q3b2+s0XX94MGDke3dbrcsy410\nAI1FkiQhREyOS9653b5np9EO5zTXBv/I3H8um80mhJAkyXqfmhDCZrNZ9dCM30mbzWbVo7Pq\noRlkWdZ13ewq4sLCn1rMTyYSD8w1QYke7Dwej9vtbvi7lZmZWV1d3XCbDh06ZGRkvP7667fd\ndpsQ4h//+IcQwuv1RjYIBoPjx4+PLN58881Tp06Ne+lmyM6O+vkGVQ1+tOzo6VySnD/5aWqL\nFtHuMxYcDkcku1tPSkqK2SXEi8vlcrlcZlcRFxb+hRRCZGVlmV1CvMTgPJmo7HZ7bI8uFArF\ncG9oHIke7MQZ/MWQmpr64IMPPv/880uXLnU6nePGjcvNzW34V4vNZhsxYkRksaCgIBAIxKtc\nk0iSpChKsP766bn7aJmorDja7tlHbZsnzP63kiTJ4XCEw2Gja9ZiZFmWJMmSZ09Zlu12u6qq\nx90Uaw2KomiaZtVDs9ls1jtJGhwORwzOkwnJ6XTG/Dyp67rd3gRyAhpK9A8sKyvL4/Houh6J\nd9XV1Sf+RdKjR4+//vWvNTU1TqdTCPHWW2+1aNDPpCjKE0880XD7srKyOBfe2CRJysrKathP\neQ5sVRVpq/5t/EPrTmfN4GF6dDuMCVmWHQ6HqqpRHl1icjqddru9pqbG7EJiLzU11W63+/1+\nS0YEt9vt9/st+cdGZmamzWbz+XyWvBSbk5NjyTOJEMLpdGqaFtujUxTFwtcTrCrRH57o1KmT\nqqq7d+82Fj0eT0lJSWFhYcNtNE1btWpVZWWly+Wy2+0bN27Udb1bt25m1BtLn3322dy5cxcu\nXFheXt447+hcufTYwHWDf8TsYQAANC2J3mOXk5MzaNCg2bNnT5s2zeFwzJ07t2PHjkZoW7Fi\nhd/vHzt2rCzLb7/99urVq++4447vvvtu9uzZl112WUZGhtm1n7uampobb7xx49q1vXKbf19b\nd58WnjVr1pVXXhnXN7V/8x/7nl1GO9wiN9i7X1zfDgAAxFyiBzshxLRp0+bMmWOMVNe9e/eH\nH37YuCy7adMmj8czduxYIcQvf/nL2bNn/+xnP0tJSRk2bNjNN99sctHR+fWvf12385vtd97Y\nLDVVCPHSlm1Tp07t2bNn5DnfmJNCqvNfy+sXJP/w0cK6D44BAGBVkiXvovhBiXyPXTAYzM/P\nXzlxfP/Wx0aPu/zNdwbfcNMvfvGLU/2UcY9dZWXlub2pc9VHjrWrjXaoR1Hd6PGn374xybKc\nnZ0dCAQseWeMte+xc7lcXq+Xe+yalszMTEVRysvLLfm/Q05OTkVFxQ9v1wQ1b95cVdXjRo2I\nkqIoTOPU5CT6PXZJyOv1BoPBPPd/3d/WPiMjfmHUvAVh+gAAIABJREFUVlmhrP/MaOtOp3/o\n8Di9EQAAiCuCXcLJzs7Ozs5ee/BwZE0oHF5/6HCHDh3i9I7OlUslTTPagSGX6K70OL0RAACI\nK4JdwrHZbPfcc8/dK/69fO9+NRw+5Ku584OVtekZP/nJT+LxdsqObfa9R5+Z0JrnqjwzAQBA\nk9UEHp5IQnfeeWdtbe3EWbMCfn9Y1wcOHPj63/7kdsd+8BEpFHJ+/GH9guS/bIywkfUBAGiq\nCHaJSJKke+65Z+rUqXv27GnWrFmLuE3qpWxYK1VXGW21e1G4bV6c3ggAADQCgl3icjgcXbt2\njd/+pdoax+drjLauOAJDL43fewEAgEbAdbfk5Vz1L6l+HAp14BCemQAAoKkj2CUpW9n3yleb\njLbuzgj2u9DcegAAQPQIdkkq5d/LRThstAPDhut2xdx6AABA9Ah2yci+Z6e8d7fR1lq3Vbv2\nMLceAAAQEwS75BMOOz9eGVkKXHKZkCQTywEAALFCsEs6yuYvbGVHjLbapZvGECcAAFgFwS65\nSMGg89NPji7IcpAhTgAAsBCCXXJxfPaJVFtjtIN9B4azcsytBwAAxBDBLonYqquUL9YZbT01\nLThwsLn1AACA2CLYJRHHJyslTTPagcHDdGeKufUAAIDYItglC/m7Q8qObUY73Ky5WtTX3HoA\nAEDMEeySheOTj4SuG+3AsBHCxkcPAIDV8L97UpAP7Lfvqx+RuG1eqGNnc+sBAADxQLBLCimf\nfBRpBy6+xMRKAABA/BDsrM++c7uttMRohzp00vLON7UcAAAQLwQ7qwuHnav/fbQtSUG66wAA\nsC6CncUp27Yem0Csaw8tt5W59QAAgPgh2Fmapjk+/fhoW5aDQ4aZWg0AAIgvgp2VOTZtsFVX\nGW21Zx8mEAMAwNoIdpYlqUHH2tVGW7fbAwOHmFsPAACIt2iDnaqqMakDMedYv1aqrTHaat+B\nujvD3HoAAEC8RRvs2rRpc/fdd3/55ZcxqQYxU1erbPjMaOopKcH+g8wtBwAANIJog12PHj1e\neOGFvn379uzZ86mnnjp06FBMykKUnOvWSIGA0Q72v0hPTTW3HgAA0AiiDXb/+te/SktLn3/+\n+ezs7AceeCAvL2/06NFvvPFGXV1dTOrDOZBqfMrG9UZbd6WrfS80tx4AANA4YvDwRKtWraZO\nnfrJJ58cOHDgj3/8Y3l5+aRJk1q1anXHHXd8/vnn0e8fZ8uxbo0UChntwKCLdUUxtx4AANA4\nYvlUrHG/3YsvvvjTn/7U4/HMnTv3wgsvHDx48IYNG2L4Ljg9qcanbP7CaOsZmaFeF5hbDwAA\naDQxC3bffffdn/70p6Kioh49erz55ptjxox5++2333vvvWAwOHDgwGXLlsXqjXB6/9Vdd+Fg\nXZbNrQcAADQae5Q/HwwGFy1a9PLLL3/wwQehUKhLly5/+MMfbrrpptatWxsbXH755ePGjbvr\nrrt27doVdbX4Acd31/XsY249AACgMUUb7Fq3bl1RUZGenj558uRbb711yJDjR8FVFKW4uHjC\nhAlRvhHOhGPtarrrAABIWtEGu27dut1yyy0TJ050uVyn2uaCCy6YO3dulG+EH6R7PcqWowMK\n0l0HAEASivYeu1WrVl1xxRXz5s2LrPn+++9nzJhx5MiRyJq8vLxbb701yjfCD9I/Xkl3HQAA\nySzaYLdjx44+ffrcd999kTW1tbXTp08vKiras2dPlDvHmZNqfOH19VNN0F0HAEBSijbYPfjg\ng+np6atXr46sad++/bZt29LT0++///4od44z51i7StTP20t3HQAAySnaYLdmzZpf/epX/fv3\nb7iysLDw/vvvX7FiRZQ7xxmSanz2zdxdBwBAsos22Pl8PofDceL69PR0TdOi3DnOkGPtqmN3\n1w0cQncdAADJKdpg16dPn1dfffW4DOf1emfNmtWnD/1GjUGq8SlbNhptPSNT7dHb3HoAAIBZ\noh3u5JFHHhk9enTnzp1Hjx7dokWLcDhcUlKyePHi8vLyJUuWxKREnN5x3XWC7joAAJJVtMFu\n1KhRy5Yte+ihh2bPnh1Z2atXr5deemnUqFFR7hw/SKrxKZuPdtdJ2Tl01wEAkMyiDXZCiJEj\nR44cObK8vPzgwYOyLOfl5bndbp/Pt3Pnzk6dOkW/f5yGY8NaSTvaXScNG053HQAAySwGwc7Q\nrFmzZs2aRRbXrVt37bXXlpeXx2r/OJFUV6ds2mC0dVe67YL+wusztyQAAGCiGAS7999/f/78\n+d9++204HDbWaJr29ddfO53O6HeO03Bs/FwKBo12cMBFil0xtx4AAGCuaIPdG2+8MWnSJLvd\n3qpVqwMHDrRp06aiosLv919yySUNp6NAzEmqqnz5udHWU1NDvfuaWw8AADBdtMOdPP3005df\nfnlFRUVJSYksy8uWLfN6vc8995yu6xdffHFMSsRJKZs2SHV1Rlu94EJdOcloggAAIKlE22P3\nzTffPPbYY26321jUdd1ut//85z/fs2fPQw899MILL0RdYVzITf0hg1DI8cVao6krSqjfhbIs\nS5LU5I/rZGw2mxDCwkdn1UOTJEkIYbPZrHp0Vj00gyzLuq6bXUVcWPhTi/nJxPgWo2mJNtip\nqhr5NXK5XFVVVUb7mmuumThxYsIGu/T0dLNLiIq+fq3u9Rpt28CL01vkCiEkSWrqx3VSxpnF\nbrdb8ugsHOyMRJ6SknLSyWmaOlmWbTabJaOP3W4XQrhcLrMLiQurnicNsizH9ugit86jCYk2\n2BUWFv7973+/9NJLHQ5HXl7esmXLjCuwFRUV1dXVsagwLhK5th8WDrs+WWlcRNdl2dejSK+u\nliQpKyuraR/XKciynJ2draqqtz7LWonT6bTb7TU1NWYXEnupqakul6u2tjYQCJhdS+y53W6/\n36+qqtmFxF5mZqaiKB6Px5KxNScnx5LnSSFE8+bNQ6FQbI9OURSeg2xyog1299xzz+TJkysr\nKz/88MOrr7768ccfP3LkSLt27ebMmVNUVBSTEnEcZcfXtsoKox3qdYGe7ja3HgAAkCCiDXY3\n3HCD3W7ft2+fEOLBBx9cu3bt3/72NyFEXl7es88+G319OJ6uK2vXHG3bbMF+A02tBgAAJJAY\njGN33XXXGY20tLTly5fv2rVLVdWCggJFYVi12LPv/kYuO2K0Q4U9wlnZ5tYDAAASR7TDnVx0\n0UVLlixpuKagoKCwsJBUFyeOdfXddZIU6H+RqbUAAIDEEm2wKykp2b59e0xKwQ+Sv90rHzxg\ntEOduoRb5JpbDwAASCjRBrvZs2fPnTt34cKFlnw6LNE4I911QgQvHGJiJQAAIAFFe4/d008/\nbbfbJ0yY4HA4mjdvftwVWOOhCsSE/N0hed8eo62d30Fr1cbcegAAQKKJNtiFw+EWLVoMHz48\nJtXgNJT1n0XagQsHm1gJAABITNEGu9WrV8ekDpyeVF2l7NhmtLWWrbXz8s2tBwAAJKBo77FD\n43B8sU7UT+2i9h9kbjEAACAxRdtj17x581O9FAwGPR5PlPuHEEIKBJSvNhltPSNT7Vxobj0A\nACAxRRvshgw5/tnMQ4cObd26tWPHjsOGDYty5zAom9ZL9bNtBvsNFFacMB4AAEQv2mC3cOHC\nE1cePnx44sSJo0ePjnLnEEIITXNs3GA0dadT7dHb3HIAAEDCiss9dq1atfrjH/84ffr0eOw8\n2Sj/2Sp5j17RVnv3151Oc+sBAAAJK14PT7Rr127btm1x2nlSUTasO9qS5WCffqbWAgAAElpc\ngp2u6/PmzWvWrFk8dp5U7Ht3yd9/Z7TVwh66O8PcegAAQCKL9h673r2Pv+VL07TDhw+XlZXd\nd999Ue4cjs+PDUqs9htoYiUAACDxRRvsTqQoSq9evcaPH19cXBzznScV+fvv5JJ9RjuUX6C1\naGlqOQAAINFFG+w2bdoUkzpwImXdp0LXjXaQQYkBAMAPicE9docPH37++ecji99///2MGTOO\nHDkS/Z6TmeT1KN/UzyHWoqV23vmmlgMAAJqAaIPdjh07+vTp0/B2utra2unTpxcVFe3ZsyfK\nnSczx4a1QtOMtnrhRUKSzK0HAAAkvmiD3YMPPpienr569erImvbt22/bti09Pf3++++PcudJ\nSwoElK0bjbaekal27mZuPQAAoEmINtitWbPmV7/6Vf/+/RuuLCwsvP/++1esWBHlzpOW8tWm\nY3OI9b2QOcQAAMCZiDbY+Xw+h8Nx4vr09HSt/koizo6uK19+frTpcKg9mUMMAACckWiDXZ8+\nfV599dXjMpzX6501a1afPn2i3Hlysu/aYauqNNpqj966M8XcegAAQFMR7XAnjzzyyOjRozt3\n7jx69OgWLVqEw+GSkpLFixeXl5cvWbIkJiUmG8cXR7vrhCSpffqfdlsAAIBjog12o0aNWrZs\n2UMPPTR79uzIyl69er300kujRo2KcudJyPb9EfnAfqMd6tApnMO0bAAA4EzFYOaJkSNHjhw5\nsry8/ODBg7Is5+Xlud3u6HebnBxfrD02KHHfC80tBgAANC0xG6C4WbNmPXv27Natm9/vZ4Di\ncyPV1dn/85XRDjfPZVBiAABwVhigOIE4Nm2QQiGjHew7gEGJAQDAWWGA4oShacrmL4ymnpoa\nKuxpbjkAAKDJYYDiRKF8s03yeoy2WtRXVxRz6wEAAE0OAxQnCkf9oMTCZgsW9TW1FgAA0CQx\nQHFCsB08YDtYarTVzoV6Rqa59QAAgKaIAYoTguOLdZF28IIBJlYCAACaLgYoNp/k8yo7txtt\nrWXrcNs8c+sBAABNVLwGKPb5fDt37uzUqVP0+7c8x8b1ov5adrDfQHOLAQAATVcMgp2hWbNm\nzZodm/9q3bp11157bXl5eaz2b1VSKHRslBNXeqhLN3PrAQAATVcMgt37778/f/78b7/9NhwO\nG2s0Tfv666+dTmf0O7c8efvXUl2d0Vb79BOybG49AACg6Yo22L3xxhuTJk2y2+2tWrU6cOBA\nmzZtKioq/H7/JZdc0nA6CpyKY+N6o6HLMqOcAACAaEQ73MnTTz99+eWXV1RUlJSUyLK8bNky\nr9f73HPP6bp+8cUXx6REC5MPlcqHDxptrUt3Pc1lbj0AAKBJizbYffPNN1OnTnW73cairut2\nu/3nP/957969H3rooajLszjHxg2RdqBPPxMrAQAAFhBtsFNVVa6/LczlclVVVRnta6655p13\n3oly5xZXVytv/9poarktw23amVsOAABo6qINdoWFhX//+9+DwaAQIi8vb9myZcb6ioqK6urq\naKuzNMfWjZIWMtoqgxIDAICoRfvwxD333DN58uTKysoPP/zw6quvfvzxx48cOdKuXbs5c+YU\nFRXFpERr0nVlU/0oJykpoa49zC0HAABYQLTB7oYbbrDb7fv27RNCPPjgg2vXrv3b3/4mhMjL\ny3v22Wejr8+q7Ht22qqPXrZWe/TWFcXcegAAgAXEYBy76667zmikpaUtX758165dqqoWFBQo\nhJVTU+pHORGSpPZmlBMAABADMZt5IqKgoCDm+7QYW1Wlfd8eox06v0M4u9nptwcAADgT0T48\ngXOgbNogdN1oq336m1sMAACwDIJdY5NCIcdXm422npEZyqeDEwAAxEbsL8XGnM/nmzNnzpYt\nW1RV7dKlS3FxcW5u7nHbHDhw4MUXX9yxY0coFMrPz588eXK3bt1MqfYH2f/zlairNdrB3v2E\njWwNAABiowmkilmzZh05cmT69OlPPfVUWlrajBkzwuFwww10XZ8xY0Z2dvacOXNefvnlHj16\nPProo16v16yCT0/ZdHS2CV2W1Z69zS0GAABYSaIHu7KysvXr10+ZMiU/P79NmzbFxcWlpaVb\nt25tuI3H4zl8+PCIESPS0tKcTucVV1zh9/sPHTpkVs2nYTt44NjksF17MDksAACIoUS/FLtz\n505FUfLz843F9PT0du3a7dixo+Hox5mZmV27dl26dGnbtm0VRVm6dGnLli3PP//8yAa6rh88\neDCy6Ha7I9OgNTLn5i8i7VDfC2NYhiRJQgizjiuubDabEEKSJKsenVUPzfidtNlsVj06qx6a\nQZZlvf4ZL4ux8KcW85OJ8S1G05Lowc7j8bjd7oa/W5mZmSdOVvbggw8+8sgj119/vRAiOzv7\nkUcecTgckVeDweD48eMjizfffPPUqVPjXPhJ6DU1we3bjLbUNi+ze+xnm8jOzo75PhOEw+Fo\n+JlaTEpKitklxIvL5XK5rNkzbeFfSCFEVlaW2SXEi4XPk3a7PbZHFwqFYrg3NI5ED3biDP5i\nCIVCM2bM6Nq16+9//3tFUZYsWTJ9+vTnn38+8vtts9lGjBgR2b6goCAQCMSx4lNZt0aEVKOp\n9x8U2xokSVIUxZi012IkSXI4HOFwWFVVs2uJPVmWJUmy5NlTlmW73a6q6nE3xVqDoiiapln1\n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\ndkhctbW1WVlZoVDof/7nfx544IFgMPjQQw/V1NSYXRfOlMfjcbvdkiRF1mRmZlZXV5tYEs4E\nX70mxOv1Pv/881dddVV2djbfOAh67JDIMjMzX3nllcjiL3/5y5tuuunTTz8dOXKkiVXhrDT8\nPwZNBV+9puLAgQO//e1ve/fufdNNNxlr+MaBYIcmIzU1tUWLFmVlZWYXgjOVlZXl8Xh0XY/8\nZ1NdXZ2dnW1uVThbfPUS0+bNm5988slJkyZdeeWVxhq+cRBcikUi279//wsvvBAKhYxFv9//\n/ffft2rVytyqcOY6deqkqmrk/i3j/u7CwkJzq8IP4quX+LZt2zZz5sx77rknkuoE3zgIIeix\nQyLLycn57LPPQqHQddddp2naK6+8kp6eftFFF5ldF06isrJS0zSv1yuEMLp20tPTc3JyBg0a\nNHv27GnTpjkcjrlz53bs2LFbt25mF4tjTvXB8dVLZMFgcNasWePGjWvfvn2kJ5VvHAySrutm\n1wCc0p49e1588UXj4couXbrccccdLVu2NLsonMTtt99+5MiR49aMGzeutrZ2zpw5Gzdu1DSt\ne/fuxcXFXBhKKKf64PjqJbLNmzf/5je/OW7lnXfeOWbMGL5xINgBAABYBPfYAQAAWATBDgAA\nwCIIdgAAABZBsAMAALAIgh0AAIBFEOwAAAAsgmAHAABgEQQ7AE3SiBEjzj//fLOrAIDEQrAD\nAACwCIIdAACARRDsAMTAxx9/PHLkyIyMjLS0tAsuuGDevHmRl/r27Tto0KCPPvpowIABaWlp\nOTk5t956a3V1dWSDDz74YOjQoW63OzU1tUePHn/6058aTnW4YsWKYcOGud3uVq1aXXvttbt2\n7Yq8ZLfb9+7dO3r0aLfb7Xa7J06cWFFR0TjHCwCJiWAHIForV64cPnx4MBh8/fXX33333Qsv\nvPC222774x//aLzqdDp37979wAMPzJo169tvv33uuedee+21W265xXh14cKFY8aMcblcr732\n2uLFi0eNGnXvvfc+8MADxqsrVqwYNWpUSkrKX/7yl8cff/yLL74YOnTo4cOHjVc1TZswYcLQ\noUNfe+214uLif/7zn/fee2/jHz4AJBAdAKLTp0+fgoKCmpqayJpx48a53e66ujpd1wcPHiyE\n+OSTTyKv3nbbbUKIb7/9Vtf1rl27nnfeeYFAIPLqVVddpShKWVmZruv9+vXLz89XVdV4ad26\ndQ6H49lnn9V1ffjw4UKIBQsWRH7woosuys3Nje+hAkBio8cOQFSOHDmycePGMWPG2Gw2f70r\nrrjC6/Vu3brV2Mblcg0ZMiTyI0OHDhVCfPXVVwcPHty+ffsVV1zhcDgir44dO1ZV1bVr15aX\nl2/YsGH06NF2u914acCAAYFAYNq0acZiSkrKVVddFfnBgoKCsrKyeB8vACQygh2AqBw8eFAI\n8eyzz6Y2UFxcLIQ4cOCAsU3Lli0lSYr8SLNmzYQQ3333XWlpqRCibdu2DXfYunVrY7eHDh0S\nQuTm5p7qrY/braIo4XA4dkcGAE2P3ewCAFjBrbfeescddxy3sqCg4KQbh0IhIYTNZjNi2XFp\nTNd141WbzXbiqwCA0yDYAYjKeeedJ4TQNG3gwIGn2ubQoUOapsmybCx+9913QoiWLVu2a9dO\nCGH020UYi+3atcvLyxNClJSUNHx1//79aWlpLVq0iPFhAIAlcCkWQFRycnIGDBiwcOHCqqqq\nyMpXXnnl4YcfNnrmhBB1dXXLly+PvPrBBx84nc4BAwa0atWqR48eixcv9vv9kVcXLFiQlpY2\naNAgt9vds2fPxYsXe71e46Xt27eff/75f/7znxvlyACg6aHHDkC0nnzyyZEjRw4bNuzee+9t\n1arVqlWrZs6cef3110ceesjLy/vFL36xf//+goKCZcuWLVy48MYbb8zOzhZCzJw5c+zYsePH\nj7/rrrscDsd77723dOnSP/zhDxkZGUKIP/zhD+PGjRs5cuTdd9/t8/mefvrp3NzcO++808yj\nBYBEZvZjuQCsYNWqVSNHjnS73YqidO7c+cknn4yMUTJ48OCuXbtu2LBh6NChaWlp2dnZd9xx\nh9frjfzs8uXLhwwZ4nK5nE5nnz595s2b13DP77///sCBA9PS0nJzcydMmPDNN98Y64cPH96+\nffuGWxqjqMT3OAEgsUl6gxHeASDmhgwZUlZWtn37drMLAQDr4x47AAAAiyDYAQAAWATBDgAA\nwCK4xw4AAMAi6LEDAACwCIIdAACARRDsAAAALIJgBwAAYBEEOwAAAIsg2AEAAFgEwQ4AAMAi\n/j8URjq0BtMhxgAAAABJRU5ErkJggg==" + "image/png": "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" }, "metadata": { "image/png": { @@ -16170,18 +16300,18 @@ "\n", "plot(my_history)" ], - "id": "a320c3e2-34a9-4c31-bd0f-5e2f3c400222" + "id": "df9e3f56-5212-4c35-8e92-46bf4c106729" }, { "cell_type": "code", - "execution_count": 414, + "execution_count": 377, "metadata": { - "id": "410b1d87-c3b4-418f-826d-00d0a7050626", - "outputId": "9406d2b2-3088-4347-9a91-b82fa5490f5a", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "93ce1f11-382f-4757-bbd1-28fc22962c4b", + "outputId": "ad8f49f9-bafd-452d-e9f1-9b088d4fefca" }, "outputs": [ { @@ -16193,13 +16323,13 @@ ".dl-inline>dt, .dl-inline>dd {float: none; width: auto; display: inline-block}\n", ".dl-inline>dt::after {content: \":\\0020\"; padding-right: .5ex}\n", ".dl-inline>dt:not(:first-of-type) {padding-left: .5ex}\n", - "
loss
0.062631219625473
accuracy
0.98089998960495
\n" + "
loss
0.0725036263465881
accuracy
0.981700003147125
\n" ], - "text/markdown": "loss\n: 0.062631219625473accuracy\n: 0.98089998960495\n\n", - "text/latex": "\\begin{description*}\n\\item[loss] 0.062631219625473\n\\item[accuracy] 0.98089998960495\n\\end{description*}\n", + "text/markdown": "loss\n: 0.0725036263465881accuracy\n: 0.981700003147125\n\n", + "text/latex": "\\begin{description*}\n\\item[loss] 0.0725036263465881\n\\item[accuracy] 0.981700003147125\n\\end{description*}\n", "text/plain": [ " loss accuracy \n", - " 0.0626 0.9809 " + " 0.0725 0.9817 " ] }, "metadata": {} @@ -16209,13 +16339,13 @@ "my_model %>%\n", " evaluate(x = x_test2d, y = y_test)" ], - "id": "410b1d87-c3b4-418f-826d-00d0a7050626" + "id": "93ce1f11-382f-4757-bbd1-28fc22962c4b" }, { "cell_type": "code", - "execution_count": 415, + "execution_count": 378, "metadata": { - "id": "34043a5d-c3ec-4644-9468-365f10dd5992" + "id": "253e56d5-c86e-4c95-9715-33dd84c68fce" }, "outputs": [], "source": [ @@ -16229,18 +16359,18 @@ " filter(y_ != y) %>% # 予測がはずれたものを残す\n", " arrange(desc(y_prob)) # 確率の大きい順に並び替える" ], - "id": "34043a5d-c3ec-4644-9468-365f10dd5992" + "id": "253e56d5-c86e-4c95-9715-33dd84c68fce" }, { "cell_type": "code", - "execution_count": 416, + "execution_count": 379, "metadata": { - "id": "4ed35f60-5527-453a-92bc-396cb6885671", - "outputId": "d1e587f6-eb96-4f09-e61d-1fe99056ae1d", "colab": { "base_uri": "https://localhost:8080/", "height": 286 - } + }, + "id": "dbd55cd7-365c-4c08-a7dd-d2c6ca4b5df9", + "outputId": "9386ea4e-99f0-4453-c49e-93339e29661b" }, "outputs": [ { @@ -16254,25 +16384,25 @@ "\t<dbl><dbl><int><int>\n", "\n", "\n", - "\t11.00053 450\n", - "\t20.999271227\n", - "\t30.999273768\n", - "\t40.999463521\n", - "\t50.999706598\n", - "\t60.998731682\n", + "\t11463521\n", + "\t21724177\n", + "\t3153 450\n", + "\t41484957\n", + "\t5106 260\n", + "\t61273768\n", "\n", "\n" ], - "text/markdown": "\nA data.frame: 6 × 4\n\n| | y_prob <dbl> | y_ <dbl> | y <int> | id <int> |\n|---|---|---|---|---|\n| 1 | 1.000 | 5 | 3 | 450 |\n| 2 | 0.999 | 2 | 7 | 1227 |\n| 3 | 0.999 | 2 | 7 | 3768 |\n| 4 | 0.999 | 4 | 6 | 3521 |\n| 5 | 0.999 | 7 | 0 | 6598 |\n| 6 | 0.998 | 7 | 3 | 1682 |\n\n", - "text/latex": "A data.frame: 6 × 4\n\\begin{tabular}{r|llll}\n & y\\_prob & y\\_ & y & id\\\\\n & & & & \\\\\n\\hline\n\t1 & 1.000 & 5 & 3 & 450\\\\\n\t2 & 0.999 & 2 & 7 & 1227\\\\\n\t3 & 0.999 & 2 & 7 & 3768\\\\\n\t4 & 0.999 & 4 & 6 & 3521\\\\\n\t5 & 0.999 & 7 & 0 & 6598\\\\\n\t6 & 0.998 & 7 & 3 & 1682\\\\\n\\end{tabular}\n", + "text/markdown": "\nA data.frame: 6 × 4\n\n| | y_prob <dbl> | y_ <dbl> | y <int> | id <int> |\n|---|---|---|---|---|\n| 1 | 1 | 4 | 6 | 3521 |\n| 2 | 1 | 7 | 2 | 4177 |\n| 3 | 1 | 5 | 3 | 450 |\n| 4 | 1 | 4 | 8 | 4957 |\n| 5 | 1 | 0 | 6 | 260 |\n| 6 | 1 | 2 | 7 | 3768 |\n\n", + "text/latex": "A data.frame: 6 × 4\n\\begin{tabular}{r|llll}\n & y\\_prob & y\\_ & y & id\\\\\n & & & & \\\\\n\\hline\n\t1 & 1 & 4 & 6 & 3521\\\\\n\t2 & 1 & 7 & 2 & 4177\\\\\n\t3 & 1 & 5 & 3 & 450\\\\\n\t4 & 1 & 4 & 8 & 4957\\\\\n\t5 & 1 & 0 & 6 & 260\\\\\n\t6 & 1 & 2 & 7 & 3768\\\\\n\\end{tabular}\n", "text/plain": [ " y_prob y_ y id \n", - "1 1.000 5 3 450\n", - "2 0.999 2 7 1227\n", - "3 0.999 2 7 3768\n", - "4 0.999 4 6 3521\n", - "5 0.999 7 0 6598\n", - "6 0.998 7 3 1682" + "1 1 4 6 3521\n", + "2 1 7 2 4177\n", + "3 1 5 3 450\n", + "4 1 4 8 4957\n", + "5 1 0 6 260\n", + "6 1 2 7 3768" ] }, "metadata": {} @@ -16281,18 +16411,18 @@ "source": [ "head(my_result)" ], - "id": "4ed35f60-5527-453a-92bc-396cb6885671" + "id": "dbd55cd7-365c-4c08-a7dd-d2c6ca4b5df9" }, { "cell_type": "code", - "execution_count": 417, + "execution_count": 380, "metadata": { - "id": "94144d0f-e83c-420a-9ebd-5839266f4966", - "outputId": "b0b278ba-7fe1-4e08-ee1b-1107adfe3920", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "eb900d0d-59cb-4f0f-bfd0-783ae3014e61", + "outputId": "bfdf3020-7bc9-4994-fb65-1ef5f5902c9b" }, "outputs": [ { @@ -16301,7 +16431,7 @@ "text/plain": [ "plot without title" ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAIAAAByhViMAAAACXBIWXMAABJ0AAASdAHeZh94\nAAAgAElEQVR4nO3de5hddXno8TVMMrlNbpNJJgnkzlUgEEAQCRAEioBQIVKPWkKfosd6jlpE\ne6qn4uXoqbbU+pxSbTmlRMUbAlIrtAJRRBRQIQmGSyAJ5J4wyUwmySSZmUxmnz/mmOe318zs\nZGCubz6fv/quWXvvFdbee77u7t+sskKhkAEAMPgd1d8HAABAzxB2AABBCDsAgCCEHQBAEMIO\nACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgB\nAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsA\ngCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcA\nEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAA\nghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBA\nEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAI\nQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABB\nCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAI\nYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh\n7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCE\nHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISw\nAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2\nAABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIO\nACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgB\nAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsA\ngCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcA\nEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAA\nghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBA\nEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAI\nQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABB\nCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAI\nYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh\n7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCE\nHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISw\nAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2\nAABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIO\nACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgB\nAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsA\ngCCEHQBAEMIOACAIYQcAEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACAIYQcA\nEISwAwAIQtgBAAQh7AAAghB2AABBCDsAgCCEHQBAEMIOACCImGHX3Nx85pln3nbbbT11h5/4\nxCeuuuqqQqHQU3dIz+rxM94Vz4QByNk/kjn7RzJnv3OFQeWFF1646qqrqqqqxo8ff9FFFz3x\nxBOd7nbTTTddfvnluY2LFy/Osuz+++9vH+fOnZv+dxg1alT79vr6+ve9731Tp06tqqq68sor\nX3311UKh0NLSMnfu3K985Su99Q+jM48++mjHZ+xtt93Wcc/cGV+5cuU555xTXl6e7rNp06b3\nvOc9kyZNGj169AUXXPDrX/+6xPauHtozoc+8vrPf6VtE6bv62te+NmvWrIqKilNPPfXHP/5x\n+8YXX3zxHe94R3V19dixY88///zHH3+84H2gz3V6anIOefYLXb/bd/WeUOjsPcTZ70ud/iLu\nKPfO3+kTpquzv3r16muvvXbixImVlZXvete7amtr27cHeO0PprBrbm6eOnXq9ddfv3LlylWr\nVi1atGjcuHG7du3K7bZu3bqKioqlS5emG7du3VpTUzNixIiDYXfMMcf8wz/8w4bf27RpU/v2\nq6++ev78+cuXL3/55Zff8573nHzyya2trYVC4b777quqqtq9e3fv/0P5/5qamjYkHn/88crK\nyueffz63W+6Mf//7358yZcqiRYtyYXfWWWfNnz9/6dKlq1ateu9731tdXd3Y2NjV9hIP7ZnQ\nN17H2e/qLaLEXS1evHjy5MkPPPDA2rVr//7v/37OnDk7d+5sa2ubPXv2+9///oaGhj179txy\nyy2VlZXbt28vOPt9qNNTk9vncM5+oet3+67eE7p6D3H2+0xXv4hTuXf+rp4wnZ79pqam4447\n7qqrrlq5cuWKFSsuvvjiCy+8sFAoxHjtD6awq62tvfXWWw+W3MqVK7MsW7ZsWW63T37yk299\n61tzGxcuXHjzzTfX1NQcDLuRI0c++OCDud3Wr19fVlZ28D7r6+uHDBnyyCOPFAqFtra2o48+\n+vbbb+/ZfxSH75JLLvnsZz/bcXvujH/zm99ct27d/fffn74p19XVXXvttS+88EL7uG7duizL\nfvOb33S1vcRDeyb0i8M5+4f5FpHe1Zw5c77xjW/kdqitrc2y7ODnPZs3b86y7Kmnnio4+32o\n01OTc5hnv9N3+xKv/U7fQwrOfl8p8Ys4lXvn7+oJ0+nZf+qpp7Is27hx48FHzLJsxYoVMV77\ngynsUnV1dR/60IdOPPHEpqam3I/mzZv3mc98Jt1y3333zZo1q7Gx8WDYNTU1ZVl24403zps3\nb/r06ddee+1LL71UKBR++MMfjhgxoq2t7eBtTz311C9+8Yvt//f111//rne9q3f/YXThe9/7\n3syZM5ubmzv+qOMZLxQKHd+UU0888UR5efmWLVsOZ3vHh/ZM6GPdPfuFrt8i0rvauHFjlmXf\n+MY35s6dO3LkyLPPPvvgG/q55557ww031NXV7d69+3Of+9ysWbP27dvX/iNnvw+UODWpwzn7\nXb3b53R87Xf6HuLs94HSv4gPSs9+V0+Yrs7+Y489lmVZXV1d+833798/dOjQxYsXF0K89gff\n4okDBw4MHz58woQJL7zwwpIlS4YNG5bbYcWKFaeddtrBcceOHR/+8Idvv/32UaNGHdy4a9eu\nmpqalpaWf/7nf/7BD36wb9++Cy64oKGhYdu2bVVVVWVlZQf3nDhxYnvCZ1l22mmnrVixojf/\ncXTuwIEDn/3sZ2+55ZaKioqOP82d8UOqr6+/8cYbP/7xj0+ePPmQ2zt9aM+EvtTds1/iLSJ3\nV+2/DBYvXnz33Xdv2LDh3HPPveKKK7Zt25Zl2b333vv0009PmDBh9OjRt99++7333jt8+PD2\nO3H2+0CJU5M6nLPf1bt9equu3hM6cvb7QOlfxAelZ7+rJ0xXZ3/evHnV1dWf+cxnWlpaWlpa\nvvCFL2RZVldXl4V47Q++sCsvL1++fPmjjz5aXV29YMGCHTt2pD/duXNna2trdXX1wS0333zz\nZZdddumll6a7TZw4cevWrd/61rfOPvvsc8455+67725sbLzvvvuyLEufTO0Obqmuru74zkIf\nuOeee/bs2bNo0aKOP+p4xktr/070ggULvvzlLx/O9k4f2jOhL3X37Jd4i+j0rj796U+feOKJ\nVVVVt956a1lZ2YMPPtjS0nLllVeee+65tbW1DQ0NH/3oRy+77LItW7a07+/s95mOpyb96WGe\n/RLv9u26eu13ytnvGyV+Ebfr9Ox3fMJ0dfZHjx597733PvTQQ5WVlZMmTcqybMaMGUOHDo3x\n2h98YZdl2YknnrhgwYK7775727Zt3/nOdzrucPAZ8Mgjj/zkJz/5yle+UvoOR48ePX369A0b\nNtTU1LR/TfLgj2pra2tqanJ3Sx+76667Fi5cOGTIkK52OMxT89Of/nT+/Pkf/ehHv/71r6c3\n6Wp7Vw/tmdCXXsfZ7+otIndXU6dOzbJs3Lhx7ePQoUOnTp26ZcuWn//8588+++xXv/rViRMn\njh079pOf/OTIkSPvueeerh6OHtfVqem45+Gf/XYH3+3bxxKv/U45+32g9C/i1MHTcZhPmPTs\nX3jhhatWraqtra2trf2rv/qr9evXT58+PcZrfzCF3cMPP3zsscfu3bu3fTzqqKOGDh2a+w89\nZsyYIUOGHGzqO++8s6Gh4fjjj6+urq6urq6trV20aNHChQufe+65D3zgAy0tLe27NTY2rl+/\nfs6cOW9+85ubm5ufeeaZ9u3bt29/8cUXzzvvvPZx27Zth//JED2loaHhkUceueqqqzr9ae6M\nl/DLX/7yuuuuu+uuuz7ykY8czvYSD+2Z0Ge6dfZLv0V0vKupU6dOmTLlySefbB/37du3fv36\nWbNmtX+5p62t7eCe+/fvP/h/O/t9oKtTk+5zmGe/q3f7rORrvyvOfh8o/Yu4Xe7sd/WE6ers\nt7a23n333Vu3bh03blxFRcXDDz/c1tY2f/78IK/9/v2KX7fU19fX1NRcd911zz///Jo1a/78\nz/98xIgRq1evzu12+umnH1zyVldXl/6Zg4kTJ95xxx3btm3bvn37hAkTFi1atGbNmpUrV157\n7bXTpk3bs2dPoVBYuHDhGWecsXz58pdeeunyyy9/85vffPArnIsWLRoUX5wMZsmSJVmWrV27\ntqsd0jNeKBS2bNmyYcOGO+64o7y8vP287969e+/evbNnz/785z+fPh8aGxu72l76oT0T+ky3\nzn7pt4hO7+pLX/pSdXX1ww8/vH79+htvvHHKlCmNjY0NDQ2TJ09+//vfX19fv3fv3r/9278d\nPnz4qlWr2m/i7PeNTk9Nbp/DOftdvduXeO13+h7S/ijOft8o8Yv4oNw7f6dPmBK/608//fRr\nrrlmw4YNv/jFL6ZOnfpnf/ZnhUIhxmt/MIVdoVBYsWLF29/+9lGjRo0ePfotb3nLkiVLOu7z\nl3/5l+edd16nN0//3MmyZcsuvvjisWPHTpw48eqrr37llVfat+/cufOGG26YMmVKdXX1Nddc\ns3nz5vbtbW1txxxzzKBY6hzMXXfdVVZW1umKyHa5Mz5jxozc/3r56le/2v5LPee2227ranuJ\nh/ZM6EvdPfsl3iI6vavW1tZPfepTNTU1FRUVF1xwwcE/frFixYorrriiurp63Lhx55133s9+\n9rP27c5+n+nq1KQO8+x3+m5f4rXf6XtIwdnvQ139Ik7lzn5XT5iufte//PLLF1100ciRIydO\n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\nOwCAIIQdAEAQwg4AIAhhBwAQhLADAAhC2AEABCHsAACCEHYAAEEIOwCAIIQdAEAQwg4AIAhh\nBwAQhLADAAhC2AEABCHsAACCEHYAAEEIOwCAIIQdAEAQwg4AIAhhBwAQhLADAAhC2AEABCHs\nAACCEHYAAEEIOwCAIIQdAEAQwg4AIAhhBwAQhLADAAhC2AEABCHsAACCEHYAAEEIOwCAIIQd\nAEAQwg4AIAhhBwAQhLADAAhC2AEABCHsAACCEHYAAEEIOwCAIIQdAEAQwg4AIAhhBwAQhLAD\nAAhC2AEABCHsAACCEHYAAEEIOwCAIIQdAEAQwg4AIAhhBwAQhLADAAhC2AEABCHsAACCEHYA\nAEEIOwCAIIQdAEAQwg4AIAhhBwAQhLADAAhC2AEABCHsAACCEHYAAEEIOwCAIIQdAEAQwg4A\nIAhhBwAQhLADAAhC2AEABCHsAACCEHYAAEEIOwCAIIQdAEAQwg4AIAhhBwAQhLADAAhC2AEA\nBCHsAACCEHYAAEEIOwCAIIQdAEAQwg4AIAhhBwAQhLADAAhC2AEABCHsAACCEHYAAEEIOwCA\nIIQdAEAQwg4AIAhhBwAQhLADAAhC2AEABCHsAACCEHYAAEEIOwCAIIQdAEAQwg4AIAhhBwAQ\nhLADAAhC2AEABCHsAACCEHYAAEEIOwCAIIQdAEAQwg4AIAhhBwAQhLADAAhC2AEABCHsAACC\nEHYAAEEIOwCAIIQdAEAQwg4AIAhhBwAQhLADAAhC2AEABCHsAACCEHYAAEEIOwCAIIQdAEAQ\nwg4AIAhhBwAQhLADAAhC2AEABCHsAACCEHYAAEEIOwCAIIQdAEAQwg4AIAhhBwAQhLADAAhC\n2AEABCHsAACCEHYAAEEIOwCAIIQdAEAQwg4AIAhhBwAQhLADAAhC2AEABCHsAACCEHYAAEEI\nOwCAIIQdAEAQwg4AIAhhBwAQhLADAAhC2AEABCHsAACCEHYAAEEIOwCAIIQdAEAQwg4AIAhh\nBwAQhLADAAhC2AEABCHsAACC+H+odovMOguTaAAAAABJRU5ErkJggg==" + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAIAAAByhViMAAAACXBIWXMAABJ0AAASdAHeZh94\nAAAgAElEQVR4nO3de5zXdZ3o8e8IDPfbMMMAclFIg1RAvKCJSF4yNd0E3XO0jfax2qM9j+7W\nPmorc9v2sfXIU57y1MaeNiu3fWjetrJOireyvBQBhiCIKFelAYYBYWAGmN/5Y06zn993mB8z\nMjfePp9/9f7O9/f9fen7+w2vfv0+fMsKhUIGAMCx77iePgEAADqHsAMACELYAQAEIewAAIIQ\ndgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDC\nDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELY\nAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7\nAIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEH\nABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewA\nAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0A\nQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMA\nCELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAA\nQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAg\nCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAE\nIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAg\nhB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCE\nsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQ\ndgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDC\nDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELY\nAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7\nAIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEH\nABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewA\nAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0A\nQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMA\nCELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAA\nQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAg\nCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAE\nIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAg\nhB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCE\nsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQ\ndgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDC\nDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELY\nAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7\nAIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQcQJu4aGhjPOOOP222/v6if6\n1Kc+deWVVxYKha5+ItrP1adZp78SXPFeznufZt77/6VwLPjWt7514oknlpeXn3baaT/72c8O\nu8/HP/7xyy67rPk/r1q16sorr6yoqBg5cuQ73vGOp556qnn79OnT0z/74MGDm7dv2bLluuuu\nGz169NChQ+fOnfvss8+2HHb16tWzZ8/u06dPy5bGxsbp06d/7Wtf65I/KsVKXJpUevVb3HHH\nHVmWPfDAAy1bWl/Nxx9/vPWb4vbbb29ru6vfU9p6U+e055XQ1u+B2tra9773vePGjauoqLji\niiteeeWVgvd7z3nhhRfe/e53V1ZWDh8+/Pzzz3/yyScPu1t7rvhLL700f/78qqqqIUOGXHPN\nNTU1Nc3bD/tK8N7vhTraACX+4jjsoYK994+BsLvjjjvGjBnz4IMPrl+//utf//qUKVN27dqV\n22fDhg3l5eVLly4tFAoNDQ3jxo173/vet3r16rVr1y5cuHDEiBG7d+8uFArjx4//5je/uenP\ntmzZ0vzwM888c86cOUuXLl27du31119fWVm5Z8+eQqFw1113jR07duHChWkKFAqF++67r6Ki\n4vXXX++OP/+bW1uXJpVe/RZbt26trq4eOHBgyy/3w17N/fv3b0o8+eSTQ4YMWblyZVvbC65+\nTyjxpk6185XQ1u+Bq666as6cOcuXL3/xxRevu+66U0455eDBgwVXvCc0NTVNnjz5xhtvrKur\n27t378033zxkyJDt27fndmvPFd+/f/9JJ5105ZVXrl69esWKFRdddNEFF1zQvOdhXwne+71N\nRxug0PZfHG0dKth7/xgIuylTpnz/+98vvc9nPvOZt7/97c3/uaam5tZbb235pb969eosy5Yt\nW1YoFAYNGvTzn/8899gdO3bMnz9/1apVzeOGDRuyLPvd735XKBR+8IMfbNiw4YEHHsiFXVNT\n0/HHH79o0aKj/sNRSolLk0qvfosFCxbcdNNN1dXVLX+dt3U1UxdffPEtt9xSerur3/1KvKlT\n7XwlHPb3wMaNG8vKylqOWVtb27dv38WLFxdc8Z5QU1OTZVnL57KvvvpqlmXPPPNMbrf2XPFn\nnnkmy7LNmzc3/3Tjxo1Zlq1YsaLQxishx3u/x3W0AUr8xXHYQ8V77/f279ht2bJl3bp1WZbN\nmDFj8ODBs2fPfvrpp1vv9tBDD1188cXN/7mqqupTn/rU0KFDsyyrra39xje+MXXq1GnTpjU0\nNNTX199///2zZs2aNGnSggULXnzxxSzLKioq7rvvvmnTprU8Y58+fSZMmJBl2cKFCydOnNj6\n6crKyi688MLFixd3zR+a/6/EpUmlV7/Z/fffv3Tp0n/8x39MN7Z1NVvcddddL7300mc/+9nS\n21397tfWmzq3W3teCW39HliyZMmAAQNmzJjRvNvIkSOnTZv27LPPZq54T6iqqjr33HMXLVpU\nW1u7Z8+ef/3Xfz3xxBNbrk6Ldl7xLMsGDhzYPI4dO7Zfv35Llixp65WQ8t7vcW+gAdr6i6Ot\nQ8V77/f2sNu8eXOWZXfcccfdd9+9adOmc8899/LLL9+2bVtutxUrVuTe84cOHRowYMCoUaNW\nrVr1yCOP9O/ff/fu3dXV1Y2Njd/5znd+/OMf79u3b+7cuXV1demjamtrb7jhhk9+8pNjxowp\nfWIzZsxYsWJFZ/wRaZcSlyZ39Xfu3PnhD3940aJFgwcPbv/xDx06dMstt9x8883l5eVH3O7q\n94jWb+rcDu15JbT1e2Dbtm0VFRVlZWUte1ZVVTV/bpS54j3h3nvvXbJkyahRo4YOHbpo0aJ7\n7713wIABuX3ac8VPP/30ysrKL3zhC42NjY2NjV/60peyLNuxY8cR/0bw3u8N3nADNEv/4mjr\nUPHe+7097Jp9/vOfnzp1akVFxa233lpWVvbzn/88/emuXbsOHjxYWVmZbuzTp8/y5csff/zx\nysrKefPm7dy5s6qqauvWrT/84Q/PPvvs2bNn33333Xv27LnvvvtaHtL8zfp58+Z95StfOeIp\nVVZWtn5t0UVKXJrWV/+mm2669NJLL7nkkg49xT333LN3796FCxe2Z7ur3yNav6nTn7bzlVDi\n90D6m71ZyxZXvJs1NjZeccUV5557bk1NTV1d3Uc/+tFLL730tddeS/dp5xUfOnTovffe+9BD\nDw0ZMmT06NFZlk2aNKlfv35H/BvBe7/3eAMNkLXxF8dhDxXsvd/bw27cuHFZlo0YMaJ57Nev\n37hx43Jv72atL8zUqVPnzZt39913b9u27Uc/+lHup0OHDp04ceKmTZuax0cffXTOnDkf/ehH\nv/3tb7c+VHueji7SnkvTsn3x4sW//OUvv/a1r3X0We68884FCxb07du3Pdtd/Z5S+k2ddfyV\n0PJ7oLq6uvm7+S0/qqmpqa6uzh2W7vHEE08899xzt912W1VV1fDhwz/zmc8MGjTonnvuab1n\ne674BRdcsHbt2pqampqams997nMbN25s/a2M3N8Imfd+7/CGG6D1XxxtHSree/8YCLuxY8e2\n/H/q+/bt27hx44knnpjuM2zYsL59+7Y09cMPP/yWt7ylvr6+eTzuuOP69etXVlb2/PPPf+AD\nH2hsbGzevmfPno0bN06ZMiXLst/85jfXXnvtnXfe+ZGPfKSdJ7Zt27bW//uATnfES5O7+t/7\n3vfq6upOPvnkysrKysrKmpqahQsXLliwoPSz1NXVLV68+Morr2zndle/m7X1pk73aecroa3f\nA2eddVZDQ8Mf/vCH5u3bt29/4YUXzjvvvObRFe9mTU1NhUKhqampZcuBAwdy+7Tzih88ePDu\nu+/eunXriBEjysvLH3744aampjlz5pT4GyHz3u813kADZG38xdHWoQK+93t48UY7fPnLX66s\nrHz44Yc3btx4ww03jB07tvU/eDFz5syWhUu1tbXV1dXXXnvtypUr161b97GPfWzgwIEvvfTS\n9u3bR40atXDhwnXr1q1evXr+/PkTJkzYu3dvfX395MmTv/jFL6ZL3Juf4rXXXtu0adN3v/vd\nPn36NG9vWfa8cOHCa665phv/a3gzKnFpUunV37FjR7pzVVXVd7/73W3bthVKXs1HHnkky7L1\n69fnjtzWdle/m7X1ps7t1p5XQlu/BwqFwoIFC2bNmrV8+fI1a9ZcdtllZ511VnNeFFzxbldX\nVzdmzJgbb7yxtra2vr7+q1/96oABA9auXZvbrZ3v/ZkzZ1599dWbNm369a9/PW7cuL/9278t\nFAolXgkF7/3epKMNUOIvjrYOFey9fwyE3cGDB//+7/++urq6vLx87ty5LWuYU5/+9KfPO++8\nlnHFihXvete7Bg8ePHTo0HPOOeeRRx5p3r5s2bKLLrpo+PDhVVVVV1111csvv1z48xs45/bb\nby8UCpMmTcptv+222wqFQlNT0/jx44+5JdDHnBKXJpW7+qn0H7lo62oWCoU777yzrKysoaEh\n9/DDbnf1e0Rbb+pUO18Jh/09UCgUdu3a9f73v3/s2LGVlZVXX331q6++2rzdFe8RK1asuPzy\nyysrK0eMGHHeeec99thjrfdp5xV/8cUX3/GOdwwaNKiqqurjH/94yzu6rVdCwXu/N+loA5T4\ni6OtQwV77x8DYdce69evLy8vX758efc83QMPPHAs/qOFUbn6NOuiV4Ir3mt579PMez9VVjgW\n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\nDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELY\nAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7\nAIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEH\nABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewA\nAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0A\nQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMA\nCELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAA\nQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAg\nCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAE\nIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAg\nhB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCE\nsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQ\ndgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDC\nDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELY\nAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7\nAIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEH\nABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewA\nAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0A\nQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMA\nCELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAA\nQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAg\nCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAE\nIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAg\nhB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCE\nsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQ\ndgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDC\nDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELY\nAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7\nAIAghB0AQBDCDgAgCGEHABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEH\nABCEsAMACELYAQAEIewAAIIQdgAAQQg7AIAghB0AQBDCDgAgCGEHABDE/wOuBW2a6FkJ3QAA\nAABJRU5ErkJggg==" }, "metadata": { "image/png": { @@ -16330,27 +16460,27 @@ " theme(legend.position = \"none\") +\n", " facet_grid(. ~ label)" ], - "id": "94144d0f-e83c-420a-9ebd-5839266f4966" + "id": "eb900d0d-59cb-4f0f-bfd0-783ae3014e61" }, { - "id": "6b7dfe70", + "id": "a328c907", "cell_type": "markdown", "source": [ "## 11.4 AutoML" ], "metadata": { - "id": "6b7dfe70" + "id": "a328c907" } }, { "cell_type": "code", - "execution_count": 418, + "execution_count": 381, "metadata": { - "id": "38722ec1-ec1e-4e8e-b088-c4fd85c7219d", - "outputId": "e29d2b3c-8a99-4762-ecf3-30833ad4c9bf", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "c08239b8-aa1b-4aea-8ab6-56ea05e3b94f", + "outputId": "1680f27f-4984-466c-fdb6-a04c2b502499" }, "outputs": [ { @@ -16399,17 +16529,25 @@ "output_type": "stream", "name": "stdout", "text": [ - " Connection successful!\n", + "\n", + "H2O is not running yet, starting it now...\n", + "\n", + "Note: In case of errors look at the following log files:\n", + " /tmp/RtmpB6geVI/file1858a6cc71/h2o_UnknownUser_started_from_r.out\n", + " /tmp/RtmpB6geVI/file1856feaa6b9/h2o_UnknownUser_started_from_r.err\n", + "\n", + "\n", + "Starting H2O JVM and connecting: .... Connection successful!\n", "\n", "R is connected to the H2O cluster: \n", - " H2O cluster uptime: 1 hours 41 minutes \n", + " H2O cluster uptime: 4 seconds 376 milliseconds \n", " H2O cluster timezone: Etc/UTC \n", " H2O data parsing timezone: UTC \n", " H2O cluster version: 3.44.0.3 \n", - " H2O cluster version age: 3 months and 2 days \n", - " H2O cluster name: H2O_started_from_R_root_zkb270 \n", + " H2O cluster version age: 3 months and 4 days \n", + " H2O cluster name: H2O_started_from_R_root_gor915 \n", " H2O cluster total nodes: 1 \n", - " H2O cluster total memory: 3.14 GB \n", + " H2O cluster total memory: 3.17 GB \n", " H2O cluster total cores: 2 \n", " H2O cluster allowed cores: 2 \n", " H2O cluster healthy: TRUE \n", @@ -16431,17 +16569,17 @@ "h2o.no_progress()\n", "# h2o.shutdown(prompt = FALSE) # 停止" ], - "id": "38722ec1-ec1e-4e8e-b088-c4fd85c7219d" + "id": "c08239b8-aa1b-4aea-8ab6-56ea05e3b94f" }, { "cell_type": "code", - "execution_count": 419, + "execution_count": 382, "metadata": { - "id": "1fdfc213-d4b9-4282-a110-c9d3a1417b16", - "outputId": "39cd585a-d800-4a98-dd45-b3b97e7c3fcb", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "e9c9a625-d1af-4f44-8111-14d8f867b289", + "outputId": "099c02ec-19a6-443b-d794-d480df83eecb" }, "outputs": [ { @@ -16466,18 +16604,18 @@ "# あるいは\n", "my_frame <- h2o.importFile(my_url, header = TRUE) # データを読み込む." ], - "id": "1fdfc213-d4b9-4282-a110-c9d3a1417b16" + "id": "e9c9a625-d1af-4f44-8111-14d8f867b289" }, { "cell_type": "code", - "execution_count": 420, + "execution_count": 383, "metadata": { - "id": "0e8ad572-d34d-4ffc-add8-515c0ec0cfb9", - "outputId": "aa839eaa-e7e4-472d-9a01-841c27a87f34", "colab": { "base_uri": "https://localhost:8080/", - "height": 442 - } + "height": 448 + }, + "id": "c4ca3bd2-c490-473c-be16-2836c4ceca7f", + "outputId": "7885acd8-538f-4f32-eb1b-fc5aa67de409" }, "outputs": [ { @@ -16539,13 +16677,13 @@ "my_frame %>% as.data.frame %>% head\n", "# 結果は割愛(見た目は同じ)" ], - "id": "0e8ad572-d34d-4ffc-add8-515c0ec0cfb9" + "id": "c4ca3bd2-c490-473c-be16-2836c4ceca7f" }, { "cell_type": "code", - "execution_count": 421, + "execution_count": 384, "metadata": { - "id": "30b1a834-1996-49ff-bd17-c1fbe4c8e361" + "id": "c66624cf-e5a4-402e-a515-c9c2d7a0c335" }, "outputs": [], "source": [ @@ -16554,30 +16692,30 @@ " training_frame = my_frame,\n", " max_runtime_secs = 60)" ], - "id": "30b1a834-1996-49ff-bd17-c1fbe4c8e361" + "id": "c66624cf-e5a4-402e-a515-c9c2d7a0c335" }, { "cell_type": "code", - "execution_count": 422, + "execution_count": 385, "metadata": { - "id": "31bffa0f-c204-4f58-9202-60148669e99a", - "outputId": "1457d8a3-ab0f-49a0-9f6f-ef8a4c10a8f4", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "e8300b70-73a9-4a55-aae4-46480fee806e", + "outputId": "ac914d79-d0fe-48cf-e966-97f8157d3ae0" }, "outputs": [ { "output_type": "display_data", "data": { "text/html": [ - "0.278905338815714" + "0.265658882087059" ], - "text/markdown": "0.278905338815714", - "text/latex": "0.278905338815714", + "text/markdown": "0.265658882087059", + "text/latex": "0.265658882087059", "text/plain": [ - "[1] 0.279" + "[1] 0.266" ] }, "metadata": {} @@ -16586,18 +16724,18 @@ "source": [ "min(my_model@leaderboard$rmse)" ], - "id": "31bffa0f-c204-4f58-9202-60148669e99a" + "id": "e8300b70-73a9-4a55-aae4-46480fee806e" }, { "cell_type": "code", - "execution_count": 423, + "execution_count": 386, "metadata": { - "id": "16782f30-d94a-4d84-979b-707002b3e0d4", - "outputId": "72c51b06-2fae-4931-bb1e-2f5a2bb17271", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "5ebfd908-fea8-4e8a-8b94-532d228b8845", + "outputId": "3c814bf0-8ec7-4903-96f5-6f3ac370feb9" }, "outputs": [ { @@ -16606,7 +16744,7 @@ "text/plain": [ "plot without title" ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAADAFBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUW\nFhYXFxcYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMkJCQlJSUmJiYnJyco\nKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6\nOjo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tM\nTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1e\nXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1ubm5vb29w\ncHBxcXFycnJzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+fn5/f3+AgICBgYGC\ngoKDg4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OU\nlJSVlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGioqKjo6OkpKSlpaWm\npqanp6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O0tLS1tbW2tra3t7e4\nuLi5ubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTFxcXGxsbHx8fIyMjJycnK\nysrLy8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc\n3Nzd3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u\n7u7v7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7+/v8/Pz9/f3+/v7////i\nsF19AAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO3deXhU1f2A8ZOdAImyR2RVkapF\n1ooWVGjc11aoSG01ihYsCipYUNkEQQXrCgJq3VcUFK1aiij9gSvQqBFEQVBQRFnCnn3uLzN3\nkgAzzEwy37lnzp3380fOgbmT+32ueR+SmTGjLABRU7oHANyAkAABhAQIICRAACEBAggJEEBI\ngABCAgQQEiCAkAABhAQIICRAACEBAggJEEBIgABCAgQQEiCAkAABhAQIICRAACEBAggJEEBI\ngABCAgQQEiCAkAABhAQIICRAACEBAggJEEBIgABCAgQQEiCAkAABhAQIICRAACEBAggJEEBI\ngABCAgQQEiCAkAABhAQIICRAACEBAggJEEBIgABCAgQQEiCAkAABhAQIICRAACEBAggJEEBI\ngABCAgQQEiCAkAABhAQIICRAACEBAggJEEBIgABCAgQQEiCAkAABhAQIICRAACEBAggJEEBI\ngABCAgQQEiCAkAABhAQIICRAACEBAggJEEBIgABCAgQQEiCAkAABhAQIICRAACEBAggJEEBI\ngABCAgQQEiCAkAABhAQIICRAACEBAggJEEBIgABCAgQ4ENJnywGjfFb7r/LYh7RMAYZZVusv\n89iH9IEqifk5AEEl6oNa34eQgIMQEiCAkAABhAQIICRAACEBAggJEEBIgABCAgQQEiCAkAAB\nhAQIICRAACEBAggJEEBIgABCMsmGO/rlDlukewoEQUgGeaVB5xtuvyA1r1z3IAhASOYoSL/b\nU7msaDpe9yQIQEjmuOIce306q0jvIAhESOZo/6i97lYf6R0EgQjJHE1f9W/SF2idA0EQkjm6\n3G2v36lVegdBIEIyx/ij9vjWmzpqHgSBCMkcO485dbVl7bo99d+6J0EAQjLIhlzV4tiUlm/o\nngOBCMkoX700e2mx7iEQBCEBAggJEEBIgABCAgQQEiCAkAABhAQIICRAACEBAggJEEBIgABC\nAgQQEiCAkAABhAQIICRAACEBAggJEEBIgABCAgQQEiCAkAABhAQIICRAACEBAggJEKAlpNIv\nl4f+vbuEBMM4G9KiPu3O/dj6d0ulsmeEOo6QYBhHQ/owVWUnN/gwu/UVlzZS74Q4kJBgGEdD\nujDnc+uXvm0677Os7e3OCXEgIcEwjobUZFLlh2XqKe/+zsYhDiQkGMbRkFKfqfywSb3l3f8z\nNcSBhATDOBpSi/GVHxarB73721qEOJCQYBhHQ7qs8XslX3Q6rs0PlrWqUf8QBxISDONoSF9l\nKaUar2pbv+8pqSmfhDiQkGAYZ59HKhjYM2+1VXBSkjrq9VDHERIMo+clQrt/CX07IcEwvNYO\n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\nAggJEPD/MYzconnkl+QAAAAASUVORK5CYII=" + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAMAAADKOT/pAAADAFBMVEUAAAABAQECAgIDAwME\nBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUW\nFhYXFxcYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMkJCQlJSUmJiYnJyco\nKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2NjY3Nzc4ODg5OTk6\nOjo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tM\nTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVlaWlpbW1tcXFxdXV1e\nXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2tsbGxtbW1ubm5vb29w\ncHBxcXFycnJzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+fn5/f3+AgICBgYGC\ngoKDg4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OU\nlJSVlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGioqKjo6OkpKSlpaWm\npqanp6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O0tLS1tbW2tra3t7e4\nuLi5ubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PExMTFxcXGxsbHx8fIyMjJycnK\nysrLy8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc\n3Nzd3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u\n7u7v7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6+vr7+/v8/Pz9/f3+/v7////i\nsF19AAAACXBIWXMAABJ0AAASdAHeZh94AAAgAElEQVR4nO3deXxU5bnA8TcrhBCCooIgYccN\nK4sUrcjFC2pBvbKoFFFBQLEC4r2iuEOtikJlUZHFDaGIVbZevXWrCq2AAilSFFlEFCQgS9gT\nEkjOzcyZJEAmM5PJc84778nv+0fe18zJzPM55vchmZnMKAtApSndAwBeQEiAAEICBBASIICQ\nAAGEBAggJEAAIQECCAkQQEiAAEICBBASIICQAAGEBAggJEAAIQECCAkQQEiAAEICBBASIICQ\nAAGEBAggJEAAIQECCAkQQEiAAEICBBASIICQAAGEBAggJEAAIQECCAkQQEiAAEICBBASIICQ\nAAGEBAggJEAAIQECCAkQQEiAAEICBBASIICQAAGEBAggJEAAIQECCAkQQEiAAEICBBASIICQ\nAAGEBAggJEAAIQECCAkQQEiAAEICBBASIICQAAGEBAggJEAAIQECCAkQQEiAAEICBBASIICQ\nAAGEBAggJEAAIQECCAkQQEiAAEICBBASIICQAAGEBAggJEAAIQECCAkQQEiAAEICBBASIICQ\nAAGEBAggJEAAIQECCAkQQEiAAEICBBASIICQAAGEBAggJEAAIQECXAjp61WAUb6u+He58yGt\nVIBhVlb429z5kJaqPMdvAxCUp5ZW+GsICTgFIQECCAkQQEiAAEICBBASIICQAAGEBAggJEAA\nIQECCAkQQEiAAEICBBASIICQAAGEBAggJCBSa0Z17z5qTdCLCAmI0NiETg880ClhbLDLCAmI\nzLvJC3zLguR5QS4kJCAybUba68i2QS4kJCAih9Rye7Ms7nDZSwkJiEiW2mBv1qusspcSEhCR\n/Or/Z2/er55f9lJCAiLT++pC31JwVe8gFxISEJn16bfssKwdt6RvCHIhIQERymylGjdWrTKD\nXUZIQKQKMmfOXFUQ9CJCAgQQEiCAkAABhAQIICRAACEBAggJEEBIgABCAgQQEiCAkAABhAQI\nICRAACEBAggJEEBIgABCAgQQEiCAkAABhAQIICRAACEBAggJEEBIgABCAgQQEiCAkAABhAQI\nICRAACEBAggJEEBIgABCAgQQEiCAkAABhAQIICRAACEBAggJEEBIgABCgkEKMmfNXat7iKAI\nCeZYfp7KqKc6rNc9RxCEBGN8nTpwp2X9cF3dn3VPUhYhwRhde/mX/F8P1jxIEIQEU+xP+Ke9\nmX2G3kGCISSYYp3aaW++VDl6JwmCkGCKbSpwL8MHyYV6JwmCkGCMJs/Y612d9c4RDCHBGNNT\nP/UtcxI/0j1JWYQEc4xMuOaRBzsmTtY9RxCEBIMsH9G124Pf6J4iGEICBBASIICQAAGEBAgg\n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\nos/aCQ0AAAAASUVORK5CYII=" }, "metadata": { "image/png": { @@ -16625,13 +16763,13 @@ "\n", "plot(y, y_)" ], - "id": "16782f30-d94a-4d84-979b-707002b3e0d4" + "id": "5ebfd908-fea8-4e8a-8b94-532d228b8845" }, { "cell_type": "code", - "execution_count": 424, + "execution_count": 387, "metadata": { - "id": "5a112da2-f188-46b2-9425-9fcfc6a9a219" + "id": "e986f8af-bd2f-47ca-8152-73d4f8a1fd7c" }, "outputs": [], "source": [ @@ -16640,13 +16778,13 @@ "x_train <- x_train[my_index, , ]\n", "y_train <- y_train[my_index]" ], - "id": "5a112da2-f188-46b2-9425-9fcfc6a9a219" + "id": "e986f8af-bd2f-47ca-8152-73d4f8a1fd7c" }, { "cell_type": "code", - "execution_count": 425, + "execution_count": 388, "metadata": { - "id": "f6a02692-7223-4b37-8f9a-c15a47d6ea77" + "id": "4e96c34c-1c9a-4f6d-bced-85671cda9a25" }, "outputs": [], "source": [ @@ -16661,17 +16799,17 @@ " as.data.frame\n", "my_test <- as.h2o(tmp)" ], - "id": "f6a02692-7223-4b37-8f9a-c15a47d6ea77" + "id": "4e96c34c-1c9a-4f6d-bced-85671cda9a25" }, { "cell_type": "code", - "execution_count": 426, + "execution_count": 389, "metadata": { - "id": "096eebe3-beeb-4496-b6dd-7d5d8d8758f4", - "outputId": "95e9834c-2610-4d20-8554-1787a049f017", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "64e8a1dd-a777-4d8b-a41e-a383bfffaaf0", + "outputId": "dc24b10f-3754-477c-c103-f261ac9c8c76" }, "outputs": [ { @@ -16679,10 +16817,10 @@ "name": "stdout", "text": [ "\n", - "15:34:27.680: _train param, Dropping bad and constant columns: [V646, V645, V644, V21, V20, V23, V22, V25, V533, V24, V27, V26, V29, V28, V252, V759, V758, V757, V756, V755, V116, V754, V30, V32, V31, V643, V35, V366, V365, V760, V704, V703, V702, V701, V700, V393, V674, V673, V672, V671, V394, V779, V778, V50, V140, V52, V51, V54, V53, V56, V55, V58, V57, V422, V421, V784, V59, V420, V783, V782, V781, V142, V780, V141, V728, V727, V726, V449, V729, V60, V170, V731, V730, V1, V2, V3, V4, V450, V5, V6, V7, V8, V9, V169, V168, V562, V561, V560, V505, V589, V83, V590, V85, V84, V87, V86, V88, V115, V478, V753, V114, V477, V752, V113, V112, V111, V197, V618, V617, V616, V338, V337, V699, V732, V10, V12, V11, V225, V588, V16, V15, V18, V17, V19]\n", - "15:35:02.765: _train param, Dropping bad and constant columns: [V646, V645, V644, V21, V20, V23, V22, V25, V533, V24, V27, V26, V29, V28, V252, V759, V758, V757, V756, V755, V116, V754, V30, V32, V31, V643, V35, V366, V365, V760, V704, V703, V702, V701, V700, V393, V674, V673, V672, V671, V394, V779, V778, V50, V140, V52, V51, V54, V53, V56, V55, V58, V57, V422, V421, V784, V59, V420, V783, V782, V781, V142, V780, V141, V728, V727, V726, V449, V729, V60, V170, V731, V730, V1, V2, V3, V4, V450, V5, V6, V7, V8, V9, V169, V168, V562, V561, V560, V505, V589, V83, V590, V85, V84, V87, V86, V88, V115, V478, V753, V114, V477, V752, V113, V112, V111, V197, V618, V617, V616, V338, V337, V699, V732, V10, V12, V11, V225, V588, V16, V15, V18, V17, V19]\n", - "15:35:37.70: _train param, Dropping bad and constant columns: [V646, V645, V644, V21, V20, V23, V22, V25, V533, V24, V27, V26, V29, V28, V252, V759, V758, V757, V756, V755, V116, V754, V30, V32, V31, V643, V35, V366, V365, V760, V704, V703, V702, V701, V700, V393, V674, V673, V672, V671, V394, V779, V778, V50, V140, V52, V51, V54, V53, V56, V55, V58, V57, V422, V421, V784, V59, V420, V783, V782, V781, V142, V780, V141, V728, V727, V726, V449, V729, V60, V170, V731, V730, V1, V2, V3, V4, V450, V5, V6, V7, V8, V9, V169, V168, V562, V561, V560, V505, V589, V83, V590, V85, V84, V87, V86, V88, V115, V478, V753, V114, V477, V752, V113, V112, V111, V197, V618, V617, V616, V338, V337, V699, V732, V10, V12, V11, V225, V588, V16, V15, V18, V17, V19]\n", - "15:36:13.7: _train param, Dropping unused columns: [V646, V645, V644, V21, V20, V23, V22, V25, V533, V24, V27, V26, V29, V28, V252, V759, V758, V757, V756, V755, V116, V754, V30, V32, V31, V643, V35, V366, V365, V760, V704, V703, V702, V701, V700, V393, V674, V673, V672, V671, V394, V779, V778, V50, V140, V52, V51, V54, V53, V56, V55, V58, V57, V422, V421, V784, V59, V420, V783, V782, V781, V142, V780, V141, V728, V727, V726, V449, V729, V60, V170, V731, V730, V1, V2, V3, V4, V450, V5, V6, V7, V8, V9, V169, V168, V562, V561, V560, V505, V589, V83, V590, V85, V84, V87, V86, V88, V115, V478, V753, V114, V477, V752, V113, V112, V111, V197, V618, V617, V616, V338, V337, V699, V732, V10, V12, V11, V225, V588, V16, V15, V18, V17, V19]" + "14:08:57.384: _train param, Dropping bad and constant columns: [V646, V645, V644, V21, V20, V23, V22, V25, V533, V24, V532, V27, V26, V29, V28, V253, V252, V759, V758, V757, V756, V755, V30, V32, V31, V34, V33, V36, V35, V763, V366, V762, V365, V761, V760, V309, V703, V702, V701, V700, V393, V392, V675, V674, V673, V672, V394, V52, V51, V54, V53, V56, V55, V58, V423, V57, V422, V421, V784, V59, V420, V783, V782, V781, V142, V780, V141, V728, V727, V726, V725, V449, V448, V729, V61, V60, V171, V62, V170, V731, V730, V1, V2, V3, V451, V4, V450, V5, V6, V7, V8, V9, V281, V169, V561, V506, V505, V589, V81, V83, V82, V590, V85, V84, V86, V89, V478, V753, V114, V477, V113, V112, V111, V110, V197, V618, V617, V616, V337, V699, V732, V10, V12, V11, V14, V225, V13, V16, V15, V18, V17, V19]\n", + "14:09:32.128: _train param, Dropping bad and constant columns: [V646, V645, V644, V21, V20, V23, V22, V25, V533, V24, V532, V27, V26, V29, V28, V253, V252, V759, V758, V757, V756, V755, V30, V32, V31, V34, V33, V36, V35, V763, V366, V762, V365, V761, V760, V309, V703, V702, V701, V700, V393, V392, V675, V674, V673, V672, V394, V52, V51, V54, V53, V56, V55, V58, V423, V57, V422, V421, V784, V59, V420, V783, V782, V781, V142, V780, V141, V728, V727, V726, V725, V449, V448, V729, V61, V60, V171, V62, V170, V731, V730, V1, V2, V3, V451, V4, V450, V5, V6, V7, V8, V9, V281, V169, V561, V506, V505, V589, V81, V83, V82, V590, V85, V84, V86, V89, V478, V753, V114, V477, V113, V112, V111, V110, V197, V618, V617, V616, V337, V699, V732, V10, V12, V11, V14, V225, V13, V16, V15, V18, V17, V19]\n", + "14:10:06.535: _train param, Dropping bad and constant columns: [V646, V645, V644, V21, V20, V23, V22, V25, V533, V24, V532, V27, V26, V29, V28, V253, V252, V759, V758, V757, V756, V755, V30, V32, V31, V34, V33, V36, V35, V763, V366, V762, V365, V761, V760, V309, V703, V702, V701, V700, V393, V392, V675, V674, V673, V672, V394, V52, V51, V54, V53, V56, V55, V58, V423, V57, V422, V421, V784, V59, V420, V783, V782, V781, V142, V780, V141, V728, V727, V726, V725, V449, V448, V729, V61, V60, V171, V62, V170, V731, V730, V1, V2, V3, V451, V4, V450, V5, V6, V7, V8, V9, V281, V169, V561, V506, V505, V589, V81, V83, V82, V590, V85, V84, V86, V89, V478, V753, V114, V477, V113, V112, V111, V110, V197, V618, V617, V616, V337, V699, V732, V10, V12, V11, V14, V225, V13, V16, V15, V18, V17, V19]\n", + "14:10:40.587: _train param, Dropping unused columns: [V646, V645, V644, V21, V20, V23, V22, V25, V533, V24, V532, V27, V26, V29, V28, V253, V252, V759, V758, V757, V756, V755, V30, V32, V31, V34, V33, V36, V35, V763, V366, V762, V365, V761, V760, V309, V703, V702, V701, V700, V393, V392, V675, V674, V673, V672, V394, V52, V51, V54, V53, V56, V55, V58, V423, V57, V422, V421, V784, V59, V420, V783, V782, V781, V142, V780, V141, V728, V727, V726, V725, V449, V448, V729, V61, V60, V171, V62, V170, V731, V730, V1, V2, V3, V451, V4, V450, V5, V6, V7, V8, V9, V281, V169, V561, V506, V505, V589, V81, V83, V82, V590, V85, V84, V86, V89, V478, V753, V114, V477, V113, V112, V111, V110, V197, V618, V617, V616, V337, V699, V732, V10, V12, V11, V14, V225, V13, V16, V15, V18, V17, V19]" ] } ], @@ -16692,30 +16830,30 @@ " training_frame = my_train,\n", " max_runtime_secs = 120)" ], - "id": "096eebe3-beeb-4496-b6dd-7d5d8d8758f4" + "id": "64e8a1dd-a777-4d8b-a41e-a383bfffaaf0" }, { "cell_type": "code", - "execution_count": 427, + "execution_count": 390, "metadata": { - "id": "72546fcf-188f-4ca8-adb5-d84b55994e33", - "outputId": "c9f5a9db-48c6-4924-d86e-91066ece6655", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "ffb36241-1792-48a0-b5f3-a766693a2aa5", + "outputId": "e7eb1fc8-451e-4791-90cd-09072c406adb" }, "outputs": [ { "output_type": "display_data", "data": { "text/html": [ - "0.0823890050637144" + "0.0752238521844489" ], - "text/markdown": "0.0823890050637144", - "text/latex": "0.0823890050637144", + "text/markdown": "0.0752238521844489", + "text/latex": "0.0752238521844489", "text/plain": [ - "[1] 0.0824" + "[1] 0.0752" ] }, "metadata": {} @@ -16725,30 +16863,30 @@ "min(my_model@leaderboard$\n", " mean_per_class_error)" ], - "id": "72546fcf-188f-4ca8-adb5-d84b55994e33" + "id": "ffb36241-1792-48a0-b5f3-a766693a2aa5" }, { "cell_type": "code", - "execution_count": 428, + "execution_count": 391, "metadata": { - "id": "39426d21-6fa9-4d0b-9d89-3768db538f7a", - "outputId": "46467842-a6f2-4782-da96-833c4a4aae02", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "4f9b9d16-279d-4fe2-84d5-2abbe0831e09", + "outputId": "02ad35b4-0ed6-49fe-d591-6c3fb95f95c2" }, "outputs": [ { "output_type": "display_data", "data": { "text/html": [ - "0.9255" + "0.9269" ], - "text/markdown": "0.9255", - "text/latex": "0.9255", + "text/markdown": "0.9269", + "text/latex": "0.9269", "text/plain": [ - "[1] 0.925" + "[1] 0.927" ] }, "metadata": {} @@ -16761,56 +16899,77 @@ "\n", "mean(y_ == y_test)" ], - "id": "39426d21-6fa9-4d0b-9d89-3768db538f7a" + "id": "4f9b9d16-279d-4fe2-84d5-2abbe0831e09" }, { - "id": "37a4678a", + "id": "18a8a207", "cell_type": "markdown", "source": [ "# 12 時系列予測" ], "metadata": { - "id": "37a4678a" + "id": "18a8a207" } }, { "cell_type": "code", - "execution_count": 429, + "execution_count": 392, "metadata": { - "id": "45899138-a738-4ae4-aa2e-b54acfdbadf9" + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "73a30842-7264-45b5-94b4-a04315f0d394", + "outputId": "1e74d60a-1a4a-4905-84b5-a56954185d75" }, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "Installing packages into ‘/usr/local/lib/R/site-library’\n", + "(as ‘lib’ is unspecified)\n", + "\n", + "also installing the dependencies ‘abind’, ‘tensorA’, ‘quadprog’, ‘checkmate’, ‘matrixStats’, ‘posterior’, ‘ggdist’, ‘warp’, ‘inline’, ‘loo’, ‘QuickJSR’, ‘fabletools’, ‘distributional’, ‘slider’, ‘dygraphs’, ‘extraDistr’, ‘RcppParallel’, ‘rstan’, ‘rstantools’, ‘StanHeaders’, ‘xts’, ‘BH’, ‘anytime’\n", + "\n", + "\n", + "Installing package into ‘/usr/local/lib/R/site-library’\n", + "(as ‘lib’ is unspecified)\n", + "\n" + ] + } + ], "source": [ "# Google Colaboratoryの環境設定\n", "if (file.exists(\"/content\")) {\n", " options(Ncpus = parallel::detectCores())\n", - " packages_to_install <- c(\"caret\", \"fable\", \"prophet\", \"tsibble\")\n", " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"caret\", \"fable\", \"feasts\", \"prophet\", \"tsibble\", \"urca\")\n", " install.packages(setdiff(packages_to_install, installed_packages))\n", + " install.packages(c(\"ggplot2\"))\n", "}" ], - "id": "45899138-a738-4ae4-aa2e-b54acfdbadf9" + "id": "73a30842-7264-45b5-94b4-a04315f0d394" }, { - "id": "fdfe5096", + "id": "5b61cff2", "cell_type": "markdown", "source": [ "## 12.1 日時と日時の列" ], "metadata": { - "id": "fdfe5096" + "id": "5b61cff2" } }, { "cell_type": "code", - "execution_count": 430, + "execution_count": 393, "metadata": { - "id": "58d833f0-99e8-4bf2-9919-c1412ae786b7", - "outputId": "07b150c3-58c4-4257-d3e6-a665e89de43c", "colab": { "base_uri": "https://localhost:8080/", - "height": 34 - } + "height": 35 + }, + "id": "a01e6c8f-fd03-45dc-8a43-80fbe7d71ecc", + "outputId": "33954437-54fa-4957-e5d6-84ed040077c9" }, "outputs": [ { @@ -16826,20 +16985,40 @@ "source": [ "as.POSIXct(\"2021-01-01\")" ], - "id": "58d833f0-99e8-4bf2-9919-c1412ae786b7" + "id": "a01e6c8f-fd03-45dc-8a43-80fbe7d71ecc" }, { "cell_type": "code", - "execution_count": 431, + "execution_count": 394, "metadata": { - "id": "31eafc9c-13b2-4a19-9726-6833b023b76c", - "outputId": "e4b7b5be-5541-4ec7-d18e-70099c2bf007", "colab": { "base_uri": "https://localhost:8080/", - "height": 208 - } + "height": 467 + }, + "id": "0175b2db-76b4-4c14-b7ab-24096b55d5c2", + "outputId": "4e727754-83fc-4568-e310-f6a6e5096d49" }, "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "\n", + "Attaching package: ‘tsibble’\n", + "\n", + "\n", + "The following object is masked from ‘package:lubridate’:\n", + "\n", + " interval\n", + "\n", + "\n", + "The following objects are masked from ‘package:base’:\n", + "\n", + " intersect, setdiff, union\n", + "\n", + "\n" + ] + }, { "output_type": "display_data", "data": { @@ -16912,53 +17091,53 @@ "seq(from = as.POSIXct(\"2021-01-01 00:00:00\"),\n", " to = as.POSIXct(\"2021-01-01 03:00:00\"), by = \"2 hour\")" ], - "id": "31eafc9c-13b2-4a19-9726-6833b023b76c" + "id": "0175b2db-76b4-4c14-b7ab-24096b55d5c2" }, { - "id": "891a5f13", + "id": "fc4c60b4", "cell_type": "markdown", "source": [ "## 12.2 時系列データの予測" ], "metadata": { - "id": "891a5f13" + "id": "fc4c60b4" } }, { "cell_type": "code", - "execution_count": 432, + "execution_count": 395, "metadata": { - "id": "f7bce79b-add8-4cd2-a82c-9c0bcc94ef22" + "id": "444e6c96-9260-4535-845f-6faf432a01c3" }, "outputs": [], "source": [ "my_data <- as.vector(AirPassengers)" ], - "id": "f7bce79b-add8-4cd2-a82c-9c0bcc94ef22" + "id": "444e6c96-9260-4535-845f-6faf432a01c3" }, { "cell_type": "code", - "execution_count": 433, + "execution_count": 396, "metadata": { - "id": "4c1398e6-41ed-4595-9466-868102717141" + "id": "31da55a3-cf97-4622-99ea-656035209365" }, "outputs": [], "source": [ "n <- length(my_data) # データ数(144)\n", "k <- 108 # 訓練データ数" ], - "id": "4c1398e6-41ed-4595-9466-868102717141" + "id": "31da55a3-cf97-4622-99ea-656035209365" }, { "cell_type": "code", - "execution_count": 434, + "execution_count": 397, "metadata": { - "id": "a963132e-418e-4b0d-9405-e25fdf68ae3b", - "outputId": "f24a7a28-2f0f-4ad9-9f24-c92fd091b961", "colab": { "base_uri": "https://localhost:8080/", "height": 286 - } + }, + "id": "bf8ebfc1-31a3-42eb-973e-e368c33e779e", + "outputId": "c1acde91-c782-449e-d921-8135c3856d1a" }, "outputs": [ { @@ -17016,13 +17195,13 @@ "\n", "head(my_df)" ], - "id": "a963132e-418e-4b0d-9405-e25fdf68ae3b" + "id": "bf8ebfc1-31a3-42eb-973e-e368c33e779e" }, { "cell_type": "code", - "execution_count": 435, + "execution_count": 398, "metadata": { - "id": "792d5368-cfa8-4168-8d6a-403992b52852" + "id": "30e9c5f5-13cd-4e26-a03a-42a933f2b710" }, "outputs": [], "source": [ @@ -17030,18 +17209,18 @@ "my_test <- my_df[-(1:k), ]\n", "y <- my_test$y" ], - "id": "792d5368-cfa8-4168-8d6a-403992b52852" + "id": "30e9c5f5-13cd-4e26-a03a-42a933f2b710" }, { "cell_type": "code", - "execution_count": 436, + "execution_count": 399, "metadata": { - "id": "e854f153-ec24-4d3b-a2c3-2add7f96b2e3", - "outputId": "68fc4bcc-c644-4c78-fa51-9cfc69501324", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "3cd80863-8045-4a26-b8e3-c2b92338e465", + "outputId": "93c0ff59-5d1e-45f6-c7a7-6c7225501c11" }, "outputs": [ { @@ -17068,18 +17247,18 @@ " geom_line()\n", "my_plot" ], - "id": "e854f153-ec24-4d3b-a2c3-2add7f96b2e3" + "id": "3cd80863-8045-4a26-b8e3-c2b92338e465" }, { "cell_type": "code", - "execution_count": 437, + "execution_count": 400, "metadata": { - "id": "71cb42e0-20d2-4ecf-8168-55ffedd882ff", - "outputId": "3e30e66a-2eaa-4d81-eec8-5c42c46a2030", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "beea8e74-af73-4e2f-9b5b-a2462046e35d", + "outputId": "8ee6a4b1-d282-4416-c6f2-79f4a8db94ae" }, "outputs": [ { @@ -17103,18 +17282,18 @@ "y_ <- my_lm_model %>% predict(my_test)\n", "caret::RMSE(y, y_) # RMSE(テスト)" ], - "id": "71cb42e0-20d2-4ecf-8168-55ffedd882ff" + "id": "beea8e74-af73-4e2f-9b5b-a2462046e35d" }, { "cell_type": "code", - "execution_count": 438, + "execution_count": 401, "metadata": { - "id": "befa876f-8829-4980-99f6-bf570079a97b", - "outputId": "36e98807-be4d-4301-e65e-6b187c246a08", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "980b4531-5c55-45ed-8c3f-d69810e3c3c7", + "outputId": "cc5be971-dea5-4172-def8-b5af97f708b3" }, "outputs": [ { @@ -17139,20 +17318,42 @@ " mutate(y = y_, label = \"model\")\n", "my_plot + geom_line(data = tmp)" ], - "id": "befa876f-8829-4980-99f6-bf570079a97b" + "id": "980b4531-5c55-45ed-8c3f-d69810e3c3c7" }, { "cell_type": "code", - "execution_count": 439, + "execution_count": 402, "metadata": { - "id": "80630a5c-e38b-4d8a-92cc-27c380aa4dd8", - "outputId": "24e0b086-3710-4395-d70c-c8141cd31697", "colab": { "base_uri": "https://localhost:8080/", - "height": 129 - } + "height": 417 + }, + "id": "08941cc6-cae7-4e09-b652-21e1ffef8148", + "outputId": "bf73650c-f610-4a1b-e61f-e3e7d0f0dde1" }, "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "Loading required package: fabletools\n", + "\n", + "\n", + "Attaching package: ‘fabletools’\n", + "\n", + "\n", + "The following object is masked from ‘package:keras’:\n", + "\n", + " new_model_class\n", + "\n", + "\n", + "The following objects are masked from ‘package:caret’:\n", + "\n", + " MAE, RMSE\n", + "\n", + "\n" + ] + }, { "output_type": "display_data", "data": { @@ -17183,18 +17384,18 @@ "my_arima_model <- my_train %>% model(ARIMA(y))\n", "my_arima_model" ], - "id": "80630a5c-e38b-4d8a-92cc-27c380aa4dd8" + "id": "08941cc6-cae7-4e09-b652-21e1ffef8148" }, { "cell_type": "code", - "execution_count": 440, + "execution_count": 403, "metadata": { - "id": "06374cc4-5298-477c-856c-3e2b944b62fd", - "outputId": "a48f1e0e-5069-4f51-c565-e0c34569e4aa", "colab": { "base_uri": "https://localhost:8080/", "height": 286 - } + }, + "id": "76ddccf9-f8bb-4c5f-9318-41b93bbf13c1", + "outputId": "099a1cd0-cddd-4928-8cbf-e8ebf67d594b" }, "outputs": [ { @@ -17236,18 +17437,18 @@ "tmp <- my_arima_model %>% forecast(h = \"3 years\")\n", "head(tmp)" ], - "id": "06374cc4-5298-477c-856c-3e2b944b62fd" + "id": "76ddccf9-f8bb-4c5f-9318-41b93bbf13c1" }, { "cell_type": "code", - "execution_count": 441, + "execution_count": 404, "metadata": { - "id": "2222a7f9-02b3-4060-9d6f-67989427aa65", - "outputId": "4ec461af-c524-4403-bb17-24aec73f2983", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "f6afa0a6-0d0a-4f57-991e-2bb088e45d23", + "outputId": "9b94c5a1-c914-405f-be85-fe36fe43b1ae" }, "outputs": [ { @@ -17269,18 +17470,18 @@ "y_ <- tmp$.mean\n", "caret::RMSE(y_, y)" ], - "id": "2222a7f9-02b3-4060-9d6f-67989427aa65" + "id": "f6afa0a6-0d0a-4f57-991e-2bb088e45d23" }, { "cell_type": "code", - "execution_count": 442, + "execution_count": 405, "metadata": { - "id": "45528a45-9cba-480b-b001-56494c8ae46d", - "outputId": "6e11a914-9c93-4de6-95b9-93df476e1f51", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "9a080c39-e319-4fe0-9bea-79db3b79bd3b", + "outputId": "dc6b4492-4ec9-45a2-c29a-29f609e6fdec" }, "outputs": [ { @@ -17309,23 +17510,52 @@ " y = y,\n", " color = label))" ], - "id": "45528a45-9cba-480b-b001-56494c8ae46d" + "id": "9a080c39-e319-4fe0-9bea-79db3b79bd3b" }, { "cell_type": "code", - "execution_count": 443, + "execution_count": 406, "metadata": { - "id": "33ea177e-0a2c-4841-abd3-7a1c4a931143", - "outputId": "93e4e988-9d20-4ea7-df65-c1dc8517f36d", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "id": "229ed834-2c5a-4496-bc1a-4971d9af500f", + "outputId": "bde9868c-dc5f-4e11-dd9d-2410262b54f8" }, "outputs": [ { "output_type": "stream", "name": "stderr", "text": [ + "Loading required package: Rcpp\n", + "\n", + "Loading required package: rlang\n", + "\n", + "\n", + "Attaching package: ‘rlang’\n", + "\n", + "\n", + "The following object is masked from ‘package:xml2’:\n", + "\n", + " as_list\n", + "\n", + "\n", + "The following objects are masked from ‘package:jsonlite’:\n", + "\n", + " flatten, unbox\n", + "\n", + "\n", + "The following objects are masked from ‘package:testthat’:\n", + "\n", + " is_false, is_null, is_true\n", + "\n", + "\n", + "The following objects are masked from ‘package:purrr’:\n", + "\n", + " %@%, flatten, flatten_chr, flatten_dbl, flatten_int, flatten_lgl,\n", + " flatten_raw, invoke, splice\n", + "\n", + "\n", "Disabling weekly seasonality. Run prophet with weekly.seasonality=TRUE to override this.\n", "\n", "Disabling daily seasonality. Run prophet with daily.seasonality=TRUE to override this.\n", @@ -17338,18 +17568,18 @@ "my_prophet_model <- my_train %>%\n", " prophet(seasonality.mode = \"multiplicative\")" ], - "id": "33ea177e-0a2c-4841-abd3-7a1c4a931143" + "id": "229ed834-2c5a-4496-bc1a-4971d9af500f" }, { "cell_type": "code", - "execution_count": 444, + "execution_count": 407, "metadata": { - "id": "77915ecb-fc9b-426d-9f41-87ac452b6118", - "outputId": "41efb72f-a09f-459e-d199-c75969b48288", "colab": { "base_uri": "https://localhost:8080/", "height": 286 - } + }, + "id": "556b75ff-3e3d-42d7-9ef1-fa99b20b8b4f", + "outputId": "2966aed1-1825-4322-ed6e-2bafcf4b273f" }, "outputs": [ { @@ -17363,24 +17593,24 @@ "\t<dttm><dbl><dbl><dbl>\n", "\n", "\n", - "\t1958-01-01359350367\n", + "\t1958-01-01359350368\n", "\t1958-02-01350342359\n", - "\t1958-03-01407398415\n", - "\t1958-04-01398389407\n", - "\t1958-05-01402393411\n", + "\t1958-03-01407398416\n", + "\t1958-04-01398390407\n", + "\t1958-05-01402393412\n", "\t1958-06-01459450468\n", "\n", "\n" ], - "text/markdown": "\nA tibble: 6 × 4\n\n| ds <dttm> | yhat <dbl> | yhat_lower <dbl> | yhat_upper <dbl> |\n|---|---|---|---|\n| 1958-01-01 | 359 | 350 | 367 |\n| 1958-02-01 | 350 | 342 | 359 |\n| 1958-03-01 | 407 | 398 | 415 |\n| 1958-04-01 | 398 | 389 | 407 |\n| 1958-05-01 | 402 | 393 | 411 |\n| 1958-06-01 | 459 | 450 | 468 |\n\n", - "text/latex": "A tibble: 6 × 4\n\\begin{tabular}{llll}\n ds & yhat & yhat\\_lower & yhat\\_upper\\\\\n & & & \\\\\n\\hline\n\t 1958-01-01 & 359 & 350 & 367\\\\\n\t 1958-02-01 & 350 & 342 & 359\\\\\n\t 1958-03-01 & 407 & 398 & 415\\\\\n\t 1958-04-01 & 398 & 389 & 407\\\\\n\t 1958-05-01 & 402 & 393 & 411\\\\\n\t 1958-06-01 & 459 & 450 & 468\\\\\n\\end{tabular}\n", + "text/markdown": "\nA tibble: 6 × 4\n\n| ds <dttm> | yhat <dbl> | yhat_lower <dbl> | yhat_upper <dbl> |\n|---|---|---|---|\n| 1958-01-01 | 359 | 350 | 368 |\n| 1958-02-01 | 350 | 342 | 359 |\n| 1958-03-01 | 407 | 398 | 416 |\n| 1958-04-01 | 398 | 390 | 407 |\n| 1958-05-01 | 402 | 393 | 412 |\n| 1958-06-01 | 459 | 450 | 468 |\n\n", + "text/latex": "A tibble: 6 × 4\n\\begin{tabular}{llll}\n ds & yhat & yhat\\_lower & yhat\\_upper\\\\\n & & & \\\\\n\\hline\n\t 1958-01-01 & 359 & 350 & 368\\\\\n\t 1958-02-01 & 350 & 342 & 359\\\\\n\t 1958-03-01 & 407 & 398 & 416\\\\\n\t 1958-04-01 & 398 & 390 & 407\\\\\n\t 1958-05-01 & 402 & 393 & 412\\\\\n\t 1958-06-01 & 459 & 450 & 468\\\\\n\\end{tabular}\n", "text/plain": [ " ds yhat yhat_lower yhat_upper\n", - "1 1958-01-01 359 350 367 \n", + "1 1958-01-01 359 350 368 \n", "2 1958-02-01 350 342 359 \n", - "3 1958-03-01 407 398 415 \n", - "4 1958-04-01 398 389 407 \n", - "5 1958-05-01 402 393 411 \n", + "3 1958-03-01 407 398 416 \n", + "4 1958-04-01 398 390 407 \n", + "5 1958-05-01 402 393 412 \n", "6 1958-06-01 459 450 468 " ] }, @@ -17391,18 +17621,18 @@ "tmp <- my_prophet_model %>% predict(my_test)\n", "head(tmp[, c(\"ds\", \"yhat\", \"yhat_lower\", \"yhat_upper\")])" ], - "id": "77915ecb-fc9b-426d-9f41-87ac452b6118" + "id": "556b75ff-3e3d-42d7-9ef1-fa99b20b8b4f" }, { "cell_type": "code", - "execution_count": 445, + "execution_count": 408, "metadata": { - "id": "a02d5093-a14e-4ec9-b838-eea9b08aa171", - "outputId": "760d037f-fa59-4fd3-b0cb-464a5f4088ec", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "3131f9d0-2762-4166-91cb-ad0be4037a70", + "outputId": "1efa964b-62d7-459e-cb45-a75c86c67dd4" }, "outputs": [ { @@ -17424,18 +17654,18 @@ "y_ <- tmp$yhat\n", "caret::RMSE(y_, y)" ], - "id": "a02d5093-a14e-4ec9-b838-eea9b08aa171" + "id": "3131f9d0-2762-4166-91cb-ad0be4037a70" }, { "cell_type": "code", - "execution_count": 446, + "execution_count": 409, "metadata": { - "id": "a5f4b48f-7d46-439d-99bf-9dde81fad277", - "outputId": "0562c6ec-ff77-4808-91bc-5410f62b5c45", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "04faa3ac-28a2-43b3-9d31-0e2e47f8b7a7", + "outputId": "19665b94-319b-4517-9914-ea7e8219fd12" }, "outputs": [ { @@ -17444,7 +17674,7 @@ "text/plain": [ "plot without title" ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAIAAAByhViMAAAACXBIWXMAABJ0AAASdAHeZh94\nAAAgAElEQVR4nOzdeXxcZ30v/s9ZZtEsmhkto8V7HGcnTshCEpb2BykU2sItNMClZSllCbkX\nfvT2V3pboIGQtCm0JO2PpoGylHsDTW6hFEpbKIWkZANCFichibFlO7a1jWafc87MmbPdPx6N\nLGsZj6SRZnT0eb948bKOxprHVmJ/8n2e5/uVPM8DEREREW1+cqcXQERERETtwWBHRERE5BMM\ndkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBH\nRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkRE\nREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE\n5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+\nwWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMM\ndkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBH\nRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkRE\nREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE\n5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+\nwWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMM\ndkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBH\nRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkRE\nREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE\n5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+\nwWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMM\ndkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBH\nRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkRE\nREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE\n5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+\nwWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMM\ndkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBH\nRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkRE\nREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+wWBHRERE5BMMdkREREQ+oXZ6AWtS\nq9Ucx+n0KrqLJEmBQMBxHP7ObC6yLEuSxO/a5iLLsqqqtm27rtvptdAKKIrieR6/a5uLqqqy\nLFuW5Xlep9fSYbIs9/T0LPfZzR3sTNO0LKvTq+guqqpGIhHbtqvVaqfXQisQDodlWeZ3bXPp\n6ekJBAK1Ws00zU6vhVYgFotZllWv1zu9EFqBeDweCAQ0TeN/ACuK0iTYcSuWiIiIyCcY7IiI\niIh8gsGOiIiIyCcY7IiIiIh8gsGOiIiIyCcY7IiIiIh8gsGOiIiIyCcY7IiIiIh8gsGOiIiI\nyCcY7IiIiIh8gsGOiIiIyCcY7IiIiIh8gsGOiIiIyCcY7IiIiIh8gsGOiIiIyCcY7IiIiIh8\ngsGOiIiIyCcY7IiIiIh8gsGOiIiIyCcY7IiIiIh8gsGOiIiICAAOTGqdXsJaMdgRERERzaa6\nzZ7tGOyIiIhoq9vseW4Ogx0RERFtab5JdWCwIyIioq3MT6kODHZEREREvsFgR0REROQTDHZE\n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\nhISEnj17mpqaaj/r6+trYmLy888/f/TRRxMnTvT29r5y5UrVO71+/bqVlZWzs7MQwtHRUeeR\nXy1atKhiL9nZ2WUUu3fvLm28bG5u3rlz58WLF+/YsaP8m+QBAFDzCHZ4CemOZ//+/XU++/e/\n/1192nhycvL06dPLXkz6UhkZGQ8ePHB3d5dSlI2NzcSJEzXauLm5DRgwoCq9SG+iXWzfvr3q\n5/j4eCHE+vXrw8LC5s6da2JiUsUeAQB4pQh2eAnpcAWdwS41NfXUqVMaxZSUFO1ihVy/fr2k\npET9mK8VK1aMGzdO9dDDw2PHjh1Vj1kLFiwwNzdXrzRs2FD9pI2TJ0/Wq1fvVWzmAgDAq0Cw\nQ1ny8vJ+++23Nm3atGzZUvvZJ0+e6HxVWlpaVTqVJtipBztzc/OQkJCYmJhDhw5dvnz5p59+\nku7SVlHbtm1//PFHDw8PIyMj6erg6tWrHR0dpWcfPHgQGxvr7e3doEGDqvcFAEANINihLOfO\nncvPzy/tPqyjo6PO7XBbtWpVlU7VV06os7e379mzp7OzczVOdOvWrdvx48fv37//7bffCiHU\nD739+eefhRCDBw+urr4AAHjVCHYoS3h4uCh9gp21tXVAQIBG8Y033iitfXkUFBRcvXrV2tq6\n6msjys/Y2HjIkCH29vahoaGqrZhPnjwphBg0aFCNDQMAgCoi2EG39PT0iIiI48ePW1hYeHp6\nltZs6dKlAQEBqut2HTt23LlzZ+WOjr13796ECROcnJwePXqUn5+vscPcq2ZkZDR+/Pjnz59L\nZ11kZWVdunSpQ4cOzZs3r8lhAABQFQQ7/UhISNi2bdv//M//nDt3Tghx586db7/9dv369Rcu\nXND30IQQ4quvvurUqZOfn9/jx48LCwvPnDlTWksTE5PPP//89u3by5cvF0L06dOnckkoMzNz\n9OjRYWFh0jkWubm5kydP1nmE66vzt7/9TaFQfPfdd0IIaSTchwUA1C1G+h7A62jjxo0rVqxQ\nHVPo4uIiHZAlPRw0aND27durclJWFf3www+rVq1SPczPz3/vvfdOnz7t6upa2ksaNGgwadKk\npUuXqs9Rq5Bt27YlJSVpFD/99NOaXJHq5OTUs2fP8+fPx8XFcR8WAFAXccWupl25cmXJkiXq\nh08nJCSoH7d68uRJ7TMPatLGjRs1Knl5edu2bSv7VfXr1+/YsWNUVJRqjlo5PX/+/PHjx3Fx\ncdpPxcXF6Tyw9dUZMmSIEMLX1/fQoUPm5uaqFbIAANQJBLuaFhoa+tI2+/fvr4GRlCY5OVm7\nqH05TZuXl1dhYWFkZGQ5O/rzzz/9/PxatWrVsWNHnTPqrKysavKkh+Tk5C+++EIIkZ2dXVxc\nnJub6+vrq/N0CgAAaieCXU1LT0+vljavTtOmTbWLDg4OL32hl5eX+P93DCnDs2fPxo8fHxER\nIV2T03nIrJ+fX3neqrosW7bs2bNn6pXExMT169fX5BgAAKgKgl1Na9OmzUvbtG3btgZGUpoZ\nM2ZoVExNTadMmfLSF3p6eioUinIGu507d5Z9FbB79+7/+te/yvNW1eWPP/7QLlbL0bcAANQM\ngl1Nmz59ur29fdltFi1aVO39pqWlzZ07193dvW3btv7+/jExMaW1nDJlSnBwsOoeqLW19fr1\n6zt27PjSLmxsbNq1a3f16lX102O1paenJyQk3LlzR/sphUKxaNGiuXPn7ty58+jRo2ZmZi/t\ntBrp3KWlclu3AACgFwS7mtaoUaM5c+aoHjZt2nTx4sUeHh6qSosWLap9KWhubu6IESO+//77\n5OTkjIyM8PDwoUOHxsbGltY+KChICOHq6hoaGvrHH3+MGjWqnB15eXkplUqdl76EEHFxcb6+\nvq6urp6enocOHdJuYGVlNW/evMWLF/v6+hoY1PQ/zn79+mkXBwwYUMPDAACg0gh2enDw4EEh\nxJEjR2JiYqKjo+fOnXv8+PGEhIQbN24MHTr0wYMHx44dq94ev/nmm/j4ePVKXl7eJ598Ulp7\naerbiBEjevfuXb9+/fJ3VMY0u2fPnk2cOFF1Z1N9XbDK2LFjy99XtVuwYEG7du3UK2+//fa0\nadP0NR4AACqKfexq2qVLlyIjI/v27StlIBUrKysrK6sFCxacOHFi1apVvr6+Oo9hrRzp9FUN\n169fL619RESEEOLtt9+uaEdlBLs9e/ZoT6pTKBSqDU3eeuutGp5Up8HCwiIsLGz79u2RkZFG\nRkZ9+vQZP358Nf4tAADwqhHsak5KSkpaWtpXX30lhAgODtbZpl27doMHD/7pp5+cnZ1LSkq6\ndu36z3/+s2vXrlXs2sTERLtoamp69+7dFy9etG7dWmMm2blz5ywsLLp06VLRjuzs7FxcXK5c\nuVJQUKCxx/Ldu3e125eUlCxfvjwvL8/d3b1Pnz41ubmJTiYmJrNmzZo1a5Z+hwEAQOVwK7Ym\n3L9/f9SoUZ06derfv//Zs2dtbW27d++us+WzZ8+kCWq5ubl5eXnnz58fOXLkzZs3qzgAnSco\nZGdn9+jRo3fv3h07dty9e7eqnpSUlJiY6OnpWbl1A15eXrm5udrXCG1sbLQbm5ubv/fee/Pm\nzevbt6/eUx0AAHUdwe6Vy8/Pnzx58vnz51WVtLS0FStW6GwcEhKSmpqqXnnx4sXSpUurOAY/\nP78xY8ZoFFVbx2VkZMybN+/UqVPSQ+n42krch5W0bt1aCLFgwYJ169alpaWp6qNHjzY1NdVo\nPGHChJpfJAEAgFzxO7XyIiMjAwICevXqNW7cuMOHD5fW7OTJk7du3dIo/vvf/87KytJufOPG\nDe1idHR0FYcqhJBuLzo6Oo4fP97T01O7gXSPWFRhgp0Q4tixYytXrhRCREVFrVixwtPTU3UQ\nhaur65o1a9SvAvbp02fJkiWV6AUAAOhEsKukI0eODB069NixY3FxcWfPng0MDCztIlxiYqJ2\nsaCgQOfJXebm5tpFCwuLqg1WCCH27t0rhFi+fPnXX3+tc3+4e/fuCSFKSkoiIiJsbGzat29f\n0S7S09Pnzp2rvtw1Ozt71qxZqpNwx48fL+2cMmPGjCNHjhw4cKCGd6oDAEDeWDxRGUql8u9/\n/7tGcd26dba2tkql0sHBoX///paWllLd1tZW+x0UCkWTJk2060OHDj1y5Ih2seoD/s9//mNj\nYzNw4MDShmRnZyeEiIuLS0tLGz58eCXukF64cCEzM1OjmJSUFB0drVr/ER0dbWxsvGTJEp3r\nOQAAQFVwxa4yYmNjMzIytOuLFi1aunTpjBkzvLy8VBu2DRo0SDtIDR06tHHjxtrv4Ofn5+/v\nr17p1KlT1Q+i+PnnnzMyMkaPHi3dCX333Xe120yePFlU7T6szvNe1evPnj27fft2586dSXUA\nALwKBLvKeOn6zdTU1BkzZjx//lwIYW1tvXnzZvXt0Hr06PHll1+W9toNGzbs27fv/fff79Sp\nkxAiMDCwivcrnz59umfPHiHExIkTpYqnp+eqVavUlzLUr19/0qRJomrBThqwhnr16nXo0EH6\n+cqVK8XFxTpn+AEAgKrjVmxltGvXrnHjxn/99VcZbZKTk3/99VdfX1/p56KiogEDBgwePNjV\n1bV79+5lR0MfHx8fH587d+707Nnz4MGDEyZMqMQgi4uLN23atH79+vT0dCGEtbV1s2bNVM8G\nBgYOHTr08uXLeXl5ERERBw4cWLVqVZ8+fSIiIhwcHFq1alWJHt3c3CZPnrxr1y714j/+8Q/V\nRifSQorStnoBAABV9P/2/a+LMjMzVRPza9ipU6ekS1xlWLt2rXTTs3fv3nFxcZcuXapoYOrX\nr9/NmzejoqKkCXDlYWRk1LBhw7y8vBUrVmis5+jVq1doaKj25LmsrKzOnTvn5ORID01MTEJC\nQkaMGFGhoUqUSuWmTZu+++67pKSk4uJiX1/f7du3q3ocPnz4pUuX4uLidO5p95ozNTU1MDAo\n7XY2aiczMzMLC4vs7Oz8/Hx9jwUVYGlpqVQqdR5siFqrfv36JiYmGRkZRUVF+h6LnhkaGlpb\nW5f2LLdiK2ngwIFubm4KhaJTp04DBw7UeQVO2tHt119/vXXr1pAhQypxGWzs2LFFRUXS2bIV\nkpOTs2bNGo1iRETEmTNntBufOnVKleqEEPn5+R988EFMTExFOxVCGBsbz5kz5/fff4+NjTUy\nMkpKSlKlOqVSefXq1bZt25LqAAB4RQh2lRQTExMbG9unT5/w8PDvv/9+6tSpGg06duzYuXPn\npKSkjRs3CiGCgoIq0cuoUaMMDQ1DQ0Mr+sLExESdlxDi4uK0i5s3b9aovHjxYuvWrRXtVJ2N\njU3Pnj1jYmKkXVSEEFFRUfn5+T169KjK2wIAgDIQ7Cpp586d4n9Xkgohli1bNnPmTGnNqYGB\ngaGhYVxcXMuWLd98880zZ840bdq0EueuCiHs7Ox69eoVFRV1586dCr2wQYMGOusNGzbULurc\nUU9nsUKGDRsmhDh69Kj08NKlS4IJdgAAvEoEu8rIycn58ccf7e3tBw8eLFVMTU0/++yze/fu\nXbx4MT4+vmXLloWFhcXFxdKzKSkpn3/+eeX6ko4Cmzdv3pdffqnaQuWlmjdvrn1tzMrKasCA\nAdqN1RdVqDg4OFRwpJqGDh1qaGio2pZPWjnBklgAAF4dgl0FFBYWbt269W9/+9vAgQNzcnLG\njh1rZPT/LSs2NjZu3bp1ZGRkQkKCxmtDQkK0N+99qYKCgv379wshIiMjV69e7evru3DhQvUG\nDx48WLBgwciRIwMDA48dO6b+1Jo1a9T3WLGwsNiwYYPORRgzZ87UqJiYmEybNq2io9XQuHFj\nb2/vqKioxMTEkpKSyMhIe3t7JyenKr4tAAAoDdudlFdRUdG4ceOkbd4kBw4cmD17dqNGjTRa\nxsfHa7+8oKAgMTGxc+fOFep07dq1586dU69s3brV29tbust5/fr1YcOGvXjxQnrq8OHDs2bN\nWrVqlfTwhx9+KCoq8vX1bdu2rb29/dChQ+3t7XX2Mm7cuPv3769bt05aI2Ztbb1q1aqKDlWn\nYcOGRUREHDt2bMCAAenp6cOHD6/6ewIAgNIQ7Mpr165d6qlOCJGamrpkyZKvv/5ao2Vpi5Ar\nsRr00KFD2sX//Oc/UrALDg5WpTrJ5s2bO3ToYGFhoVQqt2zZ0rRp002bNuk8f1bDP/7xj6lT\np8bExNSrV69Lly6q89Cq6J133lm4cOGRI0esrKyEEKycAADglSLYlZfGlTPJL7/8ol3s379/\no0aNnj59ql709vZu3rx5RTvNysrSLmZnZwsh0tLSYmNjtZ/98MMPVT9PmDChPKlO0qRJEx8f\nn4qO8KXv6e7u/scff6SkpAgh2rdvX73vDwAA1DHHrlwKCwt17oios2hjY7Np0yb163Zt27YN\nCQmpRL9ubm6lFcuzQ+Pu3bulYyf05ejRo9HR0UKI1NRUIcT06dMrtz0eAAAoD4JdWR4+fBgY\nGOji4uLk5KQzkZS2xrNv376XL1/esGHD4sWLd+zY8csvvzg6OlZiAIsXLzYxMVGvNG7cWLom\nV56FCGlpacePH69Ev9Xir7/+mjt3rvrRIOnp6TNnzlQtFgYAANWLW7Glys7OHjly5P3796WH\nDx8+1GjQsGHD5cuXl/Zya2trf3//Ko7B3d197969S5YsuXnzphCiuLh46dKltra2QgiFQrF2\n7Vo/P7+y3+Hx48dVHEOl/frrr9q3kv/888/bt2/rvBIJAACqiCt2pfr3v/+tSnUqTZs2dXd3\nd3Nze/fddyt9Ha5CevXqdebMmcTExO+//14IERYWpv5Uhw4dhBAtWrTo3r27+uYmKi1btnzV\nIyyN+jFl5akDAIAq4opdqW7cuKFdzMzMlCaN1TAzM7N+/fq1bt36p59+evz4sbQd3fXr12/e\nvPn222//+OOPQoglS5ZIx5epuLq6+vr61vxoJVLo1GBsbNy2bduaHwwAAK8DrtiVysLCQrtY\nXfuAVIJCoZg2bVpBQcF3330nVbZs2SKEeO+996SHixcvnj59umrP5B49euzcudPMzEwvoxVC\ndOvWbdSoURrF+fPnl3bcGQAAqCJFSUmJvsdQeZmZmepz86vXyZMn3333XY3i9OnTV69e/Yp6\nfKmcnJw33njDwsLi2rVr6enpb775poODw6VLlwwMDNTbpKSkWFtbN27cWF/jVMnLy/vqq6/2\n7Nnz5MmTFi1azJ49e8qUKeqjhYqpqamBgUFubq6+B4IKMDMzs7CwyM7Ozs/P1/dYUAGWlpZK\npVLakh11Rf369U1MTDIyMsqzKYS8GRoalrZjriDYlW3hwoVbt25VPezUqdORI0d0XsmrMfPm\nzdu9e7eHh0deXt6NGzdWrlw5Y8YM9QZGRkYNGzbMy8t7/vy5vgapTalUGhsb63sUtRrBri4i\n2NVRBLu6iGCnUnawY45dWVatWjVs2LDw8PDnz5937dp11KhRGofD1rDMzMxff/1VCHHlyhWp\ncu7cucDAQIVCocdRlQepDgCAGkCwewlvb29vb299j+L/+vTTT5OSktQrJ06c2LdvX9X3VQEA\nADLAbKe6RH2vE5VTp07V/EgAAEAtRLCrS3TO42GaCAAAkBDs6pIuXbpoF7t27VrzIwEAALVQ\n3Z5jZ2BgoPO4BblauXJl37591RdOtmnTJigoSP0PQfpZoVC8Vn8yMqBQKF63f88yIK1b4i+u\nzuHrVhdJXzf+1oQQZe8aVre3O8nPz3/dNkW7devWkiVLIiMjTU1NBw0a9MknnzRp0kS9gUKh\nMDIyKi4uZkF43WJgYKBQKPhbq1ukcFBUVFRcXKzvsaACDA0NS0pK+FurWwwNDQ0MDAoLC+t0\nbqkWJSUlZew1UbeD3avex64uqp372OGl2MeuLmIfuzqKfezqIvaxUyl7H7vX63IXAACAjBHs\nAAAAZIJgBwAAIBMEOwAAAJkg2AEAAMgEwQ4AAEAmCHYAAAAyQbADAACQCYIdAACATBDsAAAA\nZIJgBwAAIBMEOwAAAJkg2AEAAMgEwQ4AAEAmCHYAAAAyQbADAACQCUVJSYm+x4DqdOvWrQ8+\n+GDMmDFBQUH6HgsgcwcPHtywYcOiRYv69++v77EAMrdq1arTp0/v2rXL0dFR32Op1bhiJzeF\nhYVZWVkvXrzQ90AA+VMqlVlZWQUFBfoeCCB/L168yMrKKi4u1vdAajuCHQAAgEwQ7AAAAGTC\nSN8DQDVr1KiRn59fp06d9D0QQP5cXFz8/PxatGih74EA8te1a1cTExNLS0t9D6S2Y/EEAACA\nTHArFgAAQCYIdgAAADLBHLu6JDk5ee3atfHx8YcOHVIVU1NTt2/ffuvWrfz8/K5du86aNatB\ngwZCiODg4MTERFUzU1PT/fv3CyFycnK2bNkSHR1dUFDg6uo6a9YsW1vbGv8oQK1WLd+10uoA\n1FXo6yaEOH78+MGDB58+ferg4DB58mQPDw/BrzY1zLGrMyIiIrZu3dqlS5dffvlF9a+/oKDg\nww8/dHR0DAgIKCws3Lp1a1FR0cqVK4UQ06ZN8/Pz8/T0lFoaGBjY2NgIIT777LOcnJyZM2ea\nmJjs2bMnMTFx/fr1BgZcuwX+r+r6rpVWB6BS0a9beHj4rl27PvzwwxYtWly8ePGnn35at26d\nubk5v9pUXsfPXEcVFBSsWbNG9UtCcu/evUePHr3//vsODg5OTk5z5sy5cePG/fv3hRDZ2dn2\n9vaN/5f0G+Wvv/66cuXKe++916pVq2bNms2aNSs5OTkmJkY/Hwmolarlu1ZGHYBKRb9u+/bt\nmzJlSrdu3WxtbUeMGLFlyxZzc3N+tanjVmyd4ePjI4RISEhQL0pb3hsbG0sPra2tDQ0N4+Pj\nmzVrlp+ff/Hixd27d2dnZ7du3Xry5MkODg5//vlnvXr1WrVqJbW3tLR0dHS8fft2586da/bT\nALVXtXzXCgoKdNZr/uMAtVmFvm6WlpapqalCiODg4JSUFCcnp8DAwHbt2vGrTR1X7Oo2Z2dn\nKyurPXv2FBYWFhYW7tu3TwiRnZ2dm5vbsGHDwsLCoKCgjz/+WKlULly48Pnz51lZWfXr11co\nFKp3aNCgQWZmpv4+AVA3VPS7Vlpd358DqANK+7o9ffpUCBEWFjZ//vxt27a5urp++umnmZmZ\n/GpTxxW7us3MzGzBggUbNmw4ceKEiYnJ8OHDbW1tDQ0NGzRosGvXLlWz+fPnT5ky5bfffhNC\nqP/TB1BOFf2uDRgwoLS6PoYP1CWlfd2kZ8ePH+/o6CiEmDZt2tmzZ3///XfBrzY1BLs6r2PH\njt98883z589NTEyEEKGhoU2aNNFoY2Zm1qRJk7/++svZ2TkrK6ukpET1HcjMzLS2tq7pQQN1\nUIW+a+WsA9BJ59dNmqhqYWEhtTE0NLSxscnIyGjevDm/2lS4FVu3FRUVRUREZGRkWFhYGBkZ\nXbt2raSkpH379vfv3//6668LCwulZi9evHjy5Im9vX2bNm0KCgpUsxmysrKSkpLc3Nz09wmA\nuqGi37XS6vr7BECdUdrXzcbGxtraOi4uTmqmVCqfPHliZ2fHrzZ1XLGrMzIyMoqKirKzs4UQ\n0v/7LS0tTU1Nf/zxx/Pnz8+YMePx48chISEDBw60srJSKBQXL14sLCz09/cvKiratWuXpaWl\nt7e3iYmJl5dXSEhIcHCwsbHx1q1bXVxc2rdvr+8PB9Qi1fJdUyqVOuv6/nBA7VKhr5sQYtiw\nYT/88IOjo6Ojo+PevXtNTU09PDxMTU351abCPnZ1RmBgYFpamkZl+PDhjx49CgkJuXPnjqmp\nae/evadOnWpkZCSEuHv37vbt26W1Qq6urjNmzLCzsxNC5Obmbtmy5dq1a0VFRR06dJg1a9Zr\ne70a0Km6vmul1QGoVPTrVlxcvHv37rCwsJycHFdX16CgoObNmwt+takh2AEAAMgEc+wAAABk\ngmAHAAAgEwQ7AAAAmSDYAQAAyATBDgAAQCYIdgAAADJBsAMAAJAJgh0AVIy/v7+lpaW+RwEA\nOhDsAAAAZIJgBwAAIBMEOwAoS0lJybJly5o3b25qavrGG2+EhoaqP5uSkjJjxgwnJydTU1N7\ne/vRo0fHxcXpa6gAwFmxAFCWzz///OOPP540adLUqVPT09OXL19eUFDw8OHDnJwcIYSXl1di\nYuJnn33m7OyckpKyevXqx48f37t3z9zcXN8DB/A6ItgBQKlKSkocHR1tbGxiYmKkSkpKipOT\nk7GxcU5OTlZWVoMGDRYsWLBq1Srp2YSEhP3790+ZMqVZs2b6GzWA1xe3YgGgVElJSY8ePfLx\n8VFVmjZt2q1bN+lnMzOzRo0a7d27Nzw8vLi4WAjh4uKycOFCUh0AfSHYAUCpUlNThRBNmjRR\nL6pyW7169Q4fPmxgYNC/f39bW9sxY8bs2bOnsLBQDwMFACEEwQ4AyqBzskpRUZHq5549e/75\n55/h4eEBAQGxsbGTJk3y8vLKy8urwTECwP9DsAOAUknX6qTrdiqJiYnqDw0NDX18fL744oub\nN29u3Ljx999/379/f00OEgBUCHYAUKqWLVs2btz4xIkT0hQ6IcSdO3eioqKkn//44w9/f/+0\ntDRV+4EDBwohnjx5UvNDBQDBqlgAKNu//vWv5cuX+/n5TZo0KS0tbfXq1Y0bN46Li8vJyUlN\nTW3btm2rVq3mzJnTokWLp0+frl+//saNG1evXnVxcdH3wAG8jgh2AFCWoqKif/7znzt27EhP\nT3d1dV22bFl4ePiWLVvy8/OFENHR0UuXLr1w4UJGRkaTJk169OjxySefdOnSRd+jBvCaItgB\nAADIBHPsAAAAZIJgBwAAIBMEOwAAAJkg2AEAAMgEwQ4AAEAmCHYAAAAyQbADAACQCYIdAACA\nTBDsAAAAZIJgBwAAIBMEOwAAAJkg2AEAAMgEwQ4AAEAmCHYAAAAyQbADAACQCYIdAACATBDs\nAAAAZIJgBwAAIBMEOwAAAJkg2AEAAMgEwQ4AAEAmCHYAAAAyQbADAACQCYIdAACATBDsAAAA\nZIJgBwAAIBMEOwAAAJkg2AEAAMgEwQ4AAEAmCHYAAAAyQbADAACQCYIdAACATBDsAAAAZIJg\nBwAAIBMEOwAAAJkg2AEAAMgEwQ4AAEAmCHYAAAAyQbADAACQCYIdAACATBDsAAAAZIJgBwAA\nIBMEOwAAAJkg2AEAAMgEwQ4AAEAmCHYAAAAyQbADAACQCYIdAACATBDsAAAAZIJgBwAAIBME\nOwAAAJkg2AEAAMgEwQ4AAEAmCHYAAAAyQbADAACQCYIdAACATBDsAAAAZIJgBwAAIBMEOwAA\nAJkg2AEAAMgEwQ4AAEAmCHYAAAAyQbADAACQCYIdAACATBDsAAAAZIJgBwAAIBMEOwAAAJkg\n2AEAAMgEwQ4AAEAmCHYAAAAyQbADAACQCYIdAACATBDsAAAAZIJgBwAAIBMEOwAAAJkg2AEA\nAMgEwQ4AAEAmCHYAAAAyQbADAACQCYIdAACATBDsAAAAZIJgBwAAIBMEOwAAAJkg2AEAAMgE\nwQ4AAEAmCHYAAAAyQbADAACQCYIdAACATBDsAAAAZIJgBwAAIBMEOwAAAJkg2AEAAMgEwQ4A\nAEAmCHYAAAAyQbADAACQCYIdAACATBDsAABQPEiyAAAB4ElEQVQAZIJgBwAAIBMEOwAAAJkg\n2AEAAMgEwQ4AAEAmCHYAAAAyQbADAACQCYIdAACATBDsAAAAZIJgBwAAIBMEOwAAAJkg2AEA\nAMgEwQ4AAEAmCHYAAAAyQbADAACQCYIdAACATBDsAAAAZIJgBwAAIBMEOwAAAJkg2AEAAMgE\nwQ4AAEAmCHYAAAAyQbADAACQCYIdAACATBDsAAAAZIJgBwAAIBMEOwAAAJkg2AEAAMgEwQ4A\nAEAmCHYAAAAyQbADAACQCYIdAACATBDsAAAAZIJgBwAAIBMEOwAAAJkg2AEAAMgEwQ4AAEAm\nCHYAAAAyQbADAACQCYIdAACATBDsAAAAZIJgBwAAIBMEOwAAAJkg2AEAAMgEwQ4AAEAmCHYA\nAAAyQbADAACQCYIdAACATBDsAAAAZIJgBwAAIBMEOwAAAJkg2AEAAMgEwQ4AAEAmCHYAAAAy\nQbADAACQCYIdAACATBDsAAAAZIJgBwAAIBMEOwAAAJkg2AEAAMgEwQ4AAEAmCHYAAAAyQbAD\nAACQCYIdAACATBDsAAAAZIJgBwAAIBMEOwAAAJkg2AEAAMgEwQ4AAEAmCHYAAAAyQbADAACQ\nCYIdAACATBDsAAAAZIJgBwAAIBMEOwAAAJn4P6UMWmB++uzvAAAAAElFTkSuQmCC" + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0gAAANICAIAAAByhViMAAAACXBIWXMAABJ0AAASdAHeZh94\nAAAgAElEQVR4nOzdeZxkZX0v/s85p/aqrqW7q7dZmmEGhsXJyCagkmhEk5+JJhc1JkpQcxXQ\n5JKQ+4s3v8SoYIQYjHoTF4LhZciVBLwxXOOVGBFFWURRYUAcmJmeGWbp7uqq6lpP1dnP74+n\nq6fX6q26q/r05/3X9Omarme6YfjwfZ7n+5Vc1wURERERbX5yuxdARERERK3BYEdERETkEQx2\nRERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdE\nRETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERE\nRB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETk\nEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7B\nYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2\nRERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdE\nRETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERE\nRB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETk\nEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7B\nYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2\nRERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdE\nRETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERE\nRB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETk\nEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7B\nYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2\nRERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdE\nRETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERE\nRB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETk\nEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7B\nYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2\nRERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdE\nRETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERE\nRB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7BYEdERETkEQx2RERERB7ha/cC1kTT\nNNu2272KziJJkt/vt22b35nNRZZlSZL4U9tcZFn2+XyWZTmO0+610AooiuK6Ln9qm4vP55Nl\n2TRN13XbvZY2k2U5HA4v9tnNHex0XTdNs92r6Cw+ny8SiViWVa/X270WWoFQKCTLMn9qm0s4\nHPb7/Zqm6bre7rXQCsRiMdM0DcNo90JoBbq6uvx+f7Va5f8AK4rSJNhxK5aIiIjIIxjsiIiI\niDyCwY6IiIjIIxjsiIiIiDyCwY6IiIjIIxjsiIiIiDyCwY6IiIjIIxjsiIiIiDyCwY6IiIjI\nIxjsiIiIiDyCwY6IiIjIIxjsiIiIiDyCwY6IiIjIIxjsiIiIiDyCwY6IiIjIIxjsiIiIiDyC\nwY6IiIjIIxjsiIiIiDyCwY6IiIjIIxjsiIiIiDyCwY6IiIgIAA6MVdu9hLVisCMiIiKaSnWb\nPdsx2BEREdFWt9nz3DRfuxdARERE1DaeiXQCK3ZEREREHsFgR0REROQRDHZEREREHsFgR0RE\n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\nW6VS7dq1a+nSpe7u7sVo5blq06aNSqVSLqoePXq0SpUqRvO3EOL27duGxVu3bj3f/gFAxUew\ng1SUcSDDG+wUGRkZn376qRAiMzMzOTn5xIkT/fv3N0xgxbB69WqVSrVixYo5c+YEBgaq1erF\nixdrL/iGhIR06dLF09MzNzc3LCzsp59+Kl4r06dP/+STT6pWrao8rFOnzoYNG7TTJtLS0i5c\nuODu7u7s7FzyT/Q82Nvb161b9+rVq3/++Wd0dPQrr7ySX/42us9E6U55AQApEewglaCgIJVK\nlV+w+/777yMiInQrmZmZJZ9DcO7cuUuXLmlXVGnWrNmgQYNu3rw5YcKEWbNmLVu2bPjw4dp2\nMzIypk2bpqxaUlRqtXrGjBm3bt1SlvlNSEjQ3bf09OnTGo3Gx8enhB/nuWrTpk1ycvKaNWtE\n/tdhhRCDBw82LA4ZMuQ59gwApFBGe8UCZSA5OTkkJKRFixa1atUyeoDRwblij9jdunUrMDDw\n5s2byhIkulsUKFun7N+/P7/Xfvnll7qXUItEpVK5uLj07dv3u+++O378uHau6/Hjx4UQ3bp1\nK97bloGsrCxlbb8tW7aIf265M2ratGlXr1799ddftZUPPvggv7wOANAi2KH8SkpK+uuvv5yc\nnAqzV31sbOy2bduysrIKGAcyOvmgeJtAhISEvPHGG7p7Te7fv79r165CiNu3bz9zE4jIyMhi\nNKprwIAB33333d69e7XB7vfff7eysjK6jWx5kJubO2zYsJMnT4p/9sMZNGhQUFCQ0akkZmZm\n69atu3DhQnBwsLW19csvv1wObxkEgHKIS7EojzQazezZs93d3Xv37t2mTZsBAwbo7WGvKyYm\nZsiQIR4eHgsXLhRChIeHp6WlGT2yT58+hSw+0/Tp0/V2EFeCiBDi8OHDhntO6HF0dCxGo7ra\ntWtXu3btQ4cOKd24f//+7du3vb29DVezKye2bt2qpDqthISEgq+Dd+rUadq0aRMnTiTVAUAh\nEexQHn3++edr167Nzs5WHp49e3b06NGZmZmGR2ZnZ0+YMEG5Cqk4dOhQfnHB19f3rbfe0q00\nbtx4wYIFRe1eXFyc0Wmbp0+fFkKkpqY+8x1GjhxZ1Eb1aPeNVT678t/u3buX8G2fH+WXU5gi\nAKDYCHYod1JSUtauXatXDA8P1+6LquvUqVMXL17UK27ZsuXhw4dG33z58uVbt24dP368k5OT\nSqXasWNHMbbVUq4k5sfo+sO6S5wMHjz43XffLWqjhgYMGCCEUHbtK//BzqiCf5MAgKIi2KHc\niYmJycrKMqwbvRprtJiXl6fsW2VUz549//3vf/v7++fl5Z05c6YYPaxVq1bDhg0N6507dxZC\nvPbaay+//LLeU/PmzQsMDPz3v/8dFBS0evVqvT3vi6dDhw7Ozs6HDh1KT08/deqUi4uLMi23\nfPL29jYsGv6iAAAlQbBDuaOMpRnWa9asqf05JSXl559/Xrly5b1794y+ie7BRinLghjuvlpI\n77//vl5l9OjRnp6eQgi1Wr1+/foJEyY4ODio1eomTZqsXr166tSpw4YNGz9+fAFTQYtKrVb7\n+vomJSWNGDEiKSnJaHIqP0aMGKEEX61q1aotWrTIVP0BACmpKvSlkKSkJKNDOy8yc3PzatWq\npaenP3361NR9Kb5x48bt27dPt+Lk5HT69Gll3dqQkJCxY8fGx8crT6lU+v+Mu3XrtmPHjoKb\nyM3NVa6ZXr9+Xa0u1P/hJCQkKCvhVatW7cyZM5GRkZ6enk+fPnV0dPTz8xs6dKhhHtVoNIXc\nv8vKykqtVuc37cOomJiY/v37a6Otra3tDz/88MorrxT+HcqYRqNZs2bNsWPHkpOT27VrFxAQ\nkN/CNBWFtbW1jY1NSkqK0RtAUW7Z2tpqNBq9+U8o56pUqWJpaZmYmFi6m31XRGZmZkZXcVcQ\n7GTzPILdhQsXli1bdvPmTSXBtGjR4uuvv75586aTk9PgwYPHjRun3fygtCQkJIwdO/bcuXPK\nQ3Nz859//llZyOPp06edO3fW2w9erVbn5uYqP7dr127Dhg3PHLETQkyZMmXnzp1BQUGFGUWL\njIz09fVNSEjQVpo1a6Y3zbMkihHsBg4cqDf5oHr16mfPnmWHhjJDsKugCHYVEcFOq+Bgxzp2\neIagoKDhw4crP0dHR1+5ckX7VExMzOXLl0NDQ7/++uvSbdTBwWHz5s2NGjWqX7++k5PThQsX\ntDNkT548qZfqhBC5ublffvmlmZlZ48aNPT09C7kZa7du3Xbu3Hn8+PHCBLsZM2bopjohRHh4\n+KVLl1566aXCfaZSFh0dbTil9PHjx0eOHBk6dKhJugQAMDnusUNBcnNzDW8m07Nt2zbt0Fop\nunbtWl5eXs+ePWfPni2EWLdunVJPTEw0enzjxo1HjRrl5eVVyFQnhOjevbtKpdJdKiU/SUlJ\n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\n/xVRUlKS9sb8Mnb48GGjFzR1LVu2bNSoUUKIbt26hYeHnz9/vqiBqUePHtevXw8NDVVugCsM\nc3PzatWqpaenL1y4UG8+R5cuXXbu3Gl481xKSoqHh0dqaqry0NLSctWqVQMGDChSVxUajWb1\n6tU//vhjdHR0bm6ur6/v+vXrtS3279///PnzERERRte0e8FZWVmp1er8LmejfLK2traxsUlJ\nScnMzDR1X1AEtra2Go3G6MaGKLeqVKliaWmZmJiYk5Nj6r6YmJmZmb29fX7Pcim2mHr37t2s\nWTOVSuXh4dG7d2+jI3DKim4nTpy4fv36a6+9VoxhsMGDB+fk5Ch7yxZJamrq0qVL9YqnTp06\nduyY4cGHDh3SpjohRGZm5rvvvhsWFlbURoUQFhYWAQEBFy9eDA8PNzc3v3//vjbVaTSaS5cu\nNW3alFQHAMBzQrArprCwsPDw8G7duh09enTz5s1jxozRO6Bly5YeHh73799fvXq1+GcZuaIa\nOHCgmZnZzp07i/rCqKgoo0MIERERhsVvv/1Wr5KRkbF27dqiNqrLwcGhc+fOYWFh2tVeQkND\nMzMzO3XqVJK3BQAABSDYFdOGDRvEPzNJhRALFix4++23ld1R1Wq1mZlZREREgwYNXnrppWPH\njtWqVasY+64KIWrWrNmlS5fQ0NCbN28W6YVVq1Y1Wq9WrZphMSYmppDFIunXr58QQrt6y/nz\n5wU32AEA8DwR7IojNTV1165dzs7Offr0USpWVlYLFy6Mioo6e/bs7du369evn52dnZubqzwb\nGxv7xRdfFK+tN998Uwgxc+bM//znP9olVJ6pTp06hmNjdnZ2vXr1MjxYd1KFlouLSxF7qq9v\n375mZmbaYKfMnGBKLAAAzw/Brgiys7PXrl07atSo3r17p6amDh482Nz8/5tWbGFh0aRJk+Dg\n4MjISL3Xrlq1ynDx3mfKysravn27ECI4OHjJkiW+vr6zZ8/WPeDevXuzZs164403Jk6cuG/f\nPt2nli5damZmpn1oY2MTGBhodBLGpEmT9CqWlpbjx48vam/1ODo6ent7h4aGRkVF5eXlBQcH\nOzs716tXr4RvCwAA8sNyJ4WVk5MzZMgQZZk3xY4dO955553q1avrHXn79m3Dl2dlZUVFRbVu\n3bpIjS5fvvzkyZO6lbVr13p7eytXOa9cudKvX7+MjAzlqV9++WXy5MmLFy9WHv700085OTm+\n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\no0eP7tChg+CrTQf32FUYp06dWrt2bdu2bX///Xftv/6srKxp06a5urqOGzcuOzt77dq1OTk5\nixYtEkKMHz/ez8/P09NTOVKtVjs4OAghPv/889TU1EmTJllaWm7ZsiUqKmrlypVqNWO3wP8q\nrXMtvzoAraKebkePHt24ceO0adPq1q177ty5/fv3r1ixonLlyny1ab2In7mCysrKWrp0qfZL\nQnHnzp0HDx5MmTLFxcWlXr16M2bMuHbt2t27d4UQKSkpzs7Ojv9QvlH+/vvvkJCQt99+u0GD\nBrVr1548eXJMTExYWJhpPhJQLpXKuVZAHYBWUU+3bdu2jRkzpn379k5OTgMGDFizZk3lypX5\natPFpdgKw8fHRwgRGRmpW1SWvLewsFAe2tvbm5mZ3b59u3bt2pmZmefOndu0aVNKSkrjxo1H\njx7t4uJy69atSpUqNWjQQDne1tbW1dX1xo0brVu3LttPA5RfpXKuZWVlGa2X/ccByrMinW62\ntrZxcXFCiOnTp8fGxtarV2/ixInu7u58telixK5ia9iwoZ2d3ZYtW7Kzs7Ozs7dt2yaESElJ\nSUtLq1atWnZ29tSpUz/66CONRjN79uynT58mJydXqVJFpVJp36Fq1apJSUmm+wRAxVDUcy2/\nuqk/B1AB5He6PX78WAgRFBT04Ycfrlu3zs3N7bPPPktKSuKrTRcjdhWbtbX1rFmzAgMDDx48\naGlp2b9/fycnJzMzs6pVq27cuFF72IcffjhmzJizZ88KIXT/6QMopKKea7169cqvboruAxVJ\nfqeb8uzQoUNdXV2FEOPHjz9+/Pgff/wh+GrTQbCr8Fq2bPndd989ffrU0tJSCLFz584aNWro\nHWNtbV2jRo2///67YcOGycnJeXl52nMgKSnJ3t6+rDsNVEBFOtcKWQdglNHTTblR1cbGRjnG\nzMzMwcEhMTGxTp06fLVpcSm2YsvJyTl16lRiYqKNjY25ufnly5fz8vKaN29+9+7dr7/+Ojs7\nWzksIyPj0aNHzs7OTZo0ycrK0t7NkJycfP/+/WbNmpnuEwAVQ1HPtfzqpvsEQIWR3+nm4OBg\nb28fERGhHKbRaB49elSzZk2+2nQxYldhJCYm5uTkpKSkCCGU/++3tbW1srLatWvX6dOn/f39\nHz58uGrVqt69e9vZ2alUqnPnzmVnZw8bNiwnJ2fjxo22trbe3t6WlpZeXl6rVq2aPn26hYXF\n2rVrGzVq1Lx5c1N/OKAcKZVzTaPRGK2b+sMB5UuRTjchRL9+/X766SdXV1dXV9etW7daWVl1\n6NDBysqKrzYt1rGrMCZOnBgfH69X6d+//4MHD1atWnXz5k0rK6tXXnll7Nix5ubmQoi//vpr\n/fr1ylwhNzc3f3//mjVrCiHS0tLWrFlz+fLlnJycFi1aTJ48+YUdrwaMKq1zLb86AK2inm65\nubmbNm0KCgpKTU11c3ObOnVqnTp1BF9tOgh2AAAAkuAeOwAAAEkQ7AAAACRBsAMAAJAEwQ4A\nAEASBDsAAABJEOwAAAAkQbADAACQBMEOAIpm2LBhtra2pu4FABhBsAMAAJAEwQ4AAEASBDsA\nKEheXt78+fPr1KljZWXVqlWrnTt36j4bGxvr7+9fr149KysrZ2fnQYMGRUREmKqrAMBesQBQ\nkC+++OKjjz4aOXLk2LFjExISFixYkJWVFR0dnZqaKoTw8vKKior6/PPPGzZsGBsbu2TJkocP\nH965c6dy5cqm7jiAFxHBDgDylZeX5+rq6uDgEBYWplRiY2Pr1atnYWGRmpqanJxctWrVWbNm\nLV68WHk2MjJy+/btY8aMqV27tul6DeDFxaVYAMjX/fv3Hzx44OPjo63UqlWrffv2ys/W1tbV\nq1ffunXr0aNHc3NzhRCNGjWaPXs2qQ6AqRDsACBfcXFxQogaNWroFrW5rVKlSr/88otare7Z\ns6eTk9Obb765ZcuW7OxsE3QUAIQQBDsAKIDRm1VycnK0P3fu3PnWrVtHjx4dN25ceHj4yJEj\nvby80tPTy7CPAPB/CHYAkC9lrE4Zt9OKiorSfWhmZubj4/Pll19ev3599erVf/zxx/bt28uy\nkwCgRbADgHzVr1/f0dHx4MGDyi10QoibN2+GhoYqP1+8eHHYsGHx8fHa43v37i2EePToUdl3\nFQAEs2IBoGCffvrpggUL/Pz8Ro4cGR8fv2TJEkdHx4iIiNTU1Li4uKZNmzZo0GDGjBl169Z9\n/PjxypUrr127dunSpUaNGpm64wBeRAQ7AChITk7OJ5988sMPPyQkJLi5uc2fP//o0aNr1qzJ\nzMwUQly9enXevHlnzpxJTEysUaNGp06d/vWvf7Vt29bUvQbwgiLYAQAASIJ77AAAACRBsAMA\nAJAEwQ4AAEASBDsAAABJEOwAAAAkQbADAACQBMEOAABAEgQ7AAAASRDsAAAAJEGwAwAAkATB\nDgAAQBIEOwAAAEkQ7AAAACRBsAMAAJAEwQ4AAEASBDsAAABJEOwAAAAkQbADAACQBMEOAABA\nEgQ7AAAASRDsAAAAJEGwAwAAkATBDgAAQBIEOwAAAEkQ7AAAACRBsAMAAJAEwQ4AAEASBDsA\nAABJEOwAAAAkQbADAACQBMEOAABAEgQ7AAAASRDsAAAAJEGwAwAAkATBDgAAQBIEOwAAAEkQ\n7AAAACRBsAMAAJAEwQ4AAEASBDsAAABJEOwAAAAkQbADAACQBMEOAABAEgQ7AAAASRDsAAAA\nJEGwAwAAkATBDgAAQBIEOwAAAEkQ7AAAACRBsAMAAJAEwQ4AAEASBDsAAABJEOwAAAAkQbAD\nAACQBMEOAABAEgQ7AAAASRDsAAAAJEGwAwAAkATBDgAAQBIEOwAAAEkQ7AAAACRBsAMAAJAE\nwQ4AAEASBDsAAABJEOwAAAAkQbADAACQBMEOAABAEgQ7AAAASRDsAAAAJEGwAwAAkATBDgAA\nQBIEOwAAAEkQ7AAAACRBsAMAAJAEwQ4AAEASBDsAAABJEOwAAAAkQbADAACQBMEOAABAEgQ7\nAAAASRDsAAAAJEGwAwAAkATBDgAAQBIEOwAAAEkQ7AAAACRBsAMAAJAEwQ4AAEASBDsAAABJ\nEOwAAAAkQbADAACQBMEOAABAEgQ7AAAASRDsAAAAJEGwAwAAkATBDgAAQBIEOwAAAEkQ7AAA\nACRBsAMAAJAEwQ4AAEASBDsAAABJEOwAAAAkQbADAACQBMEOAABAEgQ7AAAASRDsAAAAJEGw\nAwAAkATBDgAAQBIEOwAAAEkQ7AAAACRBsAMe81IeAAABh0lEQVQAAJAEwQ4AAEASBDsAAABJ\nEOwAAAAkQbADAACQBMEOAABAEgQ7AAAASRDsAAAAJEGwAwAAkATBDgAAQBIEOwAAAEkQ7AAA\nACRBsAMAAJAEwQ4AAEASBDsAAABJEOwAAAAkQbADAACQBMEOAABAEgQ7AAAASRDsAAAAJEGw\nAwAAkATBDgAAQBIEOwAAAEkQ7AAAACRBsAMAAJAEwQ4AAEASBDsAAABJEOwAAAAkQbADAACQ\nBMEOAABAEgQ7AAAASRDsAAAAJEGwAwAAkATBDgAAQBIEOwAAAEkQ7AAAACRBsAMAAJAEwQ4A\nAEASBDsAAABJEOwAAAAkQbADAACQBMEOAABAEgQ7AAAASRDsAAAAJEGwAwAAkATBDgAAQBIE\nOwAAAEkQ7AAAACRBsAMAAJAEwQ4AAEASBDsAAABJEOwAAAAkQbADAACQBMEOAABAEgQ7AAAA\nSRDsAAAAJEGwAwAAkATBDgAAQBIEOwAAAEkQ7AAAACRBsAMAAJAEwQ4AAEAS/w9jgB+xsyeV\nRwAAAABJRU5ErkJggg==" }, "metadata": { "image/png": { @@ -17461,51 +17691,68 @@ " geom_line(data = my_train, aes(x = as.POSIXct(ds))) +\n", " geom_line(data = my_test, aes(x = as.POSIXct(ds)), color = \"red\")" ], - "id": "a5f4b48f-7d46-439d-99bf-9dde81fad277" + "id": "04faa3ac-28a2-43b3-9d31-0e2e47f8b7a7" }, { - "id": "94693748", + "id": "7a846408", "cell_type": "markdown", "source": [ "# 13 教師なし学習" ], "metadata": { - "id": "94693748" + "id": "7a846408" } }, { "cell_type": "code", - "execution_count": 447, + "execution_count": 410, "metadata": { - "id": "abb26daa-e845-4765-b78f-19fa9cc91c93" + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "2494be34-b0aa-4e86-beac-41d84bb72223", + "outputId": "2556c7a6-3365-4595-d545-76f1747c186f" }, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "Installing packages into ‘/usr/local/lib/R/site-library’\n", + "(as ‘lib’ is unspecified)\n", + "\n", + "also installing the dependencies ‘SparseM’, ‘MatrixModels’, ‘minqa’, ‘nloptr’, ‘carData’, ‘pbkrtest’, ‘quantreg’, ‘lme4’, ‘httpuv’, ‘estimability’, ‘mvtnorm’, ‘corrplot’, ‘viridis’, ‘car’, ‘DT’, ‘ellipse’, ‘emmeans’, ‘flashClust’, ‘multcompView’, ‘scatterplot3d’, ‘ggsci’, ‘cowplot’, ‘ggsignif’, ‘polynom’, ‘rstatix’, ‘dendextend’, ‘FactoMineR’, ‘ggpubr’\n", + "\n", + "\n" + ] + } + ], "source": [ "# Google Colaboratoryの環境設定\n", "if (file.exists(\"/content\")) {\n", " options(Ncpus = parallel::detectCores())\n", - " packages_to_install <- c(\"factoextra\", \"ggbiplot\", \"igraph\")\n", " installed_packages <- rownames(installed.packages())\n", + " packages_to_install <- c(\"factoextra\", \"ggbiplot\", \"igraph\")\n", " install.packages(setdiff(packages_to_install, installed_packages))\n", "}" ], - "id": "abb26daa-e845-4765-b78f-19fa9cc91c93" + "id": "2494be34-b0aa-4e86-beac-41d84bb72223" }, { - "id": "bade5a9b", + "id": "2f39894b", "cell_type": "markdown", "source": [ "## 13.1 主成分分析" ], "metadata": { - "id": "bade5a9b" + "id": "2f39894b" } }, { "cell_type": "code", - "execution_count": 448, + "execution_count": 411, "metadata": { - "id": "571e18eb-a9d2-46ee-8a65-cb1644601f6d" + "id": "2f174b44-c177-4804-a2bb-eed1a8e05dea" }, "outputs": [], "source": [ @@ -17520,18 +17767,18 @@ " row.names = c(\"A\", \"B\", \"C\", \"D\", \"E\", \"F\"))\n", "my_result <- my_data %>% prcomp # 主成分分析の実行" ], - "id": "571e18eb-a9d2-46ee-8a65-cb1644601f6d" + "id": "2f174b44-c177-4804-a2bb-eed1a8e05dea" }, { "cell_type": "code", - "execution_count": 449, + "execution_count": 412, "metadata": { - "id": "06d747ec-cf8d-42ee-bffc-8dc78a219ffe", - "outputId": "6667503e-7c3b-4382-cd0f-10ddc6788ef3", "colab": { "base_uri": "https://localhost:8080/", "height": 255 - } + }, + "id": "0bf6be67-e3b1-4582-a087-001330c1f6b3", + "outputId": "5b715f87-b141-4cb6-9c95-95edd949edf8" }, "outputs": [ { @@ -17571,18 +17818,18 @@ "source": [ "my_result$x # 主成分スコア" ], - "id": "06d747ec-cf8d-42ee-bffc-8dc78a219ffe" + "id": "0bf6be67-e3b1-4582-a087-001330c1f6b3" }, { "cell_type": "code", - "execution_count": 450, + "execution_count": 413, "metadata": { - "id": "cac818b0-c18c-49cf-a4f0-da6e2334a980", - "outputId": "f506824e-760c-420a-cac1-f5914befc375", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "981e56ac-f21c-4deb-b8f4-04534a309f01", + "outputId": "a3b38317-608d-4444-ca2a-f91cf6c7ff1b" }, "outputs": [ { @@ -17606,18 +17853,18 @@ " labels = row.names(my_data),\n", " scale = 0)" ], - "id": "cac818b0-c18c-49cf-a4f0-da6e2334a980" + "id": "981e56ac-f21c-4deb-b8f4-04534a309f01" }, { "cell_type": "code", - "execution_count": 451, + "execution_count": 414, "metadata": { - "id": "8477894b-d455-48e2-bc33-9727d08dda18", - "outputId": "2b9fdaae-9480-4b12-9e93-533da9850bd1", "colab": { "base_uri": "https://localhost:8080/", - "height": 224 - } + "height": 223 + }, + "id": "5ff87676-1ff4-42d5-8567-7073e29752d4", + "outputId": "7dcaf48f-6eab-4a8f-c1a0-1b800b09d9c7" }, "outputs": [ { @@ -17655,18 +17902,18 @@ "source": [ "my_result$rotation %>% t" ], - "id": "8477894b-d455-48e2-bc33-9727d08dda18" + "id": "5ff87676-1ff4-42d5-8567-7073e29752d4" }, { "cell_type": "code", - "execution_count": 452, + "execution_count": 415, "metadata": { - "id": "836c78d6-dfd8-4d53-8dd9-9701871aa0c0", - "outputId": "473a22dc-ed7b-4a95-8846-b13f3154d2d9", "colab": { "base_uri": "https://localhost:8080/", - "height": 104 - } + "height": 107 + }, + "id": "96f147a1-77f8-4993-aa9f-4209f6d7fcd5", + "outputId": "09069af8-00f2-4cf0-9949-50d77cb9e524" }, "outputs": [ { @@ -17686,18 +17933,18 @@ "source": [ "summary(my_result)" ], - "id": "836c78d6-dfd8-4d53-8dd9-9701871aa0c0" + "id": "96f147a1-77f8-4993-aa9f-4209f6d7fcd5" }, { "cell_type": "code", - "execution_count": 453, + "execution_count": 416, "metadata": { - "id": "4365699e-0bf0-4f63-91f3-60a4add8764d", - "outputId": "5411b8dc-6599-4dd2-b9a5-25c25c340011", "colab": { "base_uri": "https://localhost:8080/", "height": 255 - } + }, + "id": "23310865-d302-45c5-ab73-4c80a979e762", + "outputId": "0b778097-b5f3-4687-e261-a4d9bd92c099" }, "outputs": [ { @@ -17744,18 +17991,18 @@ "\n", "my_result$x # 主成分スコア" ], - "id": "4365699e-0bf0-4f63-91f3-60a4add8764d" + "id": "23310865-d302-45c5-ab73-4c80a979e762" }, { "cell_type": "code", - "execution_count": 454, + "execution_count": 417, "metadata": { - "id": "67619dbe-ca8a-4d70-bb2e-40effdcbd625", - "outputId": "107a61a3-a138-4b30-d259-848a39b1387e", "colab": { "base_uri": "https://localhost:8080/", "height": 240 - } + }, + "id": "aebe9ee6-7f32-4766-98d1-b281595eb6e5", + "outputId": "6c9cccc5-c8fb-4ace-dc28-efe2b19ed350" }, "outputs": [ { @@ -17819,18 +18066,18 @@ "Z %*% tmp$vectors # 主成分スコア(結果は割愛)\n", "cumsum(tmp$values) / sum(tmp$values) # 累積寄与率" ], - "id": "67619dbe-ca8a-4d70-bb2e-40effdcbd625" + "id": "aebe9ee6-7f32-4766-98d1-b281595eb6e5" }, { "cell_type": "code", - "execution_count": 455, + "execution_count": 418, "metadata": { - "id": "34be6772-92d0-431f-a670-2cb61e6bccc5", - "outputId": "1ef933ef-c133-4dea-b143-adc0b80e2161", "colab": { "base_uri": "https://localhost:8080/", "height": 257 - } + }, + "id": "72e302b5-2f34-48be-b825-00bc53875986", + "outputId": "140a03bf-4a26-4d19-f702-b76031385e9a" }, "outputs": [ { @@ -17918,23 +18165,23 @@ "e <- d^2 / (n - 1) # 分散共分散行列の固有値\n", "cumsum(e) / sum(e) # 累積寄与率" ], - "id": "34be6772-92d0-431f-a670-2cb61e6bccc5" + "id": "72e302b5-2f34-48be-b825-00bc53875986" }, { - "id": "8d28b828", + "id": "8c6bbece", "cell_type": "markdown", "source": [ "## 13.2 クラスタ分析" ], "metadata": { - "id": "8d28b828" + "id": "8c6bbece" } }, { "cell_type": "code", - "execution_count": 456, + "execution_count": 419, "metadata": { - "id": "77132ba5-1fe8-4174-a8b7-623ed6dee084" + "id": "99430d8e-7cb2-4a48-bbd1-b2a5e40750ba" }, "outputs": [], "source": [ @@ -17949,20 +18196,31 @@ " dist(\"euclidian\") %>% # distだけでも可\n", " hclust(\"complete\") # hclustだけでも可" ], - "id": "77132ba5-1fe8-4174-a8b7-623ed6dee084" + "id": "99430d8e-7cb2-4a48-bbd1-b2a5e40750ba" }, { "cell_type": "code", - "execution_count": 457, + "execution_count": 420, "metadata": { - "id": "a5a6a538-6fcc-4757-87d3-1fdcaf23ae02", - "outputId": "1b0fe59f-8703-4d08-b378-bda3cd191736", "colab": { "base_uri": "https://localhost:8080/", - "height": 437 - } + "height": 527 + }, + "id": "78b7b092-5421-48ef-9963-17a2531673e8", + "outputId": "1f41a576-a775-40b5-a49a-b90da87faccd" }, "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "Warning message:\n", + "“\u001b[1m\u001b[22mThe `` argument of `guides()` cannot be `FALSE`. Use \"none\" instead as\n", + "of ggplot2 3.3.4.\n", + "\u001b[36mℹ\u001b[39m The deprecated feature was likely used in the \u001b[34mfactoextra\u001b[39m package.\n", + " Please report the issue at \u001b[3m\u001b[34m\u001b[39m\u001b[23m.”\n" + ] + }, { "output_type": "display_data", "data": { @@ -17984,18 +18242,18 @@ " k = 3, # クラスタ数\n", " rect = TRUE, rect_fill = TRUE)" ], - "id": "a5a6a538-6fcc-4757-87d3-1fdcaf23ae02" + "id": "78b7b092-5421-48ef-9963-17a2531673e8" }, { "cell_type": "code", - "execution_count": 458, + "execution_count": 421, "metadata": { - "id": "051b42ee-bb20-4068-b1c8-52ccaa53a8e2", - "outputId": "eaf1b724-a2b4-49ca-b6ad-6721d16d764d", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "bf366906-c76b-408c-9bc4-c354fdbfa615", + "outputId": "77639963-21d9-41a7-c618-fd24c219ea11" }, "outputs": [ { @@ -18020,18 +18278,18 @@ " rect = TRUE, rect_fill = TRUE,\n", " type = \"phylogenic\")" ], - "id": "051b42ee-bb20-4068-b1c8-52ccaa53a8e2" + "id": "bf366906-c76b-408c-9bc4-c354fdbfa615" }, { "cell_type": "code", - "execution_count": 459, + "execution_count": 422, "metadata": { - "id": "25253db4-242e-4566-8f44-9317c7a738ee", - "outputId": "043a857b-1b49-4f06-8cb8-1e99a9ef4a99", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "0ac49fc4-75e5-4f83-bc66-5f8d8a8ed730", + "outputId": "206c9b82-6165-4cc6-f54a-3b77e1a7e9ca" }, "outputs": [ { @@ -18058,13 +18316,13 @@ "source": [ "my_result %>% cutree(3)" ], - "id": "25253db4-242e-4566-8f44-9317c7a738ee" + "id": "0ac49fc4-75e5-4f83-bc66-5f8d8a8ed730" }, { "cell_type": "code", - "execution_count": 460, + "execution_count": 423, "metadata": { - "id": "50172e6f-a365-4cae-8aac-285832e935ad" + "id": "c272196f-e18f-4ff6-a589-481e33640570" }, "outputs": [], "source": [ @@ -18083,13 +18341,13 @@ " gplots::heatmap.2(cexRow = 1, cexCol = 1), # ラベルのサイズを指定して描画する.\n", " silent = TRUE)" ], - "id": "50172e6f-a365-4cae-8aac-285832e935ad" + "id": "c272196f-e18f-4ff6-a589-481e33640570" }, { "cell_type": "code", - "execution_count": 461, + "execution_count": 424, "metadata": { - "id": "86e6bc97-ddd2-4ff5-b67d-8ba77d0754e3" + "id": "e0aa0c5c-07cc-404e-86fc-8cd506cee290" }, "outputs": [], "source": [ @@ -18102,18 +18360,18 @@ "\n", "my_result <- my_data %>% kmeans(3)" ], - "id": "86e6bc97-ddd2-4ff5-b67d-8ba77d0754e3" + "id": "e0aa0c5c-07cc-404e-86fc-8cd506cee290" }, { "cell_type": "code", - "execution_count": 462, + "execution_count": 425, "metadata": { - "id": "c5afd760-ff1f-4805-aa72-14d93ae8bf84", - "outputId": "1a511b3f-7cf9-4a80-b989-fda17f710f87", "colab": { "base_uri": "https://localhost:8080/", "height": 34 - } + }, + "id": "78ffb86b-446a-409c-9914-6cf57ae37980", + "outputId": "9c887e81-9a77-49ab-ef2a-3d8f8920242f" }, "outputs": [ { @@ -18140,20 +18398,28 @@ "source": [ "my_result$cluster" ], - "id": "c5afd760-ff1f-4805-aa72-14d93ae8bf84" + "id": "78ffb86b-446a-409c-9914-6cf57ae37980" }, { "cell_type": "code", - "execution_count": 463, + "execution_count": 426, "metadata": { - "id": "bcd0e490-e570-4986-b270-9b2d15e58cea", - "outputId": "fedf6ebb-6fa6-4d11-f14c-f36795d1681f", "colab": { "base_uri": "https://localhost:8080/", - "height": 437 - } + "height": 473 + }, + "id": "59366ea4-6ab2-448e-be3e-fb32e4f0fa07", + "outputId": "1278072f-7423-4e44-e3a1-3bf6e7ba2930" }, "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa\n", + "\n" + ] + }, { "output_type": "display_data", "data": { @@ -18183,18 +18449,18 @@ "})\n", "gridExtra::grid.arrange(f[[1]], f[[2]], f[[3]], f[[4]], ncol = 2)" ], - "id": "bcd0e490-e570-4986-b270-9b2d15e58cea" + "id": "59366ea4-6ab2-448e-be3e-fb32e4f0fa07" }, { "cell_type": "code", - "execution_count": 464, + "execution_count": 427, "metadata": { - "id": "e9772728-d3fa-4d93-b592-97e63fa396ee", - "outputId": "4e213750-96ab-4390-82ac-63ecc8b1b145", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "edd71658-0a7f-43b4-82b2-1924dc79f23b", + "outputId": "72e80093-b8d5-4be3-95ac-26e1d4dec4e0" }, "outputs": [ { @@ -18216,18 +18482,18 @@ "source": [ "fviz_nbclust(my_data, kmeans, method = \"wss\")" ], - "id": "e9772728-d3fa-4d93-b592-97e63fa396ee" + "id": "edd71658-0a7f-43b4-82b2-1924dc79f23b" }, { "cell_type": "code", - "execution_count": 465, + "execution_count": 428, "metadata": { - "id": "0a20b9c9-a772-4340-a472-f807197f44e0", - "outputId": "5f1a70f6-a62e-4613-8e32-4df77d1a9fc4", "colab": { "base_uri": "https://localhost:8080/", "height": 437 - } + }, + "id": "ce3d65af-a8ff-41c2-bfaf-0f23a6f639e6", + "outputId": "3b8dfe3b-3447-4c4e-8a45-79ea2c474db6" }, "outputs": [ { @@ -18263,7 +18529,7 @@ " geom_point(shape = iris$Species) + # 形で品種を表現する.\n", " theme(legend.position = \"none\")" ], - "id": "0a20b9c9-a772-4340-a472-f807197f44e0" + "id": "ce3d65af-a8ff-41c2-bfaf-0f23a6f639e6" } ], "nbformat": 4, diff --git a/code/r.Rmd b/code/r.Rmd index 2ca7d7d..5f7a999 100644 --- a/code/r.Rmd +++ b/code/r.Rmd @@ -64,6 +64,7 @@ if (file.exists("/content")) { installed_packages <- rownames(installed.packages()) packages_to_install <- c("furrr", "keras", "proxy") install.packages(setdiff(packages_to_install, installed_packages)) + install.packages(c("ggplot2")) } ``` @@ -1890,7 +1891,7 @@ registerDoSEQ() if (file.exists("/content")) { options(Ncpus = parallel::detectCores()) installed_packages <- rownames(installed.packages()) - packages_to_install <- c("caret", "ggfortify", "glmnet", "glmnetUtils", "leaps", "neuralnet", "psych") + packages_to_install <- c("caret", "ggfortify", "glmnetUtils", "leaps", "neuralnet", "psych") install.packages(setdiff(packages_to_install, installed_packages)) } ``` @@ -3053,8 +3054,8 @@ if (file.exists("/content")) { options(Ncpus = parallel::detectCores()) installed_packages <- rownames(installed.packages()) packages_to_install <- c("caret", "fable", "feasts", "prophet", "tsibble", "urca") - packages_to_upgrade <- c("ggplot2") - install.packages(union(setdiff(packages_to_install, installed_packages), packages_to_upgrade)) + install.packages(setdiff(packages_to_install, installed_packages)) + install.packages(c("ggplot2")) } ``` diff --git a/code/r.ipynb b/code/r.ipynb index 83f51e8..abc02d1 100644 --- a/code/r.ipynb +++ b/code/r.ipynb @@ -1,30 +1,30 @@ { "cells": [ { - "id": "d060ff37", + "id": "1e430fbc", "cell_type": "markdown", "source": [ "[辻真吾・矢吹太朗『ゼロからはじめるデータサイエンス入門』(講談社, 2021)](https://github.com/taroyabuki/fromzero)" ], "metadata": { - "id": "d060ff37" + "id": "1e430fbc" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "629dde29-db65-4ae4-abdc-c1201f9dabfa" + "id": "b7f3066a-1a6a-420f-a14f-b6128af18546" }, "outputs": [], "source": [ "# これはRのコードの例です.\n", "1 + 1" ], - "id": "629dde29-db65-4ae4-abdc-c1201f9dabfa" + "id": "b7f3066a-1a6a-420f-a14f-b6128af18546" }, { - "id": "b1befe1c", + "id": "e29e4d41", "cell_type": "markdown", "source": [ "# 1 コンピュータとネットワーク\n", @@ -32,11 +32,11 @@ "\n" ], "metadata": { - "id": "b1befe1c" + "id": "e29e4d41" } }, { - "id": "8e74564f", + "id": "31ae57f2", "cell_type": "markdown", "source": [ "## 1.1 コンピュータの基本操作\n", @@ -44,11 +44,11 @@ "\n" ], "metadata": { - "id": "8e74564f" + "id": "31ae57f2" } }, { - "id": "19563b2a", + "id": "976b7c14", "cell_type": "markdown", "source": [ "## 1.2 ネットワークの仕組み\n", @@ -56,11 +56,11 @@ "\n" ], "metadata": { - "id": "19563b2a" + "id": "976b7c14" } }, { - "id": "97614aed", + "id": "8d28880d", "cell_type": "markdown", "source": [ "# 2 データサイエンスのための環境\n", @@ -68,11 +68,11 @@ "\n" ], "metadata": { - "id": "97614aed" + "id": "8d28880d" } }, { - "id": "4fa9785d", + "id": "c9044c1a", "cell_type": "markdown", "source": [ "## 2.1 実行環境の選択\n", @@ -80,11 +80,11 @@ "\n" ], "metadata": { - "id": "4fa9785d" + "id": "c9044c1a" } }, { - "id": "d7bfe4c2", + "id": "e220238c", "cell_type": "markdown", "source": [ "## 2.2 クラウド\n", @@ -92,11 +92,11 @@ "\n" ], "metadata": { - "id": "d7bfe4c2" + "id": "e220238c" } }, { - "id": "30d773b4", + "id": "6bce9671", "cell_type": "markdown", "source": [ "## 2.3 Docker\n", @@ -104,11 +104,11 @@ "\n" ], "metadata": { - "id": "30d773b4" + "id": "6bce9671" } }, { - "id": "2fb621cf", + "id": "ac551726", "cell_type": "markdown", "source": [ "## 2.4 ターミナルの使い方\n", @@ -116,11 +116,11 @@ "\n" ], "metadata": { - "id": "2fb621cf" + "id": "ac551726" } }, { - "id": "faa2f46c", + "id": "875284c8", "cell_type": "markdown", "source": [ "## 2.5 RとPython\n", @@ -128,24 +128,24 @@ "\n" ], "metadata": { - "id": "faa2f46c" + "id": "875284c8" } }, { - "id": "fcc98814", + "id": "b5a56409", "cell_type": "markdown", "source": [ "## 2.6 サンプルコードの利用" ], "metadata": { - "id": "fcc98814" + "id": "b5a56409" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "162e4ad7-6b1f-431c-9abb-1234f68b7368" + "id": "47ae7791-141d-4b05-82f9-1b1895246e85" }, "outputs": [], "source": [ @@ -155,23 +155,23 @@ "\n", "1 + 3" ], - "id": "162e4ad7-6b1f-431c-9abb-1234f68b7368" + "id": "47ae7791-141d-4b05-82f9-1b1895246e85" }, { - "id": "39ce6a99", + "id": "c3552337", "cell_type": "markdown", "source": [ "# 3 RとPython" ], "metadata": { - "id": "39ce6a99" + "id": "c3552337" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a8d5454c-a2b9-417f-8402-f299adb4aaa6" + "id": "3644bfaf-8216-444a-bee4-26292272069c" }, "outputs": [], "source": [ @@ -181,73 +181,74 @@ " installed_packages <- rownames(installed.packages())\n", " packages_to_install <- c(\"furrr\", \"keras\", \"proxy\")\n", " install.packages(setdiff(packages_to_install, installed_packages))\n", + " install.packages(c(\"ggplot2\"))\n", "}" ], - "id": "a8d5454c-a2b9-417f-8402-f299adb4aaa6" + "id": "3644bfaf-8216-444a-bee4-26292272069c" }, { - "id": "c9f34664", + "id": "d77ca992", "cell_type": "markdown", "source": [ "## 3.1 入門" ], "metadata": { - "id": "c9f34664" + "id": "d77ca992" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "117519a1-aa23-4fd3-a0a4-2ff1a200d225" + "id": "a4cb5c5f-ea1d-462b-a186-12c49adc7ef8" }, "outputs": [], "source": [ "0x10" ], - "id": "117519a1-aa23-4fd3-a0a4-2ff1a200d225" + "id": "a4cb5c5f-ea1d-462b-a186-12c49adc7ef8" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "bf838440-db82-4a5b-9a95-27a45d543376" + "id": "68e88555-3399-4892-895a-3b97999c1b52" }, "outputs": [], "source": [ "1.23e5" ], - "id": "bf838440-db82-4a5b-9a95-27a45d543376" + "id": "68e88555-3399-4892-895a-3b97999c1b52" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "470062aa-263b-466f-acc2-7e3b04a13e94" + "id": "38b58ecb-b445-492d-a6b3-3b04807afc43" }, "outputs": [], "source": [ "2 * 3" ], - "id": "470062aa-263b-466f-acc2-7e3b04a13e94" + "id": "38b58ecb-b445-492d-a6b3-3b04807afc43" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b8df17ec-d7e0-406f-81a1-2f4e55e7d6e0" + "id": "8105c01e-4ee5-4b25-bd7a-46597f30b5e6" }, "outputs": [], "source": [ "10 / 3" ], - "id": "b8df17ec-d7e0-406f-81a1-2f4e55e7d6e0" + "id": "8105c01e-4ee5-4b25-bd7a-46597f30b5e6" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "570a4972-5306-426b-8251-23158389aa65" + "id": "17586aeb-7f3e-472a-99cb-496794a2ce97" }, "outputs": [], "source": [ @@ -255,13 +256,13 @@ "\n", "10 %% 3 # 余り" ], - "id": "570a4972-5306-426b-8251-23158389aa65" + "id": "17586aeb-7f3e-472a-99cb-496794a2ce97" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "94ba9dc5-6eb7-4bcb-acfb-95ac81e69380" + "id": "a1aa520b-ec6c-4191-9c09-62b32fde7555" }, "outputs": [], "source": [ @@ -272,13 +273,13 @@ "keras::`%<-%`(c(x, y), c(20, 30)) # まとめて名付け\n", "x * y" ], - "id": "94ba9dc5-6eb7-4bcb-acfb-95ac81e69380" + "id": "a1aa520b-ec6c-4191-9c09-62b32fde7555" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "577053a7-a4a7-44a6-89da-042371e80ddd" + "id": "3ecf7571-ac83-41c7-b1e7-309c014bd1c1" }, "outputs": [], "source": [ @@ -287,75 +288,75 @@ "\n", "x # 変数名を評価する." ], - "id": "577053a7-a4a7-44a6-89da-042371e80ddd" + "id": "3ecf7571-ac83-41c7-b1e7-309c014bd1c1" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "bbe7180c-1bc2-43ca-84cc-c8281ee025bf" + "id": "e931eaab-85a8-466c-9914-91c690125d4f" }, "outputs": [], "source": [ "my_s <- \"abcde\"" ], - "id": "bbe7180c-1bc2-43ca-84cc-c8281ee025bf" + "id": "e931eaab-85a8-466c-9914-91c690125d4f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "2164cbf2-6c51-462c-8e45-d08086899bdc" + "id": "7648efdf-fe79-4897-a050-4bc4765a24a0" }, "outputs": [], "source": [ "nchar(my_s)" ], - "id": "2164cbf2-6c51-462c-8e45-d08086899bdc" + "id": "7648efdf-fe79-4897-a050-4bc4765a24a0" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "2623d082-8616-4237-bc1e-c23e9fa284d9" + "id": "9f0c218b-85ca-462a-ae4f-54393f0f6acf" }, "outputs": [], "source": [ "library(tidyverse)\n", "str_c(\"This is \", \"a\", \" pen.\")" ], - "id": "2623d082-8616-4237-bc1e-c23e9fa284d9" + "id": "9f0c218b-85ca-462a-ae4f-54393f0f6acf" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "be94c127-b74c-4050-a207-3163a2662977" + "id": "8f7b6526-0666-4d74-8938-28f621aabb03" }, "outputs": [], "source": [ "substr(x = my_s, start = 2, stop = 4)" ], - "id": "be94c127-b74c-4050-a207-3163a2662977" + "id": "8f7b6526-0666-4d74-8938-28f621aabb03" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "38a9e788-fc72-4c88-80c5-e363ed2416f7" + "id": "0d1754ec-ea14-44d8-8634-a93e37f1294e" }, "outputs": [], "source": [ "tmp <- \"%s is %s.\"\n", "sprintf(tmp, \"This\", \"a pen\")" ], - "id": "38a9e788-fc72-4c88-80c5-e363ed2416f7" + "id": "0d1754ec-ea14-44d8-8634-a93e37f1294e" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a5e27c56-2abd-4e0f-b46e-8d08b73d579d" + "id": "0793b050-9953-4f61-ac8e-c79ccad8568b" }, "outputs": [], "source": [ @@ -363,13 +364,13 @@ "\n", "1 < 0" ], - "id": "a5e27c56-2abd-4e0f-b46e-8d08b73d579d" + "id": "0793b050-9953-4f61-ac8e-c79ccad8568b" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "267875a7-ccd2-4c74-937b-dc9893818bc9" + "id": "baef2854-d1f7-467a-a0ee-e9766936993d" }, "outputs": [], "source": [ @@ -377,13 +378,13 @@ "\n", "all.equal(0.1 + 0.1 + 0.1, 0.3)" ], - "id": "267875a7-ccd2-4c74-937b-dc9893818bc9" + "id": "baef2854-d1f7-467a-a0ee-e9766936993d" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "e9dc7474-bb09-4058-9a0f-486eb03f8f52" + "id": "0421a10a-14e2-4bc3-bfd8-ebc91653f682" }, "outputs": [], "source": [ @@ -393,84 +394,84 @@ "\n", "!TRUE # 否定(でない)" ], - "id": "e9dc7474-bb09-4058-9a0f-486eb03f8f52" + "id": "0421a10a-14e2-4bc3-bfd8-ebc91653f682" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "fa446c9d-5d45-45c1-a485-77bce7d392f1" + "id": "55a5aeb3-df8b-48c4-a222-47c2d0568435" }, "outputs": [], "source": [ "ifelse(3 < 5, 0, 10)" ], - "id": "fa446c9d-5d45-45c1-a485-77bce7d392f1" + "id": "55a5aeb3-df8b-48c4-a222-47c2d0568435" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b03092bc-5c79-4686-ac14-e78bff5dc6df" + "id": "29f1d8c4-1e5b-4310-8847-404866a9c9fa" }, "outputs": [], "source": [ "getwd()" ], - "id": "b03092bc-5c79-4686-ac14-e78bff5dc6df" + "id": "29f1d8c4-1e5b-4310-8847-404866a9c9fa" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "5c3c2445-6dcc-4659-baa6-c16932c4d919" + "id": "1b858e95-d033-4d2a-bc3b-507a55651648" }, "outputs": [], "source": [ "setwd(\"..\")\n", "getwd()" ], - "id": "5c3c2445-6dcc-4659-baa6-c16932c4d919" + "id": "1b858e95-d033-4d2a-bc3b-507a55651648" }, { - "id": "d1094654", + "id": "2716ffd5", "cell_type": "markdown", "source": [ "## 3.2 関数" ], "metadata": { - "id": "d1094654" + "id": "2716ffd5" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b61b1915-0bae-4db9-ad3d-a23fe69af384" + "id": "678988d9-19e6-4bd7-9625-879d2e44a224" }, "outputs": [], "source": [ "sqrt(4)" ], - "id": "b61b1915-0bae-4db9-ad3d-a23fe69af384" + "id": "678988d9-19e6-4bd7-9625-879d2e44a224" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "990150e5-8f86-407b-bf15-5e00ce105637" + "id": "4b3d46b7-f84c-46e2-a382-8cd4fddda102" }, "outputs": [], "source": [ "log(100, 10)" ], - "id": "990150e5-8f86-407b-bf15-5e00ce105637" + "id": "4b3d46b7-f84c-46e2-a382-8cd4fddda102" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "392db6fa-2f6b-4698-a081-ad2e7ac5432c" + "id": "a2e679a3-5402-4eef-b26d-d95f5e6a4036" }, "outputs": [], "source": [ @@ -478,13 +479,13 @@ "# あるいは\n", "log(100, exp(1)) # 省略しない場合\n" ], - "id": "392db6fa-2f6b-4698-a081-ad2e7ac5432c" + "id": "a2e679a3-5402-4eef-b26d-d95f5e6a4036" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a3775d65-da21-44ad-9983-af251b7bd466" + "id": "fe168aa2-2912-4c13-832f-cfcf73ea378f" }, "outputs": [], "source": [ @@ -492,26 +493,26 @@ "\n", "log2(1024) # 底が2の対数" ], - "id": "a3775d65-da21-44ad-9983-af251b7bd466" + "id": "fe168aa2-2912-4c13-832f-cfcf73ea378f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "6d3881f2-e91b-45e8-9e84-93a12f6d7855" + "id": "64f12b2b-4b75-45e8-923c-f4ef30f863f2" }, "outputs": [], "source": [ "library(tidyverse)\n", "4 %>% sqrt" ], - "id": "6d3881f2-e91b-45e8-9e84-93a12f6d7855" + "id": "64f12b2b-4b75-45e8-923c-f4ef30f863f2" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a5eaa8ba-3613-40d7-b081-6229987b3eb8" + "id": "952aa6f4-55e2-4f8e-8aee-3cc482a4454e" }, "outputs": [], "source": [ @@ -519,13 +520,13 @@ "# あるいは\n", "5 %>% log %>% exp # パイプを使う書き方\n" ], - "id": "a5eaa8ba-3613-40d7-b081-6229987b3eb8" + "id": "952aa6f4-55e2-4f8e-8aee-3cc482a4454e" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "35f1d967-45d9-402f-bedd-f2813b5b350a" + "id": "9ba6f25b-c5d9-4022-91ec-19389e87e8d3" }, "outputs": [], "source": [ @@ -533,25 +534,25 @@ " a - b\n", "}" ], - "id": "35f1d967-45d9-402f-bedd-f2813b5b350a" + "id": "9ba6f25b-c5d9-4022-91ec-19389e87e8d3" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "14e217ac-44d7-4982-9c8c-9b128c53f11c" + "id": "720e63d4-b82b-4eb6-ad92-9f1a531dc9b3" }, "outputs": [], "source": [ "f(3, 5)" ], - "id": "14e217ac-44d7-4982-9c8c-9b128c53f11c" + "id": "720e63d4-b82b-4eb6-ad92-9f1a531dc9b3" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c129cf3b-000a-4b5c-b647-a24bfceca2d9" + "id": "486c6367-d4a6-4f15-8d1e-c6ea44452a95" }, "outputs": [], "source": [ @@ -561,71 +562,71 @@ "\n", "f(3) # f(3, 5)と同じこと" ], - "id": "c129cf3b-000a-4b5c-b647-a24bfceca2d9" + "id": "486c6367-d4a6-4f15-8d1e-c6ea44452a95" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "7a5b6120-4d0a-4b28-b94b-ab3040c88153" + "id": "725ff2e2-8c1a-442a-9b66-10df634867f4" }, "outputs": [], "source": [ "(function(a, b) { a - b })(3, 5)" ], - "id": "7a5b6120-4d0a-4b28-b94b-ab3040c88153" + "id": "725ff2e2-8c1a-442a-9b66-10df634867f4" }, { - "id": "41d85363", + "id": "fe441bf8", "cell_type": "markdown", "source": [ "## 3.3 コレクション" ], "metadata": { - "id": "41d85363" + "id": "fe441bf8" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "144c4021-a4aa-4b8e-ba01-da9cae0198b5" + "id": "a5de96ab-d5f9-445d-9d6a-39ae10327993" }, "outputs": [], "source": [ "x <- c(\"foo\", \"bar\", \"baz\")" ], - "id": "144c4021-a4aa-4b8e-ba01-da9cae0198b5" + "id": "a5de96ab-d5f9-445d-9d6a-39ae10327993" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "ea286cac-4cb5-4338-927d-d2317a0aeb0f" + "id": "25d6d018-4e58-4129-8d7f-fae301015c77" }, "outputs": [], "source": [ "length(x)" ], - "id": "ea286cac-4cb5-4338-927d-d2317a0aeb0f" + "id": "25d6d018-4e58-4129-8d7f-fae301015c77" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f6c9738b-ef6f-4fda-ba65-c7a6a51a3207" + "id": "64a2cdd7-b410-4f4a-b182-e934cc32152b" }, "outputs": [], "source": [ "x[2]" ], - "id": "f6c9738b-ef6f-4fda-ba65-c7a6a51a3207" + "id": "64a2cdd7-b410-4f4a-b182-e934cc32152b" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "75082823-85b4-4361-bc81-5719dcd11895" + "id": "7da408c9-b87f-4f24-bf69-d7f8a2e10b4f" }, "outputs": [], "source": [ @@ -634,110 +635,110 @@ "\n", "x[2] <- \"bar\" # 元に戻す." ], - "id": "75082823-85b4-4361-bc81-5719dcd11895" + "id": "7da408c9-b87f-4f24-bf69-d7f8a2e10b4f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "3ea2a33c-5fe6-4370-a93a-c4aa5f3a6154" + "id": "5d2da9e0-58b0-4937-b364-251ec44cfc51" }, "outputs": [], "source": [ "x[-2]" ], - "id": "3ea2a33c-5fe6-4370-a93a-c4aa5f3a6154" + "id": "5d2da9e0-58b0-4937-b364-251ec44cfc51" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "9cac3410-7ece-484c-89c1-2c8815f16a4e" + "id": "26cc1878-d04a-4191-b94a-88039882460c" }, "outputs": [], "source": [ "c(x, \"qux\")" ], - "id": "9cac3410-7ece-484c-89c1-2c8815f16a4e" + "id": "26cc1878-d04a-4191-b94a-88039882460c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "138d5e3e-0928-48f9-b055-6f9382dd730f" + "id": "75e0ed03-f881-47e2-9beb-6ec74f5d43b9" }, "outputs": [], "source": [ "x <- c(x, \"qux\")\n", "x # 結果の確認" ], - "id": "138d5e3e-0928-48f9-b055-6f9382dd730f" + "id": "75e0ed03-f881-47e2-9beb-6ec74f5d43b9" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "880af4b2-a06b-4fb3-8e19-fcf45e11f7c9" + "id": "40cc70a3-fc1f-4c84-8f37-af284c97a69c" }, "outputs": [], "source": [ "1:5" ], - "id": "880af4b2-a06b-4fb3-8e19-fcf45e11f7c9" + "id": "40cc70a3-fc1f-4c84-8f37-af284c97a69c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "cb3c261e-e38a-4634-a4ba-bf1d9702f475" + "id": "e94110ef-ebc5-40a6-a796-05836faa44c8" }, "outputs": [], "source": [ "seq(from = 0, to = 10, by = 2)" ], - "id": "cb3c261e-e38a-4634-a4ba-bf1d9702f475" + "id": "e94110ef-ebc5-40a6-a796-05836faa44c8" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a44b4de6-59b6-46d2-b4aa-ab700e30fe98" + "id": "2240dc8f-7441-4b21-a56e-4f76ada1c746" }, "outputs": [], "source": [ "seq(from = 0, to = 1, by = 0.5)" ], - "id": "a44b4de6-59b6-46d2-b4aa-ab700e30fe98" + "id": "2240dc8f-7441-4b21-a56e-4f76ada1c746" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "fb5722e4-5bb6-46cc-8137-3820f01cfee7" + "id": "838c5078-fd3e-4172-9214-cf80025af4f5" }, "outputs": [], "source": [ "seq(from = 0, to = 100, length.out = 5)" ], - "id": "fb5722e4-5bb6-46cc-8137-3820f01cfee7" + "id": "838c5078-fd3e-4172-9214-cf80025af4f5" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "aeeb370a-2060-48e1-af84-42b824ce9dd2" + "id": "6c123409-56de-4bd4-b4f8-6bf63f1e932c" }, "outputs": [], "source": [ "rep(x = 10, times = 5)" ], - "id": "aeeb370a-2060-48e1-af84-42b824ce9dd2" + "id": "6c123409-56de-4bd4-b4f8-6bf63f1e932c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a702282f-131c-48da-b1f9-89eef85e270d" + "id": "7cadf89d-4d59-40d4-8ae0-224532020c7b" }, "outputs": [], "source": [ @@ -745,13 +746,13 @@ "x <- factor(tmp, levels = c(\"グー\", \"チョキ\", \"パー\"))\n", "x" ], - "id": "a702282f-131c-48da-b1f9-89eef85e270d" + "id": "7cadf89d-4d59-40d4-8ae0-224532020c7b" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "48bf68ad-ccab-4105-bdbe-da6e02b49ee7" + "id": "3e5ac5a5-42f8-40eb-9bc0-e2f76a1fa4fe" }, "outputs": [], "source": [ @@ -761,26 +762,26 @@ "\n", "x * 10 # 乗算" ], - "id": "48bf68ad-ccab-4105-bdbe-da6e02b49ee7" + "id": "3e5ac5a5-42f8-40eb-9bc0-e2f76a1fa4fe" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "7ff92b5a-3a36-4e20-9611-3b5c921810fe" + "id": "9a090986-88a7-409c-80a3-5b4c3bb0dfa6" }, "outputs": [], "source": [ "x <- c(2, 3)\n", "sin(x)" ], - "id": "7ff92b5a-3a36-4e20-9611-3b5c921810fe" + "id": "9a090986-88a7-409c-80a3-5b4c3bb0dfa6" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "cd3244e2-54ba-4549-ac29-8184b9ef1c5a" + "id": "7b31d842-e09c-4555-b346-bd3dcb7c396d" }, "outputs": [], "source": [ @@ -790,25 +791,25 @@ "\n", "x * y" ], - "id": "cd3244e2-54ba-4549-ac29-8184b9ef1c5a" + "id": "7b31d842-e09c-4555-b346-bd3dcb7c396d" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "1901a173-d450-4b40-9ba9-d2a5a317bb69" + "id": "6fe51f0c-bf93-4fc2-8c28-0d2aac5dc73a" }, "outputs": [], "source": [ "sum(x * y)" ], - "id": "1901a173-d450-4b40-9ba9-d2a5a317bb69" + "id": "6fe51f0c-bf93-4fc2-8c28-0d2aac5dc73a" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4c179b1d-fae3-4ce0-9744-42e449e7bfc9" + "id": "b82830f2-bc68-452b-a799-141f524950a5" }, "outputs": [], "source": [ @@ -816,13 +817,13 @@ "y <- c(TRUE, TRUE)\n", "x & y" ], - "id": "4c179b1d-fae3-4ce0-9744-42e449e7bfc9" + "id": "b82830f2-bc68-452b-a799-141f524950a5" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "d816cd3c-1d9e-4324-9942-2b7cd4de00ec" + "id": "b3342351-08f3-4ffb-b758-570ae85690a2" }, "outputs": [], "source": [ @@ -838,13 +839,13 @@ "\n", "u == w # 要素ごとの比較" ], - "id": "d816cd3c-1d9e-4324-9942-2b7cd4de00ec" + "id": "b3342351-08f3-4ffb-b758-570ae85690a2" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "edf93ea2-55c9-4da9-b0c6-35c4e6635ec1" + "id": "f478c553-6d06-4ca2-b10e-2543167e7679" }, "outputs": [], "source": [ @@ -852,62 +853,62 @@ "\n", "mean(u == w) # 同じ要素の割合" ], - "id": "edf93ea2-55c9-4da9-b0c6-35c4e6635ec1" + "id": "f478c553-6d06-4ca2-b10e-2543167e7679" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4df6a9cb-f96e-4bf1-a8ef-860f1b5d6e51" + "id": "563c169b-3fdd-44d6-a7c8-0a74123d46a4" }, "outputs": [], "source": [ "x <- list(1, \"two\")" ], - "id": "4df6a9cb-f96e-4bf1-a8ef-860f1b5d6e51" + "id": "563c169b-3fdd-44d6-a7c8-0a74123d46a4" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "df8e08fc-4a97-4032-9986-d167c37a1883" + "id": "9039faea-29ee-4e22-82c0-ff8c3fa0921d" }, "outputs": [], "source": [ "x[[2]]" ], - "id": "df8e08fc-4a97-4032-9986-d167c37a1883" + "id": "9039faea-29ee-4e22-82c0-ff8c3fa0921d" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "900421b9-7807-4864-9234-2a32e5a4f237" + "id": "6bb2319c-f7b7-460b-96f3-277ba0b888a4" }, "outputs": [], "source": [ "x <- list(\"apple\" = \"りんご\",\n", " \"orange\" = \"みかん\")" ], - "id": "900421b9-7807-4864-9234-2a32e5a4f237" + "id": "6bb2319c-f7b7-460b-96f3-277ba0b888a4" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "54e1ccd0-b202-403b-b5ba-868359388e93" + "id": "6441d69b-c27a-464a-a27d-3b0597ef213a" }, "outputs": [], "source": [ "x[[\"grape\"]] <- \"ぶどう\"" ], - "id": "54e1ccd0-b202-403b-b5ba-868359388e93" + "id": "6441d69b-c27a-464a-a27d-3b0597ef213a" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "e584fff9-ac35-4c7f-b990-e8e22964a667" + "id": "2f9597c7-0bd6-43ea-a6e8-c5a24efbb23f" }, "outputs": [], "source": [ @@ -920,13 +921,13 @@ "tmp <- \"apple\"\n", "x[[tmp]]\n" ], - "id": "e584fff9-ac35-4c7f-b990-e8e22964a667" + "id": "2f9597c7-0bd6-43ea-a6e8-c5a24efbb23f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "7089a28d-3b3c-4ecf-abf2-2566f53eb8ee" + "id": "380bb472-9720-4fc7-97c6-75163e5e81cf" }, "outputs": [], "source": [ @@ -937,35 +938,35 @@ "\n", "x # xは変わらない." ], - "id": "7089a28d-3b3c-4ecf-abf2-2566f53eb8ee" + "id": "380bb472-9720-4fc7-97c6-75163e5e81cf" }, { - "id": "509920ba", + "id": "13c55632", "cell_type": "markdown", "source": [ "## 3.4 データフレーム" ], "metadata": { - "id": "509920ba" + "id": "13c55632" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "1f38f577-872f-4d3e-80e2-a41398c5b81d" + "id": "fcbaeeaf-047a-49d5-acac-cdfd472e4086" }, "outputs": [], "source": [ "library(tidyverse)" ], - "id": "1f38f577-872f-4d3e-80e2-a41398c5b81d" + "id": "fcbaeeaf-047a-49d5-acac-cdfd472e4086" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "9d532649-fb39-4025-9dc7-8f30d65bc2e8" + "id": "bbc6b602-4df8-481c-a8d1-3c52a433deb4" }, "outputs": [], "source": [ @@ -975,13 +976,13 @@ " math = c( 70, 80, 90, 100),\n", " gender = c(\"f\", \"m\", \"m\", \"f\"))" ], - "id": "9d532649-fb39-4025-9dc7-8f30d65bc2e8" + "id": "bbc6b602-4df8-481c-a8d1-3c52a433deb4" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "3460dc75-dd34-4d29-8cdd-48e812bc73c3" + "id": "193f4492-a399-4f39-832b-6637bce85a82" }, "outputs": [], "source": [ @@ -992,26 +993,26 @@ " \"C\", 70, 90, \"m\",\n", " \"D\", 90, 100, \"f\")" ], - "id": "3460dc75-dd34-4d29-8cdd-48e812bc73c3" + "id": "193f4492-a399-4f39-832b-6637bce85a82" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "8e59b2ad-02e5-4f07-95f7-25475d439039" + "id": "c446aade-dadf-4c4a-86df-72d3f4a6df7d" }, "outputs": [], "source": [ "head(my_df)\n", "# 結果は割愛" ], - "id": "8e59b2ad-02e5-4f07-95f7-25475d439039" + "id": "c446aade-dadf-4c4a-86df-72d3f4a6df7d" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "28d5a6ca-0ea1-4674-8a33-40cdbedbef13" + "id": "1e652924-fdf6-4a62-add2-2a877a57aa3c" }, "outputs": [], "source": [ @@ -1021,13 +1022,13 @@ "\n", "ncol(my_df) # 列数" ], - "id": "28d5a6ca-0ea1-4674-8a33-40cdbedbef13" + "id": "1e652924-fdf6-4a62-add2-2a877a57aa3c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "bee3eb47-0fe3-450f-98d9-861c38c180be" + "id": "83915c8f-1e0a-46cf-8827-ee4f7acb74e1" }, "outputs": [], "source": [ @@ -1036,25 +1037,25 @@ " Y = c(10, 100))\n", "my_df2" ], - "id": "bee3eb47-0fe3-450f-98d9-861c38c180be" + "id": "83915c8f-1e0a-46cf-8827-ee4f7acb74e1" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "86fe9925-9992-4a26-954f-1d8be84d102c" + "id": "5c76647a-579f-400f-a2da-404347abecaa" }, "outputs": [], "source": [ "colnames(my_df2)" ], - "id": "86fe9925-9992-4a26-954f-1d8be84d102c" + "id": "5c76647a-579f-400f-a2da-404347abecaa" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f51150af-20b6-40c6-a9eb-67c59f68ab2d" + "id": "472bfb25-9481-459b-a88d-30a5065b24b1" }, "outputs": [], "source": [ @@ -1062,25 +1063,25 @@ "my_df2\n", "# 以下省略" ], - "id": "f51150af-20b6-40c6-a9eb-67c59f68ab2d" + "id": "472bfb25-9481-459b-a88d-30a5065b24b1" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "bbb10019-769e-44df-ae35-5e5b3f604cfe" + "id": "27b147fe-5228-4248-89c5-91617e32c824" }, "outputs": [], "source": [ "row.names(my_df)" ], - "id": "bbb10019-769e-44df-ae35-5e5b3f604cfe" + "id": "27b147fe-5228-4248-89c5-91617e32c824" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a31a2070-7a97-4c77-8251-f0786dfb3a3f" + "id": "2a910ed8-d3e9-417f-b5fb-1789a39d6eef" }, "outputs": [], "source": [ @@ -1089,13 +1090,13 @@ "my_df2\n", "# 以下省略" ], - "id": "a31a2070-7a97-4c77-8251-f0786dfb3a3f" + "id": "2a910ed8-d3e9-417f-b5fb-1789a39d6eef" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "789c9b93-7ff2-48f4-8bde-390bde9fdc93" + "id": "4e7658cf-8777-41af-bf65-7e59a7f76263" }, "outputs": [], "source": [ @@ -1106,13 +1107,13 @@ " row.names = c(\"A\", \"B\", \"C\", \"D\"))\n", "my_df3" ], - "id": "789c9b93-7ff2-48f4-8bde-390bde9fdc93" + "id": "4e7658cf-8777-41af-bf65-7e59a7f76263" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "d75bf81f-f5f4-4e08-abe4-cf59fddca524" + "id": "dc5925d2-9df6-4085-ae3a-a3609bff3d01" }, "outputs": [], "source": [ @@ -1123,26 +1124,26 @@ " gender = \"m\")\n", "my_df2 <- rbind(my_df, tmp)" ], - "id": "d75bf81f-f5f4-4e08-abe4-cf59fddca524" + "id": "dc5925d2-9df6-4085-ae3a-a3609bff3d01" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "99176d65-8fbe-4298-86a2-6b920c44ec66" + "id": "0f7dcf7b-abe0-46a1-a833-ecbbb4f4a80a" }, "outputs": [], "source": [ "my_df2 <- my_df %>%\n", " mutate(id = c(1, 2, 3, 4))" ], - "id": "99176d65-8fbe-4298-86a2-6b920c44ec66" + "id": "0f7dcf7b-abe0-46a1-a833-ecbbb4f4a80a" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c0acf0b8-3c38-438d-bafa-c3b791211a86" + "id": "384b15be-8118-42d0-bf85-54e4f1c91423" }, "outputs": [], "source": [ @@ -1150,25 +1151,25 @@ "my_df3[\"id\"] <- c(1, 2, 3, 4) # 更新\n", "my_df3 # 結果の確認(割愛)" ], - "id": "c0acf0b8-3c38-438d-bafa-c3b791211a86" + "id": "384b15be-8118-42d0-bf85-54e4f1c91423" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "bec490f6-eedc-49df-831f-e31ee0d1fe31" + "id": "95aa6978-9a1b-4730-8d70-f3bf2e4a3684" }, "outputs": [], "source": [ "my_df[1, 2]" ], - "id": "bec490f6-eedc-49df-831f-e31ee0d1fe31" + "id": "95aa6978-9a1b-4730-8d70-f3bf2e4a3684" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f7a326fc-9fcd-4ffd-a98d-4fe1c28fa362" + "id": "e3bd9373-1213-4beb-9205-b8394306fbf2" }, "outputs": [], "source": [ @@ -1185,37 +1186,37 @@ "\n", "x # 結果の確認(割愛)" ], - "id": "f7a326fc-9fcd-4ffd-a98d-4fe1c28fa362" + "id": "e3bd9373-1213-4beb-9205-b8394306fbf2" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c57992aa-652a-4c18-817b-1904ed55ac5d" + "id": "1727fc4f-ba74-46f1-80fd-96b1d6ca5821" }, "outputs": [], "source": [ "x <- my_df %>% select(name, math)" ], - "id": "c57992aa-652a-4c18-817b-1904ed55ac5d" + "id": "1727fc4f-ba74-46f1-80fd-96b1d6ca5821" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "bfeaf6e4-4c54-49d8-9e94-e5290d679a38" + "id": "4d889ff7-1ee2-48af-b9a9-1075ad214320" }, "outputs": [], "source": [ "x <- my_df[, c(1, 3)]" ], - "id": "bfeaf6e4-4c54-49d8-9e94-e5290d679a38" + "id": "4d889ff7-1ee2-48af-b9a9-1075ad214320" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4f035770-9a68-4b4e-8bc2-52060444afe7" + "id": "5af22dbf-f5e6-4ce3-97e4-b773a8447006" }, "outputs": [], "source": [ @@ -1224,37 +1225,37 @@ "# あるいは\n", "x <- my_df[, -c(2, 4)]" ], - "id": "4f035770-9a68-4b4e-8bc2-52060444afe7" + "id": "5af22dbf-f5e6-4ce3-97e4-b773a8447006" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "57b39eb5-ce93-4ce3-84e4-55660641fdec" + "id": "07d0e01f-081d-4b1a-b906-4ccde0ff275e" }, "outputs": [], "source": [ "x <- my_df[c(1, 3), ]" ], - "id": "57b39eb5-ce93-4ce3-84e4-55660641fdec" + "id": "07d0e01f-081d-4b1a-b906-4ccde0ff275e" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "cdbfbdb2-d7e8-4a07-8daa-5f5e866ccfbf" + "id": "9dbd860b-e369-42d6-b59c-67e8a57851d5" }, "outputs": [], "source": [ "x <- my_df[-c(2, 4), ]" ], - "id": "cdbfbdb2-d7e8-4a07-8daa-5f5e866ccfbf" + "id": "9dbd860b-e369-42d6-b59c-67e8a57851d5" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "5250fa57-e63c-496b-bcfb-3341e060983f" + "id": "61c26f4c-77d9-48ad-9916-b87ce0e9c815" }, "outputs": [], "source": [ @@ -1262,13 +1263,13 @@ "# あるいは\n", "x <- my_df %>% filter(gender == \"m\")" ], - "id": "5250fa57-e63c-496b-bcfb-3341e060983f" + "id": "61c26f4c-77d9-48ad-9916-b87ce0e9c815" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "140b7930-58e9-49cc-85d5-b1c7a9c9f13f" + "id": "7261d736-647f-482f-b74a-32f3ec43df4f" }, "outputs": [], "source": [ @@ -1276,13 +1277,13 @@ "# あるいは\n", "x <- my_df %>% filter(english > 80 & gender == \"m\")" ], - "id": "140b7930-58e9-49cc-85d5-b1c7a9c9f13f" + "id": "7261d736-647f-482f-b74a-32f3ec43df4f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4da750ce-15ff-489b-8dfb-84deacbed55c" + "id": "72c5607c-dbb8-47f1-bf85-7a1b07fda291" }, "outputs": [], "source": [ @@ -1290,62 +1291,62 @@ "# あるいは\n", "x <- my_df %>% filter(english == max(my_df$english))" ], - "id": "4da750ce-15ff-489b-8dfb-84deacbed55c" + "id": "72c5607c-dbb8-47f1-bf85-7a1b07fda291" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "320285a3-f2c0-43f7-958f-83f6a1654d83" + "id": "80b7d0cf-5369-446b-b59a-3ca1a9afc59f" }, "outputs": [], "source": [ "my_df2 <- my_df # コピー\n", "my_df2[my_df$gender == \"m\", ]$gender <- \"M\"" ], - "id": "320285a3-f2c0-43f7-958f-83f6a1654d83" + "id": "80b7d0cf-5369-446b-b59a-3ca1a9afc59f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "68fcfd0f-a845-44ed-af2c-ad69938a1a10" + "id": "b8eaa49a-1a22-4944-bc74-68d8e7344d12" }, "outputs": [], "source": [ "my_df2" ], - "id": "68fcfd0f-a845-44ed-af2c-ad69938a1a10" + "id": "b8eaa49a-1a22-4944-bc74-68d8e7344d12" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "00b352e0-44e7-4c5a-bddd-8d678206242d" + "id": "3a18142f-8217-4553-930f-0fc22b4f2d58" }, "outputs": [], "source": [ "x <- my_df %>% arrange(english)" ], - "id": "00b352e0-44e7-4c5a-bddd-8d678206242d" + "id": "3a18142f-8217-4553-930f-0fc22b4f2d58" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "1692fd04-e8f1-447a-9c66-4e9ac210d55b" + "id": "6cc8b353-193e-487f-a9ad-a74bf22a3a11" }, "outputs": [], "source": [ "x <- my_df %>% arrange(-english)" ], - "id": "1692fd04-e8f1-447a-9c66-4e9ac210d55b" + "id": "6cc8b353-193e-487f-a9ad-a74bf22a3a11" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "dc829003-149a-47da-89cd-b5ba60c05434" + "id": "e9aaff4e-f994-4bef-96f5-8714bc67a610" }, "outputs": [], "source": [ @@ -1357,62 +1358,62 @@ " byrow = TRUE) # 行ごとの生成\n", "A" ], - "id": "dc829003-149a-47da-89cd-b5ba60c05434" + "id": "e9aaff4e-f994-4bef-96f5-8714bc67a610" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "1dbdb3c0-9bf8-4706-9a37-96c5c756350a" + "id": "57a5f857-9f9c-48f0-9fae-3661a494c480" }, "outputs": [], "source": [ "A <- my_df[, c(2, 3)] %>% as.matrix\n", "A" ], - "id": "1dbdb3c0-9bf8-4706-9a37-96c5c756350a" + "id": "57a5f857-9f9c-48f0-9fae-3661a494c480" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "9d9235ed-a382-4a30-8a23-0361f5d91bb3" + "id": "ef6cb8f4-efdc-4fd4-a966-eac19c2c9fda" }, "outputs": [], "source": [ "as.data.frame(A)" ], - "id": "9d9235ed-a382-4a30-8a23-0361f5d91bb3" + "id": "ef6cb8f4-efdc-4fd4-a966-eac19c2c9fda" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "7433051d-e6cf-4717-8317-4b6d4430dc48" + "id": "5bd8b3a5-7c43-4e3d-a211-3ba0432e20ec" }, "outputs": [], "source": [ "t(A)" ], - "id": "7433051d-e6cf-4717-8317-4b6d4430dc48" + "id": "5bd8b3a5-7c43-4e3d-a211-3ba0432e20ec" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "cbed3ab3-fe18-4085-9af5-ab493fa3e6bc" + "id": "9aee32f1-2940-49c2-b0c3-934d6a37b8fa" }, "outputs": [], "source": [ "t(A) %*% A" ], - "id": "cbed3ab3-fe18-4085-9af5-ab493fa3e6bc" + "id": "9aee32f1-2940-49c2-b0c3-934d6a37b8fa" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "3b4215df-42fc-48f5-957f-141a4498876f" + "id": "86a061c0-e505-41cf-a59e-25792ef8a4f5" }, "outputs": [], "source": [ @@ -1421,13 +1422,13 @@ " min = c(20, 21, 15),\n", " max = c(24, 27, 21))" ], - "id": "3b4215df-42fc-48f5-957f-141a4498876f" + "id": "86a061c0-e505-41cf-a59e-25792ef8a4f5" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "bea9d989-2393-4050-8410-ddec93d55add" + "id": "e5b165d4-a37b-470f-b2a4-d3d1075e070f" }, "outputs": [], "source": [ @@ -1435,25 +1436,25 @@ " pivot_longer(-day)\n", "my_longer" ], - "id": "bea9d989-2393-4050-8410-ddec93d55add" + "id": "e5b165d4-a37b-470f-b2a4-d3d1075e070f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "1587538f-2c26-467e-9d8c-2f376093245b" + "id": "2332434e-5b8d-4ebb-9429-aa335d0c8935" }, "outputs": [], "source": [ "my_longer %>% pivot_wider()" ], - "id": "1587538f-2c26-467e-9d8c-2f376093245b" + "id": "2332434e-5b8d-4ebb-9429-aa335d0c8935" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c7b88db1-af91-4c19-8c0c-5d5860f2cba5" + "id": "dadf059e-f50f-40d5-a8f1-065c8e12015a" }, "outputs": [], "source": [ @@ -1466,23 +1467,23 @@ " scale_x_continuous(\n", " breaks = my_longer$day) # x軸目盛り" ], - "id": "c7b88db1-af91-4c19-8c0c-5d5860f2cba5" + "id": "dadf059e-f50f-40d5-a8f1-065c8e12015a" }, { - "id": "db815df0", + "id": "ab6868ae", "cell_type": "markdown", "source": [ "## 3.5 1次元データの(非)類似度" ], "metadata": { - "id": "db815df0" + "id": "ab6868ae" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "eb2ee209-64a3-4ed4-97f4-6cf60c581085" + "id": "188eb74c-ba9a-49dc-a0f4-fc71e31a1677" }, "outputs": [], "source": [ @@ -1496,13 +1497,13 @@ "\n", "sum(AC^2)^0.5" ], - "id": "eb2ee209-64a3-4ed4-97f4-6cf60c581085" + "id": "188eb74c-ba9a-49dc-a0f4-fc71e31a1677" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "6f8a2d90-0884-4db4-bd9c-ecf9aa21d057" + "id": "715869ad-2159-4982-a02d-c40452306986" }, "outputs": [], "source": [ @@ -1510,13 +1511,13 @@ "\n", "sum(abs(AC))" ], - "id": "6f8a2d90-0884-4db4-bd9c-ecf9aa21d057" + "id": "715869ad-2159-4982-a02d-c40452306986" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "fb6f7333-8f4a-4dd9-bddd-f7febc4da037" + "id": "349e1b70-3b72-45c0-84be-f6b705d811ac" }, "outputs": [], "source": [ @@ -1526,13 +1527,13 @@ "sum(A * C) /\n", " sum(A * A)^0.5 / sum(C * C)^0.5" ], - "id": "fb6f7333-8f4a-4dd9-bddd-f7febc4da037" + "id": "349e1b70-3b72-45c0-84be-f6b705d811ac" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "7ac66e97-d143-4e8d-8b07-7967c27ef04c" + "id": "9270253c-c804-44a4-98bb-2a1dca751d52" }, "outputs": [], "source": [ @@ -1540,13 +1541,13 @@ "\n", "cor(A, C)" ], - "id": "7ac66e97-d143-4e8d-8b07-7967c27ef04c" + "id": "9270253c-c804-44a4-98bb-2a1dca751d52" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "afc0d2cf-e4e3-44d4-be0c-58721ba02ed6" + "id": "7853bf2d-fac8-47f8-9a08-6b1d9e1ca411" }, "outputs": [], "source": [ @@ -1575,57 +1576,57 @@ "# 相関係数\n", "my_df %>% proxy::simil(\"correlation\")" ], - "id": "afc0d2cf-e4e3-44d4-be0c-58721ba02ed6" + "id": "7853bf2d-fac8-47f8-9a08-6b1d9e1ca411" }, { - "id": "91c8f21a", + "id": "faef4c83", "cell_type": "markdown", "source": [ "## 3.6 Rのパッケージ,Pythonのモジュール" ], "metadata": { - "id": "91c8f21a" + "id": "faef4c83" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "5f614ee2-1172-4c90-82e1-8a2f63a9a633" + "id": "6b92c3c8-d198-4a98-a27c-fac08b9eba4a" }, "outputs": [], "source": [ "library(tidyverse)" ], - "id": "5f614ee2-1172-4c90-82e1-8a2f63a9a633" + "id": "6b92c3c8-d198-4a98-a27c-fac08b9eba4a" }, { - "id": "43952b54", + "id": "35103c17", "cell_type": "markdown", "source": [ "## 3.7 反復処理" ], "metadata": { - "id": "43952b54" + "id": "35103c17" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "2b191aa4-b8d6-4562-a094-93f8266cee3e" + "id": "f8a04b64-77c9-45b3-97d7-4c8104bbc46c" }, "outputs": [], "source": [ "library(tidyverse)" ], - "id": "2b191aa4-b8d6-4562-a094-93f8266cee3e" + "id": "f8a04b64-77c9-45b3-97d7-4c8104bbc46c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "8dc9b2ba-a55b-4471-b408-857cae0a5f8c" + "id": "322ea253-0c79-46b3-aac5-93fffb957a78" }, "outputs": [], "source": [ @@ -1636,63 +1637,63 @@ "\n", "f1(10) # 動作確認" ], - "id": "8dc9b2ba-a55b-4471-b408-857cae0a5f8c" + "id": "322ea253-0c79-46b3-aac5-93fffb957a78" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "977a2f69-388b-474a-a0e2-7bc7e4a797a3" + "id": "c10d5333-85de-4b8e-8b0f-9d53432b405f" }, "outputs": [], "source": [ "replicate(n = 3, expr = f1(10))" ], - "id": "977a2f69-388b-474a-a0e2-7bc7e4a797a3" + "id": "c10d5333-85de-4b8e-8b0f-9d53432b405f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c7385070-7c59-4a04-97c2-fa13ef3db7f1" + "id": "486cd9a8-27e6-4bd1-b1ec-cdaf0cc0cd8b" }, "outputs": [], "source": [ "rep(x = f1(10), times = 3)" ], - "id": "c7385070-7c59-4a04-97c2-fa13ef3db7f1" + "id": "486cd9a8-27e6-4bd1-b1ec-cdaf0cc0cd8b" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "7117802e-7cb5-4347-8c64-9728d1325332" + "id": "5b023da1-f82e-4b7a-a151-5f0bb2764e65" }, "outputs": [], "source": [ "v <- c(5, 10, 100)\n", "v %>% map_dbl(f1)" ], - "id": "7117802e-7cb5-4347-8c64-9728d1325332" + "id": "5b023da1-f82e-4b7a-a151-5f0bb2764e65" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "dfc0cb42-22ad-4dc4-bc69-b54e5eba3ba0" + "id": "82b69452-b8b7-401a-bfde-a4aae4c32478" }, "outputs": [], "source": [ "rep(x = 10, times = 3) %>% map_dbl(f1)\n", "# 結果は割愛" ], - "id": "dfc0cb42-22ad-4dc4-bc69-b54e5eba3ba0" + "id": "82b69452-b8b7-401a-bfde-a4aae4c32478" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b2664108-f428-4429-a8d4-b64362515dc6" + "id": "a9d591f2-22c9-4830-8fb2-447b1ab3d3fb" }, "outputs": [], "source": [ @@ -1705,26 +1706,26 @@ "\n", "f2(10) # 動作確認" ], - "id": "b2664108-f428-4429-a8d4-b64362515dc6" + "id": "a9d591f2-22c9-4830-8fb2-447b1ab3d3fb" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "67632e1a-106a-4306-92ee-454894395f36" + "id": "399a4c09-4878-497c-b91d-f7da11e7241b" }, "outputs": [], "source": [ "v <- c(5, 10, 100)\n", "v %>% map_dfr(f2)" ], - "id": "67632e1a-106a-4306-92ee-454894395f36" + "id": "399a4c09-4878-497c-b91d-f7da11e7241b" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "bcafb796-14f5-4e5c-9652-c69e82f88bd0" + "id": "7dd59b18-0086-4afc-adf6-f51d44f4221c" }, "outputs": [], "source": [ @@ -1740,13 +1741,13 @@ "\n", "f3(x = 10, y = 6) # 動作確認" ], - "id": "bcafb796-14f5-4e5c-9652-c69e82f88bd0" + "id": "7dd59b18-0086-4afc-adf6-f51d44f4221c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "491820a3-3940-4d51-b184-22700149a775" + "id": "0cdb88f6-ce49-4565-b415-9c91f64f5984" }, "outputs": [], "source": [ @@ -1756,13 +1757,13 @@ "\n", "my_df %>% pmap_dfr(f3)" ], - "id": "491820a3-3940-4d51-b184-22700149a775" + "id": "0cdb88f6-ce49-4565-b415-9c91f64f5984" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a8ed1964-b29c-4a19-922b-b3b7a9797c9e" + "id": "2a4505c7-2240-43ac-9bca-b44ed1a7c388" }, "outputs": [], "source": [ @@ -1774,36 +1775,36 @@ " furrr_options(seed = TRUE))\n", "# 結果は割愛" ], - "id": "a8ed1964-b29c-4a19-922b-b3b7a9797c9e" + "id": "2a4505c7-2240-43ac-9bca-b44ed1a7c388" }, { - "id": "171c8f80", + "id": "6e7f8d23", "cell_type": "markdown", "source": [ "## 3.8 その他" ], "metadata": { - "id": "171c8f80" + "id": "6e7f8d23" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "57b6ed74-e02a-468c-9cc2-37f91a987e5e" + "id": "289deda5-01b7-4089-af87-6ed456cabaf0" }, "outputs": [], "source": [ "x <- 123\n", "typeof(x)" ], - "id": "57b6ed74-e02a-468c-9cc2-37f91a987e5e" + "id": "289deda5-01b7-4089-af87-6ed456cabaf0" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "163747da-c7a0-4a99-bdd2-cfd0346aa75c" + "id": "e460c864-27b1-497a-979d-02665c1c3091" }, "outputs": [], "source": [ @@ -1811,26 +1812,26 @@ "# あるいは\n", "help(log)" ], - "id": "163747da-c7a0-4a99-bdd2-cfd0346aa75c" + "id": "e460c864-27b1-497a-979d-02665c1c3091" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "ef637ca8-4e49-4578-9f5d-e3acf1b85b3e" + "id": "a0a17dd2-b882-4270-bc40-4b89811a716a" }, "outputs": [], "source": [ "v <- c(1, NA, 3)\n", "v" ], - "id": "ef637ca8-4e49-4578-9f5d-e3acf1b85b3e" + "id": "a0a17dd2-b882-4270-bc40-4b89811a716a" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "67f5b81a-b4ed-4b8d-ae5e-85319e5f7d6e" + "id": "51fc9d82-04b6-439e-89dd-e4325a8df2e6" }, "outputs": [], "source": [ @@ -1838,23 +1839,23 @@ "\n", "v[2] == NA # 誤り" ], - "id": "67f5b81a-b4ed-4b8d-ae5e-85319e5f7d6e" + "id": "51fc9d82-04b6-439e-89dd-e4325a8df2e6" }, { - "id": "e7d6ddb6", + "id": "ab1aca33", "cell_type": "markdown", "source": [ "# 4 統計入門" ], "metadata": { - "id": "e7d6ddb6" + "id": "ab1aca33" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "7dabed69-a8c3-40c6-aa79-0c42964ee893" + "id": "4ac9b825-a5bc-4616-8f30-59736884d415" }, "outputs": [], "source": [ @@ -1866,62 +1867,62 @@ " install.packages(setdiff(packages_to_install, installed_packages))\n", "}" ], - "id": "7dabed69-a8c3-40c6-aa79-0c42964ee893" + "id": "4ac9b825-a5bc-4616-8f30-59736884d415" }, { - "id": "6b4ce211", + "id": "ed7d6561", "cell_type": "markdown", "source": [ "## 4.1 記述統計" ], "metadata": { - "id": "6b4ce211" + "id": "ed7d6561" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "72e0de12-2c8d-4325-ba06-5617f270e3b3" + "id": "beeefb4c-a1ae-4502-8b35-2f7b09800ba4" }, "outputs": [], "source": [ "x <- c(165, 170, 175, 180, 185)\n", "mean(x) # 平均" ], - "id": "72e0de12-2c8d-4325-ba06-5617f270e3b3" + "id": "beeefb4c-a1ae-4502-8b35-2f7b09800ba4" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "0ca89453-ead7-43b6-8326-9b050b1dde76" + "id": "1836f64f-2711-45b9-93ef-b5e5433806c3" }, "outputs": [], "source": [ "n <- length(x) # サンプルサイズ\n", "sum(x) / n" ], - "id": "0ca89453-ead7-43b6-8326-9b050b1dde76" + "id": "1836f64f-2711-45b9-93ef-b5e5433806c3" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "964fd844-6a7a-46e1-8eb7-04e12907de99" + "id": "dff73f28-9653-4227-9f6f-e0863b02758f" }, "outputs": [], "source": [ "y <- c(173, 174, 175, 176, 177)\n", "mean(y)" ], - "id": "964fd844-6a7a-46e1-8eb7-04e12907de99" + "id": "dff73f28-9653-4227-9f6f-e0863b02758f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "10672762-1ab3-4a78-806e-0f4626709481" + "id": "eb3d74ad-61f9-45ca-a5c1-750b05a77800" }, "outputs": [], "source": [ @@ -1929,25 +1930,25 @@ "\n", "var(y) # yの分散" ], - "id": "10672762-1ab3-4a78-806e-0f4626709481" + "id": "eb3d74ad-61f9-45ca-a5c1-750b05a77800" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "131650f4-385e-4906-a0a1-e54a37f42d0f" + "id": "596533f1-4b40-4c90-b115-a1952c400827" }, "outputs": [], "source": [ "sum((x - mean(x))^2) / (n - 1)" ], - "id": "131650f4-385e-4906-a0a1-e54a37f42d0f" + "id": "596533f1-4b40-4c90-b115-a1952c400827" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "5b207d5d-004c-43ba-90c9-770db2085947" + "id": "63ad097e-dc62-4fae-b29a-5a2b61b3a75a" }, "outputs": [], "source": [ @@ -1955,25 +1956,25 @@ "\n", "sd(y) # yの標準偏差" ], - "id": "5b207d5d-004c-43ba-90c9-770db2085947" + "id": "63ad097e-dc62-4fae-b29a-5a2b61b3a75a" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f28421b6-2e6c-48c7-a215-05716b99339d" + "id": "c06e57ee-6531-44a3-955e-dba26f9073c0" }, "outputs": [], "source": [ "var(x)**0.5 # xの標準偏差" ], - "id": "f28421b6-2e6c-48c7-a215-05716b99339d" + "id": "c06e57ee-6531-44a3-955e-dba26f9073c0" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "3cb0dd6b-41f3-4840-bec1-80f9ac434efd" + "id": "894e6554-a14e-431e-9f99-997a5d73c447" }, "outputs": [], "source": [ @@ -1983,25 +1984,25 @@ "\n", "pastecs::stat.desc(x)" ], - "id": "3cb0dd6b-41f3-4840-bec1-80f9ac434efd" + "id": "894e6554-a14e-431e-9f99-997a5d73c447" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "cadc102d-b980-4076-8365-3ddf511d9deb" + "id": "0c752c7f-e6d8-4e22-bce2-7cd432047aa8" }, "outputs": [], "source": [ "quantile(x)" ], - "id": "cadc102d-b980-4076-8365-3ddf511d9deb" + "id": "0c752c7f-e6d8-4e22-bce2-7cd432047aa8" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "8228a372-7c8e-43ff-8eec-ed0e00bbf2f9" + "id": "2af816e8-c0f7-4b9d-b4f5-a575e7b8803b" }, "outputs": [], "source": [ @@ -2014,13 +2015,13 @@ "n <- length(x)\n", "var(x) * (n - 1) / n # 標本分散" ], - "id": "8228a372-7c8e-43ff-8eec-ed0e00bbf2f9" + "id": "2af816e8-c0f7-4b9d-b4f5-a575e7b8803b" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "50e42842-f860-43aa-bc2c-e4436cbe9c3f" + "id": "93784f0c-2fe3-46dd-89d2-9227a029d3fc" }, "outputs": [], "source": [ @@ -2030,25 +2031,25 @@ "# あるいは\n", "sd(x) * sqrt((n - 1) / n) # √標本分散" ], - "id": "50e42842-f860-43aa-bc2c-e4436cbe9c3f" + "id": "93784f0c-2fe3-46dd-89d2-9227a029d3fc" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a4f47385-d5fe-4044-9e20-452fdfea8dad" + "id": "36ee9470-868d-46ae-9703-2620bcf8ca3c" }, "outputs": [], "source": [ "sd(x) / length(x)**0.5" ], - "id": "a4f47385-d5fe-4044-9e20-452fdfea8dad" + "id": "36ee9470-868d-46ae-9703-2620bcf8ca3c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "101f266a-bbbf-471d-be97-c5af7dfe347e" + "id": "f0bb78e4-37b3-4481-b1cb-3b59ffbb59f6" }, "outputs": [], "source": [ @@ -2060,25 +2061,25 @@ " math = c( 70, 80, 90, 100),\n", " gender = c(\"f\", \"m\", \"m\", \"f\"))" ], - "id": "101f266a-bbbf-471d-be97-c5af7dfe347e" + "id": "f0bb78e4-37b3-4481-b1cb-3b59ffbb59f6" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "6875cf5d-b4c4-4ea4-ba32-0ccbd1102307" + "id": "d463b807-3c18-4d43-9eef-f4c27126046b" }, "outputs": [], "source": [ "var(my_df$english)" ], - "id": "6875cf5d-b4c4-4ea4-ba32-0ccbd1102307" + "id": "d463b807-3c18-4d43-9eef-f4c27126046b" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "e5993260-011c-43d2-9500-d75bd4510292" + "id": "e2b4d8f5-b14b-4d8a-a335-3a8066c5a0a0" }, "outputs": [], "source": [ @@ -2104,13 +2105,13 @@ " where(is.numeric), # 数値の列の\n", " function(x) { var(x) })) # 不偏分散\n" ], - "id": "e5993260-011c-43d2-9500-d75bd4510292" + "id": "e2b4d8f5-b14b-4d8a-a335-3a8066c5a0a0" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "142838e6-6e8b-4878-b927-cb6c8433be58" + "id": "a07e482d-2f59-4557-af74-a54aa2d2f4fd" }, "outputs": [], "source": [ @@ -2121,25 +2122,25 @@ "pastecs::stat.desc(my_df)\n", "# 以下省略" ], - "id": "142838e6-6e8b-4878-b927-cb6c8433be58" + "id": "a07e482d-2f59-4557-af74-a54aa2d2f4fd" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "d82eb3d8-10e7-44a0-b79a-99109af49cf9" + "id": "3e0811e3-8ae0-49c6-b611-7b7c81322ecb" }, "outputs": [], "source": [ "table(my_df$gender)\n" ], - "id": "d82eb3d8-10e7-44a0-b79a-99109af49cf9" + "id": "3e0811e3-8ae0-49c6-b611-7b7c81322ecb" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "e64bd0d4-54db-45eb-91f6-d2f557046ddf" + "id": "3f39bc67-babf-4305-93e6-44d6b9bb7c19" }, "outputs": [], "source": [ @@ -2148,13 +2149,13 @@ " excel = my_df$math >= 80)\n", "table(my_df2)\n" ], - "id": "e64bd0d4-54db-45eb-91f6-d2f557046ddf" + "id": "3f39bc67-babf-4305-93e6-44d6b9bb7c19" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c4ea1669-22b7-404d-a6d5-c4b5f1cc05c9" + "id": "aa37b858-8a84-40d6-8702-9c787fd2b09d" }, "outputs": [], "source": [ @@ -2163,60 +2164,60 @@ " where(is.numeric), mean),\n", " .groups = \"drop\") # グループ化解除\n" ], - "id": "c4ea1669-22b7-404d-a6d5-c4b5f1cc05c9" + "id": "aa37b858-8a84-40d6-8702-9c787fd2b09d" }, { - "id": "f1265721", + "id": "859a3929", "cell_type": "markdown", "source": [ "## 4.2 データの可視化" ], "metadata": { - "id": "f1265721" + "id": "859a3929" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f9bd0f7f-0ea9-4aaf-90f9-ec0b73998e49" + "id": "b00eb78e-fc56-4791-9c71-6c8df967ce9d" }, "outputs": [], "source": [ "head(iris)" ], - "id": "f9bd0f7f-0ea9-4aaf-90f9-ec0b73998e49" + "id": "b00eb78e-fc56-4791-9c71-6c8df967ce9d" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "16ff9c0b-9fca-43a1-8df8-7c1b232077e6" + "id": "b9e45600-719b-4911-bb55-eb457b657024" }, "outputs": [], "source": [ "hist(iris$Sepal.Length)" ], - "id": "16ff9c0b-9fca-43a1-8df8-7c1b232077e6" + "id": "b9e45600-719b-4911-bb55-eb457b657024" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a5f96d79-8f95-494e-ab3d-90143775d527" + "id": "793efce0-3bf8-4c28-bfe6-1fb90e155e71" }, "outputs": [], "source": [ "x <- c(10, 20, 30)\n", "hist(x, breaks = 2) # 階級数は2" ], - "id": "a5f96d79-8f95-494e-ab3d-90143775d527" + "id": "793efce0-3bf8-4c28-bfe6-1fb90e155e71" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "db2c0117-dc22-4fd6-8f3e-e76df4124d12" + "id": "9f36b11e-1001-4870-a529-9c0dc460d564" }, "outputs": [], "source": [ @@ -2225,38 +2226,38 @@ " length.out = 10)\n", "hist(x, breaks = tmp, right = FALSE)" ], - "id": "db2c0117-dc22-4fd6-8f3e-e76df4124d12" + "id": "9f36b11e-1001-4870-a529-9c0dc460d564" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "fda08245-b21e-4525-bc21-69632933fb01" + "id": "f814d3be-428d-44a6-b369-2a9db1a89170" }, "outputs": [], "source": [ "plot(iris$Sepal.Length,\n", " iris$Sepal.Width)" ], - "id": "fda08245-b21e-4525-bc21-69632933fb01" + "id": "f814d3be-428d-44a6-b369-2a9db1a89170" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "1f31c686-03cd-4ce8-ba23-8c6434c00639" + "id": "fc8d9f3f-d183-46d2-8539-364d83b56df2" }, "outputs": [], "source": [ "boxplot(iris[, -5])" ], - "id": "1f31c686-03cd-4ce8-ba23-8c6434c00639" + "id": "fc8d9f3f-d183-46d2-8539-364d83b56df2" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "cf79d660-0066-4fca-ab4b-614184ef26c8" + "id": "d72d959c-1049-4aab-8024-44a18dd37367" }, "outputs": [], "source": [ @@ -2264,13 +2265,13 @@ "my_df <- psych::describe(iris[, -5])\n", "my_df %>% select(mean, sd, se)" ], - "id": "cf79d660-0066-4fca-ab4b-614184ef26c8" + "id": "d72d959c-1049-4aab-8024-44a18dd37367" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b1c97e6d-e2a3-4ae4-9bee-37658418bd48" + "id": "9adf6667-9b48-4cc9-8410-5d3792bc5605" }, "outputs": [], "source": [ @@ -2280,13 +2281,13 @@ " geom_errorbar(aes(ymin = mean - se, ymax = mean + se)) +\n", " xlab(NULL)" ], - "id": "b1c97e6d-e2a3-4ae4-9bee-37658418bd48" + "id": "9adf6667-9b48-4cc9-8410-5d3792bc5605" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "9b5aa292-3a04-4220-8812-53af2c3efe1d" + "id": "05ee6831-0f45-42b8-ad96-87dab5aea830" }, "outputs": [], "source": [ @@ -2303,13 +2304,13 @@ "my_df$se <- tmp$value\n", "head(my_df)" ], - "id": "9b5aa292-3a04-4220-8812-53af2c3efe1d" + "id": "05ee6831-0f45-42b8-ad96-87dab5aea830" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "756b0b78-5575-40de-bff2-98c203d257a1" + "id": "204f9e39-9584-4428-a8de-76869b9c6cc6" }, "outputs": [], "source": [ @@ -2318,13 +2319,13 @@ " geom_col(position = \"dodge\") +\n", " geom_errorbar(aes(ymin = value - se, ymax = value + se), position = \"dodge\")" ], - "id": "756b0b78-5575-40de-bff2-98c203d257a1" + "id": "204f9e39-9584-4428-a8de-76869b9c6cc6" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "442c1aac-818f-4b9a-9c31-18e5b0f5c184" + "id": "6b0f72a0-828d-4d6a-b55d-89bb72033bb2" }, "outputs": [], "source": [ @@ -2341,13 +2342,13 @@ " geom_bar(stat = \"summary\", fun = mean, position = \"dodge\") +\n", " stat_summary(geom = \"errorbar\", fun.data = mean_se, position = \"dodge\")" ], - "id": "442c1aac-818f-4b9a-9c31-18e5b0f5c184" + "id": "6b0f72a0-828d-4d6a-b55d-89bb72033bb2" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "63f559a6-9430-456e-afd9-879298d60394" + "id": "fa070828-980c-40f1-b950-2e323cde2bf5" }, "outputs": [], "source": [ @@ -2360,13 +2361,13 @@ " formula = ~ Species + w_Sepal,\n", " data = my_df)" ], - "id": "63f559a6-9430-456e-afd9-879298d60394" + "id": "fa070828-980c-40f1-b950-2e323cde2bf5" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "d254c473-009a-4264-bdd6-25a5127be68e" + "id": "0152dbda-c942-41cf-bb29-f1ed777302ab" }, "outputs": [], "source": [ @@ -2374,25 +2375,25 @@ "vcd::mosaic(formula = ~w_Sepal + Species, data = my_df,\n", " labeling = labeling_values)" ], - "id": "d254c473-009a-4264-bdd6-25a5127be68e" + "id": "0152dbda-c942-41cf-bb29-f1ed777302ab" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "e1eb9ff3-65a2-4d48-ba5b-b7699cd824e4" + "id": "fbae3bbd-123a-46bc-84f0-5561eb41b47a" }, "outputs": [], "source": [ "curve(x^3 - x, -2, 2)" ], - "id": "e1eb9ff3-65a2-4d48-ba5b-b7699cd824e4" + "id": "fbae3bbd-123a-46bc-84f0-5561eb41b47a" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4f1c3f1a-1ca0-4003-8d04-5041688edb13" + "id": "83ea5cc6-a0de-46ad-aa23-04f1cee61994" }, "outputs": [], "source": [ @@ -2404,13 +2405,13 @@ " geom_histogram(breaks = tmp,\n", " closed = \"left\")" ], - "id": "4f1c3f1a-1ca0-4003-8d04-5041688edb13" + "id": "83ea5cc6-a0de-46ad-aa23-04f1cee61994" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "55094ae0-fd16-489a-bb19-7f3efa3804ce" + "id": "0a25b6eb-2b6f-4d57-bd99-b9ce3a302a57" }, "outputs": [], "source": [ @@ -2419,13 +2420,13 @@ " y = Sepal.Width)) +\n", " geom_point()" ], - "id": "55094ae0-fd16-489a-bb19-7f3efa3804ce" + "id": "0a25b6eb-2b6f-4d57-bd99-b9ce3a302a57" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "681a3f88-1c65-405d-8cb2-de8f97703a06" + "id": "ea270979-ca1c-4838-8204-f85711ac50f0" }, "outputs": [], "source": [ @@ -2438,13 +2439,13 @@ " geom_boxplot() +\n", " xlab(NULL)" ], - "id": "681a3f88-1c65-405d-8cb2-de8f97703a06" + "id": "ea270979-ca1c-4838-8204-f85711ac50f0" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "44640953-3a8a-48ea-b2a1-24148853dc5e" + "id": "6293859e-8b19-4e2e-83ee-78e711160c28" }, "outputs": [], "source": [ @@ -2457,13 +2458,13 @@ " geom_mosaic(\n", " aes(x = product(w_Sepal, Species)))" ], - "id": "44640953-3a8a-48ea-b2a1-24148853dc5e" + "id": "6293859e-8b19-4e2e-83ee-78e711160c28" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "7756ac95-a684-4629-9620-ac75e2850cd0" + "id": "0b321c17-ba71-4795-b1c4-dfac12424438" }, "outputs": [], "source": [ @@ -2472,23 +2473,23 @@ " ggplot(aes(x = x)) +\n", " stat_function(fun = f)" ], - "id": "7756ac95-a684-4629-9620-ac75e2850cd0" + "id": "0b321c17-ba71-4795-b1c4-dfac12424438" }, { - "id": "33a364e6", + "id": "dcd7da02", "cell_type": "markdown", "source": [ "## 4.3 乱数" ], "metadata": { - "id": "33a364e6" + "id": "dcd7da02" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "916a2243-f386-4738-9db7-495e96b608cd" + "id": "e5f38459-2c0a-4d1a-a002-b0d6caaac449" }, "outputs": [], "source": [ @@ -2497,13 +2498,13 @@ " replace = TRUE) # 重複あり\n", "hist(x, breaks = 0:6) # ヒストグラム" ], - "id": "916a2243-f386-4738-9db7-495e96b608cd" + "id": "e5f38459-2c0a-4d1a-a002-b0d6caaac449" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c9addf5c-036c-4ad2-99ad-5f41e0e5f523" + "id": "a9da263d-a3df-4ac0-90b7-0bf57c296c55" }, "outputs": [], "source": [ @@ -2512,13 +2513,13 @@ " n = 1000) # 乱数の数\n", "hist(x)" ], - "id": "c9addf5c-036c-4ad2-99ad-5f41e0e5f523" + "id": "a9da263d-a3df-4ac0-90b7-0bf57c296c55" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4817156d-2b25-4a81-b401-fd61cd2d04b2" + "id": "c320de46-69bd-495c-8bd6-9f6f1fb0a6dd" }, "outputs": [], "source": [ @@ -2528,13 +2529,13 @@ " n = 1000)) # 乱数の数\n", "hist(x, breaks = 0:6) # 結果は割愛" ], - "id": "4817156d-2b25-4a81-b401-fd61cd2d04b2" + "id": "c320de46-69bd-495c-8bd6-9f6f1fb0a6dd" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "24740718-c586-4b07-979a-75fedd437140" + "id": "7f948073-d8be-4480-a67d-adc5f6f8fdc9" }, "outputs": [], "source": [ @@ -2546,13 +2547,13 @@ " n = r) # 乱数の数\n", "hist(x, breaks = max(x) - min(x))" ], - "id": "24740718-c586-4b07-979a-75fedd437140" + "id": "7f948073-d8be-4480-a67d-adc5f6f8fdc9" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a737d243-6ab0-4396-9be5-25f84ed0e08c" + "id": "aca21a30-01b8-4793-b68b-632fe25abf1b" }, "outputs": [], "source": [ @@ -2562,13 +2563,13 @@ " n = r) # 乱数の数\n", "hist(x, breaks = 40)" ], - "id": "a737d243-6ab0-4396-9be5-25f84ed0e08c" + "id": "aca21a30-01b8-4793-b68b-632fe25abf1b" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b9acdeda-99b1-4cbb-9f17-cfadbf99eed4" + "id": "a5c0cee9-f1ad-40c0-9a9b-9fdbfcbb1a37" }, "outputs": [], "source": [ @@ -2582,39 +2583,39 @@ " se = sd(tmp) / sqrt(n)) # 標準誤差\n", "}" ], - "id": "b9acdeda-99b1-4cbb-9f17-cfadbf99eed4" + "id": "a5c0cee9-f1ad-40c0-9a9b-9fdbfcbb1a37" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "aac2cb51-7245-4458-b5b6-5f72dd32c186" + "id": "9fe1e63e-87d6-40c2-8342-420a23b5ad4a" }, "outputs": [], "source": [ "g <- var\n", "c(10, 20, 30) %>% map_dfr(f)" ], - "id": "aac2cb51-7245-4458-b5b6-5f72dd32c186" + "id": "9fe1e63e-87d6-40c2-8342-420a23b5ad4a" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "134c8c77-90da-4ddf-b468-b0db889884b8" + "id": "d59ab24a-e3eb-42f3-b3c8-a1a61f36179a" }, "outputs": [], "source": [ "g <- sd\n", "c(5, 10, 15, 20) %>% map_dfr(f)" ], - "id": "134c8c77-90da-4ddf-b468-b0db889884b8" + "id": "d59ab24a-e3eb-42f3-b3c8-a1a61f36179a" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "423b4894-28c2-44c8-b695-8ef0a7ce5010" + "id": "3373f31b-4da2-474e-a8f4-7ad97728b950" }, "outputs": [], "source": [ @@ -2627,23 +2628,23 @@ "}\n", "c(10, 20, 30) %>% map_dfr(f)" ], - "id": "423b4894-28c2-44c8-b695-8ef0a7ce5010" + "id": "3373f31b-4da2-474e-a8f4-7ad97728b950" }, { - "id": "9bd78044", + "id": "323f127e", "cell_type": "markdown", "source": [ "## 4.4 統計的推測" ], "metadata": { - "id": "9bd78044" + "id": "323f127e" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "fbd5a69f-55cd-49c5-a130-c087cbb017ac" + "id": "25175000-222f-45e2-bde2-7fc958342b0c" }, "outputs": [], "source": [ @@ -2661,13 +2662,13 @@ " # 左片側検定なら'less'\n", " # 右片側検定なら'greater'\n" ], - "id": "fbd5a69f-55cd-49c5-a130-c087cbb017ac" + "id": "25175000-222f-45e2-bde2-7fc958342b0c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4023b619-0d6f-4e3b-82cb-b3415964024e" + "id": "bfdd1524-f612-4602-a9d9-1209a96eabea" }, "outputs": [], "source": [ @@ -2687,37 +2688,37 @@ " geom_hline(yintercept = my_pr2) + # 水平線\n", " theme(legend.position = \"none\") # 凡例を表示しない." ], - "id": "4023b619-0d6f-4e3b-82cb-b3415964024e" + "id": "bfdd1524-f612-4602-a9d9-1209a96eabea" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "46e6f53a-157c-4798-b31b-fa3f040da826" + "id": "97659370-3601-4dfc-8a34-86c5eedbbc57" }, "outputs": [], "source": [ "# 前項の結果(再掲)" ], - "id": "46e6f53a-157c-4798-b31b-fa3f040da826" + "id": "97659370-3601-4dfc-8a34-86c5eedbbc57" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "3881d162-10d0-40b6-a6fe-8e496387bb95" + "id": "537b86a0-3d1e-44ef-91be-1ead7c0a6d79" }, "outputs": [], "source": [ "# 前項冒頭のコード" ], - "id": "3881d162-10d0-40b6-a6fe-8e496387bb95" + "id": "537b86a0-3d1e-44ef-91be-1ead7c0a6d79" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "ac32dbf2-8902-42f8-807d-e9ff81391029" + "id": "05cd01cd-cfd1-4117-8f60-11befbda1a63" }, "outputs": [], "source": [ @@ -2733,13 +2734,13 @@ " # 左片側検定なら'less'\n", " # 右片側検定なら'greater'\n" ], - "id": "ac32dbf2-8902-42f8-807d-e9ff81391029" + "id": "05cd01cd-cfd1-4117-8f60-11befbda1a63" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "324e4227-e009-4479-9b87-31c56f067c6c" + "id": "ee1ff75e-aba0-49f0-b6e9-0914dd14ed11" }, "outputs": [], "source": [ @@ -2749,13 +2750,13 @@ " alternative = \"two.sided\",\n", " conf.level = 0.95)\n" ], - "id": "324e4227-e009-4479-9b87-31c56f067c6c" + "id": "ee1ff75e-aba0-49f0-b6e9-0914dd14ed11" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "5ce2af15-c677-49ee-a5b1-551bd72bb5d1" + "id": "0a6678b8-c01e-4b17-84a0-1a84832698b5" }, "outputs": [], "source": [ @@ -2763,50 +2764,50 @@ " \"/fromzero/master/data/smoker.csv\")\n", "my_data <- read_csv(my_url)" ], - "id": "5ce2af15-c677-49ee-a5b1-551bd72bb5d1" + "id": "0a6678b8-c01e-4b17-84a0-1a84832698b5" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4663a62f-55e7-4b89-8f37-a35bd1ca53c4" + "id": "cec257c1-7602-4f7d-b01f-f354a5ca9f07" }, "outputs": [], "source": [ "head(my_data)" ], - "id": "4663a62f-55e7-4b89-8f37-a35bd1ca53c4" + "id": "cec257c1-7602-4f7d-b01f-f354a5ca9f07" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "392c713e-45c1-4566-8e77-ee2c47c849ca" + "id": "b9f036f2-a08f-418c-95a8-14b19971fd9f" }, "outputs": [], "source": [ "my_table <- table(my_data)\n", "my_table" ], - "id": "392c713e-45c1-4566-8e77-ee2c47c849ca" + "id": "b9f036f2-a08f-418c-95a8-14b19971fd9f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "0fd5f989-1195-47b0-a8eb-d3acd3e2a06d" + "id": "affc0222-847a-45e6-bc60-5c44be99cc8a" }, "outputs": [], "source": [ "chisq.test(my_table, correct = FALSE)\n" ], - "id": "0fd5f989-1195-47b0-a8eb-d3acd3e2a06d" + "id": "affc0222-847a-45e6-bc60-5c44be99cc8a" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "1f0b0503-9508-42f2-8289-4f569c07718b" + "id": "bcc37adc-e598-467b-b371-f0506c4f73be" }, "outputs": [], "source": [ @@ -2821,48 +2822,48 @@ "n <- 10^5\n", "result <- replicate(n, sum(sample(X, size = length(X), replace = TRUE))) # 手順4" ], - "id": "1f0b0503-9508-42f2-8289-4f569c07718b" + "id": "bcc37adc-e598-467b-b371-f0506c4f73be" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "85807c20-7101-41b1-9976-73f57a60a956" + "id": "c00342bf-fc4d-4cc1-aca8-14ba99933899" }, "outputs": [], "source": [ "hist(x = result, breaks = 0:15,\n", " right = FALSE)" ], - "id": "85807c20-7101-41b1-9976-73f57a60a956" + "id": "c00342bf-fc4d-4cc1-aca8-14ba99933899" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "cbdfbd07-b280-4452-9f75-c98ffab5575f" + "id": "461a0129-9f7a-444f-8f77-de43e3144f5b" }, "outputs": [], "source": [ "quantile(result, c(0.025, 0.975))" ], - "id": "cbdfbd07-b280-4452-9f75-c98ffab5575f" + "id": "461a0129-9f7a-444f-8f77-de43e3144f5b" }, { - "id": "4acc9970", + "id": "8bc5f5fd", "cell_type": "markdown", "source": [ "# 5 前処理" ], "metadata": { - "id": "4acc9970" + "id": "8bc5f5fd" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "0b310cc8-35b2-49d6-8674-ec02834a1e67" + "id": "2d9d8fc1-3420-4c0e-a166-12d131d39f3b" }, "outputs": [], "source": [ @@ -2874,23 +2875,23 @@ " install.packages(setdiff(packages_to_install, installed_packages))\n", "}" ], - "id": "0b310cc8-35b2-49d6-8674-ec02834a1e67" + "id": "2d9d8fc1-3420-4c0e-a166-12d131d39f3b" }, { - "id": "9bf6c18b", + "id": "87525fa5", "cell_type": "markdown", "source": [ "## 5.1 データの読み込み" ], "metadata": { - "id": "9bf6c18b" + "id": "87525fa5" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "ed46ebf9-bed4-45fb-8639-7e3c39c0d01d" + "id": "b5c28b09-0c0f-4d8a-bfd7-06fa91405dbe" }, "outputs": [], "source": [ @@ -2898,13 +2899,13 @@ "system(str_c(\"wget https://raw.githubusercontent.com/taroyabuki\",\n", " \"/fromzero/master/data/exam.csv\"))" ], - "id": "ed46ebf9-bed4-45fb-8639-7e3c39c0d01d" + "id": "b5c28b09-0c0f-4d8a-bfd7-06fa91405dbe" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c2c311a7-8a49-4127-a179-275b2d8056ab" + "id": "5dca006b-07ad-4bc7-947f-3e09f1f12b51" }, "outputs": [], "source": [ @@ -2915,13 +2916,13 @@ "\n", "my_df" ], - "id": "c2c311a7-8a49-4127-a179-275b2d8056ab" + "id": "5dca006b-07ad-4bc7-947f-3e09f1f12b51" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4bef7a28-3f33-4ba8-a8e1-f904dd9736e6" + "id": "e87681e4-6f3a-4df7-9bd0-755833199134" }, "outputs": [], "source": [ @@ -2931,13 +2932,13 @@ "# あるいは\n", "my_df <- read.csv(my_url, stringsAsFactors = FALSE)" ], - "id": "4bef7a28-3f33-4ba8-a8e1-f904dd9736e6" + "id": "e87681e4-6f3a-4df7-9bd0-755833199134" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "92f36f04-a6d7-43c8-821d-0552a9514767" + "id": "0a15b130-6d1e-439a-977e-36cd6ec5f4c5" }, "outputs": [], "source": [ @@ -2947,13 +2948,13 @@ " row.names = 1)\n", "my_df2" ], - "id": "92f36f04-a6d7-43c8-821d-0552a9514767" + "id": "0a15b130-6d1e-439a-977e-36cd6ec5f4c5" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "79c53431-e0a6-4107-8d14-b3a18d0fd2d2" + "id": "b76d61e7-8687-4159-9d68-5095dc48021a" }, "outputs": [], "source": [ @@ -2963,25 +2964,25 @@ " file = \"exam2.csv\",\n", " row.names = FALSE)" ], - "id": "79c53431-e0a6-4107-8d14-b3a18d0fd2d2" + "id": "b76d61e7-8687-4159-9d68-5095dc48021a" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "147d8616-dd28-4acf-983e-4dc6abca2684" + "id": "d562c9be-80d9-4ccf-930f-6b76abc6c740" }, "outputs": [], "source": [ "my_df2 %>% write.csv(\"exam3.csv\")" ], - "id": "147d8616-dd28-4acf-983e-4dc6abca2684" + "id": "d562c9be-80d9-4ccf-930f-6b76abc6c740" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c493566b-cf92-4162-abbb-2f10510c0ee5" + "id": "fb1b9e69-e8d1-4414-b437-e1bd63abc97d" }, "outputs": [], "source": [ @@ -2992,13 +2993,13 @@ " stringsAsFactors = FALSE,\n", " fileEncoding = \"UTF-8\")" ], - "id": "c493566b-cf92-4162-abbb-2f10510c0ee5" + "id": "fb1b9e69-e8d1-4414-b437-e1bd63abc97d" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "91ac796e-f43e-41c9-87ba-d73493e81a22" + "id": "eb2d9798-d854-493f-8b89-fc4c7f15caa7" }, "outputs": [], "source": [ @@ -3007,51 +3008,51 @@ "my_df %>% write.csv(file = \"exam2.csv\", row.names = FALSE,\n", " fileEncoding = \"UTF-8\")" ], - "id": "91ac796e-f43e-41c9-87ba-d73493e81a22" + "id": "eb2d9798-d854-493f-8b89-fc4c7f15caa7" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "d80cbd39-a53d-4458-a09c-5ee2533b8246" + "id": "76a014f6-1f8f-4405-9c9f-67130e56ec92" }, "outputs": [], "source": [ "my_url <- \"https://taroyabuki.github.io/fromzero/exam.html\"\n", "my_tables <- xml2::read_html(my_url) %>% rvest::html_table()" ], - "id": "d80cbd39-a53d-4458-a09c-5ee2533b8246" + "id": "76a014f6-1f8f-4405-9c9f-67130e56ec92" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "9825c484-7457-41b0-93f6-d05c628f80e4" + "id": "140e2238-924a-49d2-add0-f1a851982056" }, "outputs": [], "source": [ "my_tables" ], - "id": "9825c484-7457-41b0-93f6-d05c628f80e4" + "id": "140e2238-924a-49d2-add0-f1a851982056" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "8cf0ffc1-acbf-48bd-9e3c-64ebe2f36fc2" + "id": "f1c7145e-e3a0-4d8b-8595-6b211061beaa" }, "outputs": [], "source": [ "tmp <- my_tables[[1]]\n", "tmp" ], - "id": "8cf0ffc1-acbf-48bd-9e3c-64ebe2f36fc2" + "id": "f1c7145e-e3a0-4d8b-8595-6b211061beaa" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "bb033e5d-fd31-4c71-a919-1f66804f85f4" + "id": "dd0bdef6-633c-461a-8599-e9fca422b9be" }, "outputs": [], "source": [ @@ -3062,13 +3063,13 @@ "my_data <- tmp[-1, -1]\n", "my_data" ], - "id": "bb033e5d-fd31-4c71-a919-1f66804f85f4" + "id": "dd0bdef6-633c-461a-8599-e9fca422b9be" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f7d3887f-e229-43f8-b936-c95f19e5dad2" + "id": "1e658592-e14b-4763-b6c1-3f0750160f45" }, "outputs": [], "source": [ @@ -3079,13 +3080,13 @@ "#my_data <- fromJSON(\"exam.json\") # (ファイルを使う場合)\n", "my_data" ], - "id": "f7d3887f-e229-43f8-b936-c95f19e5dad2" + "id": "1e658592-e14b-4763-b6c1-3f0750160f45" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "08d44f32-b3b7-46f3-bc37-67544d5187ae" + "id": "a4f2543e-9e92-4b0f-94ec-a2436a08f60c" }, "outputs": [], "source": [ @@ -3096,25 +3097,25 @@ "#my_xml <- read_xml(\"exam.xml\") # (ファイルを使う場合)\n", "xml_ns(my_xml) # 名前空間の確認(d1)" ], - "id": "08d44f32-b3b7-46f3-bc37-67544d5187ae" + "id": "a4f2543e-9e92-4b0f-94ec-a2436a08f60c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "2dc7dd46-6e30-4db1-9cad-645b7a90dcfc" + "id": "18d661a5-d1f0-425c-a69d-603341e43770" }, "outputs": [], "source": [ "my_records <- xml_find_all(my_xml, \".//d1:record\")" ], - "id": "2dc7dd46-6e30-4db1-9cad-645b7a90dcfc" + "id": "18d661a5-d1f0-425c-a69d-603341e43770" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "6170e962-7024-4552-b740-5ec22efdbb58" + "id": "cf6db405-8dad-468e-90aa-1582b4315633" }, "outputs": [], "source": [ @@ -3126,13 +3127,13 @@ " tmp\n", "}" ], - "id": "6170e962-7024-4552-b740-5ec22efdbb58" + "id": "cf6db405-8dad-468e-90aa-1582b4315633" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "49ce41d0-cae8-4b0e-8fcb-8d876dfad0f9" + "id": "9a0cd990-fbfb-4a9c-9712-d1c8955ded03" }, "outputs": [], "source": [ @@ -3141,23 +3142,23 @@ "my_data$math <- as.numeric(my_data$math)\n", "my_data" ], - "id": "49ce41d0-cae8-4b0e-8fcb-8d876dfad0f9" + "id": "9a0cd990-fbfb-4a9c-9712-d1c8955ded03" }, { - "id": "ddd1bcbe", + "id": "feea1595", "cell_type": "markdown", "source": [ "## 5.2 データの変換" ], "metadata": { - "id": "ddd1bcbe" + "id": "feea1595" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "bc4fc06d-61f1-47e2-9cd2-3c6b5a8ac6a5" + "id": "02b03263-d7ad-4119-8d87-998593f4f524" }, "outputs": [], "source": [ @@ -3169,37 +3170,37 @@ "\n", "z1" ], - "id": "bc4fc06d-61f1-47e2-9cd2-3c6b5a8ac6a5" + "id": "02b03263-d7ad-4119-8d87-998593f4f524" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f6fd5b74-69bc-4b36-91cb-7afe9ab6df18" + "id": "2f7f86d8-b4d9-4b74-a854-692591408301" }, "outputs": [], "source": [ "c(mean(z1), sd(z1))" ], - "id": "f6fd5b74-69bc-4b36-91cb-7afe9ab6df18" + "id": "2f7f86d8-b4d9-4b74-a854-692591408301" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "40b5d359-0462-4793-913a-bbbc7e526aab" + "id": "5b6d21d6-0cd7-4a32-83f0-2ab27aff1726" }, "outputs": [], "source": [ "z1 * sd(x1) + mean(x1)" ], - "id": "40b5d359-0462-4793-913a-bbbc7e526aab" + "id": "5b6d21d6-0cd7-4a32-83f0-2ab27aff1726" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "2dae2a79-4930-4742-adb3-edc2b8e4b3fc" + "id": "49f3f75e-601e-4052-b2d7-fd4a39a3b85c" }, "outputs": [], "source": [ @@ -3207,13 +3208,13 @@ "z2 <- (x2 - mean(x1)) / sd(x1)\n", "c(mean(z2), sd(z2))" ], - "id": "2dae2a79-4930-4742-adb3-edc2b8e4b3fc" + "id": "49f3f75e-601e-4052-b2d7-fd4a39a3b85c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "756ba26b-ecc2-4868-81d1-e60c9a2acfcc" + "id": "bbcf9147-2fd7-40d1-ac6f-c07e482a1c21" }, "outputs": [], "source": [ @@ -3230,13 +3231,13 @@ "\n", "my_enc %>% predict(my_df)" ], - "id": "756ba26b-ecc2-4868-81d1-e60c9a2acfcc" + "id": "bbcf9147-2fd7-40d1-ac6f-c07e482a1c21" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "59364149-100d-492d-9ee4-f7105dd407ec" + "id": "6c87bfa5-2a6f-4b57-a984-0f6fb2066c41" }, "outputs": [], "source": [ @@ -3245,13 +3246,13 @@ " class = c(\"B\", \"C\", \"B\"))\n", "my_enc %>% predict(my_df2)" ], - "id": "59364149-100d-492d-9ee4-f7105dd407ec" + "id": "6c87bfa5-2a6f-4b57-a984-0f6fb2066c41" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "41b80085-1f63-4504-9cf2-0305e5764bfa" + "id": "5d6a9971-3d61-49a4-a52d-63c3a3328d60" }, "outputs": [], "source": [ @@ -3262,10 +3263,10 @@ "\n", "my_enc %>% predict(my_df2)" ], - "id": "41b80085-1f63-4504-9cf2-0305e5764bfa" + "id": "5d6a9971-3d61-49a4-a52d-63c3a3328d60" }, { - "id": "55c11048", + "id": "1df89d43", "cell_type": "markdown", "source": [ "# 6 機械学習の目的・データ・手法\n", @@ -3273,11 +3274,11 @@ "\n" ], "metadata": { - "id": "55c11048" + "id": "1df89d43" } }, { - "id": "cc79821c", + "id": "9c6dc6ca", "cell_type": "markdown", "source": [ "## 6.1 機械学習の目的(本書の場合)\n", @@ -3285,34 +3286,34 @@ "\n" ], "metadata": { - "id": "cc79821c" + "id": "9c6dc6ca" } }, { - "id": "ff4bae39", + "id": "784c2e6e", "cell_type": "markdown", "source": [ "## 6.2 機械学習のためのデータ" ], "metadata": { - "id": "ff4bae39" + "id": "784c2e6e" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a89db4e1-cecb-4129-956e-5cec4134db32" + "id": "f6627b4e-e0ee-4a8e-aadf-63a8a8ac0fa9" }, "outputs": [], "source": [ "iris\n", "# 以下省略" ], - "id": "a89db4e1-cecb-4129-956e-5cec4134db32" + "id": "f6627b4e-e0ee-4a8e-aadf-63a8a8ac0fa9" }, { - "id": "38a8c244", + "id": "4c72a568", "cell_type": "markdown", "source": [ "## 6.3 機械学習のための手法\n", @@ -3320,24 +3321,24 @@ "\n" ], "metadata": { - "id": "38a8c244" + "id": "4c72a568" } }, { - "id": "90969a63", + "id": "5b58c713", "cell_type": "markdown", "source": [ "# 7 回帰1(単回帰)" ], "metadata": { - "id": "90969a63" + "id": "5b58c713" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "598c753a-e80e-4aae-916a-4f1c85edf1c5" + "id": "1fd3a3f0-1524-4bb8-8411-5dbd84fd04e9" }, "outputs": [], "source": [ @@ -3349,10 +3350,10 @@ " install.packages(setdiff(packages_to_install, installed_packages))\n", "}" ], - "id": "598c753a-e80e-4aae-916a-4f1c85edf1c5" + "id": "1fd3a3f0-1524-4bb8-8411-5dbd84fd04e9" }, { - "id": "ba6a9b5b", + "id": "b8c6b1c3", "cell_type": "markdown", "source": [ "## 7.1 自動車の停止距離\n", @@ -3360,24 +3361,24 @@ "\n" ], "metadata": { - "id": "ba6a9b5b" + "id": "b8c6b1c3" } }, { - "id": "2b356d36", + "id": "1528c0a1", "cell_type": "markdown", "source": [ "## 7.2 データの確認" ], "metadata": { - "id": "2b356d36" + "id": "1528c0a1" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "2f2d4726-23f7-4b55-b846-a477fb1d65eb" + "id": "508e447d-4b57-4401-a870-34b94813ac9a" }, "outputs": [], "source": [ @@ -3385,50 +3386,50 @@ "library(tidyverse)\n", "my_data <- cars" ], - "id": "2f2d4726-23f7-4b55-b846-a477fb1d65eb" + "id": "508e447d-4b57-4401-a870-34b94813ac9a" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "ec35888d-95a6-4def-9f12-93e6ca2f665c" + "id": "f4688485-c843-42cd-a8af-61bd4415e199" }, "outputs": [], "source": [ "dim(my_data)" ], - "id": "ec35888d-95a6-4def-9f12-93e6ca2f665c" + "id": "f4688485-c843-42cd-a8af-61bd4415e199" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a53ca8a4-1401-4a7b-bf8c-4103fe579815" + "id": "29c54dc8-c636-4188-a9db-cdc3cb9905fd" }, "outputs": [], "source": [ "head(my_data)" ], - "id": "a53ca8a4-1401-4a7b-bf8c-4103fe579815" + "id": "29c54dc8-c636-4188-a9db-cdc3cb9905fd" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "3a49534a-04e8-4660-9806-23998b785c7c" + "id": "29ee980b-ca54-433d-a284-0146636f98ff" }, "outputs": [], "source": [ "options(digits = 3)\n", "pastecs::stat.desc(my_data)" ], - "id": "3a49534a-04e8-4660-9806-23998b785c7c" + "id": "29ee980b-ca54-433d-a284-0146636f98ff" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "09da10f9-4de4-4a53-ae04-f8a15cca9ad7" + "id": "cfef8416-0c86-4356-9fc7-c05126d1709f" }, "outputs": [], "source": [ @@ -3436,23 +3437,23 @@ " ggplot(aes(x = speed, y = dist)) +\n", " geom_point()" ], - "id": "09da10f9-4de4-4a53-ae04-f8a15cca9ad7" + "id": "cfef8416-0c86-4356-9fc7-c05126d1709f" }, { - "id": "118c6cd1", + "id": "e510dff5", "cell_type": "markdown", "source": [ "## 7.3 回帰分析" ], "metadata": { - "id": "118c6cd1" + "id": "e510dff5" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "24f57cb0-965f-4f4f-9dca-32f63998a47c" + "id": "ac373625-6356-4185-8a8c-d7fb6c9ca0d9" }, "outputs": [], "source": [ @@ -3467,13 +3468,13 @@ " geom_pointrange(data = tmp, aes(ymin = -9, ymax = dist), linetype = \"dotted\") +\n", " geom_pointrange(data = tmp, aes(xmin = 0, xmax = speed), linetype = \"dotted\")" ], - "id": "24f57cb0-965f-4f4f-9dca-32f63998a47c" + "id": "ac373625-6356-4185-8a8c-d7fb6c9ca0d9" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "af98f0d4-6e00-43ed-b887-cafd38741b90" + "id": "bb24f245-cf1a-4bb3-b75d-39efc2a9bd91" }, "outputs": [], "source": [ @@ -3481,13 +3482,13 @@ "library(tidyverse)\n", "my_data <- cars" ], - "id": "af98f0d4-6e00-43ed-b887-cafd38741b90" + "id": "bb24f245-cf1a-4bb3-b75d-39efc2a9bd91" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4aa02a77-f1ba-4380-af60-78cc414db4c6" + "id": "58e797ab-6edc-4262-a25e-1ea7f362e821" }, "outputs": [], "source": [ @@ -3495,50 +3496,50 @@ " data = my_data, # データ\n", " method = \"lm\") # 手法" ], - "id": "4aa02a77-f1ba-4380-af60-78cc414db4c6" + "id": "58e797ab-6edc-4262-a25e-1ea7f362e821" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "d51e5021-2e18-4678-a749-b6a7c63f64b8" + "id": "66000a61-cdbf-4336-974b-ad6e79381cbc" }, "outputs": [], "source": [ "coef(my_model$finalModel)" ], - "id": "d51e5021-2e18-4678-a749-b6a7c63f64b8" + "id": "66000a61-cdbf-4336-974b-ad6e79381cbc" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4e453065-83d1-491f-b8d6-e8b3a6591ec7" + "id": "32f4fe3a-0d1f-4248-a97b-b12ea7001f7c" }, "outputs": [], "source": [ "tmp <- data.frame(speed = 21.5)\n", "my_model %>% predict(tmp)" ], - "id": "4e453065-83d1-491f-b8d6-e8b3a6591ec7" + "id": "32f4fe3a-0d1f-4248-a97b-b12ea7001f7c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "79c53261-cc3d-485f-8b05-fc0a50640fee" + "id": "5e4892d5-4d99-4154-aa78-e9d7def0f4e6" }, "outputs": [], "source": [ "f <- function(x) { my_model %>% predict(data.frame(speed = x)) }" ], - "id": "79c53261-cc3d-485f-8b05-fc0a50640fee" + "id": "5e4892d5-4d99-4154-aa78-e9d7def0f4e6" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c3258c3e-8197-4c8c-b174-a15adce0228d" + "id": "1d7f8dc5-e510-42f6-b2f7-8a02fe305132" }, "outputs": [], "source": [ @@ -3550,23 +3551,23 @@ " fun = f,\n", " mapping = aes(color = \"model\"))" ], - "id": "c3258c3e-8197-4c8c-b174-a15adce0228d" + "id": "1d7f8dc5-e510-42f6-b2f7-8a02fe305132" }, { - "id": "95592be7", + "id": "87a132e0", "cell_type": "markdown", "source": [ "## 7.4 当てはまりの良さの指標" ], "metadata": { - "id": "95592be7" + "id": "87a132e0" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "672dedac-f454-4d99-85b0-4ea3ebd69ba0" + "id": "5e1b68dd-e9f8-4977-813d-a80d0f476ac5" }, "outputs": [], "source": [ @@ -3579,26 +3580,26 @@ "y_ <- my_model %>% predict(my_data)\n", "my_data$y_ <- y_" ], - "id": "672dedac-f454-4d99-85b0-4ea3ebd69ba0" + "id": "5e1b68dd-e9f8-4977-813d-a80d0f476ac5" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "0ad95ca3-4860-4b0f-b453-863e942c8b7b" + "id": "bba309a9-c921-4f36-aa50-ec6398fa9ed5" }, "outputs": [], "source": [ "my_data$residual <- y - y_\n", "head(my_data)" ], - "id": "0ad95ca3-4860-4b0f-b453-863e942c8b7b" + "id": "bba309a9-c921-4f36-aa50-ec6398fa9ed5" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c255c5dc-bde2-4a69-bce8-e686162109eb" + "id": "3d1cb023-3abd-4b11-8228-260547e3582c" }, "outputs": [], "source": [ @@ -3608,13 +3609,13 @@ " geom_line(aes(x = speed, y = y_)) +\n", " geom_linerange(mapping = aes(ymin = y_, ymax = dist), linetype = \"dotted\")" ], - "id": "c255c5dc-bde2-4a69-bce8-e686162109eb" + "id": "3d1cb023-3abd-4b11-8228-260547e3582c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "083b6079-e8dc-4fbd-9f66-9a047caa1080" + "id": "4bf75802-cc0a-4255-bedc-8817d5b9caee" }, "outputs": [], "source": [ @@ -3622,26 +3623,26 @@ "# あるいは\n", "mean((my_data$residual^2))**0.5\n" ], - "id": "083b6079-e8dc-4fbd-9f66-9a047caa1080" + "id": "4bf75802-cc0a-4255-bedc-8817d5b9caee" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a77ee473-887e-4a1f-be24-3f778df58541" + "id": "f72754c6-0a8b-458d-b6a3-85fc560b8ecb" }, "outputs": [], "source": [ "R2(pred = y_, obs = y,\n", " form = \"traditional\")" ], - "id": "a77ee473-887e-4a1f-be24-3f778df58541" + "id": "f72754c6-0a8b-458d-b6a3-85fc560b8ecb" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "0f249b5d-4aa6-4465-8bb1-dd084d03c177" + "id": "c17b2876-1303-4ba1-8009-a6d113f225a1" }, "outputs": [], "source": [ @@ -3650,13 +3651,13 @@ "# あるいは\n", "summary(my_model$finalModel)$r.squared" ], - "id": "0f249b5d-4aa6-4465-8bb1-dd084d03c177" + "id": "c17b2876-1303-4ba1-8009-a6d113f225a1" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "30a95286-2142-4a72-bf17-f3dde2429d9a" + "id": "4fb4ab7d-a394-42a0-b080-a9f7250e019c" }, "outputs": [], "source": [ @@ -3670,13 +3671,13 @@ "R2(pred = y_, obs = y,\n", " form = \"corr\")" ], - "id": "30a95286-2142-4a72-bf17-f3dde2429d9a" + "id": "4fb4ab7d-a394-42a0-b080-a9f7250e019c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "bef7b650-27a2-49f6-8e4d-17c53a635702" + "id": "d4b2f253-911a-44b0-bb4e-cd064fa3e70c" }, "outputs": [], "source": [ @@ -3686,13 +3687,13 @@ "my_idx <- c(2, 11, 27, 34, 39, 44)\n", "my_sample <- my_data[my_idx, ]" ], - "id": "bef7b650-27a2-49f6-8e4d-17c53a635702" + "id": "d4b2f253-911a-44b0-bb4e-cd064fa3e70c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f11e71fd-8a5e-4160-97e5-330f63daddbd" + "id": "a553db8e-4860-41bb-bc06-866860468a0d" }, "outputs": [], "source": [ @@ -3705,13 +3706,13 @@ "y <- my_sample$dist\n", "y_ <- my_model %>% predict(my_sample)" ], - "id": "f11e71fd-8a5e-4160-97e5-330f63daddbd" + "id": "a553db8e-4860-41bb-bc06-866860468a0d" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f48f818b-5799-405c-9304-e0b7aee05094" + "id": "255768c1-34d6-49cb-8efa-eeb2e341c8c7" }, "outputs": [], "source": [ @@ -3723,13 +3724,13 @@ "R2(pred = y_, obs = y,\n", " form = \"corr\")" ], - "id": "f48f818b-5799-405c-9304-e0b7aee05094" + "id": "255768c1-34d6-49cb-8efa-eeb2e341c8c7" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "306e2ae0-fee7-449e-a902-91bc6352da7d" + "id": "2255dc05-c57d-47f8-834a-25cac6e73ada" }, "outputs": [], "source": [ @@ -3742,23 +3743,23 @@ " stat_function(fun = f, mapping = aes(color = \"model\")) +\n", " coord_cartesian(ylim = c(0, 120))" ], - "id": "306e2ae0-fee7-449e-a902-91bc6352da7d" + "id": "2255dc05-c57d-47f8-834a-25cac6e73ada" }, { - "id": "60724521", + "id": "3e272c39", "cell_type": "markdown", "source": [ "## 7.5 K最近傍法" ], "metadata": { - "id": "60724521" + "id": "3e272c39" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b46f361d-2b39-42d1-9f32-822a8edc7620" + "id": "edcb2fd7-7433-4ebf-9636-69a3a673e2de" }, "outputs": [], "source": [ @@ -3773,13 +3774,13 @@ "# 可視化の準備\n", "f <- function(x) { my_model %>% predict(data.frame(speed = x))}" ], - "id": "b46f361d-2b39-42d1-9f32-822a8edc7620" + "id": "edcb2fd7-7433-4ebf-9636-69a3a673e2de" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f4464028-3e82-4c06-875f-8b55d0cf5299" + "id": "7c3d4d9a-eff1-4702-949f-ee3f98a08281" }, "outputs": [], "source": [ @@ -3792,13 +3793,13 @@ " fun = f,\n", " mapping = aes(color = \"model\"))" ], - "id": "f4464028-3e82-4c06-875f-8b55d0cf5299" + "id": "7c3d4d9a-eff1-4702-949f-ee3f98a08281" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "ebfd3fca-b4ef-4ee2-a5cf-ffc8673c7f19" + "id": "6dd21a1c-45bc-4c8d-93f3-e383848f1da8" }, "outputs": [], "source": [ @@ -3813,23 +3814,23 @@ "R2(pred = y_, obs = y,\n", " form = \"corr\")" ], - "id": "ebfd3fca-b4ef-4ee2-a5cf-ffc8673c7f19" + "id": "6dd21a1c-45bc-4c8d-93f3-e383848f1da8" }, { - "id": "397310f4", + "id": "3f54daa7", "cell_type": "markdown", "source": [ "## 7.6 検証" ], "metadata": { - "id": "397310f4" + "id": "3f54daa7" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "3691446e-d574-4964-ab63-0019a23be7d5" + "id": "7753fb65-72a6-42b9-ae4c-4ffb2f4b6205" }, "outputs": [], "source": [ @@ -3840,13 +3841,13 @@ "\n", "my_model$results" ], - "id": "3691446e-d574-4964-ab63-0019a23be7d5" + "id": "7753fb65-72a6-42b9-ae4c-4ffb2f4b6205" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "43e6b6fa-db3e-4f99-b589-0a0c579ba576" + "id": "4d66dc36-1c88-40de-a633-bbc45285fe0d" }, "outputs": [], "source": [ @@ -3854,13 +3855,13 @@ " trControl = trainControl(method = \"cv\", number = 5))\n", "my_model$results" ], - "id": "43e6b6fa-db3e-4f99-b589-0a0c579ba576" + "id": "4d66dc36-1c88-40de-a633-bbc45285fe0d" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "9711dca5-98a0-4c9a-8288-3c27a71e5054" + "id": "4643044d-8edc-42f2-969d-ac6849451e1c" }, "outputs": [], "source": [ @@ -3868,13 +3869,13 @@ " trControl = trainControl(method = \"LOOCV\"))\n", "my_model$results" ], - "id": "9711dca5-98a0-4c9a-8288-3c27a71e5054" + "id": "4643044d-8edc-42f2-969d-ac6849451e1c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "208d07ec-0b26-4286-b358-b7debb6fc03d" + "id": "a487ca56-b9d2-41d8-86cc-fd64bb74b8e2" }, "outputs": [], "source": [ @@ -3882,13 +3883,13 @@ "cl <- makeCluster(detectCores())\n", "registerDoParallel(cl)" ], - "id": "208d07ec-0b26-4286-b358-b7debb6fc03d" + "id": "a487ca56-b9d2-41d8-86cc-fd64bb74b8e2" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "482897f2-fbde-47bb-9a76-0e318b468e79" + "id": "3628dc2f-3e14-4527-82da-61cf309a1fcf" }, "outputs": [], "source": [ @@ -3899,13 +3900,13 @@ "y <- my_data$dist\n", "y_ <- my_model %>% predict(my_data)" ], - "id": "482897f2-fbde-47bb-9a76-0e318b468e79" + "id": "3628dc2f-3e14-4527-82da-61cf309a1fcf" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "3434aaf8-8659-46a5-8de2-43bd1b9baf16" + "id": "ccae4bf2-a512-43fa-b002-54c77c15f69d" }, "outputs": [], "source": [ @@ -3920,25 +3921,25 @@ "R2(pred = y_, obs = y,\n", " form = \"corr\")" ], - "id": "3434aaf8-8659-46a5-8de2-43bd1b9baf16" + "id": "ccae4bf2-a512-43fa-b002-54c77c15f69d" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "adee6d04-f430-4d8f-8672-91d64947a2a9" + "id": "8592f7c4-6174-4f3c-b69b-909544c66228" }, "outputs": [], "source": [ "postResample(pred = y_, obs = y)" ], - "id": "adee6d04-f430-4d8f-8672-91d64947a2a9" + "id": "8592f7c4-6174-4f3c-b69b-909544c66228" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4b2452ec-c64c-41b0-a845-92372e71b458" + "id": "3f3e57bc-4fae-4003-8db3-c99ca05e4729" }, "outputs": [], "source": [ @@ -3946,13 +3947,13 @@ "my_model$results\n", "# 左から,RMSE(検証),決定係数6(検証),MAE(検証)" ], - "id": "4b2452ec-c64c-41b0-a845-92372e71b458" + "id": "3f3e57bc-4fae-4003-8db3-c99ca05e4729" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4733a25a-8223-4cb0-bef9-20ad71012725" + "id": "687d4c3b-1f77-475a-a233-1e8100c7b145" }, "outputs": [], "source": [ @@ -3967,25 +3968,25 @@ "y_ <- my_model$pred$pred\n", "mean((y - y_)^2)**0.5" ], - "id": "4733a25a-8223-4cb0-bef9-20ad71012725" + "id": "687d4c3b-1f77-475a-a233-1e8100c7b145" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "8d2964a9-e571-4bdf-a798-23d45a8592ae" + "id": "4bf36f9c-8bd9-43a6-ad9e-76a2d3b0fce7" }, "outputs": [], "source": [ "mean(((y - y_)^2)**0.5)" ], - "id": "8d2964a9-e571-4bdf-a798-23d45a8592ae" + "id": "4bf36f9c-8bd9-43a6-ad9e-76a2d3b0fce7" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "8beb1c4d-77d6-43b9-bea2-711111312710" + "id": "972f259b-cfeb-46b2-b4ff-8a12f238173c" }, "outputs": [], "source": [ @@ -4000,13 +4001,13 @@ " tuneGrid = data.frame(k = 5),\n", " trControl = trainControl(method = \"LOOCV\"))" ], - "id": "8beb1c4d-77d6-43b9-bea2-711111312710" + "id": "972f259b-cfeb-46b2-b4ff-8a12f238173c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "cbef6830-5199-4e00-ad81-6dfd9a746168" + "id": "97306e53-7deb-4259-b5f9-2f99b756db38" }, "outputs": [], "source": [ @@ -4014,13 +4015,13 @@ "\n", "my_knn_model$results$RMSE" ], - "id": "cbef6830-5199-4e00-ad81-6dfd9a746168" + "id": "97306e53-7deb-4259-b5f9-2f99b756db38" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4dcc8ae0-5427-4b70-9827-311556f24ba2" + "id": "2778cbd1-e1b8-497f-99a6-605c374e2856" }, "outputs": [], "source": [ @@ -4034,25 +4035,25 @@ "\n", "head(my_df)" ], - "id": "4dcc8ae0-5427-4b70-9827-311556f24ba2" + "id": "2778cbd1-e1b8-497f-99a6-605c374e2856" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c89827f6-99ae-48c8-93ce-278568ac0fb6" + "id": "d3445fd9-f6ad-45bb-b347-976b412464d7" }, "outputs": [], "source": [ "boxplot(my_df, ylab = \"r^2\")" ], - "id": "c89827f6-99ae-48c8-93ce-278568ac0fb6" + "id": "d3445fd9-f6ad-45bb-b347-976b412464d7" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "ea727c02-9920-4366-8f24-a487ffa46c3a" + "id": "6b0b5c2e-2d29-4dc0-9561-4588a56a74e5" }, "outputs": [], "source": [ @@ -4061,23 +4062,23 @@ " paired = TRUE,\n", " alternative = \"two.sided\")\n" ], - "id": "ea727c02-9920-4366-8f24-a487ffa46c3a" + "id": "6b0b5c2e-2d29-4dc0-9561-4588a56a74e5" }, { - "id": "093e8f76", + "id": "0ea83b94", "cell_type": "markdown", "source": [ "## 7.7 パラメータチューニング" ], "metadata": { - "id": "093e8f76" + "id": "0ea83b94" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "1e9ae6e9-cb10-4609-8c04-77d55739b764" + "id": "a0559a26-b79b-47b3-801d-c8f0a49c9e8e" }, "outputs": [], "source": [ @@ -4087,13 +4088,13 @@ "my_model <- train(form = dist ~ speed, data = my_data, method = \"knn\")\n", "my_model$results" ], - "id": "1e9ae6e9-cb10-4609-8c04-77d55739b764" + "id": "a0559a26-b79b-47b3-801d-c8f0a49c9e8e" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f9fa1dfe-de24-4d2a-8992-441d068c6662" + "id": "cc1f8c95-68f3-4515-bf0d-3a7160c3afd6" }, "outputs": [], "source": [ @@ -4103,62 +4104,62 @@ " tuneGrid = my_params,\n", " trControl = trainControl(method = \"LOOCV\"))" ], - "id": "f9fa1dfe-de24-4d2a-8992-441d068c6662" + "id": "cc1f8c95-68f3-4515-bf0d-3a7160c3afd6" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "1ee6f90b-7712-4494-ae26-58cfe34d7cf2" + "id": "9ff42297-43ae-43e5-ab72-4d764c62c273" }, "outputs": [], "source": [ "head(my_model$results)" ], - "id": "1ee6f90b-7712-4494-ae26-58cfe34d7cf2" + "id": "9ff42297-43ae-43e5-ab72-4d764c62c273" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "8973fb2f-4bb0-43b8-9ba6-c4ca72dc044b" + "id": "9ae94d33-100b-47ae-bc69-b8de5a86ad77" }, "outputs": [], "source": [ "ggplot(my_model)" ], - "id": "8973fb2f-4bb0-43b8-9ba6-c4ca72dc044b" + "id": "9ae94d33-100b-47ae-bc69-b8de5a86ad77" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "0f12de74-3936-4d8b-8cc4-017545f1c479" + "id": "eb736cba-9583-42d9-b2f6-28b2e12cd86f" }, "outputs": [], "source": [ "my_model$bestTune" ], - "id": "0f12de74-3936-4d8b-8cc4-017545f1c479" + "id": "eb736cba-9583-42d9-b2f6-28b2e12cd86f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "9007ec32-4911-4959-808b-452366582971" + "id": "2c184213-648e-4712-b2a9-6a3ed7ae98a2" }, "outputs": [], "source": [ "my_model$results %>%\n", " filter(RMSE == min(RMSE))" ], - "id": "9007ec32-4911-4959-808b-452366582971" + "id": "2c184213-648e-4712-b2a9-6a3ed7ae98a2" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b43bb275-b249-41ff-b041-91e39520f769" + "id": "2f65a922-d32d-46d2-a9f5-1e390a5f08d5" }, "outputs": [], "source": [ @@ -4166,13 +4167,13 @@ "y_ <- my_model %>% predict(my_data)\n", "RMSE(y_, y)" ], - "id": "b43bb275-b249-41ff-b041-91e39520f769" + "id": "2f65a922-d32d-46d2-a9f5-1e390a5f08d5" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "01dfe87b-2c1a-43d3-a787-8b836a03e033" + "id": "ed1a64ad-eea1-4239-9034-e8e10d70bec8" }, "outputs": [], "source": [ @@ -4193,13 +4194,13 @@ "\n", "my_results <- 1:15 %>% map_dfr(my_loocv)" ], - "id": "01dfe87b-2c1a-43d3-a787-8b836a03e033" + "id": "ed1a64ad-eea1-4239-9034-e8e10d70bec8" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "7015d39d-128e-4619-8379-7a945697a9a9" + "id": "f208065f-0020-477b-a10f-ce5bc125f61d" }, "outputs": [], "source": [ @@ -4212,13 +4213,13 @@ " theme(legend.position = c(1, 0),\n", " legend.justification = c(1, 0))" ], - "id": "7015d39d-128e-4619-8379-7a945697a9a9" + "id": "f208065f-0020-477b-a10f-ce5bc125f61d" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "ad22b0fd-1a8a-4f84-8d4b-16a6f3974bf3" + "id": "10c01915-113a-4af2-aca7-03ab714a4b2a" }, "outputs": [], "source": [ @@ -4226,23 +4227,23 @@ "stopCluster(cl)\n", "registerDoSEQ()" ], - "id": "ad22b0fd-1a8a-4f84-8d4b-16a6f3974bf3" + "id": "10c01915-113a-4af2-aca7-03ab714a4b2a" }, { - "id": "2a395208", + "id": "ea88df27", "cell_type": "markdown", "source": [ "# 8 回帰2(重回帰)" ], "metadata": { - "id": "2a395208" + "id": "ea88df27" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "863ddbd7-9348-44be-9052-6b547df1b4e5" + "id": "379f2240-2aa4-492c-87e7-bbef33e4b5cc" }, "outputs": [], "source": [ @@ -4254,23 +4255,23 @@ " install.packages(setdiff(packages_to_install, installed_packages))\n", "}" ], - "id": "863ddbd7-9348-44be-9052-6b547df1b4e5" + "id": "379f2240-2aa4-492c-87e7-bbef33e4b5cc" }, { - "id": "37e6f249", + "id": "279fba58", "cell_type": "markdown", "source": [ "## 8.1 ブドウの生育条件とワインの価格" ], "metadata": { - "id": "37e6f249" + "id": "279fba58" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "817cde13-b10d-4ca0-8387-48a82e1ed9ae" + "id": "b4cdd59c-5582-447d-ad7e-4757bf9ede01" }, "outputs": [], "source": [ @@ -4283,50 +4284,50 @@ " nrows = 38) # 読み込む行数\n", "psych::describe(tmp)" ], - "id": "817cde13-b10d-4ca0-8387-48a82e1ed9ae" + "id": "b4cdd59c-5582-447d-ad7e-4757bf9ede01" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b1232266-e40b-42fb-bd97-d92f3c574a85" + "id": "774c85de-89e3-4469-9a19-aa70446d9d33" }, "outputs": [], "source": [ "my_data <- na.omit(tmp[, -c(1, 2)])\n", "head(my_data)" ], - "id": "b1232266-e40b-42fb-bd97-d92f3c574a85" + "id": "774c85de-89e3-4469-9a19-aa70446d9d33" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a8320177-7870-4640-b4f6-bd3f91f9449e" + "id": "40c05e43-7232-4a54-a4f1-206148569a7e" }, "outputs": [], "source": [ "dim(my_data)" ], - "id": "a8320177-7870-4640-b4f6-bd3f91f9449e" + "id": "40c05e43-7232-4a54-a4f1-206148569a7e" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "82e12995-c516-4ce2-b598-2a901a243f64" + "id": "99996286-13cb-4fff-887e-4a205000b882" }, "outputs": [], "source": [ "my_data %>% write_csv(\"wine.csv\")" ], - "id": "82e12995-c516-4ce2-b598-2a901a243f64" + "id": "99996286-13cb-4fff-887e-4a205000b882" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "68776af5-0092-4362-963e-8952fbf7a161" + "id": "b43b73da-3c6c-4375-8bf4-0987ff7bdebb" }, "outputs": [], "source": [ @@ -4335,23 +4336,23 @@ " \"/fromzero/master/data/wine.csv\")\n", "my_data <- read_csv(my_url)" ], - "id": "68776af5-0092-4362-963e-8952fbf7a161" + "id": "b43b73da-3c6c-4375-8bf4-0987ff7bdebb" }, { - "id": "39d3d891", + "id": "7d8ec028", "cell_type": "markdown", "source": [ "## 8.2 重回帰分析" ], "metadata": { - "id": "39d3d891" + "id": "7d8ec028" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "940d40b4-4aa5-4b97-833b-8136e6ba08bd" + "id": "d36b3c29-acaf-4e7e-8a16-a84746375d2d" }, "outputs": [], "source": [ @@ -4366,26 +4367,26 @@ " method = \"lm\",\n", " trControl = trainControl(method = \"LOOCV\"))" ], - "id": "940d40b4-4aa5-4b97-833b-8136e6ba08bd" + "id": "d36b3c29-acaf-4e7e-8a16-a84746375d2d" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b25ea2fa-9723-437b-b74a-015f6a75a6e6" + "id": "0c8623c4-6a3a-45cb-8115-ba99c60e56c0" }, "outputs": [], "source": [ "coef(my_model$finalModel) %>%\n", " as.data.frame" ], - "id": "b25ea2fa-9723-437b-b74a-015f6a75a6e6" + "id": "0c8623c4-6a3a-45cb-8115-ba99c60e56c0" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "326f99ec-ea3a-4150-85c1-9e2ab54c2a12" + "id": "8711900e-222e-4771-aac5-6ac837440378" }, "outputs": [], "source": [ @@ -4394,13 +4395,13 @@ " HRAIN = 120, TIME_SV = 2)\n", "my_model %>% predict(my_test)" ], - "id": "326f99ec-ea3a-4150-85c1-9e2ab54c2a12" + "id": "8711900e-222e-4771-aac5-6ac837440378" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4d24b366-d2be-4c79-bab8-4c231e86d640" + "id": "cb7940b2-35c1-453c-8cd6-27f647930805" }, "outputs": [], "source": [ @@ -4415,25 +4416,25 @@ "R2(pred = y_, obs = y,\n", " form = \"corr\")" ], - "id": "4d24b366-d2be-4c79-bab8-4c231e86d640" + "id": "cb7940b2-35c1-453c-8cd6-27f647930805" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "dcbd63c9-92d4-4d79-9ca0-83de4eacca48" + "id": "b2f4a62e-7b3c-4f77-a0e1-aa8539bc4f75" }, "outputs": [], "source": [ "my_model$results" ], - "id": "dcbd63c9-92d4-4d79-9ca0-83de4eacca48" + "id": "b2f4a62e-7b3c-4f77-a0e1-aa8539bc4f75" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "3aa98966-e7c3-42b6-a769-2031c2ae784d" + "id": "a96f0d55-68b0-4309-b298-c3d9b03bbbb3" }, "outputs": [], "source": [ @@ -4443,23 +4444,23 @@ "matrix(b,\n", " dimnames = list(colnames(M)))" ], - "id": "3aa98966-e7c3-42b6-a769-2031c2ae784d" + "id": "a96f0d55-68b0-4309-b298-c3d9b03bbbb3" }, { - "id": "0211fa9d", + "id": "b859ec38", "cell_type": "markdown", "source": [ "## 8.3 標準化" ], "metadata": { - "id": "0211fa9d" + "id": "b859ec38" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b6ba7b01-afc4-4aaa-bc35-eb2f8ee77747" + "id": "e1923c9f-3807-4823-955d-8903797d1dd2" }, "outputs": [], "source": [ @@ -4477,13 +4478,13 @@ " stat_summary(fun = mean, geom = \"point\", size = 3) +\n", " xlab(NULL)" ], - "id": "b6ba7b01-afc4-4aaa-bc35-eb2f8ee77747" + "id": "e1923c9f-3807-4823-955d-8903797d1dd2" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c5331606-2d03-45e3-b67d-a00e8e308fb8" + "id": "9819300a-46bc-429f-948f-9fb4c1939bd0" }, "outputs": [], "source": [ @@ -4493,26 +4494,26 @@ " method = \"lm\",\n", " preProcess = c(\"center\", \"scale\"))" ], - "id": "c5331606-2d03-45e3-b67d-a00e8e308fb8" + "id": "9819300a-46bc-429f-948f-9fb4c1939bd0" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "9732fdf9-cf42-4b93-a510-e7c4735a9a76" + "id": "282283bc-e325-457a-8551-e41f821a3e49" }, "outputs": [], "source": [ "coef(my_model$finalModel) %>%\n", " as.data.frame" ], - "id": "9732fdf9-cf42-4b93-a510-e7c4735a9a76" + "id": "282283bc-e325-457a-8551-e41f821a3e49" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b067f75e-53e2-4219-b43a-84d6c5155a4f" + "id": "b496b090-c1be-46d4-ba82-f27970687596" }, "outputs": [], "source": [ @@ -4521,23 +4522,23 @@ " HRAIN = 120, TIME_SV = 2)\n", "my_model %>% predict(my_test)" ], - "id": "b067f75e-53e2-4219-b43a-84d6c5155a4f" + "id": "b496b090-c1be-46d4-ba82-f27970687596" }, { - "id": "66fad470", + "id": "5b0a2ab0", "cell_type": "markdown", "source": [ "## 8.4 入力変数の数とモデルの良さ" ], "metadata": { - "id": "66fad470" + "id": "5b0a2ab0" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "df819782-e8b9-4929-9be7-29e5a8d2f5c7" + "id": "1d2314ce-930d-40ec-9909-dd587fb91d4f" }, "outputs": [], "source": [ @@ -4552,13 +4553,13 @@ " v2 = 0:(n - 1) %% 3)\n", "head(my_data2)" ], - "id": "df819782-e8b9-4929-9be7-29e5a8d2f5c7" + "id": "1d2314ce-930d-40ec-9909-dd587fb91d4f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "56f35500-ad17-441e-98b7-6fb488657511" + "id": "63baa206-2408-4fe4-8dc8-17b1fb965182" }, "outputs": [], "source": [ @@ -4571,23 +4572,23 @@ "\n", "my_model2$results$RMSE" ], - "id": "56f35500-ad17-441e-98b7-6fb488657511" + "id": "63baa206-2408-4fe4-8dc8-17b1fb965182" }, { - "id": "09276cc1", + "id": "3f208f93", "cell_type": "markdown", "source": [ "## 8.5 変数選択" ], "metadata": { - "id": "09276cc1" + "id": "3f208f93" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "ce1fb978-473d-4a7a-b474-abc86773595e" + "id": "5a1305d0-1af5-4d7b-875b-f2db94543ff7" }, "outputs": [], "source": [ @@ -4600,13 +4601,13 @@ "my_data2 <- my_data %>% mutate(v1 = 0:(n - 1) %% 2,\n", " v2 = 0:(n - 1) %% 3)" ], - "id": "ce1fb978-473d-4a7a-b474-abc86773595e" + "id": "5a1305d0-1af5-4d7b-875b-f2db94543ff7" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "1caf0971-6b5f-4897-a74b-1167bab77024" + "id": "cf36f080-8614-4677-bfee-d0edde1849ef" }, "outputs": [], "source": [ @@ -4617,23 +4618,23 @@ " tuneGrid = data.frame(nvmax = 1:6)) # 選択する変数の上限\n", "summary(my_model$finalModel)$outmat" ], - "id": "1caf0971-6b5f-4897-a74b-1167bab77024" + "id": "cf36f080-8614-4677-bfee-d0edde1849ef" }, { - "id": "6c46e251", + "id": "061ea0e0", "cell_type": "markdown", "source": [ "## 8.6 補足:正則化" ], "metadata": { - "id": "6c46e251" + "id": "061ea0e0" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "0bac1627-3df5-414c-9243-511d8a26fffd" + "id": "01cf2326-fc3a-4afd-b88d-6cbdb0e213d5" }, "outputs": [], "source": [ @@ -4643,13 +4644,13 @@ " \"/fromzero/master/data/wine.csv\")\n", "my_data <- read_csv(my_url)" ], - "id": "0bac1627-3df5-414c-9243-511d8a26fffd" + "id": "01cf2326-fc3a-4afd-b88d-6cbdb0e213d5" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c0ca7b08-ba0e-469b-87b1-3dd460528a55" + "id": "54d36924-aa0c-4a41-a0a9-7707321ed393" }, "outputs": [], "source": [ @@ -4665,25 +4666,25 @@ " lambda = A,\n", " alpha = B))" ], - "id": "c0ca7b08-ba0e-469b-87b1-3dd460528a55" + "id": "54d36924-aa0c-4a41-a0a9-7707321ed393" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "bb8e0d9c-02af-430e-a62b-4a18a3eb4d95" + "id": "71c8216a-b035-4fa4-9ea9-c8110e7ffe3b" }, "outputs": [], "source": [ "coef(my_model$finalModel, A)" ], - "id": "bb8e0d9c-02af-430e-a62b-4a18a3eb4d95" + "id": "71c8216a-b035-4fa4-9ea9-c8110e7ffe3b" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "12b9890c-5a6e-45e6-9ef5-4d80ba47dd8f" + "id": "6d3b37b5-4293-4f84-89b6-04e97e0767a4" }, "outputs": [], "source": [ @@ -4692,13 +4693,13 @@ " HRAIN = 120, TIME_SV = 2)\n", "my_model %>% predict(my_test)" ], - "id": "12b9890c-5a6e-45e6-9ef5-4d80ba47dd8f" + "id": "6d3b37b5-4293-4f84-89b6-04e97e0767a4" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "bd0754aa-6592-4b0f-bd9b-9c6d305710b8" + "id": "e74f3dbe-15d0-471c-bf72-7846b8ac9780" }, "outputs": [], "source": [ @@ -4718,13 +4719,13 @@ " xlab(\"log A ( = log lambda)\") +\n", " theme(legend.position = c(0.15, 0.25))" ], - "id": "bd0754aa-6592-4b0f-bd9b-9c6d305710b8" + "id": "e74f3dbe-15d0-471c-bf72-7846b8ac9780" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "ad010f95-7650-4b68-b7f3-80b7a44332fc" + "id": "e6ec587d-3448-4356-800c-30101e758c23" }, "outputs": [], "source": [ @@ -4738,13 +4739,13 @@ "\n", "my_model$bestTune" ], - "id": "ad010f95-7650-4b68-b7f3-80b7a44332fc" + "id": "e6ec587d-3448-4356-800c-30101e758c23" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "7db501eb-fca8-498b-b28c-34cdbb614c1b" + "id": "d942dde7-2a49-49e6-abf0-1d1e4e640998" }, "outputs": [], "source": [ @@ -4754,48 +4755,48 @@ " xlab(\"A ( = lambda)\") +\n", " guides(shape = guide_legend(tmp), color = guide_legend(tmp))" ], - "id": "7db501eb-fca8-498b-b28c-34cdbb614c1b" + "id": "d942dde7-2a49-49e6-abf0-1d1e4e640998" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c0a0fe0f-143f-4c83-92bd-c241ba83b234" + "id": "18faf59f-03a9-4dc4-882a-da67947a1eb6" }, "outputs": [], "source": [ "my_model$results %>%\n", " filter(RMSE == min(RMSE))" ], - "id": "c0a0fe0f-143f-4c83-92bd-c241ba83b234" + "id": "18faf59f-03a9-4dc4-882a-da67947a1eb6" }, { - "id": "13a6a815", + "id": "3cdeadb0", "cell_type": "markdown", "source": [ "## 8.7 ニューラルネットワーク" ], "metadata": { - "id": "13a6a815" + "id": "3cdeadb0" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "abc5435b-cd7e-48dc-9118-46f3cfeb39ee" + "id": "ed4cee84-4d3e-4734-97e3-94aa20787822" }, "outputs": [], "source": [ "curve(1 / (1 + exp(-x)), -6, 6)" ], - "id": "abc5435b-cd7e-48dc-9118-46f3cfeb39ee" + "id": "ed4cee84-4d3e-4734-97e3-94aa20787822" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "3bfd9f13-93d1-4ef8-a42c-866b431a89ee" + "id": "a4d8b731-55cb-4875-9fec-c1a2eab16bcd" }, "outputs": [], "source": [ @@ -4805,13 +4806,13 @@ " \"/fromzero/master/data/wine.csv\")\n", "my_data <- read_csv(my_url)" ], - "id": "3bfd9f13-93d1-4ef8-a42c-866b431a89ee" + "id": "a4d8b731-55cb-4875-9fec-c1a2eab16bcd" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "3754cc40-f70f-4df9-b99b-d247e2968cff" + "id": "56fd7f2c-ef8f-4fa0-b991-1d7f433e3a19" }, "outputs": [], "source": [ @@ -4822,25 +4823,25 @@ " trControl = trainControl(method = \"LOOCV\"))\n", "plot(my_model$finalModel) # 訓練済ネットワークの描画" ], - "id": "3754cc40-f70f-4df9-b99b-d247e2968cff" + "id": "56fd7f2c-ef8f-4fa0-b991-1d7f433e3a19" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "6e5a314c-f9b2-4be6-a4fa-0f497152cd85" + "id": "510d326f-342e-4132-ba30-b4a4800878e6" }, "outputs": [], "source": [ "my_model$results" ], - "id": "6e5a314c-f9b2-4be6-a4fa-0f497152cd85" + "id": "510d326f-342e-4132-ba30-b4a4800878e6" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f729a43d-e558-4010-b204-59046eca70f8" + "id": "e6b0ebc5-58cb-4b4c-8684-f50e3434774c" }, "outputs": [], "source": [ @@ -4854,36 +4855,36 @@ " layer2 = 0:2,\n", " layer3 = 0))" ], - "id": "f729a43d-e558-4010-b204-59046eca70f8" + "id": "e6b0ebc5-58cb-4b4c-8684-f50e3434774c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "be63dc43-dd44-4881-9d59-a2253acf886f" + "id": "abd1a6ae-afa5-4fdc-aaf2-e81be2dc098e" }, "outputs": [], "source": [ "my_model$results %>%\n", " filter(RMSE == min(RMSE))" ], - "id": "be63dc43-dd44-4881-9d59-a2253acf886f" + "id": "abd1a6ae-afa5-4fdc-aaf2-e81be2dc098e" }, { - "id": "14c51cca", + "id": "a9630aa3", "cell_type": "markdown", "source": [ "# 9 分類1(多値分類)" ], "metadata": { - "id": "14c51cca" + "id": "a9630aa3" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "cd6dfe04-dc3e-4e70-b9f9-b1e87e8f9507" + "id": "da8d2c4f-aa1d-4a15-b64b-36f135598018" }, "outputs": [], "source": [ @@ -4895,58 +4896,58 @@ " install.packages(setdiff(packages_to_install, installed_packages))\n", "}" ], - "id": "cd6dfe04-dc3e-4e70-b9f9-b1e87e8f9507" + "id": "da8d2c4f-aa1d-4a15-b64b-36f135598018" }, { - "id": "9e59a5c5", + "id": "fa17bbec", "cell_type": "markdown", "source": [ "## 9.1 アヤメのデータ" ], "metadata": { - "id": "9e59a5c5" + "id": "fa17bbec" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "62f8eb92-1be0-4ba9-983e-2b0ebdfd14a7" + "id": "650a8f09-bae6-45d0-af8f-133b5f89eca6" }, "outputs": [], "source": [ "my_data <- iris\n", "head(my_data)" ], - "id": "62f8eb92-1be0-4ba9-983e-2b0ebdfd14a7" + "id": "650a8f09-bae6-45d0-af8f-133b5f89eca6" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b14e13a7-261f-4b66-9eaf-2270673ac1e1" + "id": "d859e5ee-f0c1-40ad-9d1d-e5cc4381f168" }, "outputs": [], "source": [ "psych::describe(my_data)" ], - "id": "b14e13a7-261f-4b66-9eaf-2270673ac1e1" + "id": "d859e5ee-f0c1-40ad-9d1d-e5cc4381f168" }, { - "id": "0fc63830", + "id": "20e5dc1f", "cell_type": "markdown", "source": [ "## 9.2 木による分類" ], "metadata": { - "id": "0fc63830" + "id": "20e5dc1f" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b54ed12b-6b29-4fe6-b1ea-9e0e971f58b8" + "id": "6e74f98b-3801-4ffb-be78-9ed420162d06" }, "outputs": [], "source": [ @@ -4955,25 +4956,25 @@ "my_data <- iris\n", "my_model <- train(form = Species ~ ., data = my_data, method = \"rpart\")" ], - "id": "b54ed12b-6b29-4fe6-b1ea-9e0e971f58b8" + "id": "6e74f98b-3801-4ffb-be78-9ed420162d06" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4304c2a0-b029-4923-a4a7-0bdc636deb0f" + "id": "db506107-f8b0-4013-9deb-5a3508a6c30e" }, "outputs": [], "source": [ "rpart.plot::rpart.plot(my_model$finalModel, extra = 1)" ], - "id": "4304c2a0-b029-4923-a4a7-0bdc636deb0f" + "id": "db506107-f8b0-4013-9deb-5a3508a6c30e" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "153fc673-1150-48fc-8ab6-f9caebc04052" + "id": "2b4f0351-be1b-42b9-8c2a-80ccd94c1bd1" }, "outputs": [], "source": [ @@ -4984,36 +4985,36 @@ "\n", "my_model %>% predict(my_test)" ], - "id": "153fc673-1150-48fc-8ab6-f9caebc04052" + "id": "2b4f0351-be1b-42b9-8c2a-80ccd94c1bd1" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b3153a9c-eb76-4258-95c2-84c7273e762c" + "id": "2541cbf3-b89e-4278-ba42-ba8588db7de1" }, "outputs": [], "source": [ "my_model %>% predict(my_test,\n", " type = \"prob\")" ], - "id": "b3153a9c-eb76-4258-95c2-84c7273e762c" + "id": "2541cbf3-b89e-4278-ba42-ba8588db7de1" }, { - "id": "17a89605", + "id": "03363422", "cell_type": "markdown", "source": [ "## 9.3 正解率" ], "metadata": { - "id": "17a89605" + "id": "03363422" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "87f4370d-a033-47f0-aaa4-3c5ed5915960" + "id": "50c7ea81-372c-4c09-901b-aa331fd75fb7" }, "outputs": [], "source": [ @@ -5027,13 +5028,13 @@ "confusionMatrix(data = y_, reference = y)\n", "# 以下は割愛" ], - "id": "87f4370d-a033-47f0-aaa4-3c5ed5915960" + "id": "50c7ea81-372c-4c09-901b-aa331fd75fb7" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "eb40035f-28fa-41a2-a017-04e98f766ec9" + "id": "32d598e9-f9d9-4b80-bc39-e1560c2d4377" }, "outputs": [], "source": [ @@ -5041,13 +5042,13 @@ "y_ <- my_model %>% predict(my_data)\n", "mean(y_ == y)" ], - "id": "eb40035f-28fa-41a2-a017-04e98f766ec9" + "id": "32d598e9-f9d9-4b80-bc39-e1560c2d4377" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "5478b58c-e51d-45a4-8c15-57ec0d220851" + "id": "1ec7e210-99bc-4389-93d9-54e9d4176ac2" }, "outputs": [], "source": [ @@ -5055,13 +5056,13 @@ " trControl = trainControl(method = \"LOOCV\"))\n", "my_model$results" ], - "id": "5478b58c-e51d-45a4-8c15-57ec0d220851" + "id": "1ec7e210-99bc-4389-93d9-54e9d4176ac2" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "379d2479-8dc5-4f76-a904-858fd41b3291" + "id": "ea688a43-90b9-4831-97c4-6dd3e665842e" }, "outputs": [], "source": [ @@ -5070,13 +5071,13 @@ " trControl = trainControl(method = \"LOOCV\"))\n", "my_model$results %>% filter(Accuracy == max(Accuracy))" ], - "id": "379d2479-8dc5-4f76-a904-858fd41b3291" + "id": "ea688a43-90b9-4831-97c4-6dd3e665842e" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "0e8f2b49-8ff7-4af0-bd8e-a388ccb56757" + "id": "239dd8d3-7eee-40c0-873d-fa7db1fbe026" }, "outputs": [], "source": [ @@ -5094,13 +5095,13 @@ " Accuracy = my_model$results$Accuracy)\n", "}" ], - "id": "0e8f2b49-8ff7-4af0-bd8e-a388ccb56757" + "id": "239dd8d3-7eee-40c0-873d-fa7db1fbe026" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "8a1ef5f3-d19d-4db9-b421-17dfaee71bc3" + "id": "13f50948-0762-4bc3-a0f3-9b2014eece6f" }, "outputs": [], "source": [ @@ -5116,13 +5117,13 @@ "\n", "my_results %>% filter(Accuracy == max(Accuracy)) # 正解率(検証)の最大値" ], - "id": "8a1ef5f3-d19d-4db9-b421-17dfaee71bc3" + "id": "13f50948-0762-4bc3-a0f3-9b2014eece6f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "5b1fed90-c83c-42a8-b81e-1613a4b9be45" + "id": "ffe886ce-a444-4b7a-8bb1-7ed2f4fef7df" }, "outputs": [], "source": [ @@ -5133,36 +5134,36 @@ " minbucket = 5,\n", " minsplit = 2))" ], - "id": "5b1fed90-c83c-42a8-b81e-1613a4b9be45" + "id": "ffe886ce-a444-4b7a-8bb1-7ed2f4fef7df" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "748f7466-5191-4a4e-bd63-3353476d62ca" + "id": "8c7d8162-9fe2-4645-b10c-079fad793141" }, "outputs": [], "source": [ "rpart.plot::rpart.plot(\n", " my_model$finalModel, extra = 1)" ], - "id": "748f7466-5191-4a4e-bd63-3353476d62ca" + "id": "8c7d8162-9fe2-4645-b10c-079fad793141" }, { - "id": "d390dff5", + "id": "35362e76", "cell_type": "markdown", "source": [ "## 9.4 複数の木を使う方法" ], "metadata": { - "id": "d390dff5" + "id": "35362e76" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "6523b00d-8458-49db-9944-074f6e856813" + "id": "c0370be0-073f-43a7-8b6b-3402c28330ef" }, "outputs": [], "source": [ @@ -5175,13 +5176,13 @@ " trControl = trainControl(method = \"LOOCV\"))\n", "my_model$results" ], - "id": "6523b00d-8458-49db-9944-074f6e856813" + "id": "c0370be0-073f-43a7-8b6b-3402c28330ef" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "717c4406-d5d7-4704-8c11-efda5c223fab" + "id": "a8688ff3-024d-4d59-ad01-5a22d436746f" }, "outputs": [], "source": [ @@ -5198,36 +5199,36 @@ " trControl = trainControl(method = \"cv\", number = 5)) # 5分割交差検証\n", "my_model$results %>% filter(Accuracy == max(Accuracy)) %>% head(5) %>% t" ], - "id": "717c4406-d5d7-4704-8c11-efda5c223fab" + "id": "a8688ff3-024d-4d59-ad01-5a22d436746f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f9cbaaeb-c450-47d0-8103-4dc1c91a3ca1" + "id": "de6f287c-4213-4d60-8e1f-bddcc691aaac" }, "outputs": [], "source": [ "my_model <- train(form = Species ~ ., data = my_data, method = \"rf\")\n", "ggplot(varImp(my_model))" ], - "id": "f9cbaaeb-c450-47d0-8103-4dc1c91a3ca1" + "id": "de6f287c-4213-4d60-8e1f-bddcc691aaac" }, { - "id": "34ac2b65", + "id": "38bb6546", "cell_type": "markdown", "source": [ "## 9.5 欠損のあるデータでの学習" ], "metadata": { - "id": "34ac2b65" + "id": "38bb6546" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "6c368f91-0982-4703-b90b-71e6130ec735" + "id": "cbfac048-be87-48ed-b5e0-b7b6b96019d5" }, "outputs": [], "source": [ @@ -5241,13 +5242,13 @@ "\n", "psych::describe(my_data) # nの値が135の変数に,150 - 135 = 15個の欠損がある." ], - "id": "6c368f91-0982-4703-b90b-71e6130ec735" + "id": "cbfac048-be87-48ed-b5e0-b7b6b96019d5" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "e0907c4d-d57a-4152-97c6-7532fdaffeb9" + "id": "97ea12b0-7b3a-4674-b399-8ffd919b2160" }, "outputs": [], "source": [ @@ -5261,13 +5262,13 @@ " minbucket = 1)) # 終端ノードの条件\n", "max(my_model$results$Accuracy)" ], - "id": "e0907c4d-d57a-4152-97c6-7532fdaffeb9" + "id": "97ea12b0-7b3a-4674-b399-8ffd919b2160" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "72f03f3f-3e47-4868-a77d-acfad9f5d3cd" + "id": "30a3082a-40e2-45b6-8bc7-c30383d069c2" }, "outputs": [], "source": [ @@ -5276,23 +5277,23 @@ " trControl = trainControl(method = \"cv\", number = 5))\n", "max(my_model$results$Accuracy)" ], - "id": "72f03f3f-3e47-4868-a77d-acfad9f5d3cd" + "id": "30a3082a-40e2-45b6-8bc7-c30383d069c2" }, { - "id": "9590e3c0", + "id": "bacf46dd", "cell_type": "markdown", "source": [ "## 9.6 他の分類手法" ], "metadata": { - "id": "9590e3c0" + "id": "bacf46dd" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "afb97986-1ae8-4c77-8e60-36b65366b466" + "id": "d57eb209-48af-4958-bcd8-46712c5f84a2" }, "outputs": [], "source": [ @@ -5304,13 +5305,13 @@ " trControl = trainControl(method = \"LOOCV\"))\n", "my_model$results %>% filter(Accuracy == max(Accuracy))" ], - "id": "afb97986-1ae8-4c77-8e60-36b65366b466" + "id": "d57eb209-48af-4958-bcd8-46712c5f84a2" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "8955664e-e95b-4796-a80f-b3501cb51b54" + "id": "2bea54d9-6321-462b-b100-f5878a3bb419" }, "outputs": [], "source": [ @@ -5324,23 +5325,23 @@ " trace = FALSE) # 途中経過を表示しない\n", "my_model$results %>% filter(Accuracy == max(Accuracy))" ], - "id": "8955664e-e95b-4796-a80f-b3501cb51b54" + "id": "2bea54d9-6321-462b-b100-f5878a3bb419" }, { - "id": "e6ee6fec", + "id": "2521a809", "cell_type": "markdown", "source": [ "# 10 分類2(2値分類)" ], "metadata": { - "id": "e6ee6fec" + "id": "2521a809" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "ded38757-7de5-482e-82f9-3f90357d67af" + "id": "2192e8c0-f1d3-40a1-ac08-8ab5845a96d6" }, "outputs": [], "source": [ @@ -5352,49 +5353,49 @@ " install.packages(setdiff(packages_to_install, installed_packages))\n", "}" ], - "id": "ded38757-7de5-482e-82f9-3f90357d67af" + "id": "2192e8c0-f1d3-40a1-ac08-8ab5845a96d6" }, { - "id": "7841a497", + "id": "f5cc5c86", "cell_type": "markdown", "source": [ "## 10.1 2値分類の性能指標" ], "metadata": { - "id": "7841a497" + "id": "f5cc5c86" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "9ff35d0a-1f07-47e5-89f3-59cef1410a11" + "id": "f7616375-1812-41e1-bb58-5eb76cc2125c" }, "outputs": [], "source": [ "y <- c( 0, 1, 1, 0, 1, 0, 1, 0, 0, 1)\n", "y_score <- c(0.7, 0.8, 0.3, 0.4, 0.9, 0.6, 0.99, 0.1, 0.2, 0.5)" ], - "id": "9ff35d0a-1f07-47e5-89f3-59cef1410a11" + "id": "f7616375-1812-41e1-bb58-5eb76cc2125c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c7def63e-01c6-457c-b580-2626f56699dd" + "id": "c7c88d74-cba1-4e20-85f4-5adb837fabf0" }, "outputs": [], "source": [ "y_ <- ifelse(0.5 <= y_score, 1, 0)\n", "y_" ], - "id": "c7def63e-01c6-457c-b580-2626f56699dd" + "id": "c7c88d74-cba1-4e20-85f4-5adb837fabf0" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4a1cb193-9283-4b30-97ae-b3a3ceef1570" + "id": "c7472736-6226-4d5a-9e24-c688744f2ece" }, "outputs": [], "source": [ @@ -5404,23 +5405,23 @@ " positive = \"1\", # 「1」を陽性とする.\n", " mode = \"everything\") # 全ての指標を求める." ], - "id": "4a1cb193-9283-4b30-97ae-b3a3ceef1570" + "id": "c7472736-6226-4d5a-9e24-c688744f2ece" }, { - "id": "3300152d", + "id": "41d14b33", "cell_type": "markdown", "source": [ "## 10.2 トレードオフ" ], "metadata": { - "id": "3300152d" + "id": "41d14b33" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "988e8b5b-6cb3-4370-ad2e-ff2fa7b0eab9" + "id": "4466f9c5-d703-4d27-975d-557b3916b7ad" }, "outputs": [], "source": [ @@ -5434,13 +5435,13 @@ "c(sum((y == 0) & (y_ == 1)) / sum(y == 0), # FPR\n", " sum((y == 1) & (y_ == 1)) / sum(y == 1)) # TPR" ], - "id": "988e8b5b-6cb3-4370-ad2e-ff2fa7b0eab9" + "id": "4466f9c5-d703-4d27-975d-557b3916b7ad" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f0ed6044-2f31-4928-8921-b1097fb14914" + "id": "a1fa6503-9620-4546-a6de-1e21dfa1a691" }, "outputs": [], "source": [ @@ -5451,38 +5452,38 @@ " ylab = \"True Positive Rate\",\n", " legend = FALSE)" ], - "id": "f0ed6044-2f31-4928-8921-b1097fb14914" + "id": "a1fa6503-9620-4546-a6de-1e21dfa1a691" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "6f33efc4-4bbb-499d-8172-328557eec677" + "id": "6baf9c27-2b3f-43de-b343-9d27f2eb6c7c" }, "outputs": [], "source": [ "my_roc$auc" ], - "id": "6f33efc4-4bbb-499d-8172-328557eec677" + "id": "6baf9c27-2b3f-43de-b343-9d27f2eb6c7c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "ab17deaf-e0b6-49c1-a66d-00c39592c16f" + "id": "7c8f0d03-652c-4021-8c61-6e4fa6213a65" }, "outputs": [], "source": [ "c(sum((y == 1) & (y_ == 1)) / sum(y == 1), # Recall == TPR\n", " sum((y == 1) & (y_ == 1)) / sum(y_ == 1)) # Precision" ], - "id": "ab17deaf-e0b6-49c1-a66d-00c39592c16f" + "id": "7c8f0d03-652c-4021-8c61-6e4fa6213a65" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c3f8f0d0-1d93-4f54-bfb1-48864157de1c" + "id": "2a0a34c7-8980-4a2e-b0ab-fdf8559b2e4e" }, "outputs": [], "source": [ @@ -5493,35 +5494,35 @@ " ylab = \"Precision\",\n", " legend = FALSE)" ], - "id": "c3f8f0d0-1d93-4f54-bfb1-48864157de1c" + "id": "2a0a34c7-8980-4a2e-b0ab-fdf8559b2e4e" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a724ac12-fa1f-4be1-a1a4-e44404297015" + "id": "2ad79e87-e0ac-43f9-bf1a-a762a5e85df5" }, "outputs": [], "source": [ "my_pr$auc.integral" ], - "id": "a724ac12-fa1f-4be1-a1a4-e44404297015" + "id": "2ad79e87-e0ac-43f9-bf1a-a762a5e85df5" }, { - "id": "05bbad36", + "id": "17a0ed00", "cell_type": "markdown", "source": [ "## 10.3 タイタニック" ], "metadata": { - "id": "05bbad36" + "id": "17a0ed00" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c3faf654-a12d-4975-b933-f9ed3532c5b7" + "id": "d7b676a0-5133-43a2-ac1a-858643d17010" }, "outputs": [], "source": [ @@ -5533,25 +5534,25 @@ " \"/fromzero/master/data/titanic.csv\")\n", "my_data <- read_csv(my_url)" ], - "id": "c3faf654-a12d-4975-b933-f9ed3532c5b7" + "id": "d7b676a0-5133-43a2-ac1a-858643d17010" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "819254a7-bc6c-43e8-a1dd-02595cb6d24b" + "id": "a23fbd41-362e-44d1-8ed6-8a176ba10133" }, "outputs": [], "source": [ "head(my_data)" ], - "id": "819254a7-bc6c-43e8-a1dd-02595cb6d24b" + "id": "a23fbd41-362e-44d1-8ed6-8a176ba10133" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "e9ce7f93-6884-4b6a-98e9-bfd4241b42c8" + "id": "b26a4b88-beba-4d4e-b5da-71c85bc45e04" }, "outputs": [], "source": [ @@ -5559,37 +5560,37 @@ " tuneGrid = data.frame(maxdepth = 2),\n", " trControl = trainControl(method = \"LOOCV\"))" ], - "id": "e9ce7f93-6884-4b6a-98e9-bfd4241b42c8" + "id": "b26a4b88-beba-4d4e-b5da-71c85bc45e04" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "238c9873-082a-4d63-b4a1-1f02287aee01" + "id": "567a8a34-47fa-475f-a0ac-d324a3d857d7" }, "outputs": [], "source": [ "rpart.plot::rpart.plot(my_model$finalModel, extra = 1)" ], - "id": "238c9873-082a-4d63-b4a1-1f02287aee01" + "id": "567a8a34-47fa-475f-a0ac-d324a3d857d7" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b4501350-df0a-404c-b99f-c37a671c3c12" + "id": "29e2f0ee-59c0-43c5-b093-2997b92c27bb" }, "outputs": [], "source": [ "my_model$results" ], - "id": "b4501350-df0a-404c-b99f-c37a671c3c12" + "id": "29e2f0ee-59c0-43c5-b093-2997b92c27bb" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "6348caa2-3d00-4020-bfa1-8984656fcc43" + "id": "22f88d9c-413d-4c2f-a16a-883ffb471071" }, "outputs": [], "source": [ @@ -5606,13 +5607,13 @@ " ylab = \"True Positive Rate\",\n", " legend = FALSE)" ], - "id": "6348caa2-3d00-4020-bfa1-8984656fcc43" + "id": "22f88d9c-413d-4c2f-a16a-883ffb471071" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "0a3100cc-ad93-4462-b381-25ed6605e35f" + "id": "ea947bac-5fb5-48ba-b426-c319eee6478d" }, "outputs": [], "source": [ @@ -5628,13 +5629,13 @@ "rpart.plot::rpart.plot(my_model1$finalModel, extra = 1)\n", "my_model1$results" ], - "id": "0a3100cc-ad93-4462-b381-25ed6605e35f" + "id": "ea947bac-5fb5-48ba-b426-c319eee6478d" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "2dfc522b-6bb4-45d4-a6c1-4c3166496271" + "id": "0403b893-2b00-44f0-bef7-002e37d8eb9f" }, "outputs": [], "source": [ @@ -5650,13 +5651,13 @@ "rpart.plot::rpart.plot(my_model2$finalModel, extra = 1)\n", "my_model2$results" ], - "id": "2dfc522b-6bb4-45d4-a6c1-4c3166496271" + "id": "0403b893-2b00-44f0-bef7-002e37d8eb9f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "46e0559a-07ec-427e-8e8e-22d68cd2cea7" + "id": "a0eec41e-f6b0-43b6-a408-7632979f27cf" }, "outputs": [], "source": [ @@ -5666,35 +5667,35 @@ "rpart.plot::rpart.plot(my_model3$finalModel, extra = 1)\n", "my_model3$results" ], - "id": "46e0559a-07ec-427e-8e8e-22d68cd2cea7" + "id": "a0eec41e-f6b0-43b6-a408-7632979f27cf" }, { - "id": "ffa70dc6", + "id": "47603a96", "cell_type": "markdown", "source": [ "## 10.4 ロジスティック回帰" ], "metadata": { - "id": "ffa70dc6" + "id": "47603a96" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "54a95945-ffed-486c-832c-1b0cf707564e" + "id": "240e9fe9-e13a-49a0-be5c-56f54f2f1f37" }, "outputs": [], "source": [ "curve(1 / (1 + exp(-x)), -6, 6)" ], - "id": "54a95945-ffed-486c-832c-1b0cf707564e" + "id": "240e9fe9-e13a-49a0-be5c-56f54f2f1f37" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a855312a-31d3-49cc-89f8-123df301d8eb" + "id": "16b09cc8-2127-41d9-af7f-7d1614704210" }, "outputs": [], "source": [ @@ -5709,48 +5710,48 @@ "my_model <- train(form = Survived ~ ., data = my_data, method = \"glm\",\n", " trControl = trainControl(method = \"LOOCV\"))" ], - "id": "a855312a-31d3-49cc-89f8-123df301d8eb" + "id": "16b09cc8-2127-41d9-af7f-7d1614704210" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "ec6c5df7-0d0d-44fc-b5ed-0c5b2bae22be" + "id": "a1312f09-30f8-4c04-adc1-7ef23a335c3a" }, "outputs": [], "source": [ "coef(my_model$finalModel) %>%\n", " as.data.frame" ], - "id": "ec6c5df7-0d0d-44fc-b5ed-0c5b2bae22be" + "id": "a1312f09-30f8-4c04-adc1-7ef23a335c3a" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "78f31f31-7424-4daa-b230-0090a829ece9" + "id": "752a312b-0c66-477e-8364-851fe0d947f4" }, "outputs": [], "source": [ "my_model$results" ], - "id": "78f31f31-7424-4daa-b230-0090a829ece9" + "id": "752a312b-0c66-477e-8364-851fe0d947f4" }, { - "id": "a706a8ad", + "id": "c69f1ad0", "cell_type": "markdown", "source": [ "# 11 深層学習とAutoML" ], "metadata": { - "id": "a706a8ad" + "id": "c69f1ad0" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "ffee0f43-4fd0-4164-bae1-53e6cbf1491e" + "id": "270d8808-f766-47d9-b42e-77f50952f07b" }, "outputs": [], "source": [ @@ -5762,23 +5763,23 @@ " install.packages(setdiff(packages_to_install, installed_packages))\n", "}" ], - "id": "ffee0f43-4fd0-4164-bae1-53e6cbf1491e" + "id": "270d8808-f766-47d9-b42e-77f50952f07b" }, { - "id": "26b732fb", + "id": "4c03a295", "cell_type": "markdown", "source": [ "## 11.1 Kerasによる回帰" ], "metadata": { - "id": "26b732fb" + "id": "4c03a295" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "d7d5f6d7-0704-4b57-99e1-b7ab831dff09" + "id": "7a77be40-ba1e-4aa6-b0bf-74bc21fe828d" }, "outputs": [], "source": [ @@ -5788,25 +5789,25 @@ " \"/fromzero/master/data/wine.csv\")\n", "tmp <- read_csv(my_url)" ], - "id": "d7d5f6d7-0704-4b57-99e1-b7ab831dff09" + "id": "7a77be40-ba1e-4aa6-b0bf-74bc21fe828d" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "dffd1daa-7a98-43fa-93a2-c888f452cdf0" + "id": "ffd26607-6971-4c6b-b3a2-631606555bff" }, "outputs": [], "source": [ "my_data <- tmp[sample(nrow(tmp)), ]" ], - "id": "dffd1daa-7a98-43fa-93a2-c888f452cdf0" + "id": "ffd26607-6971-4c6b-b3a2-631606555bff" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "8795dc76-5c4a-47f9-afac-bc92c54c4303" + "id": "2326e6ce-3762-445f-88e4-5b4854b3a18d" }, "outputs": [], "source": [ @@ -5814,25 +5815,25 @@ " select(-LPRICE2) %>% scale\n", "y <- my_data$LPRICE2" ], - "id": "8795dc76-5c4a-47f9-afac-bc92c54c4303" + "id": "2326e6ce-3762-445f-88e4-5b4854b3a18d" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "7c0ff55e-17be-473c-ba0d-65c566300c12" + "id": "204dddec-c298-435f-902a-6f8c346fb39b" }, "outputs": [], "source": [ "curve(activation_relu(x), -3, 3)" ], - "id": "7c0ff55e-17be-473c-ba0d-65c566300c12" + "id": "204dddec-c298-435f-902a-6f8c346fb39b" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f5bd4346-27f2-4138-a318-ed9e84c2cb10" + "id": "ba55237e-8561-4352-aad1-fef7e9fca4bd" }, "outputs": [], "source": [ @@ -5843,13 +5844,13 @@ "summary(my_model) # ネットワークの概要\n", "# 割愛(Pythonの結果を参照)" ], - "id": "f5bd4346-27f2-4138-a318-ed9e84c2cb10" + "id": "ba55237e-8561-4352-aad1-fef7e9fca4bd" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "d7d28c33-bfab-42c1-9257-3fceebaef2fd" + "id": "afcbb90d-126d-4c9b-968e-26ed66b037f1" }, "outputs": [], "source": [ @@ -5857,13 +5858,13 @@ " loss = \"mse\",\n", " optimizer = \"rmsprop\")" ], - "id": "d7d28c33-bfab-42c1-9257-3fceebaef2fd" + "id": "afcbb90d-126d-4c9b-968e-26ed66b037f1" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "926c9740-31cf-456a-894f-305422148f90" + "id": "f6c8cb88-ace4-4771-8778-8e9efdd6990a" }, "outputs": [], "source": [ @@ -5871,13 +5872,13 @@ " patience = 20,\n", " restore_best_weights = TRUE)" ], - "id": "926c9740-31cf-456a-894f-305422148f90" + "id": "f6c8cb88-ace4-4771-8778-8e9efdd6990a" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "2f634682-a98e-49a3-b9d4-05ae8b611c49" + "id": "706c14cb-3430-4645-949a-75b388ccfdc1" }, "outputs": [], "source": [ @@ -5890,60 +5891,60 @@ " callbacks = list(my_cb),\n", " verbose = 0)" ], - "id": "2f634682-a98e-49a3-b9d4-05ae8b611c49" + "id": "706c14cb-3430-4645-949a-75b388ccfdc1" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "afd07e0b-a817-4ad4-89a6-5b7f9bb41d9a" + "id": "c5ba663e-2082-4351-a82e-5162855d1a9b" }, "outputs": [], "source": [ "plot(my_history)" ], - "id": "afd07e0b-a817-4ad4-89a6-5b7f9bb41d9a" + "id": "c5ba663e-2082-4351-a82e-5162855d1a9b" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "6e94f527-75bb-436e-a3f0-6eda54642189" + "id": "f893fbf4-0e06-469b-8696-3f09ee60c540" }, "outputs": [], "source": [ "my_history" ], - "id": "6e94f527-75bb-436e-a3f0-6eda54642189" + "id": "f893fbf4-0e06-469b-8696-3f09ee60c540" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "2acbe111-03be-4e15-8e8c-d7d423e6aa99" + "id": "a0f9cbd8-bb5e-4b58-b2d3-69860b30a25f" }, "outputs": [], "source": [ "y_ <- my_model %>% predict(X)\n", "mean((y_ - y)^2)**0.5" ], - "id": "2acbe111-03be-4e15-8e8c-d7d423e6aa99" + "id": "a0f9cbd8-bb5e-4b58-b2d3-69860b30a25f" }, { - "id": "2333d0cf", + "id": "2ddf726c", "cell_type": "markdown", "source": [ "## 11.2 Kerasによる分類" ], "metadata": { - "id": "2333d0cf" + "id": "2ddf726c" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "393662b7-c8dc-4943-a9d4-90b8e26da76e" + "id": "0e1532c0-36dd-48f0-995b-e7e44168b796" }, "outputs": [], "source": [ @@ -5951,13 +5952,13 @@ "library(tidyverse)\n", "my_data <- iris[sample(nrow(iris)), ]" ], - "id": "393662b7-c8dc-4943-a9d4-90b8e26da76e" + "id": "0e1532c0-36dd-48f0-995b-e7e44168b796" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4e9c2b59-3646-4a9f-86a9-ccc4d2397852" + "id": "db5cda5a-326a-41bb-bff4-df697d822092" }, "outputs": [], "source": [ @@ -5965,13 +5966,13 @@ " select(-Species) %>% scale\n", "y <- as.integer(my_data$Species) - 1" ], - "id": "4e9c2b59-3646-4a9f-86a9-ccc4d2397852" + "id": "db5cda5a-326a-41bb-bff4-df697d822092" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "24d33fac-5a0d-4c05-a34b-54c4aa7e249a" + "id": "ebdf7309-f0aa-45eb-9cf3-27ced560bc26" }, "outputs": [], "source": [ @@ -5979,13 +5980,13 @@ " layer_dense(units = 3, activation = \"relu\", input_shape = c(4)) %>%\n", " layer_dense(units = 3, activation = \"softmax\")" ], - "id": "24d33fac-5a0d-4c05-a34b-54c4aa7e249a" + "id": "ebdf7309-f0aa-45eb-9cf3-27ced560bc26" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "d7526f7e-0f8b-46c9-9fb5-520f865c9b6f" + "id": "ab622858-6ecc-4389-b1f9-6aceb1d1bf83" }, "outputs": [], "source": [ @@ -5993,13 +5994,13 @@ " optimizer = \"rmsprop\",\n", " metrics = c(\"accuracy\"))" ], - "id": "d7526f7e-0f8b-46c9-9fb5-520f865c9b6f" + "id": "ab622858-6ecc-4389-b1f9-6aceb1d1bf83" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "1c9ef290-b2c0-4c10-b4e4-dd1adaa06622" + "id": "a3b72d4a-17b3-49d1-98c7-cf9c1dc6e360" }, "outputs": [], "source": [ @@ -6018,25 +6019,25 @@ "\n", "plot(my_history)" ], - "id": "1c9ef290-b2c0-4c10-b4e4-dd1adaa06622" + "id": "a3b72d4a-17b3-49d1-98c7-cf9c1dc6e360" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b31d9539-9a0c-4dfa-97e5-f99478e41975" + "id": "a7af21c5-e6c0-4e4c-bd89-27c0b3c142c1" }, "outputs": [], "source": [ "my_history" ], - "id": "b31d9539-9a0c-4dfa-97e5-f99478e41975" + "id": "a7af21c5-e6c0-4e4c-bd89-27c0b3c142c1" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "6e5bf35c-a03b-4113-b996-7e5ee2efe364" + "id": "b8e6f656-2f70-4676-a9e7-ffb461adbccc" }, "outputs": [], "source": [ @@ -6044,13 +6045,13 @@ "y_ <- apply(tmp, 1, which.max) - 1\n", "mean(y_ == y)" ], - "id": "6e5bf35c-a03b-4113-b996-7e5ee2efe364" + "id": "b8e6f656-2f70-4676-a9e7-ffb461adbccc" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "62e43441-193e-4ef7-8fd8-a1062c7e07c3" + "id": "2b895387-7206-4507-b895-6159bd4d2160" }, "outputs": [], "source": [ @@ -6058,13 +6059,13 @@ "\n", "-mean(log(c(0.7, 0.6, 0.2, 0.7)))" ], - "id": "62e43441-193e-4ef7-8fd8-a1062c7e07c3" + "id": "2b895387-7206-4507-b895-6159bd4d2160" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a6ecf4d0-f743-4054-a579-cec66fb3ff2a" + "id": "c8d6f9bd-6386-4562-8c10-1fe706c491b5" }, "outputs": [], "source": [ @@ -6078,36 +6079,36 @@ " c(0.2, 0.5, 0.3),\n", " c(0.2, 0.7, 0.1))" ], - "id": "a6ecf4d0-f743-4054-a579-cec66fb3ff2a" + "id": "c8d6f9bd-6386-4562-8c10-1fe706c491b5" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "ba95630a-e344-4c0e-99e6-93b1c43a11ff" + "id": "e292173c-2379-421f-b07e-f85e776d7f95" }, "outputs": [], "source": [ "c(mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_1))),\n", " mean(as.array(loss_sparse_categorical_crossentropy(y_true = y, y_pred = y_2))))" ], - "id": "ba95630a-e344-4c0e-99e6-93b1c43a11ff" + "id": "e292173c-2379-421f-b07e-f85e776d7f95" }, { - "id": "915a37cc", + "id": "630bfa2d", "cell_type": "markdown", "source": [ "## 11.3 MNIST:手書き数字の分類" ], "metadata": { - "id": "915a37cc" + "id": "630bfa2d" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "89365c73-2d21-4676-991d-89c707434dac" + "id": "6637d327-5399-40c9-abbb-f67a822e9394" }, "outputs": [], "source": [ @@ -6115,87 +6116,87 @@ "library(tidyverse)\n", "keras::`%<-%`(c(c(x_train, y_train), c(x_test, y_test)), dataset_mnist())" ], - "id": "89365c73-2d21-4676-991d-89c707434dac" + "id": "6637d327-5399-40c9-abbb-f67a822e9394" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "90580ebf-863e-40b2-9e72-b37469bd89ed" + "id": "38e2c258-ef74-4b69-906d-e415d4740146" }, "outputs": [], "source": [ "dim(x_train)" ], - "id": "90580ebf-863e-40b2-9e72-b37469bd89ed" + "id": "38e2c258-ef74-4b69-906d-e415d4740146" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "5d5a7661-c0e1-4bef-9f23-91b548aa1864" + "id": "d78e4877-3f31-47da-832c-6a02aa69a4a4" }, "outputs": [], "source": [ "x_train[5, , ]" ], - "id": "5d5a7661-c0e1-4bef-9f23-91b548aa1864" + "id": "d78e4877-3f31-47da-832c-6a02aa69a4a4" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "e8414c1e-95ef-4cab-8ffc-d569abcd6936" + "id": "21c13ef9-0329-48d5-8ade-b402d12f7bfe" }, "outputs": [], "source": [ "plot(as.raster(x = x_train[5, , ],\n", " max = max(x_train)))" ], - "id": "e8414c1e-95ef-4cab-8ffc-d569abcd6936" + "id": "21c13ef9-0329-48d5-8ade-b402d12f7bfe" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "3bb196b5-fe28-4481-96c2-a619aac2d828" + "id": "20f2ab02-9e36-4ea3-b212-9b4d7ee65c42" }, "outputs": [], "source": [ "head(y_train)" ], - "id": "3bb196b5-fe28-4481-96c2-a619aac2d828" + "id": "20f2ab02-9e36-4ea3-b212-9b4d7ee65c42" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "e1f0f829-e67e-496a-86b9-641d0620ae1e" + "id": "9d8baf8b-c43a-4a23-b894-33d7a9850e3a" }, "outputs": [], "source": [ "c(min(x_train), max(x_train))" ], - "id": "e1f0f829-e67e-496a-86b9-641d0620ae1e" + "id": "9d8baf8b-c43a-4a23-b894-33d7a9850e3a" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "eb9aeb9c-45b6-4c8d-9823-54d95b3e76bd" + "id": "971617a3-220d-4f90-89c5-06a9db9845a7" }, "outputs": [], "source": [ "x_train <- x_train / 255\n", "x_test <- x_test / 255" ], - "id": "eb9aeb9c-45b6-4c8d-9823-54d95b3e76bd" + "id": "971617a3-220d-4f90-89c5-06a9db9845a7" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "3ba6e014-db23-490a-8c1c-c26f7a65946d" + "id": "b3f0db09-c310-4148-9007-8bfa7d4f88d9" }, "outputs": [], "source": [ @@ -6203,13 +6204,13 @@ "x_train <- x_train[my_index, , ]\n", "y_train <- y_train[my_index]" ], - "id": "3ba6e014-db23-490a-8c1c-c26f7a65946d" + "id": "b3f0db09-c310-4148-9007-8bfa7d4f88d9" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "e2020774-665b-4eed-a8f2-3bef7283a4c9" + "id": "5d260e35-d03b-4f06-87a2-cd866e0c2062" }, "outputs": [], "source": [ @@ -6227,13 +6228,13 @@ "my_cb <- callback_early_stopping(patience = 5,\n", " restore_best_weights = TRUE)" ], - "id": "e2020774-665b-4eed-a8f2-3bef7283a4c9" + "id": "5d260e35-d03b-4f06-87a2-cd866e0c2062" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "58fa95a2-dada-40e5-8cd9-22713a24f799" + "id": "4513ef65-be2b-4306-b936-d17ac3a2ab1b" }, "outputs": [], "source": [ @@ -6248,13 +6249,13 @@ "\n", "plot(my_history)" ], - "id": "58fa95a2-dada-40e5-8cd9-22713a24f799" + "id": "4513ef65-be2b-4306-b936-d17ac3a2ab1b" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "382cec95-1f90-4633-8281-a853152a844c" + "id": "193c05db-b490-471e-af56-8763deac5b39" }, "outputs": [], "source": [ @@ -6262,61 +6263,61 @@ "y_ <- apply(tmp, 1, which.max) - 1\n", "table(y_, y_test)" ], - "id": "382cec95-1f90-4633-8281-a853152a844c" + "id": "193c05db-b490-471e-af56-8763deac5b39" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "acd856a8-7a4d-41d4-8390-d1053af994ba" + "id": "d3367189-c3b4-422d-80ad-08224443440a" }, "outputs": [], "source": [], - "id": "acd856a8-7a4d-41d4-8390-d1053af994ba" + "id": "d3367189-c3b4-422d-80ad-08224443440a" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "17e70c6f-91bd-4322-8332-bee410c79c3d" + "id": "f16da2a1-68fb-40be-8701-8317d1359221" }, "outputs": [], "source": [ "mean(y_ == y_test)" ], - "id": "17e70c6f-91bd-4322-8332-bee410c79c3d" + "id": "f16da2a1-68fb-40be-8701-8317d1359221" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f5ee2450-ccaf-403c-954a-1bf8040d9447" + "id": "493883d1-7426-4662-adbf-8de53aa9373b" }, "outputs": [], "source": [ "my_model %>%\n", " evaluate(x = x_test, y = y_test)" ], - "id": "f5ee2450-ccaf-403c-954a-1bf8040d9447" + "id": "493883d1-7426-4662-adbf-8de53aa9373b" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "8f9581b2-d328-4a1c-ace0-55e519f1a879" + "id": "40f627cb-dd69-4324-82a5-442001ed1c12" }, "outputs": [], "source": [ "x_train2d <- x_train %>% array_reshape(c(-1, 28, 28, 1))\n", "x_test2d <- x_test %>% array_reshape(c(-1, 28, 28, 1))" ], - "id": "8f9581b2-d328-4a1c-ace0-55e519f1a879" + "id": "40f627cb-dd69-4324-82a5-442001ed1c12" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "084f455b-8a5d-4af1-898b-7dea833e0a59" + "id": "b8989289-9810-4d92-b22e-170e8fd94dcf" }, "outputs": [], "source": [ @@ -6339,13 +6340,13 @@ "my_cb <- callback_early_stopping(patience = 5,\n", " restore_best_weights = TRUE)" ], - "id": "084f455b-8a5d-4af1-898b-7dea833e0a59" + "id": "b8989289-9810-4d92-b22e-170e8fd94dcf" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "552c2e71-34e2-4618-a9bc-ba062b106663" + "id": "92d64806-286c-442d-882b-a6705f3caffa" }, "outputs": [], "source": [ @@ -6360,26 +6361,26 @@ "\n", "plot(my_history)" ], - "id": "552c2e71-34e2-4618-a9bc-ba062b106663" + "id": "92d64806-286c-442d-882b-a6705f3caffa" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "46a08383-b767-4862-83c9-833cf488988f" + "id": "0a2a2ccf-59fa-4eb5-9eb5-dc36e0437421" }, "outputs": [], "source": [ "my_model %>%\n", " evaluate(x = x_test2d, y = y_test)" ], - "id": "46a08383-b767-4862-83c9-833cf488988f" + "id": "0a2a2ccf-59fa-4eb5-9eb5-dc36e0437421" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "fa32dbb7-e82c-4cb5-81d8-749db59765dc" + "id": "caf1f1d8-3dad-4609-82da-956436ee334f" }, "outputs": [], "source": [ @@ -6403,13 +6404,13 @@ "my_cb <- callback_early_stopping(patience = 5,\n", " restore_best_weights = TRUE)" ], - "id": "fa32dbb7-e82c-4cb5-81d8-749db59765dc" + "id": "caf1f1d8-3dad-4609-82da-956436ee334f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "3487e4b5-b6f4-4abb-8f82-664d6d02003e" + "id": "df9e3f56-5212-4c35-8e92-46bf4c106729" }, "outputs": [], "source": [ @@ -6424,26 +6425,26 @@ "\n", "plot(my_history)" ], - "id": "3487e4b5-b6f4-4abb-8f82-664d6d02003e" + "id": "df9e3f56-5212-4c35-8e92-46bf4c106729" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b9b3ea01-b7e8-46a8-985f-4d9a14fdbed1" + "id": "93ce1f11-382f-4757-bbd1-28fc22962c4b" }, "outputs": [], "source": [ "my_model %>%\n", " evaluate(x = x_test2d, y = y_test)" ], - "id": "b9b3ea01-b7e8-46a8-985f-4d9a14fdbed1" + "id": "93ce1f11-382f-4757-bbd1-28fc22962c4b" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f81bff22-1e09-4c1c-b6f1-4d9e2e9aab9d" + "id": "253e56d5-c86e-4c95-9715-33dd84c68fce" }, "outputs": [], "source": [ @@ -6457,25 +6458,25 @@ " filter(y_ != y) %>% # 予測がはずれたものを残す\n", " arrange(desc(y_prob)) # 確率の大きい順に並び替える" ], - "id": "f81bff22-1e09-4c1c-b6f1-4d9e2e9aab9d" + "id": "253e56d5-c86e-4c95-9715-33dd84c68fce" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "91a9d3f7-424c-4570-8b1c-f24c4c48fa9d" + "id": "dbd55cd7-365c-4c08-a7dd-d2c6ca4b5df9" }, "outputs": [], "source": [ "head(my_result)" ], - "id": "91a9d3f7-424c-4570-8b1c-f24c4c48fa9d" + "id": "dbd55cd7-365c-4c08-a7dd-d2c6ca4b5df9" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a82a8152-bb4b-44b4-b7d3-b51e6edfb12d" + "id": "eb900d0d-59cb-4f0f-bfd0-783ae3014e61" }, "outputs": [], "source": [ @@ -6497,23 +6498,23 @@ " theme(legend.position = \"none\") +\n", " facet_grid(. ~ label)" ], - "id": "a82a8152-bb4b-44b4-b7d3-b51e6edfb12d" + "id": "eb900d0d-59cb-4f0f-bfd0-783ae3014e61" }, { - "id": "2f023b95", + "id": "a328c907", "cell_type": "markdown", "source": [ "## 11.4 AutoML" ], "metadata": { - "id": "2f023b95" + "id": "a328c907" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "aa4353c5-b41d-442f-919e-0c035e69f636" + "id": "c08239b8-aa1b-4aea-8ab6-56ea05e3b94f" }, "outputs": [], "source": [ @@ -6525,13 +6526,13 @@ "h2o.no_progress()\n", "# h2o.shutdown(prompt = FALSE) # 停止" ], - "id": "aa4353c5-b41d-442f-919e-0c035e69f636" + "id": "c08239b8-aa1b-4aea-8ab6-56ea05e3b94f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "d78b3057-d48a-469c-b098-6f440fe5bd89" + "id": "e9c9a625-d1af-4f44-8111-14d8f867b289" }, "outputs": [], "source": [ @@ -6542,13 +6543,13 @@ "# あるいは\n", "my_frame <- h2o.importFile(my_url, header = TRUE) # データを読み込む." ], - "id": "d78b3057-d48a-469c-b098-6f440fe5bd89" + "id": "e9c9a625-d1af-4f44-8111-14d8f867b289" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "3ab6a27c-12b2-4673-9307-c7b1f84103e4" + "id": "c4ca3bd2-c490-473c-be16-2836c4ceca7f" }, "outputs": [], "source": [ @@ -6558,13 +6559,13 @@ "my_frame %>% as.data.frame %>% head\n", "# 結果は割愛(見た目は同じ)" ], - "id": "3ab6a27c-12b2-4673-9307-c7b1f84103e4" + "id": "c4ca3bd2-c490-473c-be16-2836c4ceca7f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "ce53c669-040a-4c1f-927b-ccb8c9d371cd" + "id": "c66624cf-e5a4-402e-a515-c9c2d7a0c335" }, "outputs": [], "source": [ @@ -6573,25 +6574,25 @@ " training_frame = my_frame,\n", " max_runtime_secs = 60)" ], - "id": "ce53c669-040a-4c1f-927b-ccb8c9d371cd" + "id": "c66624cf-e5a4-402e-a515-c9c2d7a0c335" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "1ff895ce-febf-48f9-b8fc-75ee0db4c2dd" + "id": "e8300b70-73a9-4a55-aae4-46480fee806e" }, "outputs": [], "source": [ "min(my_model@leaderboard$rmse)" ], - "id": "1ff895ce-febf-48f9-b8fc-75ee0db4c2dd" + "id": "e8300b70-73a9-4a55-aae4-46480fee806e" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "6dd38cb9-8bad-43d7-a1ca-407b12943d0f" + "id": "5ebfd908-fea8-4e8a-8b94-532d228b8845" }, "outputs": [], "source": [ @@ -6603,13 +6604,13 @@ "\n", "plot(y, y_)" ], - "id": "6dd38cb9-8bad-43d7-a1ca-407b12943d0f" + "id": "5ebfd908-fea8-4e8a-8b94-532d228b8845" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "7e67fd8c-ea11-48f1-9415-0f8eb6b9634a" + "id": "e986f8af-bd2f-47ca-8152-73d4f8a1fd7c" }, "outputs": [], "source": [ @@ -6618,13 +6619,13 @@ "x_train <- x_train[my_index, , ]\n", "y_train <- y_train[my_index]" ], - "id": "7e67fd8c-ea11-48f1-9415-0f8eb6b9634a" + "id": "e986f8af-bd2f-47ca-8152-73d4f8a1fd7c" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "e16e7501-a54f-4890-97b1-3aeadc70760f" + "id": "4e96c34c-1c9a-4f6d-bced-85671cda9a25" }, "outputs": [], "source": [ @@ -6639,13 +6640,13 @@ " as.data.frame\n", "my_test <- as.h2o(tmp)" ], - "id": "e16e7501-a54f-4890-97b1-3aeadc70760f" + "id": "4e96c34c-1c9a-4f6d-bced-85671cda9a25" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "d562c8af-31bb-40ff-8e37-88709b624bad" + "id": "64e8a1dd-a777-4d8b-a41e-a383bfffaaf0" }, "outputs": [], "source": [ @@ -6654,26 +6655,26 @@ " training_frame = my_train,\n", " max_runtime_secs = 120)" ], - "id": "d562c8af-31bb-40ff-8e37-88709b624bad" + "id": "64e8a1dd-a777-4d8b-a41e-a383bfffaaf0" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "46ba59f9-503b-45b3-b3d1-c3f1db813c3b" + "id": "ffb36241-1792-48a0-b5f3-a766693a2aa5" }, "outputs": [], "source": [ "min(my_model@leaderboard$\n", " mean_per_class_error)" ], - "id": "46ba59f9-503b-45b3-b3d1-c3f1db813c3b" + "id": "ffb36241-1792-48a0-b5f3-a766693a2aa5" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4893a7d7-94c1-4588-9da4-2d3be69a5261" + "id": "4f9b9d16-279d-4fe2-84d5-2abbe0831e09" }, "outputs": [], "source": [ @@ -6683,23 +6684,23 @@ "\n", "mean(y_ == y_test)" ], - "id": "4893a7d7-94c1-4588-9da4-2d3be69a5261" + "id": "4f9b9d16-279d-4fe2-84d5-2abbe0831e09" }, { - "id": "4a41ef83", + "id": "18a8a207", "cell_type": "markdown", "source": [ "# 12 時系列予測" ], "metadata": { - "id": "4a41ef83" + "id": "18a8a207" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "d76025c7-9db5-4535-950d-165842a1f0be" + "id": "73a30842-7264-45b5-94b4-a04315f0d394" }, "outputs": [], "source": [ @@ -6708,39 +6709,39 @@ " options(Ncpus = parallel::detectCores())\n", " installed_packages <- rownames(installed.packages())\n", " packages_to_install <- c(\"caret\", \"fable\", \"feasts\", \"prophet\", \"tsibble\", \"urca\")\n", - " packages_to_upgrade <- c(\"ggplot2\")\n", - " install.packages(union(setdiff(packages_to_install, installed_packages), packages_to_upgrade))\n", + " install.packages(setdiff(packages_to_install, installed_packages))\n", + " install.packages(c(\"ggplot2\"))\n", "}" ], - "id": "d76025c7-9db5-4535-950d-165842a1f0be" + "id": "73a30842-7264-45b5-94b4-a04315f0d394" }, { - "id": "d491eecf", + "id": "5b61cff2", "cell_type": "markdown", "source": [ "## 12.1 日時と日時の列" ], "metadata": { - "id": "d491eecf" + "id": "5b61cff2" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c236e872-3328-46ff-9006-1210ca69a125" + "id": "a01e6c8f-fd03-45dc-8a43-80fbe7d71ecc" }, "outputs": [], "source": [ "as.POSIXct(\"2021-01-01\")" ], - "id": "c236e872-3328-46ff-9006-1210ca69a125" + "id": "a01e6c8f-fd03-45dc-8a43-80fbe7d71ecc" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "51380e88-5900-45f4-827d-3f3e0667eadb" + "id": "0175b2db-76b4-4c14-b7ab-24096b55d5c2" }, "outputs": [], "source": [ @@ -6755,48 +6756,48 @@ "seq(from = as.POSIXct(\"2021-01-01 00:00:00\"),\n", " to = as.POSIXct(\"2021-01-01 03:00:00\"), by = \"2 hour\")" ], - "id": "51380e88-5900-45f4-827d-3f3e0667eadb" + "id": "0175b2db-76b4-4c14-b7ab-24096b55d5c2" }, { - "id": "135e56c1", + "id": "fc4c60b4", "cell_type": "markdown", "source": [ "## 12.2 時系列データの予測" ], "metadata": { - "id": "135e56c1" + "id": "fc4c60b4" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c1a0744b-b83b-404f-be29-4bcd643e8d42" + "id": "444e6c96-9260-4535-845f-6faf432a01c3" }, "outputs": [], "source": [ "my_data <- as.vector(AirPassengers)" ], - "id": "c1a0744b-b83b-404f-be29-4bcd643e8d42" + "id": "444e6c96-9260-4535-845f-6faf432a01c3" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "0adca80d-38dd-48f3-ab17-f2393de13f6d" + "id": "31da55a3-cf97-4622-99ea-656035209365" }, "outputs": [], "source": [ "n <- length(my_data) # データ数(144)\n", "k <- 108 # 訓練データ数" ], - "id": "0adca80d-38dd-48f3-ab17-f2393de13f6d" + "id": "31da55a3-cf97-4622-99ea-656035209365" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "d87c6500-774f-4f39-a63e-4a55de455d8f" + "id": "bf8ebfc1-31a3-42eb-973e-e368c33e779e" }, "outputs": [], "source": [ @@ -6819,13 +6820,13 @@ "\n", "head(my_df)" ], - "id": "d87c6500-774f-4f39-a63e-4a55de455d8f" + "id": "bf8ebfc1-31a3-42eb-973e-e368c33e779e" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "cb9de935-c701-4c7a-96a1-34a0a55f1cec" + "id": "30e9c5f5-13cd-4e26-a03a-42a933f2b710" }, "outputs": [], "source": [ @@ -6833,13 +6834,13 @@ "my_test <- my_df[-(1:k), ]\n", "y <- my_test$y" ], - "id": "cb9de935-c701-4c7a-96a1-34a0a55f1cec" + "id": "30e9c5f5-13cd-4e26-a03a-42a933f2b710" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "5bc69945-5952-4170-8f10-62adf8a06e36" + "id": "3cd80863-8045-4a26-b8e3-c2b92338e465" }, "outputs": [], "source": [ @@ -6850,13 +6851,13 @@ " geom_line()\n", "my_plot" ], - "id": "5bc69945-5952-4170-8f10-62adf8a06e36" + "id": "3cd80863-8045-4a26-b8e3-c2b92338e465" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "382487f2-d824-4ff8-abb5-ea2958102b91" + "id": "beea8e74-af73-4e2f-9b5b-a2462046e35d" }, "outputs": [], "source": [ @@ -6865,13 +6866,13 @@ "y_ <- my_lm_model %>% predict(my_test)\n", "caret::RMSE(y, y_) # RMSE(テスト)" ], - "id": "382487f2-d824-4ff8-abb5-ea2958102b91" + "id": "beea8e74-af73-4e2f-9b5b-a2462046e35d" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "ec4ef0d1-1bab-4e86-979b-ab257cd2dd97" + "id": "980b4531-5c55-45ed-8c3f-d69810e3c3c7" }, "outputs": [], "source": [ @@ -6880,13 +6881,13 @@ " mutate(y = y_, label = \"model\")\n", "my_plot + geom_line(data = tmp)" ], - "id": "ec4ef0d1-1bab-4e86-979b-ab257cd2dd97" + "id": "980b4531-5c55-45ed-8c3f-d69810e3c3c7" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "d14868cc-5634-4706-a604-ff65a0f9a132" + "id": "08941cc6-cae7-4e09-b652-21e1ffef8148" }, "outputs": [], "source": [ @@ -6894,39 +6895,39 @@ "my_arima_model <- my_train %>% model(ARIMA(y))\n", "my_arima_model" ], - "id": "d14868cc-5634-4706-a604-ff65a0f9a132" + "id": "08941cc6-cae7-4e09-b652-21e1ffef8148" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "c0b4927d-4a9a-4e87-8191-e06f19eb5ad2" + "id": "76ddccf9-f8bb-4c5f-9318-41b93bbf13c1" }, "outputs": [], "source": [ "tmp <- my_arima_model %>% forecast(h = \"3 years\")\n", "head(tmp)" ], - "id": "c0b4927d-4a9a-4e87-8191-e06f19eb5ad2" + "id": "76ddccf9-f8bb-4c5f-9318-41b93bbf13c1" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "d398a371-d07b-4cb9-b861-e7b7f205ff70" + "id": "f6afa0a6-0d0a-4f57-991e-2bb088e45d23" }, "outputs": [], "source": [ "y_ <- tmp$.mean\n", "caret::RMSE(y_, y)" ], - "id": "d398a371-d07b-4cb9-b861-e7b7f205ff70" + "id": "f6afa0a6-0d0a-4f57-991e-2bb088e45d23" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "181dff7e-4641-431f-95c0-633bf3f64948" + "id": "9a080c39-e319-4fe0-9bea-79db3b79bd3b" }, "outputs": [], "source": [ @@ -6939,13 +6940,13 @@ " y = y,\n", " color = label))" ], - "id": "181dff7e-4641-431f-95c0-633bf3f64948" + "id": "9a080c39-e319-4fe0-9bea-79db3b79bd3b" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "b32d3fde-4090-4ba5-aa1b-a00a197ce46f" + "id": "229ed834-2c5a-4496-bc1a-4971d9af500f" }, "outputs": [], "source": [ @@ -6953,39 +6954,39 @@ "my_prophet_model <- my_train %>%\n", " prophet(seasonality.mode = \"multiplicative\")" ], - "id": "b32d3fde-4090-4ba5-aa1b-a00a197ce46f" + "id": "229ed834-2c5a-4496-bc1a-4971d9af500f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "48b715b1-26f0-406a-a97c-6c6d1b2481b4" + "id": "556b75ff-3e3d-42d7-9ef1-fa99b20b8b4f" }, "outputs": [], "source": [ "tmp <- my_prophet_model %>% predict(my_test)\n", "head(tmp[, c(\"ds\", \"yhat\", \"yhat_lower\", \"yhat_upper\")])" ], - "id": "48b715b1-26f0-406a-a97c-6c6d1b2481b4" + "id": "556b75ff-3e3d-42d7-9ef1-fa99b20b8b4f" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "cda6e808-b015-488d-a3bf-d8b55d8d4915" + "id": "3131f9d0-2762-4166-91cb-ad0be4037a70" }, "outputs": [], "source": [ "y_ <- tmp$yhat\n", "caret::RMSE(y_, y)" ], - "id": "cda6e808-b015-488d-a3bf-d8b55d8d4915" + "id": "3131f9d0-2762-4166-91cb-ad0be4037a70" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "210aa431-a55a-42ae-9fb0-46d84eca30c2" + "id": "04faa3ac-28a2-43b3-9d31-0e2e47f8b7a7" }, "outputs": [], "source": [ @@ -6995,23 +6996,23 @@ " geom_line(data = my_train, aes(x = as.POSIXct(ds))) +\n", " geom_line(data = my_test, aes(x = as.POSIXct(ds)), color = \"red\")" ], - "id": "210aa431-a55a-42ae-9fb0-46d84eca30c2" + "id": "04faa3ac-28a2-43b3-9d31-0e2e47f8b7a7" }, { - "id": "25da6ce2", + "id": "7a846408", "cell_type": "markdown", "source": [ "# 13 教師なし学習" ], "metadata": { - "id": "25da6ce2" + "id": "7a846408" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "4c3a4a1d-72f7-433c-accd-cb1c328e6e78" + "id": "2494be34-b0aa-4e86-beac-41d84bb72223" }, "outputs": [], "source": [ @@ -7023,23 +7024,23 @@ " install.packages(setdiff(packages_to_install, installed_packages))\n", "}" ], - "id": "4c3a4a1d-72f7-433c-accd-cb1c328e6e78" + "id": "2494be34-b0aa-4e86-beac-41d84bb72223" }, { - "id": "42040090", + "id": "2f39894b", "cell_type": "markdown", "source": [ "## 13.1 主成分分析" ], "metadata": { - "id": "42040090" + "id": "2f39894b" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "bace0761-27d6-4d69-964a-1fe62b343c0c" + "id": "2f174b44-c177-4804-a2bb-eed1a8e05dea" }, "outputs": [], "source": [ @@ -7054,25 +7055,25 @@ " row.names = c(\"A\", \"B\", \"C\", \"D\", \"E\", \"F\"))\n", "my_result <- my_data %>% prcomp # 主成分分析の実行" ], - "id": "bace0761-27d6-4d69-964a-1fe62b343c0c" + "id": "2f174b44-c177-4804-a2bb-eed1a8e05dea" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f25443b1-a7ce-425e-961c-7436e6119f06" + "id": "0bf6be67-e3b1-4582-a087-001330c1f6b3" }, "outputs": [], "source": [ "my_result$x # 主成分スコア" ], - "id": "f25443b1-a7ce-425e-961c-7436e6119f06" + "id": "0bf6be67-e3b1-4582-a087-001330c1f6b3" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "dc52c296-eb05-4672-99f3-597735dc21eb" + "id": "981e56ac-f21c-4deb-b8f4-04534a309f01" }, "outputs": [], "source": [ @@ -7080,37 +7081,37 @@ " labels = row.names(my_data),\n", " scale = 0)" ], - "id": "dc52c296-eb05-4672-99f3-597735dc21eb" + "id": "981e56ac-f21c-4deb-b8f4-04534a309f01" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "9a529296-1f80-4442-9786-4a84de81071f" + "id": "5ff87676-1ff4-42d5-8567-7073e29752d4" }, "outputs": [], "source": [ "my_result$rotation %>% t" ], - "id": "9a529296-1f80-4442-9786-4a84de81071f" + "id": "5ff87676-1ff4-42d5-8567-7073e29752d4" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "9e3dde31-371d-4b5a-a4a7-605330bd7973" + "id": "96f147a1-77f8-4993-aa9f-4209f6d7fcd5" }, "outputs": [], "source": [ "summary(my_result)" ], - "id": "9e3dde31-371d-4b5a-a4a7-605330bd7973" + "id": "96f147a1-77f8-4993-aa9f-4209f6d7fcd5" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "8fd66f28-cc72-4b56-9185-26302560771f" + "id": "23310865-d302-45c5-ab73-4c80a979e762" }, "outputs": [], "source": [ @@ -7123,13 +7124,13 @@ "\n", "my_result$x # 主成分スコア" ], - "id": "8fd66f28-cc72-4b56-9185-26302560771f" + "id": "23310865-d302-45c5-ab73-4c80a979e762" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "5500f230-e2c0-402e-814f-85cc07c1c15c" + "id": "aebe9ee6-7f32-4766-98d1-b281595eb6e5" }, "outputs": [], "source": [ @@ -7143,13 +7144,13 @@ "Z %*% tmp$vectors # 主成分スコア(結果は割愛)\n", "cumsum(tmp$values) / sum(tmp$values) # 累積寄与率" ], - "id": "5500f230-e2c0-402e-814f-85cc07c1c15c" + "id": "aebe9ee6-7f32-4766-98d1-b281595eb6e5" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "a2dd9166-958f-42a2-b314-6e75487901d2" + "id": "72e302b5-2f34-48be-b825-00bc53875986" }, "outputs": [], "source": [ @@ -7168,23 +7169,23 @@ "e <- d^2 / (n - 1) # 分散共分散行列の固有値\n", "cumsum(e) / sum(e) # 累積寄与率" ], - "id": "a2dd9166-958f-42a2-b314-6e75487901d2" + "id": "72e302b5-2f34-48be-b825-00bc53875986" }, { - "id": "738c4a6c", + "id": "8c6bbece", "cell_type": "markdown", "source": [ "## 13.2 クラスタ分析" ], "metadata": { - "id": "738c4a6c" + "id": "8c6bbece" } }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "3009e1d9-2bb9-47f2-9dda-12e00fae4695" + "id": "99430d8e-7cb2-4a48-bbd1-b2a5e40750ba" }, "outputs": [], "source": [ @@ -7199,13 +7200,13 @@ " dist(\"euclidian\") %>% # distだけでも可\n", " hclust(\"complete\") # hclustだけでも可" ], - "id": "3009e1d9-2bb9-47f2-9dda-12e00fae4695" + "id": "99430d8e-7cb2-4a48-bbd1-b2a5e40750ba" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "faba169d-9c06-4dd8-be64-0d25fd7c1c15" + "id": "78b7b092-5421-48ef-9963-17a2531673e8" }, "outputs": [], "source": [ @@ -7213,13 +7214,13 @@ " k = 3, # クラスタ数\n", " rect = TRUE, rect_fill = TRUE)" ], - "id": "faba169d-9c06-4dd8-be64-0d25fd7c1c15" + "id": "78b7b092-5421-48ef-9963-17a2531673e8" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "aa3a52e2-d6be-4bb0-b59d-411d1ec2018b" + "id": "bf366906-c76b-408c-9bc4-c354fdbfa615" }, "outputs": [], "source": [ @@ -7228,25 +7229,25 @@ " rect = TRUE, rect_fill = TRUE,\n", " type = \"phylogenic\")" ], - "id": "aa3a52e2-d6be-4bb0-b59d-411d1ec2018b" + "id": "bf366906-c76b-408c-9bc4-c354fdbfa615" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "10df7ddd-bf5f-4558-a7ae-810782332505" + "id": "0ac49fc4-75e5-4f83-bc66-5f8d8a8ed730" }, "outputs": [], "source": [ "my_result %>% cutree(3)" ], - "id": "10df7ddd-bf5f-4558-a7ae-810782332505" + "id": "0ac49fc4-75e5-4f83-bc66-5f8d8a8ed730" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "81ece475-e824-4402-a391-4628e9f1b54a" + "id": "c272196f-e18f-4ff6-a589-481e33640570" }, "outputs": [], "source": [ @@ -7265,13 +7266,13 @@ " gplots::heatmap.2(cexRow = 1, cexCol = 1), # ラベルのサイズを指定して描画する.\n", " silent = TRUE)" ], - "id": "81ece475-e824-4402-a391-4628e9f1b54a" + "id": "c272196f-e18f-4ff6-a589-481e33640570" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "92c15122-a56f-4337-ab2d-3bb39d689a74" + "id": "e0aa0c5c-07cc-404e-86fc-8cd506cee290" }, "outputs": [], "source": [ @@ -7284,25 +7285,25 @@ "\n", "my_result <- my_data %>% kmeans(3)" ], - "id": "92c15122-a56f-4337-ab2d-3bb39d689a74" + "id": "e0aa0c5c-07cc-404e-86fc-8cd506cee290" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "3971a1da-150d-4412-9fa2-5e813999f2f3" + "id": "78ffb86b-446a-409c-9914-6cf57ae37980" }, "outputs": [], "source": [ "my_result$cluster" ], - "id": "3971a1da-150d-4412-9fa2-5e813999f2f3" + "id": "78ffb86b-446a-409c-9914-6cf57ae37980" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "682a3fde-0fb7-499b-8576-82fc0c850f43" + "id": "59366ea4-6ab2-448e-be3e-fb32e4f0fa07" }, "outputs": [], "source": [ @@ -7318,25 +7319,25 @@ "})\n", "gridExtra::grid.arrange(f[[1]], f[[2]], f[[3]], f[[4]], ncol = 2)" ], - "id": "682a3fde-0fb7-499b-8576-82fc0c850f43" + "id": "59366ea4-6ab2-448e-be3e-fb32e4f0fa07" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "f4c98574-d531-4a77-b396-05d84edfc9bf" + "id": "edd71658-0a7f-43b4-82b2-1924dc79f23b" }, "outputs": [], "source": [ "fviz_nbclust(my_data, kmeans, method = \"wss\")" ], - "id": "f4c98574-d531-4a77-b396-05d84edfc9bf" + "id": "edd71658-0a7f-43b4-82b2-1924dc79f23b" }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "263b99e2-cd79-4962-a698-fd2a5823de76" + "id": "ce3d65af-a8ff-41c2-bfaf-0f23a6f639e6" }, "outputs": [], "source": [ @@ -7356,7 +7357,7 @@ " geom_point(shape = iris$Species) + # 形で品種を表現する.\n", " theme(legend.position = \"none\")" ], - "id": "263b99e2-cd79-4962-a698-fd2a5823de76" + "id": "ce3d65af-a8ff-41c2-bfaf-0f23a6f639e6" } ], "nbformat": 4, diff --git a/docker/jupyter.sh b/docker/jupyter.sh index 521c3ab..58d67f6 100644 --- a/docker/jupyter.sh +++ b/docker/jupyter.sh @@ -3,6 +3,7 @@ docker run \ -d \ -p 8888:8888 \ -v "$(pwd):/home/jovyan/work" \ +--platform linux/x86_64 \ --name jr \ taroyabuki/jupyter \ start-notebook.sh \ diff --git a/docker/rstudio-gpu.sh b/docker/rstudio-gpu.sh deleted file mode 100644 index 7c2d594..0000000 --- a/docker/rstudio-gpu.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -docker run \ ---gpus all \ --d \ --e PASSWORD=password \ --e ROOT=TRUE \ --p 8787:8787 \ --v "$(pwd):/home/rstudio/work" \ ---name rs \ -taroyabuki/rstudio-gpu diff --git a/docker/rstudio-gpu/Dockerfile b/docker/rstudio-gpu/Dockerfile deleted file mode 100644 index fe6208a..0000000 --- a/docker/rstudio-gpu/Dockerfile +++ /dev/null @@ -1,80 +0,0 @@ -FROM rocker/ml - -USER root - -RUN rm /etc/dpkg/dpkg.cfg.d/excludes \ - && sed -i -e 's%http://[^ ]\+%mirror://mirrors.ubuntu.com/mirrors.txt%g' /etc/apt/sources.list \ - && wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin \ - && mv cuda-wsl-ubuntu.pin /etc/apt/preferences.d/cuda-repository-pin-600 \ - && apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/7fa2af80.pub \ - && add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/ /" \ - && apt-get update \ - && apt-get install -y --no-install-recommends \ - cuda \ - curl \ - default-jdk \ - dnsutils \ - iputils-ping \ - less \ - libcudnn8 \ - libglpk-dev \ - libnode64 \ - libtbb2 \ - libxt6 \ - net-tools \ - vim-tiny \ - && apt-get --reinstall install -y man-db coreutils manpages \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* \ - && yes | unminimize - -RUN Rscript -e ' \ - options(Ncpus = 32); \ - options(repos = "https://cran.ism.ac.jp"); \ - install.packages("keras"); \ - keras::install_keras(tensorflow = "gpu");' - -USER rstudio - -RUN Rscript -e ' \ - options(Ncpus = 32); \ - options(repos = "https://cran.ism.ac.jp"); \ - Sys.setenv(DOWNLOAD_STATIC_LIBV8=1); \ - install.packages(c( \ - "caret", \ - "doParallel", \ - "e1071", \ - "epitools", \ - "exactci", \ - "fable", \ - "factoextra", \ - "feasts", \ - "forecast", \ - "furrr", \ - "ggfortify", \ - "ggrepel", \ - "ggmosaic", \ - "glmnetUtils", \ - "gplots", \ - "gridExtra", \ - "h2o", \ - "igraph", \ - "lintr", \ - "MLmetrics", \ - "neuralnet", \ - "pastecs", \ - "prophet", \ - "PRROC", \ - "pryr", \ - "psych", \ - "randomForest", \ - "rpart.plot", \ - "tsibble", \ - "vcd" \ - )); \ - remotes::install_version("xgboost", version = "1.4.1.1"); \ - remotes::install_github(c("vqv/ggbiplot"));' - -WORKDIR /home/rstudio - -USER root diff --git a/docker/rstudio-gpu/README.md b/docker/rstudio-gpu/README.md deleted file mode 100644 index f1f7b9f..0000000 --- a/docker/rstudio-gpu/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# RStudio用のコンテナ(NVIDIAのGPU) - -- Docker Hub: https://hub.docker.com/r/taroyabuki/rstudio-gpu -- 起動方法(3種類) - - [rstudio-gpu.sh](../rstudio-gpu.sh)を実行する. - - `wget https://raw.githubusercontent.com/taroyabuki/rp/master/docker/rstudio-gpu.sh`の後で,`sh rstudio-gpu.sh` - - `git clone https://github.com/taroyabuki/fromzero.git`の後で,`sh fromzero/docker/rstudio-gpu.sh` -- RStudio Serverへのアクセス:http://localhost:8787 -- Windows 10で使うための準備 - 1. https://www.microsoft.com/ja-jp/software-download/windows10 でWindowsを最新にする. - 1. https://developer.nvidia.com/cuda/wsl からCUDA Driverをダウンロード,インストールする. - 1. `docker run --rm --gpus all nvcr.io/nvidia/k8s/cuda-sample:nbody nbody -gpu -benchmark`(GPUの動作確認) diff --git a/docker/rstudio-mac.sh b/docker/rstudio-mac.sh deleted file mode 100644 index 83a7928..0000000 --- a/docker/rstudio-mac.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -docker run \ --d \ --e PASSWORD=password \ --e ROOT=TRUE \ --p 8787:8787 \ --v "$(pwd):/home/rstudio/work" \ ---name rs \ -taroyabuki/rstudio-mac diff --git a/docker/rstudio-mac/Dockerfile b/docker/rstudio-mac/Dockerfile deleted file mode 100644 index 2f0fc6e..0000000 --- a/docker/rstudio-mac/Dockerfile +++ /dev/null @@ -1,60 +0,0 @@ -FROM amoselb/rstudio-m1 - -USER root - -RUN rm /etc/dpkg/dpkg.cfg.d/excludes \ - && apt-get update \ - && apt-get install -y --no-install-recommends \ - curl \ - dnsutils \ - iputils-ping \ - less \ - libgit2-dev \ - libglpk-dev \ - libnode64 \ - libtbb2 \ - net-tools \ - vim-tiny \ - && apt-get --reinstall install -y man-db coreutils manpages \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -RUN Rscript -e ' \ - options(Ncpus = 8); \ - options(repos = "https://cran.ism.ac.jp"); \ - install.packages(c("https://cran.r-project.org/bin/macosx/big-sur-arm64/contrib/4.1/RcppEigen_0.3.3.9.1.tgz"), repos = NULL); \ - install.packages(c( \ - "caret", \ - "doParallel", \ - "epitools", \ - "exactci", \ - "factoextra", \ - "fable", \ - "feasts", \ - "furrr", \ - "ggfortify", \ - "ggmosaic", \ - "glmnetUtils", \ - "gplots", \ - "igraph", \ - "keras", \ - "leaps", \ - "neuralnet", \ - "pastecs", \ - "prophet", \ - "proxy", \ - "PRROC", \ - "psych", \ - "Rcpp", \ - "randomForest", \ - "remotes", \ - "reticulate", \ - "rpart.plot", \ - "tsibble", \ - "urca", \ - "vcd" \ - )); \ - remotes::install_version("xgboost", version = "1.4.1.1"); \ - remotes::install_github(c("vqv/ggbiplot"));' - -WORKDIR /home/rstudio diff --git a/docker/rstudio-mac/README.md b/docker/rstudio-mac/README.md deleted file mode 100644 index a4b062e..0000000 --- a/docker/rstudio-mac/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# RStudio用のコンテナ(Apple Chip) - -- Docker Hub: https://hub.docker.com/r/taroyabuki/rstudio-mac -- 起動方法(3種類) - - [rstudio-mac.sh](../rstudio-mac.sh)を実行する. - - `wget https://raw.githubusercontent.com/taroyabuki/rp/master/docker/rstudio-mac.sh`の後で,`sh rstudio-mac.sh` - - `git clone https://github.com/taroyabuki/fromzero.git`の後で,`sh fromzero/docker/rstudio-mac.sh` -- RStudio Serverへのアクセス:http://localhost:8787 -- 11章のコードは実行できません.11章を読む際には,Google Colabを使ってください([R](../code/R-notebook)・[Python](../code/Python-notebook)). diff --git a/docker/rstudio.sh b/docker/rstudio.sh index 7732cb7..af9c8f2 100644 --- a/docker/rstudio.sh +++ b/docker/rstudio.sh @@ -5,5 +5,6 @@ docker run \ -e ROOT=TRUE \ -p 8787:8787 \ -v "$(pwd):/home/rstudio/work" \ +--platform linux/x86_64 \ --name rs \ taroyabuki/rstudio