├── README.md ├── cover_fifa_22.jpg ├── fifa.ipynb └── players_22.csv /README.md: -------------------------------------------------------------------------------- 1 | # K-Means Clustering 2 | 3 | # ![fifa2022](https://i0.wp.com/gnova.com.ar/wp-content/uploads/2021/10/ea-fifa-22-cover-kylian-mbappe_1qeaco87s803l13iu0tnr84jhq.jpg) 4 | 5 | 6 | Building a K-means clustering algorithm from scratch and using it to cluster the FIFA22 data. 7 | 8 | Clustering is an unsupervised machine learning technique that can find patterns in your data. K-means is one of the most popular forms of clustering. 9 | 10 | We'll create our algorithm using python and pandas. We'll then compare it to the reference implementation from scikit-learn. 11 | 12 | Project Steps 13 | 14 | * Write out pseudocode for the algorithm 15 | * Code the k-means algorithm 16 | * Plot the clusters from the algorithm 17 | * Compare performance to the scikit-learn algorithm 18 | 19 | # K-means overview 20 | 21 | K-means is an unsupervised machine learning technique that allow us to cluster data points. This enables us to find patterns in the data that can help us analyze it more effectively. K-means is an iterative algorithm, which means that it will converge to the optimal clustering over time. 22 | 23 | To run a k-means clustering: 24 | 25 | * Specify the number of clusters you want (usually referred to as `k`). 26 | * Randomly initialize the centroid for each cluster. The centroid is the data point that is in the center of the cluster. 27 | * Determine which data points belong to which cluster by finding the closest `centroid` to each data point. 28 | * Update the centroids based on the geometric mean of all the data points in the cluster. 29 | * Run 3 and 4 until the `centroids` stop changing. Each run is referred to as an iteration. 30 | 31 | # Code 32 | 33 | You can find the code for this project [here](https://github.com/taureanjoe/kmeans-clustering). 34 | 35 | ## Data 36 | 37 | We'll be using data from FIFA, which you can download [here](https://www.kaggle.com/datasets/stefanoleone992/fifa-22-complete-player-dataset?select=players_22.csv). We'll use the file `players_22.csv`. 38 | -------------------------------------------------------------------------------- /cover_fifa_22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taureanjoe/kmeans-clustering/6317826da46702012622970ee99312d9da507125/cover_fifa_22.jpg -------------------------------------------------------------------------------- /fifa.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "We are going to cluster the FIFA data dataset using our own K-means clustering algorithm.\n", 8 | "\n", 9 | "# ![fifa2022](cover_fifa_22.jpg)\n", 10 | "\n", 11 | "The datasets provided include the players data for the Career Mode from FIFA 15 to FIFA 22 (\"players_22.csv\"). The data allows multiple comparisons for the same players across the last 8 version of the videogame.\n", 12 | "\n", 13 | "### Content\n", 14 | "\n", 15 | "* Every player available in FIFA 15, 16, 17, 18, 19, 20, 21, and also FIFA 22\n", 16 | "* 100+ attributes\n", 17 | "* URL of the scraped players\n", 18 | "* URL of the uploaded player faces, club and nation logos\n", 19 | "* Player positions, with the role in the club and in the national team\n", 20 | "* Player attributes with statistics as Attacking, Skills, Defense, Mentality, GK Skills, etc.\n", 21 | "* Player personal data like Nationality, Club, DateOfBirth, Wage, Salary, etc.\n", 22 | "\n", 23 | "Data has been scraped from the publicly available website [sofifa.com](https://sofifa.com/)." 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 2, 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "import pandas as pd\n", 33 | "import numpy as np" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 18, 39 | "metadata": {}, 40 | "outputs": [ 41 | { 42 | "name": "stderr", 43 | "output_type": "stream", 44 | "text": [ 45 | "/var/folders/tm/5w0c8x0d2rzck8tf0hvstwf40000gn/T/ipykernel_5324/2061566770.py:1: DtypeWarning: Columns (25,108) have mixed types. Specify dtype option on import or set low_memory=False.\n", 46 | " players = pd.read_csv(\"players_22.csv\")\n" 47 | ] 48 | } 49 | ], 50 | "source": [ 51 | "players = pd.read_csv(\"players_22.csv\")" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": 19, 57 | "metadata": {}, 58 | "outputs": [ 59 | { 60 | "data": { 61 | "text/html": [ 62 | "
\n", 63 | "\n", 76 | "\n", 77 | " \n", 78 | " \n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | " \n", 178 | " \n", 179 | " \n", 180 | " \n", 181 | " \n", 182 | " \n", 183 | " \n", 184 | " \n", 185 | " \n", 186 | " \n", 187 | " \n", 188 | " \n", 189 | " \n", 190 | " \n", 191 | " \n", 192 | " \n", 193 | " \n", 194 | " \n", 195 | " \n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | " \n", 202 | " \n", 203 | " \n", 204 | " \n", 205 | " \n", 206 | " \n", 207 | " \n", 208 | " \n", 209 | " \n", 210 | " \n", 211 | " \n", 212 | " \n", 213 | " \n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | " \n", 266 | " \n", 267 | " \n", 268 | " \n", 269 | " \n", 270 | " \n", 271 | " \n", 272 | " \n", 273 | " \n", 274 | " \n", 275 | " \n", 276 | " \n", 277 | " \n", 278 | " \n", 279 | " \n", 280 | " \n", 281 | " \n", 282 | " \n", 283 | " \n", 284 | " \n", 285 | " \n", 286 | " \n", 287 | " \n", 288 | " \n", 289 | " \n", 290 | " \n", 291 | " \n", 292 | " \n", 293 | " \n", 294 | " \n", 295 | " \n", 296 | " \n", 297 | " \n", 298 | " \n", 299 | " \n", 300 | " \n", 301 | " \n", 302 | " \n", 303 | " \n", 304 | " \n", 305 | " \n", 306 | " \n", 307 | " \n", 308 | " \n", 309 | " \n", 310 | " \n", 311 | " \n", 312 | " \n", 313 | " \n", 314 | " \n", 315 | " \n", 316 | " \n", 317 | " \n", 318 | " \n", 319 | " \n", 320 | " \n", 321 | " \n", 322 | " \n", 323 | " \n", 324 | " \n", 325 | " \n", 326 | " \n", 327 | " \n", 328 | " \n", 329 | " \n", 330 | " \n", 331 | " \n", 332 | " \n", 333 | " \n", 334 | " \n", 335 | " \n", 336 | " \n", 337 | " \n", 338 | " \n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | "
sofifa_idplayer_urlshort_namelong_nameplayer_positionsoverallpotentialvalue_eurwage_eurage...lcbcbrcbrbgkplayer_face_urlclub_logo_urlclub_flag_urlnation_logo_urlnation_flag_url
0158023https://sofifa.com/player/158023/lionel-messi/...L. MessiLionel Andrés Messi CuccittiniRW, ST, CF939378000000.0320000.034...50+350+350+361+319+3https://cdn.sofifa.net/players/158/023/22_120.pnghttps://cdn.sofifa.net/teams/73/60.pnghttps://cdn.sofifa.net/flags/fr.pnghttps://cdn.sofifa.net/teams/1369/60.pnghttps://cdn.sofifa.net/flags/ar.png
1188545https://sofifa.com/player/188545/robert-lewand...R. LewandowskiRobert LewandowskiST9292119500000.0270000.032...60+360+360+361+319+3https://cdn.sofifa.net/players/188/545/22_120.pnghttps://cdn.sofifa.net/teams/21/60.pnghttps://cdn.sofifa.net/flags/de.pnghttps://cdn.sofifa.net/teams/1353/60.pnghttps://cdn.sofifa.net/flags/pl.png
220801https://sofifa.com/player/20801/c-ronaldo-dos-...Cristiano RonaldoCristiano Ronaldo dos Santos AveiroST, LW919145000000.0270000.036...53+353+353+360+320+3https://cdn.sofifa.net/players/020/801/22_120.pnghttps://cdn.sofifa.net/teams/11/60.pnghttps://cdn.sofifa.net/flags/gb-eng.pnghttps://cdn.sofifa.net/teams/1354/60.pnghttps://cdn.sofifa.net/flags/pt.png
3190871https://sofifa.com/player/190871/neymar-da-sil...Neymar JrNeymar da Silva Santos JúniorLW, CAM9191129000000.0270000.029...50+350+350+362+320+3https://cdn.sofifa.net/players/190/871/22_120.pnghttps://cdn.sofifa.net/teams/73/60.pnghttps://cdn.sofifa.net/flags/fr.pngNaNhttps://cdn.sofifa.net/flags/br.png
4192985https://sofifa.com/player/192985/kevin-de-bruy...K. De BruyneKevin De BruyneCM, CAM9191125500000.0350000.030...69+369+369+375+321+3https://cdn.sofifa.net/players/192/985/22_120.pnghttps://cdn.sofifa.net/teams/10/60.pnghttps://cdn.sofifa.net/flags/gb-eng.pnghttps://cdn.sofifa.net/teams/1325/60.pnghttps://cdn.sofifa.net/flags/be.png
..................................................................
19234261962https://sofifa.com/player/261962/defu-song/220002Song Defu宋德福CDM475270000.01000.022...46+246+246+248+215+2https://cdn.sofifa.net/players/261/962/22_120.pnghttps://cdn.sofifa.net/teams/112541/60.pnghttps://cdn.sofifa.net/flags/cn.pngNaNhttps://cdn.sofifa.net/flags/cn.png
19235262040https://sofifa.com/player/262040/caoimhin-port...C. PorterCaoimhin PorterCM4759110000.0500.019...44+244+244+248+214+2https://cdn.sofifa.net/players/262/040/22_120.pnghttps://cdn.sofifa.net/teams/445/60.pnghttps://cdn.sofifa.net/flags/ie.pngNaNhttps://cdn.sofifa.net/flags/ie.png
19236262760https://sofifa.com/player/262760/nathan-logue/...N. LogueNathan Logue-CunninghamCM4755100000.0500.021...45+245+245+247+212+2https://cdn.sofifa.net/players/262/760/22_120.pnghttps://cdn.sofifa.net/teams/111131/60.pnghttps://cdn.sofifa.net/flags/ie.pngNaNhttps://cdn.sofifa.net/flags/ie.png
19237262820https://sofifa.com/player/262820/luke-rudden/2...L. RuddenLuke RuddenST4760110000.0500.019...26+226+226+232+215+2https://cdn.sofifa.net/players/262/820/22_120.pnghttps://cdn.sofifa.net/teams/111131/60.pnghttps://cdn.sofifa.net/flags/ie.pngNaNhttps://cdn.sofifa.net/flags/ie.png
19238264540https://sofifa.com/player/264540/emanuel-lalch...E. LalchhanchhuahaEmanuel LalchhanchhuahaCAM4760110000.0500.019...41+241+241+245+216+2https://cdn.sofifa.net/players/264/540/22_120.pnghttps://cdn.sofifa.net/teams/113040/60.pnghttps://cdn.sofifa.net/flags/in.pngNaNhttps://cdn.sofifa.net/flags/in.png
\n", 370 | "

19239 rows × 110 columns

\n", 371 | "
" 372 | ], 373 | "text/plain": [ 374 | " sofifa_id player_url \\\n", 375 | "0 158023 https://sofifa.com/player/158023/lionel-messi/... \n", 376 | "1 188545 https://sofifa.com/player/188545/robert-lewand... \n", 377 | "2 20801 https://sofifa.com/player/20801/c-ronaldo-dos-... \n", 378 | "3 190871 https://sofifa.com/player/190871/neymar-da-sil... \n", 379 | "4 192985 https://sofifa.com/player/192985/kevin-de-bruy... \n", 380 | "... ... ... \n", 381 | "19234 261962 https://sofifa.com/player/261962/defu-song/220002 \n", 382 | "19235 262040 https://sofifa.com/player/262040/caoimhin-port... \n", 383 | "19236 262760 https://sofifa.com/player/262760/nathan-logue/... \n", 384 | "19237 262820 https://sofifa.com/player/262820/luke-rudden/2... \n", 385 | "19238 264540 https://sofifa.com/player/264540/emanuel-lalch... \n", 386 | "\n", 387 | " short_name long_name \\\n", 388 | "0 L. Messi Lionel Andrés Messi Cuccittini \n", 389 | "1 R. Lewandowski Robert Lewandowski \n", 390 | "2 Cristiano Ronaldo Cristiano Ronaldo dos Santos Aveiro \n", 391 | "3 Neymar Jr Neymar da Silva Santos Júnior \n", 392 | "4 K. De Bruyne Kevin De Bruyne \n", 393 | "... ... ... \n", 394 | "19234 Song Defu 宋德福 \n", 395 | "19235 C. Porter Caoimhin Porter \n", 396 | "19236 N. Logue Nathan Logue-Cunningham \n", 397 | "19237 L. Rudden Luke Rudden \n", 398 | "19238 E. Lalchhanchhuaha Emanuel Lalchhanchhuaha \n", 399 | "\n", 400 | " player_positions overall potential value_eur wage_eur age ... \\\n", 401 | "0 RW, ST, CF 93 93 78000000.0 320000.0 34 ... \n", 402 | "1 ST 92 92 119500000.0 270000.0 32 ... \n", 403 | "2 ST, LW 91 91 45000000.0 270000.0 36 ... \n", 404 | "3 LW, CAM 91 91 129000000.0 270000.0 29 ... \n", 405 | "4 CM, CAM 91 91 125500000.0 350000.0 30 ... \n", 406 | "... ... ... ... ... ... ... ... \n", 407 | "19234 CDM 47 52 70000.0 1000.0 22 ... \n", 408 | "19235 CM 47 59 110000.0 500.0 19 ... \n", 409 | "19236 CM 47 55 100000.0 500.0 21 ... \n", 410 | "19237 ST 47 60 110000.0 500.0 19 ... \n", 411 | "19238 CAM 47 60 110000.0 500.0 19 ... \n", 412 | "\n", 413 | " lcb cb rcb rb gk \\\n", 414 | "0 50+3 50+3 50+3 61+3 19+3 \n", 415 | "1 60+3 60+3 60+3 61+3 19+3 \n", 416 | "2 53+3 53+3 53+3 60+3 20+3 \n", 417 | "3 50+3 50+3 50+3 62+3 20+3 \n", 418 | "4 69+3 69+3 69+3 75+3 21+3 \n", 419 | "... ... ... ... ... ... \n", 420 | "19234 46+2 46+2 46+2 48+2 15+2 \n", 421 | "19235 44+2 44+2 44+2 48+2 14+2 \n", 422 | "19236 45+2 45+2 45+2 47+2 12+2 \n", 423 | "19237 26+2 26+2 26+2 32+2 15+2 \n", 424 | "19238 41+2 41+2 41+2 45+2 16+2 \n", 425 | "\n", 426 | " player_face_url \\\n", 427 | "0 https://cdn.sofifa.net/players/158/023/22_120.png \n", 428 | "1 https://cdn.sofifa.net/players/188/545/22_120.png \n", 429 | "2 https://cdn.sofifa.net/players/020/801/22_120.png \n", 430 | "3 https://cdn.sofifa.net/players/190/871/22_120.png \n", 431 | "4 https://cdn.sofifa.net/players/192/985/22_120.png \n", 432 | "... ... \n", 433 | "19234 https://cdn.sofifa.net/players/261/962/22_120.png \n", 434 | "19235 https://cdn.sofifa.net/players/262/040/22_120.png \n", 435 | "19236 https://cdn.sofifa.net/players/262/760/22_120.png \n", 436 | "19237 https://cdn.sofifa.net/players/262/820/22_120.png \n", 437 | "19238 https://cdn.sofifa.net/players/264/540/22_120.png \n", 438 | "\n", 439 | " club_logo_url \\\n", 440 | "0 https://cdn.sofifa.net/teams/73/60.png \n", 441 | "1 https://cdn.sofifa.net/teams/21/60.png \n", 442 | "2 https://cdn.sofifa.net/teams/11/60.png \n", 443 | "3 https://cdn.sofifa.net/teams/73/60.png \n", 444 | "4 https://cdn.sofifa.net/teams/10/60.png \n", 445 | "... ... \n", 446 | "19234 https://cdn.sofifa.net/teams/112541/60.png \n", 447 | "19235 https://cdn.sofifa.net/teams/445/60.png \n", 448 | "19236 https://cdn.sofifa.net/teams/111131/60.png \n", 449 | "19237 https://cdn.sofifa.net/teams/111131/60.png \n", 450 | "19238 https://cdn.sofifa.net/teams/113040/60.png \n", 451 | "\n", 452 | " club_flag_url \\\n", 453 | "0 https://cdn.sofifa.net/flags/fr.png \n", 454 | "1 https://cdn.sofifa.net/flags/de.png \n", 455 | "2 https://cdn.sofifa.net/flags/gb-eng.png \n", 456 | "3 https://cdn.sofifa.net/flags/fr.png \n", 457 | "4 https://cdn.sofifa.net/flags/gb-eng.png \n", 458 | "... ... \n", 459 | "19234 https://cdn.sofifa.net/flags/cn.png \n", 460 | "19235 https://cdn.sofifa.net/flags/ie.png \n", 461 | "19236 https://cdn.sofifa.net/flags/ie.png \n", 462 | "19237 https://cdn.sofifa.net/flags/ie.png \n", 463 | "19238 https://cdn.sofifa.net/flags/in.png \n", 464 | "\n", 465 | " nation_logo_url \\\n", 466 | "0 https://cdn.sofifa.net/teams/1369/60.png \n", 467 | "1 https://cdn.sofifa.net/teams/1353/60.png \n", 468 | "2 https://cdn.sofifa.net/teams/1354/60.png \n", 469 | "3 NaN \n", 470 | "4 https://cdn.sofifa.net/teams/1325/60.png \n", 471 | "... ... \n", 472 | "19234 NaN \n", 473 | "19235 NaN \n", 474 | "19236 NaN \n", 475 | "19237 NaN \n", 476 | "19238 NaN \n", 477 | "\n", 478 | " nation_flag_url \n", 479 | "0 https://cdn.sofifa.net/flags/ar.png \n", 480 | "1 https://cdn.sofifa.net/flags/pl.png \n", 481 | "2 https://cdn.sofifa.net/flags/pt.png \n", 482 | "3 https://cdn.sofifa.net/flags/br.png \n", 483 | "4 https://cdn.sofifa.net/flags/be.png \n", 484 | "... ... \n", 485 | "19234 https://cdn.sofifa.net/flags/cn.png \n", 486 | "19235 https://cdn.sofifa.net/flags/ie.png \n", 487 | "19236 https://cdn.sofifa.net/flags/ie.png \n", 488 | "19237 https://cdn.sofifa.net/flags/ie.png \n", 489 | "19238 https://cdn.sofifa.net/flags/in.png \n", 490 | "\n", 491 | "[19239 rows x 110 columns]" 492 | ] 493 | }, 494 | "execution_count": 19, 495 | "metadata": {}, 496 | "output_type": "execute_result" 497 | } 498 | ], 499 | "source": [ 500 | "players" 501 | ] 502 | }, 503 | { 504 | "cell_type": "markdown", 505 | "metadata": {}, 506 | "source": [ 507 | "Let's list the features based on which we will cluster our players\n", 508 | "\n", 509 | "* `overall` - overall rating of the player\n", 510 | "* `potential` - potential rating of the player\n", 511 | "* `value_eur` - total value of the player to the Club in Euros\n", 512 | "* `wage_eur` - wage of the player in Euros\n", 513 | "* `age` - age of the player" 514 | ] 515 | }, 516 | { 517 | "cell_type": "code", 518 | "execution_count": 20, 519 | "metadata": {}, 520 | "outputs": [], 521 | "source": [ 522 | "features = [\"overall\", \"potential\", \"wage_eur\", \"value_eur\", \"age\"]" 523 | ] 524 | }, 525 | { 526 | "cell_type": "code", 527 | "execution_count": 21, 528 | "metadata": {}, 529 | "outputs": [], 530 | "source": [ 531 | "# dropping null values from columns mentioned in features\n", 532 | "players = players.dropna(subset=features)\n", 533 | "# this will make sure that there will be no missing values in the columns that we are clustering" 534 | ] 535 | }, 536 | { 537 | "cell_type": "code", 538 | "execution_count": 22, 539 | "metadata": {}, 540 | "outputs": [], 541 | "source": [ 542 | "data = players[features].copy()" 543 | ] 544 | }, 545 | { 546 | "cell_type": "code", 547 | "execution_count": 23, 548 | "metadata": {}, 549 | "outputs": [ 550 | { 551 | "data": { 552 | "text/html": [ 553 | "
\n", 554 | "\n", 567 | "\n", 568 | " \n", 569 | " \n", 570 | " \n", 571 | " \n", 572 | " \n", 573 | " \n", 574 | " \n", 575 | " \n", 576 | " \n", 577 | " \n", 578 | " \n", 579 | " \n", 580 | " \n", 581 | " \n", 582 | " \n", 583 | " \n", 584 | " \n", 585 | " \n", 586 | " \n", 587 | " \n", 588 | " \n", 589 | " \n", 590 | " \n", 591 | " \n", 592 | " \n", 593 | " \n", 594 | " \n", 595 | " \n", 596 | " \n", 597 | " \n", 598 | " \n", 599 | " \n", 600 | " \n", 601 | " \n", 602 | " \n", 603 | " \n", 604 | " \n", 605 | " \n", 606 | " \n", 607 | " \n", 608 | " \n", 609 | " \n", 610 | " \n", 611 | " \n", 612 | " \n", 613 | " \n", 614 | " \n", 615 | " \n", 616 | " \n", 617 | " \n", 618 | " \n", 619 | " \n", 620 | " \n", 621 | " \n", 622 | " \n", 623 | " \n", 624 | " \n", 625 | " \n", 626 | " \n", 627 | " \n", 628 | " \n", 629 | " \n", 630 | " \n", 631 | " \n", 632 | " \n", 633 | " \n", 634 | " \n", 635 | " \n", 636 | " \n", 637 | " \n", 638 | " \n", 639 | " \n", 640 | " \n", 641 | " \n", 642 | " \n", 643 | " \n", 644 | " \n", 645 | " \n", 646 | " \n", 647 | " \n", 648 | " \n", 649 | " \n", 650 | " \n", 651 | " \n", 652 | " \n", 653 | " \n", 654 | " \n", 655 | " \n", 656 | " \n", 657 | " \n", 658 | " \n", 659 | " \n", 660 | " \n", 661 | " \n", 662 | " \n", 663 | " \n", 664 | " \n", 665 | " \n", 666 | " \n", 667 | " \n", 668 | "
overallpotentialwage_eurvalue_eurage
09393320000.078000000.034
19292270000.0119500000.032
29191270000.045000000.036
39191270000.0129000000.029
49191350000.0125500000.030
..................
1923447521000.070000.022
192354759500.0110000.019
192364755500.0100000.021
192374760500.0110000.019
192384760500.0110000.019
\n", 669 | "

19165 rows × 5 columns

\n", 670 | "
" 671 | ], 672 | "text/plain": [ 673 | " overall potential wage_eur value_eur age\n", 674 | "0 93 93 320000.0 78000000.0 34\n", 675 | "1 92 92 270000.0 119500000.0 32\n", 676 | "2 91 91 270000.0 45000000.0 36\n", 677 | "3 91 91 270000.0 129000000.0 29\n", 678 | "4 91 91 350000.0 125500000.0 30\n", 679 | "... ... ... ... ... ...\n", 680 | "19234 47 52 1000.0 70000.0 22\n", 681 | "19235 47 59 500.0 110000.0 19\n", 682 | "19236 47 55 500.0 100000.0 21\n", 683 | "19237 47 60 500.0 110000.0 19\n", 684 | "19238 47 60 500.0 110000.0 19\n", 685 | "\n", 686 | "[19165 rows x 5 columns]" 687 | ] 688 | }, 689 | "execution_count": 23, 690 | "metadata": {}, 691 | "output_type": "execute_result" 692 | } 693 | ], 694 | "source": [ 695 | "data" 696 | ] 697 | }, 698 | { 699 | "cell_type": "markdown", 700 | "metadata": {}, 701 | "source": [ 702 | "1. Scale the data\n", 703 | "2. Initialize random centroids\n", 704 | "3. Label each data points\n", 705 | "4. Update centroids\n", 706 | "5. Repeat steps 3 and 4 until centroids stop changing" 707 | ] 708 | }, 709 | { 710 | "cell_type": "markdown", 711 | "metadata": {}, 712 | "source": [ 713 | "## 1. Scaling the Data" 714 | ] 715 | }, 716 | { 717 | "cell_type": "code", 718 | "execution_count": 26, 719 | "metadata": {}, 720 | "outputs": [], 721 | "source": [ 722 | "data = ((data - data.min()) / (data.max() - data.min())) * 9 + 1" 723 | ] 724 | }, 725 | { 726 | "cell_type": "code", 727 | "execution_count": 27, 728 | "metadata": {}, 729 | "outputs": [ 730 | { 731 | "data": { 732 | "text/html": [ 733 | "
\n", 734 | "\n", 747 | "\n", 748 | " \n", 749 | " \n", 750 | " \n", 751 | " \n", 752 | " \n", 753 | " \n", 754 | " \n", 755 | " \n", 756 | " \n", 757 | " \n", 758 | " \n", 759 | " \n", 760 | " \n", 761 | " \n", 762 | " \n", 763 | " \n", 764 | " \n", 765 | " \n", 766 | " \n", 767 | " \n", 768 | " \n", 769 | " \n", 770 | " \n", 771 | " \n", 772 | " \n", 773 | " \n", 774 | " \n", 775 | " \n", 776 | " \n", 777 | " \n", 778 | " \n", 779 | " \n", 780 | " \n", 781 | " \n", 782 | " \n", 783 | " \n", 784 | " \n", 785 | " \n", 786 | " \n", 787 | " \n", 788 | " \n", 789 | " \n", 790 | " \n", 791 | " \n", 792 | " \n", 793 | " \n", 794 | " \n", 795 | " \n", 796 | " \n", 797 | " \n", 798 | " \n", 799 | " \n", 800 | " \n", 801 | " \n", 802 | " \n", 803 | " \n", 804 | " \n", 805 | " \n", 806 | " \n", 807 | " \n", 808 | " \n", 809 | " \n", 810 | " \n", 811 | " \n", 812 | " \n", 813 | " \n", 814 | " \n", 815 | " \n", 816 | " \n", 817 | " \n", 818 | " \n", 819 | " \n", 820 | " \n", 821 | " \n", 822 | " \n", 823 | " \n", 824 | "
overallpotentialwage_eurvalue_eurage
count19165.00000019165.00000019165.00000019165.00000019165.000000
mean4.6704725.3199981.2194431.1318264.063345
std1.3466351.1910760.5015280.3532291.575838
min1.0000001.0000001.0000001.0000001.000000
25%3.7391304.5217391.0128761.0216202.666667
50%4.7173915.3043481.0643781.0448174.000000
75%5.5000006.0869571.1931331.0923705.333333
max10.00000010.00000010.00000010.00000010.000000
\n", 825 | "
" 826 | ], 827 | "text/plain": [ 828 | " overall potential wage_eur value_eur age\n", 829 | "count 19165.000000 19165.000000 19165.000000 19165.000000 19165.000000\n", 830 | "mean 4.670472 5.319998 1.219443 1.131826 4.063345\n", 831 | "std 1.346635 1.191076 0.501528 0.353229 1.575838\n", 832 | "min 1.000000 1.000000 1.000000 1.000000 1.000000\n", 833 | "25% 3.739130 4.521739 1.012876 1.021620 2.666667\n", 834 | "50% 4.717391 5.304348 1.064378 1.044817 4.000000\n", 835 | "75% 5.500000 6.086957 1.193133 1.092370 5.333333\n", 836 | "max 10.000000 10.000000 10.000000 10.000000 10.000000" 837 | ] 838 | }, 839 | "execution_count": 27, 840 | "metadata": {}, 841 | "output_type": "execute_result" 842 | } 843 | ], 844 | "source": [ 845 | "data.describe()" 846 | ] 847 | }, 848 | { 849 | "cell_type": "code", 850 | "execution_count": 28, 851 | "metadata": {}, 852 | "outputs": [ 853 | { 854 | "data": { 855 | "text/html": [ 856 | "
\n", 857 | "\n", 870 | "\n", 871 | " \n", 872 | " \n", 873 | " \n", 874 | " \n", 875 | " \n", 876 | " \n", 877 | " \n", 878 | " \n", 879 | " \n", 880 | " \n", 881 | " \n", 882 | " \n", 883 | " \n", 884 | " \n", 885 | " \n", 886 | " \n", 887 | " \n", 888 | " \n", 889 | " \n", 890 | " \n", 891 | " \n", 892 | " \n", 893 | " \n", 894 | " \n", 895 | " \n", 896 | " \n", 897 | " \n", 898 | " \n", 899 | " \n", 900 | " \n", 901 | " \n", 902 | " \n", 903 | " \n", 904 | " \n", 905 | " \n", 906 | " \n", 907 | " \n", 908 | " \n", 909 | " \n", 910 | " \n", 911 | " \n", 912 | " \n", 913 | " \n", 914 | " \n", 915 | " \n", 916 | " \n", 917 | " \n", 918 | " \n", 919 | " \n", 920 | " \n", 921 | " \n", 922 | " \n", 923 | "
overallpotentialwage_eurvalue_eurage
010.0000009.6086969.2274684.6183077.000000
19.8043489.4130437.9399146.5436546.333333
29.6086969.2173917.9399143.0873087.666667
39.6086969.2173917.9399146.9843965.333333
49.6086969.21739110.0000006.8220185.666667
\n", 924 | "
" 925 | ], 926 | "text/plain": [ 927 | " overall potential wage_eur value_eur age\n", 928 | "0 10.000000 9.608696 9.227468 4.618307 7.000000\n", 929 | "1 9.804348 9.413043 7.939914 6.543654 6.333333\n", 930 | "2 9.608696 9.217391 7.939914 3.087308 7.666667\n", 931 | "3 9.608696 9.217391 7.939914 6.984396 5.333333\n", 932 | "4 9.608696 9.217391 10.000000 6.822018 5.666667" 933 | ] 934 | }, 935 | "execution_count": 28, 936 | "metadata": {}, 937 | "output_type": "execute_result" 938 | } 939 | ], 940 | "source": [ 941 | "data.head()" 942 | ] 943 | }, 944 | { 945 | "cell_type": "markdown", 946 | "metadata": {}, 947 | "source": [ 948 | "## 2. Intializing Random Centroids" 949 | ] 950 | }, 951 | { 952 | "cell_type": "code", 953 | "execution_count": 32, 954 | "metadata": {}, 955 | "outputs": [], 956 | "source": [ 957 | "def random_centroid(data, k):\n", 958 | " centroids = []\n", 959 | " for i in range(k):\n", 960 | " centroid = data.apply(lambda x: float(x.sample()))\n", 961 | " centroids.append(centroid)\n", 962 | " return pd.concat(centroids, axis=1)" 963 | ] 964 | }, 965 | { 966 | "cell_type": "code", 967 | "execution_count": 33, 968 | "metadata": {}, 969 | "outputs": [], 970 | "source": [ 971 | "centroids = random_centroid(data, 5)" 972 | ] 973 | }, 974 | { 975 | "cell_type": "code", 976 | "execution_count": 34, 977 | "metadata": {}, 978 | "outputs": [ 979 | { 980 | "data": { 981 | "text/html": [ 982 | "
\n", 983 | "\n", 996 | "\n", 997 | " \n", 998 | " \n", 999 | " \n", 1000 | " \n", 1001 | " \n", 1002 | " \n", 1003 | " \n", 1004 | " \n", 1005 | " \n", 1006 | " \n", 1007 | " \n", 1008 | " \n", 1009 | " \n", 1010 | " \n", 1011 | " \n", 1012 | " \n", 1013 | " \n", 1014 | " \n", 1015 | " \n", 1016 | " \n", 1017 | " \n", 1018 | " \n", 1019 | " \n", 1020 | " \n", 1021 | " \n", 1022 | " \n", 1023 | " \n", 1024 | " \n", 1025 | " \n", 1026 | " \n", 1027 | " \n", 1028 | " \n", 1029 | " \n", 1030 | " \n", 1031 | " \n", 1032 | " \n", 1033 | " \n", 1034 | " \n", 1035 | " \n", 1036 | " \n", 1037 | " \n", 1038 | " \n", 1039 | " \n", 1040 | " \n", 1041 | " \n", 1042 | " \n", 1043 | " \n", 1044 | " \n", 1045 | " \n", 1046 | " \n", 1047 | " \n", 1048 | " \n", 1049 | "
01234
overall6.2826095.1086966.2826095.5000004.521739
potential6.4782614.7173915.1086964.1304355.695652
wage_eur1.1158801.0128761.3733911.2703861.064378
value_eur1.0970101.0250991.1758791.0877311.055255
age7.0000005.6666672.6666672.0000002.666667
\n", 1050 | "
" 1051 | ], 1052 | "text/plain": [ 1053 | " 0 1 2 3 4\n", 1054 | "overall 6.282609 5.108696 6.282609 5.500000 4.521739\n", 1055 | "potential 6.478261 4.717391 5.108696 4.130435 5.695652\n", 1056 | "wage_eur 1.115880 1.012876 1.373391 1.270386 1.064378\n", 1057 | "value_eur 1.097010 1.025099 1.175879 1.087731 1.055255\n", 1058 | "age 7.000000 5.666667 2.666667 2.000000 2.666667" 1059 | ] 1060 | }, 1061 | "execution_count": 34, 1062 | "metadata": {}, 1063 | "output_type": "execute_result" 1064 | } 1065 | ], 1066 | "source": [ 1067 | "centroids" 1068 | ] 1069 | }, 1070 | { 1071 | "cell_type": "code", 1072 | "execution_count": 41, 1073 | "metadata": {}, 1074 | "outputs": [], 1075 | "source": [ 1076 | "def get_labels(data, centroids):\n", 1077 | " distances = centroids.apply(lambda x: np.sqrt(((data - x) ** 2).sum(axis=1)))\n", 1078 | " return distances.idxmin(axis=1)" 1079 | ] 1080 | }, 1081 | { 1082 | "cell_type": "code", 1083 | "execution_count": 43, 1084 | "metadata": {}, 1085 | "outputs": [], 1086 | "source": [ 1087 | "labels = get_labels(data, centroids)" 1088 | ] 1089 | }, 1090 | { 1091 | "cell_type": "code", 1092 | "execution_count": 45, 1093 | "metadata": {}, 1094 | "outputs": [ 1095 | { 1096 | "data": { 1097 | "text/plain": [ 1098 | "4 9064\n", 1099 | "1 6605\n", 1100 | "0 1713\n", 1101 | "2 1701\n", 1102 | "3 82\n", 1103 | "dtype: int64" 1104 | ] 1105 | }, 1106 | "execution_count": 45, 1107 | "metadata": {}, 1108 | "output_type": "execute_result" 1109 | } 1110 | ], 1111 | "source": [ 1112 | "labels.value_counts()" 1113 | ] 1114 | }, 1115 | { 1116 | "cell_type": "code", 1117 | "execution_count": 48, 1118 | "metadata": {}, 1119 | "outputs": [], 1120 | "source": [ 1121 | "def new_centroids(data, labels, k):\n", 1122 | " return data.groupby(labels).apply(lambda x: np.exp(np.log(x).mean())).T\n" 1123 | ] 1124 | }, 1125 | { 1126 | "cell_type": "code", 1127 | "execution_count": 49, 1128 | "metadata": {}, 1129 | "outputs": [], 1130 | "source": [ 1131 | "from sklearn.decomposition import PCA\n", 1132 | "import matplotlib.pyplot as plt\n", 1133 | "from IPython.display import clear_output" 1134 | ] 1135 | }, 1136 | { 1137 | "cell_type": "code", 1138 | "execution_count": 54, 1139 | "metadata": {}, 1140 | "outputs": [], 1141 | "source": [ 1142 | "def plot_clusters(data, labels, centroids, iteration):\n", 1143 | " pca = PCA(n_components=2)\n", 1144 | " data_2d = pca.fit_transform(data)\n", 1145 | " centroids_2d = pca.transform(centroids.T)\n", 1146 | " clear_output(wait=True)\n", 1147 | " plt.title(f'Iteration {iteration}')\n", 1148 | " plt.scatter(x=data_2d[:, 0], y=data_2d[:,1], c=labels)\n", 1149 | " plt.show()" 1150 | ] 1151 | }, 1152 | { 1153 | "cell_type": "code", 1154 | "execution_count": 55, 1155 | "metadata": {}, 1156 | "outputs": [ 1157 | { 1158 | "data": { 1159 | "image/png": "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", 1160 | "text/plain": [ 1161 | "
" 1162 | ] 1163 | }, 1164 | "metadata": { 1165 | "needs_background": "light" 1166 | }, 1167 | "output_type": "display_data" 1168 | } 1169 | ], 1170 | "source": [ 1171 | "max_iterations = 100\n", 1172 | "k = 3 # number of clusters\n", 1173 | "\n", 1174 | "centroids = random_centroid(data, k)\n", 1175 | "old_centroids = pd.DataFrame()\n", 1176 | "iteration = 1\n", 1177 | "\n", 1178 | "while iteration < max_iterations and not centroids.equals(old_centroids):\n", 1179 | " old_centroids = centroids\n", 1180 | "\n", 1181 | " labels = get_labels(data, centroids)\n", 1182 | " centroids = new_centroids(data, labels, k)\n", 1183 | " plot_clusters(data, labels, centroids, iteration)\n", 1184 | " iteration += 1" 1185 | ] 1186 | }, 1187 | { 1188 | "cell_type": "code", 1189 | "execution_count": 56, 1190 | "metadata": {}, 1191 | "outputs": [ 1192 | { 1193 | "data": { 1194 | "text/html": [ 1195 | "
\n", 1196 | "\n", 1209 | "\n", 1210 | " \n", 1211 | " \n", 1212 | " \n", 1213 | " \n", 1214 | " \n", 1215 | " \n", 1216 | " \n", 1217 | " \n", 1218 | " \n", 1219 | " \n", 1220 | " \n", 1221 | " \n", 1222 | " \n", 1223 | " \n", 1224 | " \n", 1225 | " \n", 1226 | " \n", 1227 | " \n", 1228 | " \n", 1229 | " \n", 1230 | " \n", 1231 | " \n", 1232 | " \n", 1233 | " \n", 1234 | " \n", 1235 | " \n", 1236 | " \n", 1237 | " \n", 1238 | " \n", 1239 | " \n", 1240 | " \n", 1241 | " \n", 1242 | " \n", 1243 | " \n", 1244 | " \n", 1245 | " \n", 1246 | " \n", 1247 | " \n", 1248 | " \n", 1249 | " \n", 1250 | "
012
overall5.8075034.7819603.205672
potential6.4978704.5068134.930905
wage_eur1.4205001.1184981.028564
value_eur1.2856851.0449091.026655
age3.5982155.4676482.514741
\n", 1251 | "
" 1252 | ], 1253 | "text/plain": [ 1254 | " 0 1 2\n", 1255 | "overall 5.807503 4.781960 3.205672\n", 1256 | "potential 6.497870 4.506813 4.930905\n", 1257 | "wage_eur 1.420500 1.118498 1.028564\n", 1258 | "value_eur 1.285685 1.044909 1.026655\n", 1259 | "age 3.598215 5.467648 2.514741" 1260 | ] 1261 | }, 1262 | "execution_count": 56, 1263 | "metadata": {}, 1264 | "output_type": "execute_result" 1265 | } 1266 | ], 1267 | "source": [ 1268 | "centroids" 1269 | ] 1270 | }, 1271 | { 1272 | "cell_type": "code", 1273 | "execution_count": 58, 1274 | "metadata": {}, 1275 | "outputs": [ 1276 | { 1277 | "data": { 1278 | "text/html": [ 1279 | "
\n", 1280 | "\n", 1293 | "\n", 1294 | " \n", 1295 | " \n", 1296 | " \n", 1297 | " \n", 1298 | " \n", 1299 | " \n", 1300 | " \n", 1301 | " \n", 1302 | " \n", 1303 | " \n", 1304 | " \n", 1305 | " \n", 1306 | " \n", 1307 | " \n", 1308 | " \n", 1309 | " \n", 1310 | " \n", 1311 | " \n", 1312 | " \n", 1313 | " \n", 1314 | " \n", 1315 | " \n", 1316 | " \n", 1317 | " \n", 1318 | " \n", 1319 | " \n", 1320 | " \n", 1321 | " \n", 1322 | " \n", 1323 | " \n", 1324 | " \n", 1325 | " \n", 1326 | " \n", 1327 | " \n", 1328 | " \n", 1329 | " \n", 1330 | " \n", 1331 | " \n", 1332 | " \n", 1333 | " \n", 1334 | " \n", 1335 | " \n", 1336 | " \n", 1337 | " \n", 1338 | " \n", 1339 | " \n", 1340 | " \n", 1341 | " \n", 1342 | " \n", 1343 | " \n", 1344 | " \n", 1345 | " \n", 1346 | " \n", 1347 | " \n", 1348 | " \n", 1349 | " \n", 1350 | " \n", 1351 | " \n", 1352 | " \n", 1353 | " \n", 1354 | " \n", 1355 | " \n", 1356 | " \n", 1357 | " \n", 1358 | " \n", 1359 | " \n", 1360 | " \n", 1361 | " \n", 1362 | " \n", 1363 | " \n", 1364 | " \n", 1365 | " \n", 1366 | " \n", 1367 | " \n", 1368 | " \n", 1369 | " \n", 1370 | " \n", 1371 | " \n", 1372 | " \n", 1373 | " \n", 1374 | " \n", 1375 | " \n", 1376 | " \n", 1377 | " \n", 1378 | " \n", 1379 | " \n", 1380 | " \n", 1381 | " \n", 1382 | " \n", 1383 | " \n", 1384 | " \n", 1385 | " \n", 1386 | " \n", 1387 | " \n", 1388 | " \n", 1389 | " \n", 1390 | " \n", 1391 | " \n", 1392 | " \n", 1393 | " \n", 1394 | " \n", 1395 | " \n", 1396 | " \n", 1397 | " \n", 1398 | " \n", 1399 | " \n", 1400 | " \n", 1401 | " \n", 1402 | " \n", 1403 | " \n", 1404 | " \n", 1405 | " \n", 1406 | "
short_nameoverallpotentialwage_eurvalue_eurage
199Pepe828214000.05500000.038
284Joaquín818123000.08500000.039
292José Fonte818130000.04600000.037
388G. Buffon808018000.02300000.043
509Iniesta797910000.05500000.037
.....................
18890S. Haokip5151500.060000.028
18971Lalkhawpuimawia5151500.060000.029
19032Song Yue50502000.040000.029
19100J. Russell4949500.015000.036
19118Gao Xiang49492000.035000.032
\n", 1407 | "

7191 rows × 6 columns

\n", 1408 | "
" 1409 | ], 1410 | "text/plain": [ 1411 | " short_name overall potential wage_eur value_eur age\n", 1412 | "199 Pepe 82 82 14000.0 5500000.0 38\n", 1413 | "284 Joaquín 81 81 23000.0 8500000.0 39\n", 1414 | "292 José Fonte 81 81 30000.0 4600000.0 37\n", 1415 | "388 G. Buffon 80 80 18000.0 2300000.0 43\n", 1416 | "509 Iniesta 79 79 10000.0 5500000.0 37\n", 1417 | "... ... ... ... ... ... ...\n", 1418 | "18890 S. Haokip 51 51 500.0 60000.0 28\n", 1419 | "18971 Lalkhawpuimawia 51 51 500.0 60000.0 29\n", 1420 | "19032 Song Yue 50 50 2000.0 40000.0 29\n", 1421 | "19100 J. Russell 49 49 500.0 15000.0 36\n", 1422 | "19118 Gao Xiang 49 49 2000.0 35000.0 32\n", 1423 | "\n", 1424 | "[7191 rows x 6 columns]" 1425 | ] 1426 | }, 1427 | "execution_count": 58, 1428 | "metadata": {}, 1429 | "output_type": "execute_result" 1430 | } 1431 | ], 1432 | "source": [ 1433 | "players[labels == 1][[\"short_name\"] + features]" 1434 | ] 1435 | }, 1436 | { 1437 | "cell_type": "markdown", 1438 | "metadata": {}, 1439 | "source": [ 1440 | "## Conclusion\n", 1441 | "Cluster 0 represets star players\n", 1442 | "\n", 1443 | "Cluster 1 represents older players who have hit their potential.\n", 1444 | "\n", 1445 | "Cluster 2 represents young players\n", 1446 | "\n", 1447 | "We were able to confirm this hypothesis by looking at the name of players. \n", 1448 | "\n", 1449 | "K-means allows you to find patterns in your data that you didn't know were there. This allowed us to categorize players automatically into different groups. " 1450 | ] 1451 | }, 1452 | { 1453 | "cell_type": "code", 1454 | "execution_count": 60, 1455 | "metadata": {}, 1456 | "outputs": [], 1457 | "source": [ 1458 | "from sklearn.cluster import KMeans" 1459 | ] 1460 | }, 1461 | { 1462 | "cell_type": "code", 1463 | "execution_count": 61, 1464 | "metadata": {}, 1465 | "outputs": [ 1466 | { 1467 | "data": { 1468 | "text/html": [ 1469 | "
KMeans(n_clusters=3)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" 1470 | ], 1471 | "text/plain": [ 1472 | "KMeans(n_clusters=3)" 1473 | ] 1474 | }, 1475 | "execution_count": 61, 1476 | "metadata": {}, 1477 | "output_type": "execute_result" 1478 | } 1479 | ], 1480 | "source": [ 1481 | "kmeans = KMeans(3)\n", 1482 | "kmeans.fit(data)" 1483 | ] 1484 | }, 1485 | { 1486 | "cell_type": "code", 1487 | "execution_count": 62, 1488 | "metadata": {}, 1489 | "outputs": [], 1490 | "source": [ 1491 | "centroids = kmeans.cluster_centers_" 1492 | ] 1493 | }, 1494 | { 1495 | "cell_type": "code", 1496 | "execution_count": 63, 1497 | "metadata": {}, 1498 | "outputs": [ 1499 | { 1500 | "data": { 1501 | "text/html": [ 1502 | "
\n", 1503 | "\n", 1516 | "\n", 1517 | " \n", 1518 | " \n", 1519 | " \n", 1520 | " \n", 1521 | " \n", 1522 | " \n", 1523 | " \n", 1524 | " \n", 1525 | " \n", 1526 | " \n", 1527 | " \n", 1528 | " \n", 1529 | " \n", 1530 | " \n", 1531 | " \n", 1532 | " \n", 1533 | " \n", 1534 | " \n", 1535 | " \n", 1536 | " \n", 1537 | " \n", 1538 | " \n", 1539 | " \n", 1540 | " \n", 1541 | " \n", 1542 | " \n", 1543 | " \n", 1544 | " \n", 1545 | " \n", 1546 | " \n", 1547 | " \n", 1548 | " \n", 1549 | " \n", 1550 | " \n", 1551 | " \n", 1552 | " \n", 1553 | " \n", 1554 | " \n", 1555 | " \n", 1556 | " \n", 1557 | "
012
overall6.2329404.8008603.601045
potential6.6235094.5038555.207475
wage_eur1.6579001.1128851.040009
value_eur1.4141341.0400071.035859
age4.1421025.6089232.712137
\n", 1558 | "
" 1559 | ], 1560 | "text/plain": [ 1561 | " 0 1 2\n", 1562 | "overall 6.232940 4.800860 3.601045\n", 1563 | "potential 6.623509 4.503855 5.207475\n", 1564 | "wage_eur 1.657900 1.112885 1.040009\n", 1565 | "value_eur 1.414134 1.040007 1.035859\n", 1566 | "age 4.142102 5.608923 2.712137" 1567 | ] 1568 | }, 1569 | "execution_count": 63, 1570 | "metadata": {}, 1571 | "output_type": "execute_result" 1572 | } 1573 | ], 1574 | "source": [ 1575 | "pd.DataFrame(centroids, columns=features).T" 1576 | ] 1577 | }, 1578 | { 1579 | "cell_type": "code", 1580 | "execution_count": null, 1581 | "metadata": {}, 1582 | "outputs": [], 1583 | "source": [] 1584 | } 1585 | ], 1586 | "metadata": { 1587 | "kernelspec": { 1588 | "display_name": "Python 3.9.13 64-bit", 1589 | "language": "python", 1590 | "name": "python3" 1591 | }, 1592 | "language_info": { 1593 | "codemirror_mode": { 1594 | "name": "ipython", 1595 | "version": 3 1596 | }, 1597 | "file_extension": ".py", 1598 | "mimetype": "text/x-python", 1599 | "name": "python", 1600 | "nbconvert_exporter": "python", 1601 | "pygments_lexer": "ipython3", 1602 | "version": "3.9.13" 1603 | }, 1604 | "orig_nbformat": 4, 1605 | "vscode": { 1606 | "interpreter": { 1607 | "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49" 1608 | } 1609 | } 1610 | }, 1611 | "nbformat": 4, 1612 | "nbformat_minor": 2 1613 | } 1614 | --------------------------------------------------------------------------------