├── .gitattributes
├── logo.png
├── requirements.txt
├── datasets
├── voicegender.zip
├── iris.data
├── iris_data.csv
└── diabetes_data.csv
├── Logistic Regression
└── README.md
├── Apriori algorithm
├── README.md
└── apriori_algorithm.py
├── Naive Bayes
├── README.md
└── Naive Bayes.ipynb
├── Decision Trees
└── README.md
├── K-Nearest Neigbors
├── README.md
├── KNN-Classifier.ipynb
└── KNN_weighted_classification.ipynb
├── .gitignore
├── Linear Regression
└── README.md
├── Principal Component Analysis
├── README.md
└── dimensionality reduction.ipynb
├── Random Forest
├── decision_tree.py
└── random_forest.ipynb
├── K-means
└── Spiral.txt
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/veb-101/Machine-Learning-Algorithms/HEAD/logo.png
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | pip
2 | numpy
3 | pandas
4 | scipy
5 | scikit-learn
6 | matplotlib
7 | seaborn
8 |
--------------------------------------------------------------------------------
/datasets/voicegender.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/veb-101/Machine-Learning-Algorithms/HEAD/datasets/voicegender.zip
--------------------------------------------------------------------------------
/Logistic Regression/README.md:
--------------------------------------------------------------------------------
1 | ## Logistic Regression
2 | _______________
3 |
4 | * Articles Used
5 | * [x] [Logistic Regression - YouTube](https://www.youtube.com/playlist?list=PLblh5JKOoLUKxzEP5HA2d-Li7IJkHfXSe)
6 | * [x] [TLM | Logistic Regression](https://www.thelearningmachine.ai/logistic)
7 | * [x] [Logistic regression - Wikipedia](https://en.wikipedia.org/wiki/Logistic_regression)
8 | * [x] [Maximum likelihood and gradient descent demonstration – Zlatan Kremonic](https://zlatankr.github.io/posts/2017/03/06/mle-gradient-descent)
9 | * [x] [An Introduction to Logistic Regression - Towards Data Science](https://towardsdatascience.com/an-introduction-to-logistic-regression-8136ad65da2e)
10 | * [x] [A Gentle Introduction to Logistic Regression With Maximum Likelihood Estimation](https://machinelearningmastery.com/logistic-regression-with-maximum-likelihood-estimation/)
11 | * [x] [Logistic model - Maximum likelihood](https://www.statlect.com/fundamentals-of-statistics/logistic-model-maximum-likelihood)
12 |
--------------------------------------------------------------------------------
/Apriori algorithm/README.md:
--------------------------------------------------------------------------------
1 | # Apriori Algorithm (Association Rule Mining)
2 |
3 | --------
4 |
5 |
6 | * Articles/videos used:
7 | * [x] [Apriori Algorithm : Know How to Find Frequent Itemsets | Edureka](https://www.edureka.co/blog/apriori-algorithm/)
8 | * [x] [Apriori Algorithm Explained | Association Rule Mining | Finding Frequent Itemset | Edureka - YouTube](https://www.youtube.com/watch?v=guVvtZ7ZClw)
9 | * [x] [Apriori Algorithm (Associated Learning) - Fun and Easy Machine Learning - YouTube](https://www.youtube.com/watch?v=WGlMlS_Yydk)
10 | * [x] [Apriori Algorithm - GeeksforGeeks](https://www.geeksforgeeks.org/apriori-algorithm/?ref=lbp)
11 | * [x] [Apriori Algorithm - GeeksforGeeks](https://www.geeksforgeeks.org/apriori-algorithm/)
12 | * [x] [Implementing Apriori algorithm in Python - GeeksforGeeks](https://www.geeksforgeeks.org/implementing-apriori-algorithm-in-python/)
13 | * [x] [Association Rule Mining via Apriori Algorithm in Python](https://stackabuse.com/association-rule-mining-via-apriori-algorithm-in-python/)
14 | * [ ] [Apriori Algorithm in Python - CodeSpeedy](https://www.codespeedy.com/apriori-algorithm-in-python/)
15 | * [ ] [Data Science Apriori Algorithm in Python- Market Basket Analysis - Intellipaat](https://intellipaat.com/blog/data-science-apriori-algorithm/)
16 | * [ ] [Apriori Algorithm from Scratch - Python](http://www.vucreations.com/articles/apriori-algorithm-from-scratch-Python.html)
17 |
18 |
--------------------------------------------------------------------------------
/Naive Bayes/README.md:
--------------------------------------------------------------------------------
1 | # Gaussian Naive Bayes
2 |
3 | ---
4 |
5 | - Articles used
6 | - [x] [3blue1brown- Bayes theorem, and making probability intuitive](https://www.youtube.com/watch?v=HZGCoVF3YvM)
7 | - [x] [3blue1brown- The quick proof of Bayes' theorem](https://www.youtube.com/watch?v=U_85TaXbeIo)
8 | - [x] [Luis Serrano - Naive Bayes classifier: A friendly approach](https://www.youtube.com/watch?v=Q8l0Vip5YUw)
9 | - [x] [Andrew Ng Naive Bayes Generative Learning Algorithms](https://www.youtube.com/watch?v=z5UQyCESW64)
10 | - [x] [Andrew Ng Naive Bayes Text Clasification](https://www.youtube.com/watch?v=NFd0ZQk5bR4)
11 | - [x] [Brandon Rohrer - How Bayes Theorem works](https://www.youtube.com/watch?v=5NMxiOGL39M)
12 | - [x] [Naive Bayes Classifiers](https://www.geeksforgeeks.org/naive-bayes-classifiers)
13 | - [x] [In Depth: Naive Bayes Classification](https://jakevdp.github.io/PythonDataScienceHandbook/05.05-naive-bayes.html)
14 | - [x] [Naive Bayes Classifier in Python | Naive Bayes Algorithm | Machine Learning Algorithm | Edureka](https://www.youtube.com/watch?v=vz_xuxYS2PM&t=11s)
15 | - [x] [How to Develop a Naive Bayes Classifier from Scratch in Python](https://machinelearningmastery.com/classification-as-conditional-probability-and-the-naive-bayes-algorithm//)
16 | - [x] [Naive Bayes Classifier From Scratch](https://chrisalbon.com/machine_learning/naive_bayes/naive_bayes_classifier_from_scratch/)
17 | - [x] [kDnuggets - Naive Bayes from Scratch using Python only – No Fancy Frameworks](https://www.kdnuggets.com/2018/10/naive-bayes-from-scratch-python.html)
18 |
--------------------------------------------------------------------------------
/Decision Trees/README.md:
--------------------------------------------------------------------------------
1 | ## Decision Tree Classifier
2 | _______________
3 |
4 | * Articles/videos read and used
5 | * [x] [StatQuest: Decision Trees](https://www.youtube.com/watch?v=7VeUPuFGJHk&list=PLblh5JKOoLUICTaGLRoHQDuF_7q2GfuJF&index=34)
6 | * [x] [Decision tree learning](https://en.wikipedia.org/wiki/Decision_tree_learning)
7 | * [x] [Decision Tree Algorithm | Decision Tree in Python | Machine Learning Algorithms | Edureka](https://www.youtube.com/watch?v=qDcl-FRnwSU)
8 | * [x] [Classification And Regression Trees for Machine Learning](https://machinelearningmastery.com/classification-and-regression-trees-for-machine-learning/)
9 | * [x] [How To Implement The Decision Tree Algorithm From Scratch In Python](https://machinelearningmastery.com/implement-decision-tree-algorithm-scratch-python/)
10 | * [x] [Clas - 5 Data Science Training | Decision Tree Classifier Explained | Edureka](https://www.youtube.com/watch?v=v3tsrs1wpi4)
11 | * [x] [Understanding Decision Trees for Classification in Python](https://www.kdnuggets.com/2019/08/understanding-decision-trees-classification-python.html)
12 | * [x] [A Simple Explanation of Information Gain and Entropy](https://victorzhou.com/blog/information-gain/)
13 | * [x] [A Simple Explanation of Gini Impurity](https://victorzhou.com/blog/gini-impurity/)
14 | * [x] [In-Depth: Decision Trees and Random Forests](https://jakevdp.github.io/PythonDataScienceHandbook/05.08-random-forests.html)
15 | * [x] [The Simple Math behind 3 Decision Tree Splitting criterions](https://towardsdatascience.com/the-simple-math-behind-3-decision-tree-splitting-criterions-85d4de2a75fe)
16 |
--------------------------------------------------------------------------------
/K-Nearest Neigbors/README.md:
--------------------------------------------------------------------------------
1 | ### k-Nearest Neighbors README
2 | --------------------
3 |
4 | * Articles used:
5 | 1. [A Detailed Introduction to K-Nearest Neighbor (KNN) Algorithm](https://saravananthirumuruganathan.wordpress.com/2010/05/17/a-detailed-introduction-to-k-nearest-neighbor-knn-algorithm/)
6 | 2. [A Complete Guide to K-Nearest-Neighbors with Applications in Python and R](https://kevinzakka.github.io/2016/07/13/k-nearest-neighbor/)
7 | 3. [Tutorial To Implement k-Nearest Neighbors in Python From Scratch](https://machinelearningmastery.com/tutorial-to-implement-k-nearest-neighbors-in-python-from-scratch/)
8 | 4. [A Practical Introduction to K-Nearest Neighbors Algorithm for Regression](https://www.analyticsvidhya.com/blog/2018/08/k-nearest-neighbor-introduction-regression-python/)
9 | 5. [Introduction to k-Nearest Neighbors: A powerful Machine Learning Algorithm](https://www.analyticsvidhya.com/blog/2018/03/introduction-k-neighbours-algorithm-clustering/)
10 | 6. [Wikipedia - k-nearest neighbors algorithm](https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm)
11 | 7. [Building a k-Nearest-Neighbors (k-NN) Model with Scikit-learn](https://towardsdatascience.com/building-a-k-nearest-neighbors-k-nn-model-with-scikit-learn-51209555453a)
12 | 8. [Understanding KNN(K-nearest neighbor) with example](https://kraj3.com.np/blog/2019/06/understanding-knnk-nearest-neighbor-with-example/)
13 | 9. [Dataset Extraction and analysis - Regression](https://towardsdatascience.com/linear-regression-on-boston-housing-dataset-f409b7e4a155)
14 | 10. [Weighted K-NN](https://www.geeksforgeeks.org/weighted-k-nn/)
15 |
16 | * Bias - Variance in K-NN
17 | * [Why does the variance decreases in KNN algorithm when we increase the K?](https://www.quora.com/Why-does-the-variance-decreases-in-KNN-algorithm-when-we-increase-the-K#)
18 | * [KNN: 1-nearest neighbor](https://stats.stackexchange.com/questions/151756/knn-1-nearest-neighbor/151770)
19 | * [Day 3 — K-Nearest Neighbors and Bias–Variance Tradeoff](https://medium.com/30-days-of-machine-learning/day-3-k-nearest-neighbors-and-bias-variance-tradeoff-75f84d515bdb)
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | .hypothesis/
51 | .pytest_cache/
52 |
53 | # Translations
54 | *.mo
55 | *.pot
56 |
57 | # Django stuff:
58 | *.log
59 | local_settings.py
60 | db.sqlite3
61 |
62 | # Flask stuff:
63 | instance/
64 | .webassets-cache
65 |
66 | # Scrapy stuff:
67 | .scrapy
68 |
69 | # Sphinx documentation
70 | docs/_build/
71 |
72 | # PyBuilder
73 | target/
74 |
75 | # Jupyter Notebook
76 | .ipynb_checkpoints
77 |
78 | # IPython
79 | profile_default/
80 | ipython_config.py
81 |
82 | # pyenv
83 | .python-version
84 |
85 | # pipenv
86 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
87 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
88 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
89 | # install all needed dependencies.
90 | #Pipfile.lock
91 |
92 | # celery beat schedule file
93 | celerybeat-schedule
94 |
95 | # SageMath parsed files
96 | *.sage.py
97 |
98 | # Environments
99 | .env
100 | .venv
101 | env/
102 | venv/
103 | ENV/
104 | env.bak/
105 | venv.bak/
106 |
107 | # Spyder project settings
108 | .spyderproject
109 | .spyproject
110 |
111 | # Rope project settings
112 | .ropeproject
113 |
114 | # mkdocs documentation
115 | /site
116 |
117 | # mypy
118 | .mypy_cache/
119 | .dmypy.json
120 | dmypy.json
121 |
122 | # Pyre type checker
123 | .pyre/
124 | Decision Trees/.vscode/settings.json
125 | .vscode/settings.json
126 |
--------------------------------------------------------------------------------
/Linear Regression/README.md:
--------------------------------------------------------------------------------
1 | - Linear Regression Articles and Videos
2 |
3 | - [x] [A BEGINNERS GUIDE TO REGRESSION TECHNIQUES](https://analyticsindiamag.com/a-beginners-guide-to-regression-techniques/)
4 | - [x] [Linear Regression Algorithm | Linear Regression in Python | Machine Learning Algorithm | Edureka - YouTube](https://www.youtube.com/watch?v=E5RjzSK0fvY)
5 | - [x] [In Depth: Linear Regression | Python Data Science Handbook](https://jakevdp.github.io/PythonDataScienceHandbook/05.06-linear-regression.html)
6 | - [x] [Linear Models - YouTube](https://www.youtube.com/playlist?list=PLblh5JKOoLUIzaEkCLIUxQFjPIlapw8nU)
7 | - [x] [Statistics 101: Linear Regression, The Very Basics - YouTube](https://www.youtube.com/watch?v=ZkjP5RJLQF4&list=PLIeGtxpvyG-LoKUpV0fSY8BGKIMIdmfCi&index=1)
8 | - [x] [How to Implement Linear Regression From Scratch in Python](https://machinelearningmastery.com/implement-linear-regression-stochastic-gradient-descent-scratch-python/)
9 | - [x] [Linear Regression using Python - Towards Data Science](https://towardsdatascience.com/linear-regression-using-python-b136c91bf0a2)
10 | - [x] [Mathematical explanation for Linear Regression working - GeeksforGeeks](https://www.geeksforgeeks.org/mathematical-explanation-for-linear-regression-working/)
11 | - [x] [Gradient Descent in Linear Regression - GeeksforGeeks](https://www.geeksforgeeks.org/gradient-descent-in-linear-regression/)
12 | - [x] [ML | Normal Equation in Linear Regression - GeeksforGeeks](https://www.geeksforgeeks.org/ml-normal-equation-in-linear-regression/)
13 | - [x] [Univariate Linear Regression in Python - GeeksforGeeks](https://www.geeksforgeeks.org/univariate-linear-regression-in-python/)
14 | - [x] [How to do Linear Regression and Logistic Regression in Machine Learning?](https://mlfromscratch.com/machine-learning-introduction-8-linear-regression-and-logistic-regression/#/)
15 | - [x] [Linear Regression (Python Implementation) - GeeksforGeeks](https://www.geeksforgeeks.org/linear-regression-python-implementation/)
16 | - [x] [ML | Multiple Linear Regression using Python - GeeksforGeeks](https://www.geeksforgeeks.org/ml-multiple-linear-regression-using-python/)
17 | - [x] [A Complete Tutorial on Ridge and Lasso Regression in Python](https://www.analyticsvidhya.com/blog/2016/01/complete-tutorial-ridge-lasso-regression-python/)
18 | - [x] [Python/linear_regression.py at master · TheAlgorithms/Python](https://github.com/TheAlgorithms/Python/blob/master/machine_learning/linear_regression.py)
19 | - [x] [Python | Linear Regression using sklearn - GeeksforGeeks](https://www.geeksforgeeks.org/python-linear-regression-using-sklearn/)
20 | - [ ] [ML | Locally weighted Linear Regression - GeeksforGeeks](https://www.geeksforgeeks.org/ml-locally-weighted-linear-regression/)
21 | - [x] [Statistics PL15 - Multiple Regression - YouTube](https://www.youtube.com/playlist?list=PLIeGtxpvyG-IqjoU8IiF0Yu1WtxNq_4z-)
22 | - [ ] [Statistics PL18 - Nonlinear Regression - YouTube](https://www.youtube.com/playlist?list=PLIeGtxpvyG-KE0M1r5cjbC_7Q_dVlKVq4)
23 | - [ ] [Isotonic Regression is THE Coolest Machine-Learning Model You Might Not Have Heard Of](https://towardsdatascience.com/isotonic-regression-is-the-coolest-machine-learning-model-you-might-not-have-heard-of-3ce14afc6d1e)
24 |
25 | - For 3-D plot:
26 | - [Multiple linear regression with Python, numpy, matplotlib, plot in 3d](https://www.aiproblog.com/index.php/forums/topic/multiple-linear-regression-with-python-numpy-matplotlib-plot-in-3d/)
27 |
--------------------------------------------------------------------------------
/Principal Component Analysis/README.md:
--------------------------------------------------------------------------------
1 | # Principal Component Analysis
2 |
3 | ---
4 | **Articles Used**
5 |
6 | * PCA
7 | * [x] [Principal Component Analysis](https://sebastianraschka.com/Articles/2015_pca_in_3_steps.html#preparing-the-iris-dataset)
8 | * [x] [Implementing a Principal Component Analysis (PCA)](https://sebastianraschka.com/Articles/2014_pca_step_by_step.html#4-computing-eigenvectors-and-corresponding-eigenvalues)
9 | * [x] [Kernel tricks and nonlinear dimensionality reduction via RBF kernel PCA](https://sebastianraschka.com/Articles/2014_kernel_pca.html)
10 | * [x] [The Mathematics Behind Principal Component Analysis](https://towardsdatascience.com/the-mathematics-behind-principal-component-analysis-fff2d7f4b643)
11 | * [x] [A tutorial on Principal Components Analysis](http://www.cs.otago.ac.nz/cosc453/student_tutorials/principal_components.pdf)
12 | * [x] [Principal Component Analysis - Youtube](https://www.youtube.com/playlist?list=PLBv09BD7ez_5_yapAg86Od6JeeypkS4YM)
13 | * [x] [Dimensionality Reduction For Dummies — Part 1: Intuition](https://towardsdatascience.com/https-medium-com-abdullatif-h-dimensionality-reduction-for-dummies-part-1-a8c9ec7b7e79)
14 | * [x] [Data Analysis 6: Principal Component Analysis (PCA) - Computerphile](https://www.youtube.com/watch?v=TJdH6rPA-TI)
15 | * [x] [Visual Explanation of Principal Component Analysis, Covariance, SVD](https://www.youtube.com/watch?v=5HNr_j6LmPc)
16 | * [x] [luis serrano pca](https://www.youtube.com/watch?v=g-Hb26agBFg)
17 | * [ ] [Dimensionality reduction and PCA](https://www.youtube.com/playlist?list=PLBv09BD7ez_4InDh85LM_43Bsw0cFDHdN)
18 | * [x] [What is an intuitive explanation for PCA? - Quora](https://www.quora.com/What-is-an-intuitive-explanation-for-PCA)
19 | * [x] [What is an intuitive explanation of the relation between PCA and SVD?](https://www.quora.com/What-is-an-intuitive-explanation-of-the-relation-between-PCA-and-SVD)
20 | * [x] [Why don't people use SVD in PCA rather than eigen value decomposition? - Quora](https://www.quora.com/Why-dont-people-use-SVD-in-PCA-rather-than-eigen-value-decomposition)
21 | * [x] [In Depth: Principal Component Analysis](https://jakevdp.github.io/PythonDataScienceHandbook/05.09-principal-component-analysis.html)
22 |
23 | * SVD
24 | * [x] [Gilbert strang - SVD](https://www.youtube.com/watch?v=rYz83XPxiZo)
25 | * [x] [You Don’t Know SVD (Singular Value Decomposition)](https://towardsdatascience.com/svd-8c2f72e264f)
26 | * [x] [(114) A geometrical interpretation of the SVD - YouTube](https://www.youtube.com/watch?v=NsNNI_-JPUY)
27 | * [ ] [SVD playlist](https://www.youtube.com/playlist?list=PLMrJAkhIeNNSVjnsviglFoY2nXildDCcv)
28 | * [ ] [Gilbert strang - Computing Eigenvalues and Singular Values](https://www.youtube.com/watch?v=d32WV1rKoVk)
29 | * [x] [Gilbert strang - Singular Value Decomposition](https://www.youtube.com/watch?v=mBcLRGuAFUk)
30 | * [x] [Computing the SVD](https://www.youtube.com/watch?v=cOUTpqlX-Xs&t=22s)
31 | * [x] [Lecture 47 — Singular Value Decomposition | Stanford University](https://www.youtube.com/watch?v=P5mlg91as1c)
32 | * [x] [How to Calculate the Singular-Value Decomposition (SVD) from Scratch with Python](https://machinelearningmastery.com/singular-value-decomposition-for-machine-learning/)
33 | * [x] [What is an intuitive explanation of singular value decomposition (SVD)? - Quora](https://www.quora.com/What-is-an-intuitive-explanation-of-singular-value-decomposition-SVD)
34 | * [x] [What is the meaning behind the singular value in Singular Value Decomposition? - Quora](https://www.quora.com/What-is-the-meaning-behind-the-singular-value-in-Singular-Value-Decomposition)
35 | * [x] [What is the best way of introducing singular value decomposition (SVD) on a linear algebra course? Why is it so important? Are there any applications which have a real impact? - Quora](https://www.quora.com/What-is-the-best-way-of-introducing-singular-value-decomposition-SVD-on-a-linear-algebra-course-Why-is-it-so-important-Are-there-any-applications-which-have-a-real-impact)
36 | * [x] [What's the difference between SVD and SVD++? - Quora](https://www.quora.com/Whats-the-difference-between-SVD-and-SVD++)
37 | * [x] [What is the purpose of Singular Value Decomposition? - Quora](https://www.quora.com/What-is-the-purpose-of-Singular-Value-Decomposition)
38 |
--------------------------------------------------------------------------------
/Random Forest/decision_tree.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from collections import Counter
3 |
4 |
5 | def giniImpurity(y):
6 | hist = np.bincount(y)
7 | ps = hist / len(y)
8 | return np.sum(ps * (1 - ps))
9 |
10 |
11 | class Node:
12 |
13 | def __init__(self, feature=None, threshold=None, left=None, right=None, *, value=None):
14 | self.feature = feature
15 | self.threshold = threshold
16 | self.left = left
17 | self.right = right
18 | self.value = value
19 |
20 | def is_leaf_node(self):
21 | return self.value is not None
22 |
23 |
24 | class DecisionTree():
25 |
26 | def __init__(self, min_samples_split=5, max_depth=100, n_feats=None):
27 | self.min_samples_split = min_samples_split
28 | self.max_depth = max_depth
29 | self.n_feats = n_feats # for random forest, choosing a subset of features
30 | self.root = None
31 |
32 | def fit(self, X, y):
33 | self.n_feats = X.shape[1] if not self.n_feats else min(
34 | self.n_feats, X.shape[1])
35 | self.root = self._grow_tree(X, y)
36 |
37 | def _grow_tree(self, X, y, depth=0):
38 | n_samples, n_features = X.shape
39 | n_labels = len(np.unique(y))
40 |
41 | # stopping criteria
42 | if (depth >= self.max_depth or n_labels == 1 or n_samples < self.min_samples_split):
43 | leaf_value = self._most_common_label(y)
44 | return Node(value=leaf_value)
45 |
46 | feat_idxs = np.random.choice(n_features, self.n_feats, replace=False)
47 |
48 | # greedily select the best split according to the gini gain
49 | best_feat, best_thresh = self._best_criteria(X, y, feat_idxs)
50 |
51 | # grow the children that result from the split
52 | left_idxs, right_idxs = self._split(X[:, best_feat], best_thresh)
53 | left = self._grow_tree(X[left_idxs, :], y[left_idxs], depth+1)
54 | right = self._grow_tree(X[right_idxs, :], y[right_idxs], depth+1)
55 | return Node(best_feat, best_thresh, left, right)
56 |
57 | def _best_criteria(self, X, y, feat_idxs):
58 | best_gain = -1
59 | split_idx, split_thresh = None, None
60 | for feat_idx in feat_idxs:
61 | X_column = X[:, feat_idx]
62 | thresholds = np.unique(X_column)
63 | for threshold in thresholds:
64 | gain = self._gini_gain(y, X_column, threshold)
65 |
66 | if gain > best_gain:
67 | best_gain = gain
68 | split_idx = feat_idx
69 | split_thresh = threshold
70 |
71 | return split_idx, split_thresh
72 |
73 | def _gini_gain(self, y, X_column, split_thresh):
74 | # parent
75 | parent_gini_impurity = giniImpurity(y)
76 |
77 | # generate split
78 | left_idxs, right_idxs = self._split(X_column, split_thresh)
79 |
80 | if len(left_idxs) == 0 or len(right_idxs) == 0:
81 | return 0
82 |
83 | # compute the weighted avg. for the children
84 | n = len(y)
85 | n_l, n_r = len(left_idxs), len(right_idxs)
86 | g_l, g_r = giniImpurity(y[left_idxs]), giniImpurity(y[right_idxs])
87 | child_gini_impurity = (n_l / n) * g_l + (n_r / n) * g_r
88 |
89 | # gini gain is difference in loss before vs. after split
90 | gg = parent_gini_impurity - child_gini_impurity
91 | return gg
92 |
93 | def _split(self, X_column, split_thresh):
94 | left_idxs = np.argwhere(X_column <= split_thresh).flatten()
95 | right_idxs = np.argwhere(X_column > split_thresh).flatten()
96 | return left_idxs, right_idxs
97 |
98 | def _most_common_label(self, y):
99 | counter = Counter(y)
100 | most_common = counter.most_common(1)[0][0]
101 | return most_common
102 |
103 | def predict(self, X):
104 | return np.array([self._traverse_tree(x, self.root) for x in X])
105 |
106 | def _traverse_tree(self, x, node):
107 | if node.is_leaf_node():
108 | return node.value
109 |
110 | if x[node.feature] <= node.threshold:
111 | return self._traverse_tree(x, node.left)
112 | return self._traverse_tree(x, node.right)
113 |
--------------------------------------------------------------------------------
/datasets/iris.data:
--------------------------------------------------------------------------------
1 | 5.1,3.5,1.4,0.2,Iris-setosa
2 | 4.9,3.0,1.4,0.2,Iris-setosa
3 | 4.7,3.2,1.3,0.2,Iris-setosa
4 | 4.6,3.1,1.5,0.2,Iris-setosa
5 | 5.0,3.6,1.4,0.2,Iris-setosa
6 | 5.4,3.9,1.7,0.4,Iris-setosa
7 | 4.6,3.4,1.4,0.3,Iris-setosa
8 | 5.0,3.4,1.5,0.2,Iris-setosa
9 | 4.4,2.9,1.4,0.2,Iris-setosa
10 | 4.9,3.1,1.5,0.1,Iris-setosa
11 | 5.4,3.7,1.5,0.2,Iris-setosa
12 | 4.8,3.4,1.6,0.2,Iris-setosa
13 | 4.8,3.0,1.4,0.1,Iris-setosa
14 | 4.3,3.0,1.1,0.1,Iris-setosa
15 | 5.8,4.0,1.2,0.2,Iris-setosa
16 | 5.7,4.4,1.5,0.4,Iris-setosa
17 | 5.4,3.9,1.3,0.4,Iris-setosa
18 | 5.1,3.5,1.4,0.3,Iris-setosa
19 | 5.7,3.8,1.7,0.3,Iris-setosa
20 | 5.1,3.8,1.5,0.3,Iris-setosa
21 | 5.4,3.4,1.7,0.2,Iris-setosa
22 | 5.1,3.7,1.5,0.4,Iris-setosa
23 | 4.6,3.6,1.0,0.2,Iris-setosa
24 | 5.1,3.3,1.7,0.5,Iris-setosa
25 | 4.8,3.4,1.9,0.2,Iris-setosa
26 | 5.0,3.0,1.6,0.2,Iris-setosa
27 | 5.0,3.4,1.6,0.4,Iris-setosa
28 | 5.2,3.5,1.5,0.2,Iris-setosa
29 | 5.2,3.4,1.4,0.2,Iris-setosa
30 | 4.7,3.2,1.6,0.2,Iris-setosa
31 | 4.8,3.1,1.6,0.2,Iris-setosa
32 | 5.4,3.4,1.5,0.4,Iris-setosa
33 | 5.2,4.1,1.5,0.1,Iris-setosa
34 | 5.5,4.2,1.4,0.2,Iris-setosa
35 | 4.9,3.1,1.5,0.1,Iris-setosa
36 | 5.0,3.2,1.2,0.2,Iris-setosa
37 | 5.5,3.5,1.3,0.2,Iris-setosa
38 | 4.9,3.1,1.5,0.1,Iris-setosa
39 | 4.4,3.0,1.3,0.2,Iris-setosa
40 | 5.1,3.4,1.5,0.2,Iris-setosa
41 | 5.0,3.5,1.3,0.3,Iris-setosa
42 | 4.5,2.3,1.3,0.3,Iris-setosa
43 | 4.4,3.2,1.3,0.2,Iris-setosa
44 | 5.0,3.5,1.6,0.6,Iris-setosa
45 | 5.1,3.8,1.9,0.4,Iris-setosa
46 | 4.8,3.0,1.4,0.3,Iris-setosa
47 | 5.1,3.8,1.6,0.2,Iris-setosa
48 | 4.6,3.2,1.4,0.2,Iris-setosa
49 | 5.3,3.7,1.5,0.2,Iris-setosa
50 | 5.0,3.3,1.4,0.2,Iris-setosa
51 | 7.0,3.2,4.7,1.4,Iris-versicolor
52 | 6.4,3.2,4.5,1.5,Iris-versicolor
53 | 6.9,3.1,4.9,1.5,Iris-versicolor
54 | 5.5,2.3,4.0,1.3,Iris-versicolor
55 | 6.5,2.8,4.6,1.5,Iris-versicolor
56 | 5.7,2.8,4.5,1.3,Iris-versicolor
57 | 6.3,3.3,4.7,1.6,Iris-versicolor
58 | 4.9,2.4,3.3,1.0,Iris-versicolor
59 | 6.6,2.9,4.6,1.3,Iris-versicolor
60 | 5.2,2.7,3.9,1.4,Iris-versicolor
61 | 5.0,2.0,3.5,1.0,Iris-versicolor
62 | 5.9,3.0,4.2,1.5,Iris-versicolor
63 | 6.0,2.2,4.0,1.0,Iris-versicolor
64 | 6.1,2.9,4.7,1.4,Iris-versicolor
65 | 5.6,2.9,3.6,1.3,Iris-versicolor
66 | 6.7,3.1,4.4,1.4,Iris-versicolor
67 | 5.6,3.0,4.5,1.5,Iris-versicolor
68 | 5.8,2.7,4.1,1.0,Iris-versicolor
69 | 6.2,2.2,4.5,1.5,Iris-versicolor
70 | 5.6,2.5,3.9,1.1,Iris-versicolor
71 | 5.9,3.2,4.8,1.8,Iris-versicolor
72 | 6.1,2.8,4.0,1.3,Iris-versicolor
73 | 6.3,2.5,4.9,1.5,Iris-versicolor
74 | 6.1,2.8,4.7,1.2,Iris-versicolor
75 | 6.4,2.9,4.3,1.3,Iris-versicolor
76 | 6.6,3.0,4.4,1.4,Iris-versicolor
77 | 6.8,2.8,4.8,1.4,Iris-versicolor
78 | 6.7,3.0,5.0,1.7,Iris-versicolor
79 | 6.0,2.9,4.5,1.5,Iris-versicolor
80 | 5.7,2.6,3.5,1.0,Iris-versicolor
81 | 5.5,2.4,3.8,1.1,Iris-versicolor
82 | 5.5,2.4,3.7,1.0,Iris-versicolor
83 | 5.8,2.7,3.9,1.2,Iris-versicolor
84 | 6.0,2.7,5.1,1.6,Iris-versicolor
85 | 5.4,3.0,4.5,1.5,Iris-versicolor
86 | 6.0,3.4,4.5,1.6,Iris-versicolor
87 | 6.7,3.1,4.7,1.5,Iris-versicolor
88 | 6.3,2.3,4.4,1.3,Iris-versicolor
89 | 5.6,3.0,4.1,1.3,Iris-versicolor
90 | 5.5,2.5,4.0,1.3,Iris-versicolor
91 | 5.5,2.6,4.4,1.2,Iris-versicolor
92 | 6.1,3.0,4.6,1.4,Iris-versicolor
93 | 5.8,2.6,4.0,1.2,Iris-versicolor
94 | 5.0,2.3,3.3,1.0,Iris-versicolor
95 | 5.6,2.7,4.2,1.3,Iris-versicolor
96 | 5.7,3.0,4.2,1.2,Iris-versicolor
97 | 5.7,2.9,4.2,1.3,Iris-versicolor
98 | 6.2,2.9,4.3,1.3,Iris-versicolor
99 | 5.1,2.5,3.0,1.1,Iris-versicolor
100 | 5.7,2.8,4.1,1.3,Iris-versicolor
101 | 6.3,3.3,6.0,2.5,Iris-virginica
102 | 5.8,2.7,5.1,1.9,Iris-virginica
103 | 7.1,3.0,5.9,2.1,Iris-virginica
104 | 6.3,2.9,5.6,1.8,Iris-virginica
105 | 6.5,3.0,5.8,2.2,Iris-virginica
106 | 7.6,3.0,6.6,2.1,Iris-virginica
107 | 4.9,2.5,4.5,1.7,Iris-virginica
108 | 7.3,2.9,6.3,1.8,Iris-virginica
109 | 6.7,2.5,5.8,1.8,Iris-virginica
110 | 7.2,3.6,6.1,2.5,Iris-virginica
111 | 6.5,3.2,5.1,2.0,Iris-virginica
112 | 6.4,2.7,5.3,1.9,Iris-virginica
113 | 6.8,3.0,5.5,2.1,Iris-virginica
114 | 5.7,2.5,5.0,2.0,Iris-virginica
115 | 5.8,2.8,5.1,2.4,Iris-virginica
116 | 6.4,3.2,5.3,2.3,Iris-virginica
117 | 6.5,3.0,5.5,1.8,Iris-virginica
118 | 7.7,3.8,6.7,2.2,Iris-virginica
119 | 7.7,2.6,6.9,2.3,Iris-virginica
120 | 6.0,2.2,5.0,1.5,Iris-virginica
121 | 6.9,3.2,5.7,2.3,Iris-virginica
122 | 5.6,2.8,4.9,2.0,Iris-virginica
123 | 7.7,2.8,6.7,2.0,Iris-virginica
124 | 6.3,2.7,4.9,1.8,Iris-virginica
125 | 6.7,3.3,5.7,2.1,Iris-virginica
126 | 7.2,3.2,6.0,1.8,Iris-virginica
127 | 6.2,2.8,4.8,1.8,Iris-virginica
128 | 6.1,3.0,4.9,1.8,Iris-virginica
129 | 6.4,2.8,5.6,2.1,Iris-virginica
130 | 7.2,3.0,5.8,1.6,Iris-virginica
131 | 7.4,2.8,6.1,1.9,Iris-virginica
132 | 7.9,3.8,6.4,2.0,Iris-virginica
133 | 6.4,2.8,5.6,2.2,Iris-virginica
134 | 6.3,2.8,5.1,1.5,Iris-virginica
135 | 6.1,2.6,5.6,1.4,Iris-virginica
136 | 7.7,3.0,6.1,2.3,Iris-virginica
137 | 6.3,3.4,5.6,2.4,Iris-virginica
138 | 6.4,3.1,5.5,1.8,Iris-virginica
139 | 6.0,3.0,4.8,1.8,Iris-virginica
140 | 6.9,3.1,5.4,2.1,Iris-virginica
141 | 6.7,3.1,5.6,2.4,Iris-virginica
142 | 6.9,3.1,5.1,2.3,Iris-virginica
143 | 5.8,2.7,5.1,1.9,Iris-virginica
144 | 6.8,3.2,5.9,2.3,Iris-virginica
145 | 6.7,3.3,5.7,2.5,Iris-virginica
146 | 6.7,3.0,5.2,2.3,Iris-virginica
147 | 6.3,2.5,5.0,1.9,Iris-virginica
148 | 6.5,3.0,5.2,2.0,Iris-virginica
149 | 6.2,3.4,5.4,2.3,Iris-virginica
150 | 5.9,3.0,5.1,1.8,Iris-virginica
151 |
152 |
--------------------------------------------------------------------------------
/datasets/iris_data.csv:
--------------------------------------------------------------------------------
1 | 5.1,3.5,1.4,0.2,Iris-setosa
2 | 4.9,3.0,1.4,0.2,Iris-setosa
3 | 4.7,3.2,1.3,0.2,Iris-setosa
4 | 4.6,3.1,1.5,0.2,Iris-setosa
5 | 5.0,3.6,1.4,0.2,Iris-setosa
6 | 5.4,3.9,1.7,0.4,Iris-setosa
7 | 4.6,3.4,1.4,0.3,Iris-setosa
8 | 5.0,3.4,1.5,0.2,Iris-setosa
9 | 4.4,2.9,1.4,0.2,Iris-setosa
10 | 4.9,3.1,1.5,0.1,Iris-setosa
11 | 5.4,3.7,1.5,0.2,Iris-setosa
12 | 4.8,3.4,1.6,0.2,Iris-setosa
13 | 4.8,3.0,1.4,0.1,Iris-setosa
14 | 4.3,3.0,1.1,0.1,Iris-setosa
15 | 5.8,4.0,1.2,0.2,Iris-setosa
16 | 5.7,4.4,1.5,0.4,Iris-setosa
17 | 5.4,3.9,1.3,0.4,Iris-setosa
18 | 5.1,3.5,1.4,0.3,Iris-setosa
19 | 5.7,3.8,1.7,0.3,Iris-setosa
20 | 5.1,3.8,1.5,0.3,Iris-setosa
21 | 5.4,3.4,1.7,0.2,Iris-setosa
22 | 5.1,3.7,1.5,0.4,Iris-setosa
23 | 4.6,3.6,1.0,0.2,Iris-setosa
24 | 5.1,3.3,1.7,0.5,Iris-setosa
25 | 4.8,3.4,1.9,0.2,Iris-setosa
26 | 5.0,3.0,1.6,0.2,Iris-setosa
27 | 5.0,3.4,1.6,0.4,Iris-setosa
28 | 5.2,3.5,1.5,0.2,Iris-setosa
29 | 5.2,3.4,1.4,0.2,Iris-setosa
30 | 4.7,3.2,1.6,0.2,Iris-setosa
31 | 4.8,3.1,1.6,0.2,Iris-setosa
32 | 5.4,3.4,1.5,0.4,Iris-setosa
33 | 5.2,4.1,1.5,0.1,Iris-setosa
34 | 5.5,4.2,1.4,0.2,Iris-setosa
35 | 4.9,3.1,1.5,0.1,Iris-setosa
36 | 5.0,3.2,1.2,0.2,Iris-setosa
37 | 5.5,3.5,1.3,0.2,Iris-setosa
38 | 4.9,3.1,1.5,0.1,Iris-setosa
39 | 4.4,3.0,1.3,0.2,Iris-setosa
40 | 5.1,3.4,1.5,0.2,Iris-setosa
41 | 5.0,3.5,1.3,0.3,Iris-setosa
42 | 4.5,2.3,1.3,0.3,Iris-setosa
43 | 4.4,3.2,1.3,0.2,Iris-setosa
44 | 5.0,3.5,1.6,0.6,Iris-setosa
45 | 5.1,3.8,1.9,0.4,Iris-setosa
46 | 4.8,3.0,1.4,0.3,Iris-setosa
47 | 5.1,3.8,1.6,0.2,Iris-setosa
48 | 4.6,3.2,1.4,0.2,Iris-setosa
49 | 5.3,3.7,1.5,0.2,Iris-setosa
50 | 5.0,3.3,1.4,0.2,Iris-setosa
51 | 7.0,3.2,4.7,1.4,Iris-versicolor
52 | 6.4,3.2,4.5,1.5,Iris-versicolor
53 | 6.9,3.1,4.9,1.5,Iris-versicolor
54 | 5.5,2.3,4.0,1.3,Iris-versicolor
55 | 6.5,2.8,4.6,1.5,Iris-versicolor
56 | 5.7,2.8,4.5,1.3,Iris-versicolor
57 | 6.3,3.3,4.7,1.6,Iris-versicolor
58 | 4.9,2.4,3.3,1.0,Iris-versicolor
59 | 6.6,2.9,4.6,1.3,Iris-versicolor
60 | 5.2,2.7,3.9,1.4,Iris-versicolor
61 | 5.0,2.0,3.5,1.0,Iris-versicolor
62 | 5.9,3.0,4.2,1.5,Iris-versicolor
63 | 6.0,2.2,4.0,1.0,Iris-versicolor
64 | 6.1,2.9,4.7,1.4,Iris-versicolor
65 | 5.6,2.9,3.6,1.3,Iris-versicolor
66 | 6.7,3.1,4.4,1.4,Iris-versicolor
67 | 5.6,3.0,4.5,1.5,Iris-versicolor
68 | 5.8,2.7,4.1,1.0,Iris-versicolor
69 | 6.2,2.2,4.5,1.5,Iris-versicolor
70 | 5.6,2.5,3.9,1.1,Iris-versicolor
71 | 5.9,3.2,4.8,1.8,Iris-versicolor
72 | 6.1,2.8,4.0,1.3,Iris-versicolor
73 | 6.3,2.5,4.9,1.5,Iris-versicolor
74 | 6.1,2.8,4.7,1.2,Iris-versicolor
75 | 6.4,2.9,4.3,1.3,Iris-versicolor
76 | 6.6,3.0,4.4,1.4,Iris-versicolor
77 | 6.8,2.8,4.8,1.4,Iris-versicolor
78 | 6.7,3.0,5.0,1.7,Iris-versicolor
79 | 6.0,2.9,4.5,1.5,Iris-versicolor
80 | 5.7,2.6,3.5,1.0,Iris-versicolor
81 | 5.5,2.4,3.8,1.1,Iris-versicolor
82 | 5.5,2.4,3.7,1.0,Iris-versicolor
83 | 5.8,2.7,3.9,1.2,Iris-versicolor
84 | 6.0,2.7,5.1,1.6,Iris-versicolor
85 | 5.4,3.0,4.5,1.5,Iris-versicolor
86 | 6.0,3.4,4.5,1.6,Iris-versicolor
87 | 6.7,3.1,4.7,1.5,Iris-versicolor
88 | 6.3,2.3,4.4,1.3,Iris-versicolor
89 | 5.6,3.0,4.1,1.3,Iris-versicolor
90 | 5.5,2.5,4.0,1.3,Iris-versicolor
91 | 5.5,2.6,4.4,1.2,Iris-versicolor
92 | 6.1,3.0,4.6,1.4,Iris-versicolor
93 | 5.8,2.6,4.0,1.2,Iris-versicolor
94 | 5.0,2.3,3.3,1.0,Iris-versicolor
95 | 5.6,2.7,4.2,1.3,Iris-versicolor
96 | 5.7,3.0,4.2,1.2,Iris-versicolor
97 | 5.7,2.9,4.2,1.3,Iris-versicolor
98 | 6.2,2.9,4.3,1.3,Iris-versicolor
99 | 5.1,2.5,3.0,1.1,Iris-versicolor
100 | 5.7,2.8,4.1,1.3,Iris-versicolor
101 | 6.3,3.3,6.0,2.5,Iris-virginica
102 | 5.8,2.7,5.1,1.9,Iris-virginica
103 | 7.1,3.0,5.9,2.1,Iris-virginica
104 | 6.3,2.9,5.6,1.8,Iris-virginica
105 | 6.5,3.0,5.8,2.2,Iris-virginica
106 | 7.6,3.0,6.6,2.1,Iris-virginica
107 | 4.9,2.5,4.5,1.7,Iris-virginica
108 | 7.3,2.9,6.3,1.8,Iris-virginica
109 | 6.7,2.5,5.8,1.8,Iris-virginica
110 | 7.2,3.6,6.1,2.5,Iris-virginica
111 | 6.5,3.2,5.1,2.0,Iris-virginica
112 | 6.4,2.7,5.3,1.9,Iris-virginica
113 | 6.8,3.0,5.5,2.1,Iris-virginica
114 | 5.7,2.5,5.0,2.0,Iris-virginica
115 | 5.8,2.8,5.1,2.4,Iris-virginica
116 | 6.4,3.2,5.3,2.3,Iris-virginica
117 | 6.5,3.0,5.5,1.8,Iris-virginica
118 | 7.7,3.8,6.7,2.2,Iris-virginica
119 | 7.7,2.6,6.9,2.3,Iris-virginica
120 | 6.0,2.2,5.0,1.5,Iris-virginica
121 | 6.9,3.2,5.7,2.3,Iris-virginica
122 | 5.6,2.8,4.9,2.0,Iris-virginica
123 | 7.7,2.8,6.7,2.0,Iris-virginica
124 | 6.3,2.7,4.9,1.8,Iris-virginica
125 | 6.7,3.3,5.7,2.1,Iris-virginica
126 | 7.2,3.2,6.0,1.8,Iris-virginica
127 | 6.2,2.8,4.8,1.8,Iris-virginica
128 | 6.1,3.0,4.9,1.8,Iris-virginica
129 | 6.4,2.8,5.6,2.1,Iris-virginica
130 | 7.2,3.0,5.8,1.6,Iris-virginica
131 | 7.4,2.8,6.1,1.9,Iris-virginica
132 | 7.9,3.8,6.4,2.0,Iris-virginica
133 | 6.4,2.8,5.6,2.2,Iris-virginica
134 | 6.3,2.8,5.1,1.5,Iris-virginica
135 | 6.1,2.6,5.6,1.4,Iris-virginica
136 | 7.7,3.0,6.1,2.3,Iris-virginica
137 | 6.3,3.4,5.6,2.4,Iris-virginica
138 | 6.4,3.1,5.5,1.8,Iris-virginica
139 | 6.0,3.0,4.8,1.8,Iris-virginica
140 | 6.9,3.1,5.4,2.1,Iris-virginica
141 | 6.7,3.1,5.6,2.4,Iris-virginica
142 | 6.9,3.1,5.1,2.3,Iris-virginica
143 | 5.8,2.7,5.1,1.9,Iris-virginica
144 | 6.8,3.2,5.9,2.3,Iris-virginica
145 | 6.7,3.3,5.7,2.5,Iris-virginica
146 | 6.7,3.0,5.2,2.3,Iris-virginica
147 | 6.3,2.5,5.0,1.9,Iris-virginica
148 | 6.5,3.0,5.2,2.0,Iris-virginica
149 | 6.2,3.4,5.4,2.3,Iris-virginica
150 | 5.9,3.0,5.1,1.8,Iris-virginica
151 |
152 |
--------------------------------------------------------------------------------
/Apriori algorithm/apriori_algorithm.py:
--------------------------------------------------------------------------------
1 | # Apriori algorithm developed and used on a sample dataset
2 | # This code was written just for demonstration and learning purposes
3 |
4 | from collections import Counter
5 | from itertools import combinations
6 | import numpy as np
7 |
8 | # transactions = {
9 | # 1: ["a", "c", "d"],
10 | # 2: ["b", "c", "e"],
11 | # 3: ["a", "b", "c", "e"],
12 | # 5: ["b", "e"],
13 | # 6: ["a", "c", "e"]
14 | # }
15 |
16 |
17 | transactions = {
18 | 1: ["1", "3", "4"],
19 | 2: ["2", "3", "5"],
20 | 3: ["1", "2", "3", "5"],
21 | 5: ["2", "5"],
22 | 6: ["1", "3", "5"]
23 | }
24 |
25 | min_support_count = 2
26 | min_confidence_value = 0.6
27 |
28 |
29 | # apriori pruning concept
30 | def _pruning(current, previous, size):
31 | final_keys = []
32 | previous = [tuple(i) for i in previous]
33 | for key in current:
34 | FLAG = False
35 | current_comb = list(combinations(key, size))
36 | for i in current_comb:
37 | if i in previous or i[::-1] in previous:
38 | FLAG = True
39 | else:
40 | FLAG = False
41 | break
42 |
43 | if FLAG:
44 | final_keys.append(key)
45 |
46 | return final_keys
47 |
48 |
49 | def support_value(itemset_keys_, transactions):
50 | itemset = {key: 0 for key in itemset_keys_}
51 |
52 | for keys in itemset_keys_:
53 | for val in transactions.values():
54 | if set(keys) & set(val) == set(keys):
55 | itemset[keys] += 1
56 | return itemset
57 |
58 |
59 | # creating frequent itemset
60 | def get_frequent_itemset(size=None, transactions=None, itemset=None):
61 | if size == 1:
62 | itemset = Counter()
63 |
64 | for val in transactions.values():
65 | itemset.update(val)
66 |
67 | else:
68 |
69 | prev_itemset_keys = list(itemset.keys())
70 | prev_itemset = itemset.copy()
71 |
72 | valid_keys = list(set(itemset.keys()))
73 | # flatten list of tuple -> keys: [(), ()] -> []
74 | # useful for running a combination of all the chosen features
75 | l = []
76 | for row in valid_keys:
77 | l.extend(row)
78 |
79 | valid_keys = set(l)
80 |
81 | # candidate itemset keys
82 | itemset_keys_ = list(combinations(valid_keys, size))
83 |
84 | # Apriori algorithm is based on theconcept that a subset
85 | # of a frequent itemset must also be a frequent itemset
86 | # so we are pruning away those features whose subset are not present
87 | # in the previous frequent itemset
88 | if size >= 2:
89 | itemset_keys_ = _pruning(
90 | itemset_keys_, prev_itemset_keys, size - 1)
91 |
92 | # finding support value for each of the selected itemset feature combination
93 | itemset = support_value(itemset_keys_, transactions)
94 |
95 | # defaulting back to th previous frequent itemset if
96 | # the iteration doesn't find any itemset which has the theshold required
97 | if itemset == {}:
98 | itemset = prev_itemset
99 |
100 | # getting frequent itemset from itemset
101 | # Frequent Itemset is an itemset whose support
102 | # value is greater than a threshold value(support).
103 |
104 | frequent_itemset = {}
105 | for key, val in itemset.items():
106 | if val >= min_support_count:
107 | frequent_itemset[key] = val
108 |
109 | return frequent_itemset
110 |
111 |
112 | def finding_subsets(frequent_set):
113 | item_list = []
114 | size = len(list(frequent_set.keys())[0])
115 | for key in frequent_set.keys():
116 | subsets = []
117 | for i in range(1, size):
118 | subsets.append(list(combinations(key, i)))
119 |
120 | subsets = list(np.array(subsets).flatten())
121 | subsets.insert(0, key)
122 | item_list.append(subsets)
123 |
124 | return item_list
125 |
126 |
127 | def finding_rules(itemset_sub):
128 | print("Antecedents --> Consequents --- Confidence")
129 | for i in range(1, len(itemset_sub)):
130 |
131 | # passing as list as we have designed support_value function as
132 | # a function that takes an iteratable list of itemsets
133 | x = support_value([itemset_sub[0], ], transactions)
134 | y = support_value([itemset_sub[i], ], transactions)
135 | confidence = list(x.values())[0] / list(y.values())[0]
136 | if confidence >= min_confidence_value:
137 | print(
138 | f"{itemset_sub[i]} --> {itemset_sub[0]} --- {round(confidence, 2)}")
139 |
140 |
141 | print("""
142 | ITEMS
143 | 1: Banana
144 | 2: Eggs
145 | 3: Milk
146 | 4: Tea
147 | 5: Bread
148 |
149 | """)
150 |
151 | f = {}
152 |
153 | for i in range(1, 5):
154 | f = get_frequent_itemset(size=i, transactions=transactions,
155 | itemset=f)
156 |
157 | # frequent_itemsets
158 |
159 | print("Frequent Itemsets...")
160 | for key, val in f.items():
161 | print(f"Itemset: {key}, support value: {val}")
162 |
163 |
164 | subset = finding_subsets(f)
165 |
166 | for i in subset:
167 | print(f"Rules for itemset - {i[0]}")
168 | finding_rules(i)
169 | print()
170 |
--------------------------------------------------------------------------------
/K-means/Spiral.txt:
--------------------------------------------------------------------------------
1 | f1 f2 label
2 | 31.95 7.95 3
3 | 31.15 7.3 3
4 | 30.45 6.65 3
5 | 29.7 6 3
6 | 28.9 5.55 3
7 | 28.05 5 3
8 | 27.2 4.55 3
9 | 26.35 4.15 3
10 | 25.4 3.85 3
11 | 24.6 3.6 3
12 | 23.6 3.3 3
13 | 22.75 3.15 3
14 | 21.85 3.05 3
15 | 20.9 3 3
16 | 20 2.9 3
17 | 19.1 3 3
18 | 18.2 3.2 3
19 | 17.3 3.25 3
20 | 16.55 3.5 3
21 | 15.7 3.7 3
22 | 14.85 4.1 3
23 | 14.15 4.4 3
24 | 13.4 4.75 3
25 | 12.7 5.2 3
26 | 12.05 5.65 3
27 | 11.45 6.15 3
28 | 10.9 6.65 3
29 | 10.3 7.25 3
30 | 9.7 7.85 3
31 | 9.35 8.35 3
32 | 8.9 9.05 3
33 | 8.55 9.65 3
34 | 8.15 10.35 3
35 | 7.95 10.95 3
36 | 7.75 11.7 3
37 | 7.55 12.35 3
38 | 7.45 13 3
39 | 7.35 13.75 3
40 | 7.3 14.35 3
41 | 7.35 14.95 3
42 | 7.35 15.75 3
43 | 7.55 16.35 3
44 | 7.7 16.95 3
45 | 7.8 17.55 3
46 | 8.05 18.15 3
47 | 8.3 18.75 3
48 | 8.65 19.3 3
49 | 8.9 19.85 3
50 | 9.3 20.3 3
51 | 9.65 20.8 3
52 | 10.2 21.25 3
53 | 10.6 21.65 3
54 | 11.1 22.15 3
55 | 11.55 22.45 3
56 | 11.95 22.7 3
57 | 12.55 23 3
58 | 13.05 23.2 3
59 | 13.45 23.4 3
60 | 14 23.55 3
61 | 14.55 23.6 3
62 | 15.1 23.75 3
63 | 15.7 23.75 3
64 | 16.15 23.85 3
65 | 16.7 23.8 3
66 | 17.15 23.75 3
67 | 17.75 23.75 3
68 | 18.2 23.6 3
69 | 18.65 23.5 3
70 | 19.1 23.35 3
71 | 19.6 23.15 3
72 | 20 22.95 3
73 | 20.4 22.7 3
74 | 20.7 22.55 3
75 | 21 22.15 3
76 | 21.45 21.95 3
77 | 21.75 21.55 3
78 | 22 21.25 3
79 | 22.25 21 3
80 | 22.5 20.7 3
81 | 22.65 20.35 3
82 | 22.75 20.05 3
83 | 22.9 19.65 3
84 | 23 19.35 3
85 | 23.1 19 3
86 | 23.15 18.65 3
87 | 23.2 18.25 3
88 | 23.2 18.05 3
89 | 23.2 17.8 3
90 | 23.1 17.45 3
91 | 23.05 17.15 3
92 | 22.9 16.9 3
93 | 22.85 16.6 3
94 | 22.7 16.4 3
95 | 22.6 16.2 3
96 | 22.55 16.05 3
97 | 22.4 15.95 3
98 | 22.35 15.8 3
99 | 22.2 15.65 3
100 | 22.15 15.55 3
101 | 22 15.4 3
102 | 21.9 15.3 3
103 | 21.85 15.25 3
104 | 21.75 15.15 3
105 | 21.65 15.05 3
106 | 21.55 15 3
107 | 21.5 14.9 3
108 | 19.35 31.65 1
109 | 20.35 31.45 1
110 | 21.35 31.1 1
111 | 22.25 30.9 1
112 | 23.2 30.45 1
113 | 23.95 30.05 1
114 | 24.9 29.65 1
115 | 25.6 29.05 1
116 | 26.35 28.5 1
117 | 27.15 27.9 1
118 | 27.75 27.35 1
119 | 28.3 26.6 1
120 | 28.95 25.85 1
121 | 29.5 25.15 1
122 | 29.95 24.45 1
123 | 30.4 23.7 1
124 | 30.6 22.9 1
125 | 30.9 22.1 1
126 | 31.25 21.3 1
127 | 31.35 20.55 1
128 | 31.5 19.7 1
129 | 31.55 18.9 1
130 | 31.65 18.15 1
131 | 31.6 17.35 1
132 | 31.45 16.55 1
133 | 31.3 15.8 1
134 | 31.15 15.05 1
135 | 30.9 14.35 1
136 | 30.6 13.65 1
137 | 30.3 13 1
138 | 29.9 12.3 1
139 | 29.5 11.75 1
140 | 29 11.15 1
141 | 28.5 10.6 1
142 | 28 10.1 1
143 | 27.55 9.65 1
144 | 26.9 9.1 1
145 | 26.25 8.8 1
146 | 25.7 8.4 1
147 | 25.15 8.05 1
148 | 24.5 7.75 1
149 | 23.9 7.65 1
150 | 23.15 7.4 1
151 | 22.5 7.3 1
152 | 21.9 7.1 1
153 | 21.25 7.05 1
154 | 20.5 7 1
155 | 19.9 6.95 1
156 | 19.25 7.05 1
157 | 18.75 7.1 1
158 | 18.05 7.25 1
159 | 17.5 7.35 1
160 | 16.9 7.6 1
161 | 16.35 7.8 1
162 | 15.8 8.05 1
163 | 15.4 8.35 1
164 | 14.9 8.7 1
165 | 14.45 8.9 1
166 | 13.95 9.3 1
167 | 13.6 9.65 1
168 | 13.25 10.1 1
169 | 12.95 10.55 1
170 | 12.65 10.9 1
171 | 12.35 11.4 1
172 | 12.2 11.75 1
173 | 11.95 12.2 1
174 | 11.8 12.65 1
175 | 11.75 13.05 1
176 | 11.55 13.6 1
177 | 11.55 14 1
178 | 11.55 14.35 1
179 | 11.55 14.7 1
180 | 11.6 15.25 1
181 | 11.65 15.7 1
182 | 11.8 16.05 1
183 | 11.85 16.5 1
184 | 12 16.75 1
185 | 12.15 17.2 1
186 | 12.3 17.6 1
187 | 12.55 17.85 1
188 | 12.8 18.05 1
189 | 13.1 18.4 1
190 | 13.3 18.6 1
191 | 13.55 18.85 1
192 | 13.8 19.05 1
193 | 14.15 19.25 1
194 | 14.45 19.5 1
195 | 14.85 19.55 1
196 | 15 19.7 1
197 | 15.25 19.7 1
198 | 15.55 19.85 1
199 | 15.95 19.9 1
200 | 16.2 19.9 1
201 | 16.55 19.9 1
202 | 16.85 19.9 1
203 | 17.2 19.9 1
204 | 17.4 19.8 1
205 | 17.65 19.75 1
206 | 17.8 19.7 1
207 | 18 19.6 1
208 | 18.2 19.55 1
209 | 3.9 9.6 2
210 | 3.55 10.65 2
211 | 3.35 11.4 2
212 | 3.1 12.35 2
213 | 3.1 13.25 2
214 | 3.05 14.15 2
215 | 3 15.1 2
216 | 3.1 16 2
217 | 3.2 16.85 2
218 | 3.45 17.75 2
219 | 3.7 18.7 2
220 | 3.95 19.55 2
221 | 4.35 20.25 2
222 | 4.7 21.1 2
223 | 5.15 21.8 2
224 | 5.6 22.5 2
225 | 6.2 23.3 2
226 | 6.8 23.85 2
227 | 7.35 24.45 2
228 | 8.05 24.95 2
229 | 8.8 25.45 2
230 | 9.5 26 2
231 | 10.2 26.35 2
232 | 10.9 26.75 2
233 | 11.7 27 2
234 | 12.45 27.25 2
235 | 13.3 27.6 2
236 | 14.05 27.6 2
237 | 14.7 27.75 2
238 | 15.55 27.75 2
239 | 16.4 27.75 2
240 | 17.1 27.75 2
241 | 17.9 27.75 2
242 | 18.55 27.7 2
243 | 19.35 27.6 2
244 | 20.1 27.35 2
245 | 20.7 27.1 2
246 | 21.45 26.8 2
247 | 22.05 26.5 2
248 | 22.7 26.15 2
249 | 23.35 25.65 2
250 | 23.8 25.3 2
251 | 24.3 24.85 2
252 | 24.75 24.35 2
253 | 25.25 23.95 2
254 | 25.65 23.45 2
255 | 26.05 23 2
256 | 26.2 22.3 2
257 | 26.6 21.8 2
258 | 26.75 21.25 2
259 | 27 20.7 2
260 | 27.15 20.15 2
261 | 27.15 19.6 2
262 | 27.35 19.1 2
263 | 27.35 18.45 2
264 | 27.4 18 2
265 | 27.3 17.4 2
266 | 27.15 16.9 2
267 | 27 16.4 2
268 | 27 15.9 2
269 | 26.75 15.35 2
270 | 26.55 14.85 2
271 | 26.3 14.45 2
272 | 25.95 14.1 2
273 | 25.75 13.7 2
274 | 25.35 13.3 2
275 | 25.05 12.95 2
276 | 24.8 12.7 2
277 | 24.4 12.45 2
278 | 24.05 12.2 2
279 | 23.55 11.85 2
280 | 23.2 11.65 2
281 | 22.75 11.4 2
282 | 22.3 11.3 2
283 | 21.9 11.1 2
284 | 21.45 11.05 2
285 | 21.1 11 2
286 | 20.7 10.95 2
287 | 20.35 10.95 2
288 | 19.95 11 2
289 | 19.55 11 2
290 | 19.15 11.05 2
291 | 18.85 11.1 2
292 | 18.45 11.25 2
293 | 18.15 11.35 2
294 | 17.85 11.5 2
295 | 17.5 11.7 2
296 | 17.2 11.95 2
297 | 17 12.05 2
298 | 16.75 12.2 2
299 | 16.65 12.35 2
300 | 16.5 12.5 2
301 | 16.35 12.7 2
302 | 16.2 12.8 2
303 | 16.15 12.95 2
304 | 16 13.1 2
305 | 15.95 13.25 2
306 | 15.9 13.4 2
307 | 15.8 13.5 2
308 | 15.8 13.65 2
309 | 15.75 13.85 2
310 | 15.65 14.05 2
311 | 15.65 14.25 2
312 | 15.65 14.5 2
313 | 15.65 14.6 2
314 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Machine Learning Algorithms
2 |
3 | [](https://mybinder.org/v2/gh/veb-101/Machine-Learning-Algorithms/master) [](https://colab.research.google.com/github/veb-101/Machine-Learning-Algorithms/blob/master/) [](https://github.com/veb-101/Machine-Learning-Algorithms/issues) [](https://github.com/veb-101/Machine-Learning-Algorithms/pulls)
4 |
5 | [](https://repl.it/repls/folder/machine%20learning%20algorithms?ref=button)
6 |
7 | ---
8 |
9 | #### Numpy implementation of some basic machine learning algorithms
10 |
11 |
12 |
13 | ---
14 |
15 | ##### Run Online
16 |
17 | | Sr. No. | Algorithm | View | Python File | Colab Notebook |
18 | | ------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
19 | | 1.a | KNN - Classification | [notebook](https://nbviewer.jupyter.org/github/veb-101/Machine-Learning-Algorithms/blob/master/K-Nearest%20Neigbors/KNN-Classifier.ipynb) | [.py](https://repl.it/@VaibhavSingh4/1a-k-NN-classification) | [](https://colab.research.google.com/github/veb-101/Machine-Learning-Algorithms/blob/master/K-Nearest%20Neigbors/KNN-Classifier.ipynb) |
20 | | 1.b | KNN - Regression | [notebook](https://nbviewer.jupyter.org/github/veb-101/Machine-Learning-Algorithms/blob/master/K-Nearest%20Neigbors/KNN-Regression.ipynb) | [.py](https://repl.it/@VaibhavSingh4/1b-k-NN-Regression) | [](https://colab.research.google.com/github/veb-101/Machine-Learning-Algorithms/blob/master/K-Nearest%20Neigbors/KNN-Regression.ipynb) |
21 | | 1.c | KNN - Weighted Classification | [notebook](https://nbviewer.jupyter.org/github/veb-101/Machine-Learning-Algorithms/blob/master/K-Nearest%20Neigbors/KNN_weighted_classification.ipynb) | [.py](https://repl.it/@VaibhavSingh4/1c-KNN-weighted-classification) | [](https://colab.research.google.com/github/veb-101/Machine-Learning-Algorithms/blob/master/K-Nearest%20Neigbors/KNN_weighted_classification.ipynb) |
22 | | 2 | Linear Regression | [notebook](https://nbviewer.jupyter.org/github/veb-101/Machine-Learning-Algorithms/blob/master/Linear%20Regression/linear_regression.ipynb) | | [](https://colab.research.google.com/github/veb-101/Machine-Learning-Algorithms/blob/master/Linear%20Regression/linear_regression.ipynb) |
23 | | 3 | Logistic Regression | [notebook](https://nbviewer.jupyter.org/github/veb-101/Machine-Learning-Algorithms/blob/master/Logistic%20Regression/logistic%20regression.ipynb) | [.py](https/repl.it/@VaibhavSingh4/Logistic-Regression) | [](https://colab.research.google.com/github/veb-101/Machine-Learning-Algorithms/blob/master/Logistic%20Regression/logistic%20regression.ipynb) |
24 | | 4 | Decision Trees | [notebook](https://nbviewer.jupyter.org/github/veb-101/Machine-Learning-Algorithms/blob/master/Decision%20Trees/decision%20tree.ipynb) | [.py](https://repl.it/@VaibhavSingh4/decision-tree) | [](https://colab.research.google.com/github/veb-101/Machine-Learning-Algorithms/blob/master/Decision%20Trees/decision%20tree.ipynb) |
25 | | 5 | Naive Bayes | [notebook](https://nbviewer.jupyter.org/github/veb-101/Machine-Learning-Algorithms/blob/master/Naive%20Bayes/Naive%20Bayes.ipynb) | | [](https://colab.research.google.com/github/veb-101/Machine-Learning-Algorithms/blob/master/Naive%20Bayes/Naive%20Bayes.ipynb) |
26 | | 6 | Random Forest | [notebook](https://nbviewer.jupyter.org/github/veb-101/Machine-Learning-Algorithms/blob/master/Random%20Forest/random_forest.ipynb) | | [](https://colab.research.google.com/github/veb-101/Machine-Learning-Algorithms/blob/master/Random%20Forest/random_forest.ipynb) |
27 | | 7 | AdaBoost | [notebook](https://nbviewer.jupyter.org/github/veb-101/Machine-Learning-Algorithms/blob/master/Boosting%20-%20AdaBoost/adaboost.ipynb) | | [](https://colab.research.google.com/github/veb-101/Machine-Learning-Algorithms/blob/master/Boosting%20-%20AdaBoost/adaboost.ipynb) |
28 | | 8 | K-means Clustering | [notebook](https://nbviewer.jupyter.org/github/veb-101/Machine-Learning-Algorithms/blob/master/K-means/K_means.ipynb) | [.py](https://repl.it/@VaibhavSingh4/k-means) | [](https://colab.research.google.com/github/veb-101/Machine-Learning-Algorithms/blob/master/K-means/K_means.ipynb) |
29 | | 9 | PCA | [notebook](https://nbviewer.jupyter.org/github/veb-101/Machine-Learning-Algorithms/blob/master/Principal%20Component%20Analysis/dimensionality%20reduction.ipynb) | | [](https://colab.research.google.com/github/veb-101/Machine-Learning-Algorithms/blob/master/Principal%20Component%20Analysis/dimensionality%20reduction.ipynb) |
30 | | 10 | Apriori Algorithm | | [.py](https://repl.it/@VaibhavSingh4/Apriori-Algorithm) | |
--------------------------------------------------------------------------------
/Random Forest/random_forest.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "toc": true
7 | },
8 | "source": [
9 | "
Table of Contents
\n",
10 | ""
11 | ]
12 | },
13 | {
14 | "cell_type": "code",
15 | "execution_count": 1,
16 | "metadata": {
17 | "ExecuteTime": {
18 | "end_time": "2020-04-12T16:49:27.604267Z",
19 | "start_time": "2020-04-12T16:49:25.091457Z"
20 | }
21 | },
22 | "outputs": [],
23 | "source": [
24 | "import numpy as np\n",
25 | "\n",
26 | "from sklearn import datasets\n",
27 | "from sklearn.model_selection import train_test_split\n",
28 | "from sklearn.metrics import precision_score, recall_score, f1_score\n",
29 | "\n",
30 | "import pandas as pd\n",
31 | "\n",
32 | "from collections import Counter\n",
33 | "from decision_tree import DecisionTree"
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {},
39 | "source": [
40 | "# Model Definition\n",
41 | "\n",
42 | "Using previously written Decision tree"
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": 2,
48 | "metadata": {
49 | "ExecuteTime": {
50 | "end_time": "2020-04-12T16:49:27.617602Z",
51 | "start_time": "2020-04-12T16:49:27.610032Z"
52 | }
53 | },
54 | "outputs": [],
55 | "source": [
56 | "def bootstrap_sample(X, y):\n",
57 | " n_samples = X.shape[0]\n",
58 | " idxs = np.random.choice(n_samples, n_samples, replace=True)\n",
59 | " return X[idxs], y[idxs]\n",
60 | "\n",
61 | "\n",
62 | "def most_common_label(y):\n",
63 | " counter = Counter(y)\n",
64 | " most_common = counter.most_common(1)[0][0]\n",
65 | " return most_common"
66 | ]
67 | },
68 | {
69 | "cell_type": "code",
70 | "execution_count": 3,
71 | "metadata": {
72 | "ExecuteTime": {
73 | "end_time": "2020-04-12T16:49:27.819326Z",
74 | "start_time": "2020-04-12T16:49:27.621157Z"
75 | }
76 | },
77 | "outputs": [],
78 | "source": [
79 | "class RandomForest:\n",
80 | "\n",
81 | " def __init__(self, n_trees=10, min_samples_split=2,\n",
82 | " max_depth=100, n_feats=None):\n",
83 | " self.n_trees = n_trees\n",
84 | " self.min_samples_split = min_samples_split\n",
85 | " self.max_depth = max_depth\n",
86 | " self.n_feats = n_feats\n",
87 | " self.trees = []\n",
88 | "\n",
89 | " def fit(self, X, y):\n",
90 | " self.trees = []\n",
91 | " for _ in range(self.n_trees):\n",
92 | " tree = DecisionTree(min_samples_split=self.min_samples_split,\n",
93 | " max_depth=self.max_depth, n_feats=self.n_feats)\n",
94 | " X_samp, y_samp = bootstrap_sample(X, y)\n",
95 | " tree.fit(X_samp, y_samp)\n",
96 | " self.trees.append(tree)\n",
97 | "\n",
98 | " def predict(self, X):\n",
99 | " tree_preds = np.array([tree.predict(X) for tree in self.trees])\n",
100 | " tree_preds = np.swapaxes(tree_preds, 0, 1)\n",
101 | " y_pred = [most_common_label(tree_pred) for tree_pred in tree_preds]\n",
102 | " return np.array(y_pred)"
103 | ]
104 | },
105 | {
106 | "cell_type": "code",
107 | "execution_count": 4,
108 | "metadata": {
109 | "ExecuteTime": {
110 | "end_time": "2020-04-12T16:49:27.994854Z",
111 | "start_time": "2020-04-12T16:49:27.833497Z"
112 | }
113 | },
114 | "outputs": [],
115 | "source": [
116 | "def accuracy(y_true, y_pred):\n",
117 | " accuracy = np.sum(y_true == y_pred) / len(y_true)\n",
118 | " return accuracy"
119 | ]
120 | },
121 | {
122 | "cell_type": "markdown",
123 | "metadata": {},
124 | "source": [
125 | "# Training and testing on Diabetes Dataset"
126 | ]
127 | },
128 | {
129 | "cell_type": "code",
130 | "execution_count": 5,
131 | "metadata": {
132 | "ExecuteTime": {
133 | "end_time": "2020-04-12T16:49:29.037211Z",
134 | "start_time": "2020-04-12T16:49:28.003482Z"
135 | }
136 | },
137 | "outputs": [],
138 | "source": [
139 | "cols = [\"Pregnancies\", \"Glucose\", \"BloodPressure\", \"SkinThickness\",\n",
140 | " \"Insulin\", \"BMI\", \"DiabetesPedigreeFunction\", \"Age\", \"Outcome\"]\n",
141 | "url = \"https://gist.githubusercontent.com/ktisha/c21e73a1bd1700294ef790c56c8aec1f/raw/819b69b5736821ccee93d05b51de0510bea00294/pima-indians-diabetes.csv\"\n",
142 | "diabetes_data = pd.read_csv(url, skiprows=9, header=None, names=cols)"
143 | ]
144 | },
145 | {
146 | "cell_type": "code",
147 | "execution_count": 6,
148 | "metadata": {
149 | "ExecuteTime": {
150 | "end_time": "2020-04-12T16:49:29.087001Z",
151 | "start_time": "2020-04-12T16:49:29.044736Z"
152 | }
153 | },
154 | "outputs": [
155 | {
156 | "data": {
157 | "text/plain": [
158 | "(768, 9)"
159 | ]
160 | },
161 | "execution_count": 6,
162 | "metadata": {},
163 | "output_type": "execute_result"
164 | }
165 | ],
166 | "source": [
167 | "diabetes_data.shape"
168 | ]
169 | },
170 | {
171 | "cell_type": "code",
172 | "execution_count": 7,
173 | "metadata": {
174 | "ExecuteTime": {
175 | "end_time": "2020-04-12T16:49:29.305869Z",
176 | "start_time": "2020-04-12T16:49:29.103088Z"
177 | }
178 | },
179 | "outputs": [],
180 | "source": [
181 | "X = diabetes_data[cols[:-1]].values\n",
182 | "y = diabetes_data[cols[-1]].values"
183 | ]
184 | },
185 | {
186 | "cell_type": "code",
187 | "execution_count": 8,
188 | "metadata": {
189 | "ExecuteTime": {
190 | "end_time": "2020-04-12T16:49:29.457842Z",
191 | "start_time": "2020-04-12T16:49:29.316553Z"
192 | }
193 | },
194 | "outputs": [],
195 | "source": [
196 | "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, stratify=y, random_state=42)"
197 | ]
198 | },
199 | {
200 | "cell_type": "code",
201 | "execution_count": 9,
202 | "metadata": {
203 | "ExecuteTime": {
204 | "end_time": "2020-04-12T16:49:43.284602Z",
205 | "start_time": "2020-04-12T16:49:29.464289Z"
206 | }
207 | },
208 | "outputs": [],
209 | "source": [
210 | "rnd_clf = RandomForest(max_depth=10, n_trees=10, n_feats=6)\n",
211 | "rnd_clf.fit(X_train, y_train)\n",
212 | "y_pred = rnd_clf.predict(X_test)"
213 | ]
214 | },
215 | {
216 | "cell_type": "markdown",
217 | "metadata": {},
218 | "source": [
219 | "# Metrics"
220 | ]
221 | },
222 | {
223 | "cell_type": "code",
224 | "execution_count": 10,
225 | "metadata": {
226 | "ExecuteTime": {
227 | "end_time": "2020-04-12T16:49:43.300402Z",
228 | "start_time": "2020-04-12T16:49:43.288586Z"
229 | }
230 | },
231 | "outputs": [
232 | {
233 | "name": "stdout",
234 | "output_type": "stream",
235 | "text": [
236 | "Accuracy: 0.8181818181818182\n"
237 | ]
238 | }
239 | ],
240 | "source": [
241 | "print(f\"Accuracy: {accuracy(y_test, y_pred)}\")"
242 | ]
243 | },
244 | {
245 | "cell_type": "code",
246 | "execution_count": 11,
247 | "metadata": {
248 | "ExecuteTime": {
249 | "end_time": "2020-04-12T16:49:43.470452Z",
250 | "start_time": "2020-04-12T16:49:43.306229Z"
251 | }
252 | },
253 | "outputs": [
254 | {
255 | "name": "stdout",
256 | "output_type": "stream",
257 | "text": [
258 | "Precision: 0.782608695652174\n",
259 | "Recall: 0.6666666666666666\n",
260 | "F1-Score: 0.72\n"
261 | ]
262 | }
263 | ],
264 | "source": [
265 | "print(f\"Precision: {precision_score(y_test, y_pred)}\")\n",
266 | "print(f\"Recall: {recall_score(y_test, y_pred)}\")\n",
267 | "print(f\"F1-Score: {f1_score(y_test, y_pred)}\")"
268 | ]
269 | }
270 | ],
271 | "metadata": {
272 | "kernelspec": {
273 | "display_name": "Python 3",
274 | "language": "python",
275 | "name": "python3"
276 | },
277 | "language_info": {
278 | "codemirror_mode": {
279 | "name": "ipython",
280 | "version": 3
281 | },
282 | "file_extension": ".py",
283 | "mimetype": "text/x-python",
284 | "name": "python",
285 | "nbconvert_exporter": "python",
286 | "pygments_lexer": "ipython3",
287 | "version": "3.7.6"
288 | },
289 | "toc": {
290 | "base_numbering": 1,
291 | "nav_menu": {},
292 | "number_sections": true,
293 | "sideBar": true,
294 | "skip_h1_title": false,
295 | "title_cell": "Table of Contents",
296 | "title_sidebar": "Contents",
297 | "toc_cell": true,
298 | "toc_position": {},
299 | "toc_section_display": true,
300 | "toc_window_display": false
301 | },
302 | "varInspector": {
303 | "cols": {
304 | "lenName": 16,
305 | "lenType": 16,
306 | "lenVar": 40
307 | },
308 | "kernels_config": {
309 | "python": {
310 | "delete_cmd_postfix": "",
311 | "delete_cmd_prefix": "del ",
312 | "library": "var_list.py",
313 | "varRefreshCmd": "print(var_dic_list())"
314 | },
315 | "r": {
316 | "delete_cmd_postfix": ") ",
317 | "delete_cmd_prefix": "rm(",
318 | "library": "var_list.r",
319 | "varRefreshCmd": "cat(var_dic_list()) "
320 | }
321 | },
322 | "types_to_exclude": [
323 | "module",
324 | "function",
325 | "builtin_function_or_method",
326 | "instance",
327 | "_Feature"
328 | ],
329 | "window_display": false
330 | }
331 | },
332 | "nbformat": 4,
333 | "nbformat_minor": 4
334 | }
335 |
--------------------------------------------------------------------------------
/K-Nearest Neigbors/KNN-Classifier.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {
7 | "ExecuteTime": {
8 | "end_time": "2020-02-16T23:06:30.008859Z",
9 | "start_time": "2020-02-16T23:06:30.002839Z"
10 | }
11 | },
12 | "outputs": [],
13 | "source": [
14 | "import csv\n",
15 | "import random\n",
16 | "import operator\n",
17 | "import math\n",
18 | "\n",
19 | "random.seed(47)"
20 | ]
21 | },
22 | {
23 | "cell_type": "code",
24 | "execution_count": 2,
25 | "metadata": {
26 | "ExecuteTime": {
27 | "end_time": "2020-02-16T23:06:30.143114Z",
28 | "start_time": "2020-02-16T23:06:30.010816Z"
29 | }
30 | },
31 | "outputs": [],
32 | "source": [
33 | "def viewDataset(file):\n",
34 | " with open(file) as csvfile:\n",
35 | " lines = csv.reader(csvfile)\n",
36 | " for row in lines:\n",
37 | " print(', '.join(row))\n"
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": 3,
43 | "metadata": {
44 | "ExecuteTime": {
45 | "end_time": "2020-02-16T23:06:30.290169Z",
46 | "start_time": "2020-02-16T23:06:30.149057Z"
47 | }
48 | },
49 | "outputs": [],
50 | "source": [
51 | "dataset = r'../datasets/iris.data'\n",
52 | "# viewDataset(dataset)"
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "execution_count": 4,
58 | "metadata": {
59 | "ExecuteTime": {
60 | "end_time": "2020-02-16T23:06:30.439251Z",
61 | "start_time": "2020-02-16T23:06:30.293164Z"
62 | }
63 | },
64 | "outputs": [],
65 | "source": [
66 | "def handleDataset(filename, split):\n",
67 | " trainingSet = []\n",
68 | " testSet = []\n",
69 | " with open(filename, 'r') as csvfile:\n",
70 | " lines = csv.reader(csvfile)\n",
71 | " dataset = list(lines)\n",
72 | " for x in range(len(dataset) - 1):\n",
73 | " for y in range(4):\n",
74 | " dataset[x][y] = float(dataset[x][y])\n",
75 | " if random.random() < split:\n",
76 | " trainingSet.append(dataset[x])\n",
77 | " else:\n",
78 | " testSet.append(dataset[x])\n",
79 | " return trainingSet, testSet"
80 | ]
81 | },
82 | {
83 | "cell_type": "code",
84 | "execution_count": 5,
85 | "metadata": {
86 | "ExecuteTime": {
87 | "end_time": "2020-02-16T23:06:30.580287Z",
88 | "start_time": "2020-02-16T23:06:30.440284Z"
89 | }
90 | },
91 | "outputs": [
92 | {
93 | "name": "stdout",
94 | "output_type": "stream",
95 | "text": [
96 | "Train: 101\n",
97 | "Test: 49\n"
98 | ]
99 | }
100 | ],
101 | "source": [
102 | "# test handleDataset\n",
103 | "\n",
104 | "trainingSet, testSet = handleDataset(dataset, 0.66)\n",
105 | "print ('Train: ' + repr(len(trainingSet)))\n",
106 | "print ('Test: ' + repr(len(testSet)))"
107 | ]
108 | },
109 | {
110 | "cell_type": "code",
111 | "execution_count": 6,
112 | "metadata": {
113 | "ExecuteTime": {
114 | "end_time": "2020-02-16T23:06:30.721943Z",
115 | "start_time": "2020-02-16T23:06:30.582311Z"
116 | }
117 | },
118 | "outputs": [],
119 | "source": [
120 | "def euclideanDistance(instance1, instance2, length):\n",
121 | " distance = 0\n",
122 | " for x in range(length):\n",
123 | " distance += pow((instance1[x] - instance2[x]), 2)\n",
124 | " return math.sqrt(distance)"
125 | ]
126 | },
127 | {
128 | "cell_type": "code",
129 | "execution_count": 7,
130 | "metadata": {
131 | "ExecuteTime": {
132 | "end_time": "2020-02-16T23:06:30.858538Z",
133 | "start_time": "2020-02-16T23:06:30.731964Z"
134 | }
135 | },
136 | "outputs": [
137 | {
138 | "name": "stdout",
139 | "output_type": "stream",
140 | "text": [
141 | "Distance: 3.4641016151377544\n"
142 | ]
143 | }
144 | ],
145 | "source": [
146 | "# Test Euclidean Distance\n",
147 | "data1 = [2, 2, 2, 'a']\n",
148 | "data2 = [4, 4, 4, 'b']\n",
149 | "distance = euclideanDistance(data1, data2, 3)\n",
150 | "print('Distance: ' + repr(distance))"
151 | ]
152 | },
153 | {
154 | "cell_type": "code",
155 | "execution_count": 8,
156 | "metadata": {
157 | "ExecuteTime": {
158 | "end_time": "2020-02-16T23:06:30.995044Z",
159 | "start_time": "2020-02-16T23:06:30.861489Z"
160 | }
161 | },
162 | "outputs": [],
163 | "source": [
164 | "def getKNeighbors(trainingSet, testInstance, k):\n",
165 | " distances = []\n",
166 | " length = len(testInstance) - 1\n",
167 | " for x in range(len(trainingSet)):\n",
168 | " dist = euclideanDistance(testInstance, trainingSet[x], length)\n",
169 | " distances.append((trainingSet[x], dist))\n",
170 | " distances.sort(key=operator.itemgetter(1))\n",
171 | " neighbors = []\n",
172 | " for x in range(k):\n",
173 | " neighbors.append(distances[x][0])\n",
174 | " return neighbors"
175 | ]
176 | },
177 | {
178 | "cell_type": "code",
179 | "execution_count": 9,
180 | "metadata": {
181 | "ExecuteTime": {
182 | "end_time": "2020-02-16T23:06:31.162445Z",
183 | "start_time": "2020-02-16T23:06:30.996140Z"
184 | }
185 | },
186 | "outputs": [
187 | {
188 | "name": "stdout",
189 | "output_type": "stream",
190 | "text": [
191 | "[[4, 4, 4, 'b']]\n"
192 | ]
193 | }
194 | ],
195 | "source": [
196 | "# test getKNeighbors\n",
197 | "\n",
198 | "trainSet = [[2, 2, 2, 'a'], [4, 4, 4, 'b']]\n",
199 | "testInstance = [5, 5, 5]\n",
200 | "k = 1\n",
201 | "neighbors = getKNeighbors(trainSet, testInstance, 1)\n",
202 | "print(neighbors)"
203 | ]
204 | },
205 | {
206 | "cell_type": "code",
207 | "execution_count": 10,
208 | "metadata": {
209 | "ExecuteTime": {
210 | "end_time": "2020-02-16T23:06:31.315818Z",
211 | "start_time": "2020-02-16T23:06:31.163407Z"
212 | }
213 | },
214 | "outputs": [],
215 | "source": [
216 | "def getResponse(neighbors):\n",
217 | " classVotes = {}\n",
218 | " for x in range(len(neighbors)):\n",
219 | " response = neighbors[x][-1]\n",
220 | " if response in classVotes:\n",
221 | " classVotes[response] += 1\n",
222 | " else:\n",
223 | " classVotes[response] = 1\n",
224 | "# print(classVotes)\n",
225 | " sortedVotes = sorted(classVotes.items(),\n",
226 | " key=operator.itemgetter(1), reverse=True)\n",
227 | "# print(sortedVotes)\n",
228 | " return sortedVotes[0][0]"
229 | ]
230 | },
231 | {
232 | "cell_type": "code",
233 | "execution_count": 11,
234 | "metadata": {
235 | "ExecuteTime": {
236 | "end_time": "2020-02-16T23:06:31.484233Z",
237 | "start_time": "2020-02-16T23:06:31.321761Z"
238 | }
239 | },
240 | "outputs": [
241 | {
242 | "name": "stdout",
243 | "output_type": "stream",
244 | "text": [
245 | "a\n"
246 | ]
247 | }
248 | ],
249 | "source": [
250 | "# test getResponse\n",
251 | "\n",
252 | "neighbors = [[1, 1, 1, 'a'], [2, 2, 2, 'a'], [3, 3, 3, 'b']]\n",
253 | "print(getResponse(neighbors))"
254 | ]
255 | },
256 | {
257 | "cell_type": "code",
258 | "execution_count": 12,
259 | "metadata": {
260 | "ExecuteTime": {
261 | "end_time": "2020-02-16T23:06:31.632980Z",
262 | "start_time": "2020-02-16T23:06:31.490217Z"
263 | }
264 | },
265 | "outputs": [],
266 | "source": [
267 | "def getAccuracy(testSet, predictions):\n",
268 | " correct = 0\n",
269 | " testSet_length = len(testSet)\n",
270 | " for x in range(testSet_length):\n",
271 | " if testSet[x][-1] == predictions[x]:\n",
272 | " correct += 1\n",
273 | " return (correct/testSet_length) * 100.0"
274 | ]
275 | },
276 | {
277 | "cell_type": "code",
278 | "execution_count": 13,
279 | "metadata": {
280 | "ExecuteTime": {
281 | "end_time": "2020-02-16T23:06:31.768505Z",
282 | "start_time": "2020-02-16T23:06:31.638927Z"
283 | }
284 | },
285 | "outputs": [
286 | {
287 | "name": "stdout",
288 | "output_type": "stream",
289 | "text": [
290 | "66.66666666666666\n"
291 | ]
292 | }
293 | ],
294 | "source": [
295 | "# test getAccuracy\n",
296 | "\n",
297 | "testSet = [[1, 1, 1, 'a'], [2, 2, 2, 'a'], [3, 3, 3, 'b']]\n",
298 | "predictions = ['a', 'a', 'a']\n",
299 | "accuracy = getAccuracy(testSet, predictions)\n",
300 | "print(accuracy)"
301 | ]
302 | },
303 | {
304 | "cell_type": "code",
305 | "execution_count": 14,
306 | "metadata": {
307 | "ExecuteTime": {
308 | "end_time": "2020-02-16T23:06:32.449281Z",
309 | "start_time": "2020-02-16T23:06:31.769490Z"
310 | }
311 | },
312 | "outputs": [],
313 | "source": [
314 | "from sklearn.metrics import accuracy_score"
315 | ]
316 | },
317 | {
318 | "cell_type": "code",
319 | "execution_count": 15,
320 | "metadata": {
321 | "ExecuteTime": {
322 | "end_time": "2020-02-16T23:06:32.465145Z",
323 | "start_time": "2020-02-16T23:06:32.455179Z"
324 | }
325 | },
326 | "outputs": [],
327 | "source": [
328 | "def main():\n",
329 | " # prepare data\n",
330 | " split = 0.8\n",
331 | " trainingSet, testSet = handleDataset(dataset, split)\n",
332 | " print('Train: ' + repr(len(trainingSet)))\n",
333 | " print('Test: ' + repr(len(testSet)))\n",
334 | " # generate predictions\n",
335 | " predictions = []\n",
336 | " k = 3\n",
337 | " for x in range(len(testSet)):\n",
338 | " neighbors = getKNeighbors(trainingSet, testSet[x], k)\n",
339 | " result = getResponse(neighbors) \n",
340 | " predictions.append(result)\n",
341 | " print(f'> predicted = {result}, actual = {testSet[x][-1]}')\n",
342 | " \n",
343 | " accuracy = getAccuracy(testSet, predictions)\n",
344 | " print(f'k: {k}, Accuracy: {round(accuracy,3)}%')"
345 | ]
346 | },
347 | {
348 | "cell_type": "code",
349 | "execution_count": 16,
350 | "metadata": {
351 | "ExecuteTime": {
352 | "end_time": "2020-02-16T23:06:32.623369Z",
353 | "start_time": "2020-02-16T23:06:32.467140Z"
354 | }
355 | },
356 | "outputs": [
357 | {
358 | "name": "stdout",
359 | "output_type": "stream",
360 | "text": [
361 | "Train: 121\n",
362 | "Test: 29\n",
363 | "> predicted = Iris-setosa, actual = Iris-setosa\n",
364 | "> predicted = Iris-setosa, actual = Iris-setosa\n",
365 | "> predicted = Iris-setosa, actual = Iris-setosa\n",
366 | "> predicted = Iris-setosa, actual = Iris-setosa\n",
367 | "> predicted = Iris-setosa, actual = Iris-setosa\n",
368 | "> predicted = Iris-setosa, actual = Iris-setosa\n",
369 | "> predicted = Iris-setosa, actual = Iris-setosa\n",
370 | "> predicted = Iris-setosa, actual = Iris-setosa\n",
371 | "> predicted = Iris-setosa, actual = Iris-setosa\n",
372 | "> predicted = Iris-setosa, actual = Iris-setosa\n",
373 | "> predicted = Iris-versicolor, actual = Iris-versicolor\n",
374 | "> predicted = Iris-versicolor, actual = Iris-versicolor\n",
375 | "> predicted = Iris-versicolor, actual = Iris-versicolor\n",
376 | "> predicted = Iris-versicolor, actual = Iris-versicolor\n",
377 | "> predicted = Iris-versicolor, actual = Iris-versicolor\n",
378 | "> predicted = Iris-versicolor, actual = Iris-versicolor\n",
379 | "> predicted = Iris-virginica, actual = Iris-versicolor\n",
380 | "> predicted = Iris-versicolor, actual = Iris-versicolor\n",
381 | "> predicted = Iris-virginica, actual = Iris-versicolor\n",
382 | "> predicted = Iris-versicolor, actual = Iris-versicolor\n",
383 | "> predicted = Iris-versicolor, actual = Iris-virginica\n",
384 | "> predicted = Iris-virginica, actual = Iris-virginica\n",
385 | "> predicted = Iris-virginica, actual = Iris-virginica\n",
386 | "> predicted = Iris-virginica, actual = Iris-virginica\n",
387 | "> predicted = Iris-virginica, actual = Iris-virginica\n",
388 | "> predicted = Iris-virginica, actual = Iris-virginica\n",
389 | "> predicted = Iris-virginica, actual = Iris-virginica\n",
390 | "> predicted = Iris-virginica, actual = Iris-virginica\n",
391 | "> predicted = Iris-virginica, actual = Iris-virginica\n",
392 | "k: 3, Accuracy: 89.655%\n"
393 | ]
394 | }
395 | ],
396 | "source": [
397 | "main()"
398 | ]
399 | }
400 | ],
401 | "metadata": {
402 | "kernelspec": {
403 | "display_name": "Python 3",
404 | "language": "python",
405 | "name": "python3"
406 | },
407 | "language_info": {
408 | "codemirror_mode": {
409 | "name": "ipython",
410 | "version": 3
411 | },
412 | "file_extension": ".py",
413 | "mimetype": "text/x-python",
414 | "name": "python",
415 | "nbconvert_exporter": "python",
416 | "pygments_lexer": "ipython3",
417 | "version": "3.7.6"
418 | },
419 | "toc": {
420 | "base_numbering": 1,
421 | "nav_menu": {},
422 | "number_sections": true,
423 | "sideBar": true,
424 | "skip_h1_title": false,
425 | "title_cell": "Table of Contents",
426 | "title_sidebar": "Contents",
427 | "toc_cell": false,
428 | "toc_position": {},
429 | "toc_section_display": true,
430 | "toc_window_display": false
431 | },
432 | "varInspector": {
433 | "cols": {
434 | "lenName": 16,
435 | "lenType": 16,
436 | "lenVar": 40
437 | },
438 | "kernels_config": {
439 | "python": {
440 | "delete_cmd_postfix": "",
441 | "delete_cmd_prefix": "del ",
442 | "library": "var_list.py",
443 | "varRefreshCmd": "print(var_dic_list())"
444 | },
445 | "r": {
446 | "delete_cmd_postfix": ") ",
447 | "delete_cmd_prefix": "rm(",
448 | "library": "var_list.r",
449 | "varRefreshCmd": "cat(var_dic_list()) "
450 | }
451 | },
452 | "types_to_exclude": [
453 | "module",
454 | "function",
455 | "builtin_function_or_method",
456 | "instance",
457 | "_Feature"
458 | ],
459 | "window_display": false
460 | }
461 | },
462 | "nbformat": 4,
463 | "nbformat_minor": 2
464 | }
465 |
--------------------------------------------------------------------------------
/Naive Bayes/Naive Bayes.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "**Gaussian Naive Bayes**\n",
8 | "\n",
9 | "***Bayes Theorem:***\n",
10 | "$P(A|B) = \\frac{P(B|A)P(A)}{P(B}$\n",
11 | "\n",
12 | "\n",
13 | "***Naive Bayes:***\n",
14 | "\n",
15 | "$\\mathbf{P(y|X) = \\frac{P(X|y)P(y)}{P(X}}$\n",
16 | "\n",
17 | "\n",
18 | "$\\mathbf{X = (x_{1}, x_{2}, x_{3}, x_{4}, x_{5},...,x_{n})}$\n",
19 | "\n",
20 | "\n",
21 | "$\\mathbf{P(y|X) = \\frac{P(x_{1}|y).P(x_{2}|y)....P(x_{n}|y).P(y)}{P(X)}}$"
22 | ]
23 | },
24 | {
25 | "cell_type": "code",
26 | "execution_count": 1,
27 | "metadata": {
28 | "ExecuteTime": {
29 | "end_time": "2020-04-11T22:38:10.083585Z",
30 | "start_time": "2020-04-11T22:38:08.030037Z"
31 | }
32 | },
33 | "outputs": [],
34 | "source": [
35 | "import numpy as np\n",
36 | "import pandas as pd\n",
37 | "from sklearn.model_selection import train_test_split"
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": 2,
43 | "metadata": {
44 | "ExecuteTime": {
45 | "end_time": "2020-04-11T22:38:10.137508Z",
46 | "start_time": "2020-04-11T22:38:10.091643Z"
47 | }
48 | },
49 | "outputs": [],
50 | "source": [
51 | "class NaiveBayes(object):\n",
52 | " \n",
53 | " def fit(self, X, y):\n",
54 | " n_samples, n_features = X.shape\n",
55 | " self._classes = np.unique(y)\n",
56 | " n_classes = len(self._classes)\n",
57 | " \n",
58 | " # mean, variance, priors\n",
59 | " self._mean = np.zeros((n_classes, n_features), dtype=np.float64)\n",
60 | " self._var = np.zeros((n_classes, n_features), dtype=np.float64)\n",
61 | " self._priors = np.zeros(n_classes, dtype=np.float64)\n",
62 | "\n",
63 | " # extracting mean, variance and priors for each class\n",
64 | " # useful in calculating pdf during prediction\n",
65 | " for c in self._classes:\n",
66 | " X_c = X[y==c]\n",
67 | " self._mean[c, :] = X_c.mean(axis=0)\n",
68 | " self._var[c, :] = X_c.var(axis=0)\n",
69 | " self._priors[c] = X_c.shape[0] / float(n_samples)\n",
70 | "\n",
71 | " def predict(self, X):\n",
72 | " y_pred = [self._predict(x) for x in X]\n",
73 | " return np.array(y_pred)\n",
74 | "\n",
75 | " def _predict(self, x):\n",
76 | " posteriors = []\n",
77 | "\n",
78 | " # calculate posterior probability for each class\n",
79 | " for idx, c in enumerate(self._classes):\n",
80 | " prior = np.log(self._priors[idx])\n",
81 | " class_conditional = np.sum(np.log(self.gaussian_pdf(idx, x)))\n",
82 | " posterior = prior + class_conditional\n",
83 | " posteriors.append(posterior)\n",
84 | " \n",
85 | " # return class with highest posterior probability\n",
86 | " return self._classes[np.argmax(posteriors)]\n",
87 | " \n",
88 | "\n",
89 | " def gaussian_pdf(self, class_idx, x):\n",
90 | " mean = self._mean[class_idx]\n",
91 | " var = self._var[class_idx]\n",
92 | " numerator = np.exp(- (x-mean)**2 / (2 * var))\n",
93 | " denominator = np.sqrt(2 * np.pi * var)\n",
94 | " return numerator / denominator"
95 | ]
96 | },
97 | {
98 | "cell_type": "code",
99 | "execution_count": 3,
100 | "metadata": {
101 | "ExecuteTime": {
102 | "end_time": "2020-04-11T22:38:10.283490Z",
103 | "start_time": "2020-04-11T22:38:10.144440Z"
104 | }
105 | },
106 | "outputs": [],
107 | "source": [
108 | "def accuracy(y_true, y_pred):\n",
109 | " accuracy = np.sum(y_true == y_pred) / len(y_true)\n",
110 | " return accuracy"
111 | ]
112 | },
113 | {
114 | "cell_type": "code",
115 | "execution_count": 4,
116 | "metadata": {
117 | "ExecuteTime": {
118 | "end_time": "2020-04-11T22:38:10.548884Z",
119 | "start_time": "2020-04-11T22:38:10.292962Z"
120 | }
121 | },
122 | "outputs": [],
123 | "source": [
124 | "from sklearn.datasets import load_iris\n",
125 | "\n",
126 | "data = load_iris()"
127 | ]
128 | },
129 | {
130 | "cell_type": "code",
131 | "execution_count": 5,
132 | "metadata": {
133 | "ExecuteTime": {
134 | "end_time": "2020-04-11T22:38:10.561691Z",
135 | "start_time": "2020-04-11T22:38:10.549919Z"
136 | }
137 | },
138 | "outputs": [],
139 | "source": [
140 | "X_train, X_test, y_train, y_test = train_test_split(data.data, data.target)"
141 | ]
142 | },
143 | {
144 | "cell_type": "code",
145 | "execution_count": 6,
146 | "metadata": {
147 | "ExecuteTime": {
148 | "end_time": "2020-04-11T22:38:10.695826Z",
149 | "start_time": "2020-04-11T22:38:10.566489Z"
150 | }
151 | },
152 | "outputs": [
153 | {
154 | "name": "stdout",
155 | "output_type": "stream",
156 | "text": [
157 | "(112, 4)\n",
158 | "(38, 4)\n",
159 | "(112,)\n",
160 | "(38,)\n"
161 | ]
162 | }
163 | ],
164 | "source": [
165 | "print(X_train.shape)\n",
166 | "print(X_test.shape)\n",
167 | "print(y_train.shape)\n",
168 | "print(y_test.shape)"
169 | ]
170 | },
171 | {
172 | "cell_type": "code",
173 | "execution_count": 7,
174 | "metadata": {
175 | "ExecuteTime": {
176 | "end_time": "2020-04-11T22:38:10.840526Z",
177 | "start_time": "2020-04-11T22:38:10.707061Z"
178 | }
179 | },
180 | "outputs": [],
181 | "source": [
182 | "nb = NaiveBayes()\n",
183 | "nb.fit(X_train, y_train.ravel())\n",
184 | "y_pred = nb.predict(X_test)"
185 | ]
186 | },
187 | {
188 | "cell_type": "code",
189 | "execution_count": 8,
190 | "metadata": {
191 | "ExecuteTime": {
192 | "end_time": "2020-04-11T22:38:10.969671Z",
193 | "start_time": "2020-04-11T22:38:10.849490Z"
194 | }
195 | },
196 | "outputs": [
197 | {
198 | "name": "stdout",
199 | "output_type": "stream",
200 | "text": [
201 | "Naive Bayes accuracy: 0.8947368421052632\n"
202 | ]
203 | }
204 | ],
205 | "source": [
206 | "print(f\"Naive Bayes accuracy: {accuracy(y_test, y_pred)}\")"
207 | ]
208 | },
209 | {
210 | "cell_type": "code",
211 | "execution_count": 9,
212 | "metadata": {
213 | "ExecuteTime": {
214 | "end_time": "2020-04-11T22:38:11.108872Z",
215 | "start_time": "2020-04-11T22:38:10.977849Z"
216 | }
217 | },
218 | "outputs": [],
219 | "source": [
220 | "# Diabetes Dataset"
221 | ]
222 | },
223 | {
224 | "cell_type": "code",
225 | "execution_count": 10,
226 | "metadata": {
227 | "ExecuteTime": {
228 | "end_time": "2020-04-11T22:38:11.985904Z",
229 | "start_time": "2020-04-11T22:38:11.118415Z"
230 | }
231 | },
232 | "outputs": [
233 | {
234 | "data": {
235 | "text/html": [
236 | "\n",
237 | "\n",
250 | "
\n",
251 | " \n",
252 | " \n",
253 | " | \n",
254 | " Pregnancies | \n",
255 | " Glucose | \n",
256 | " BloodPressure | \n",
257 | " SkinThickness | \n",
258 | " Insulin | \n",
259 | " BMI | \n",
260 | " DiabetesPedigreeFunction | \n",
261 | " Age | \n",
262 | " Outcome | \n",
263 | "
\n",
264 | " \n",
265 | " \n",
266 | " \n",
267 | " | 0 | \n",
268 | " 6 | \n",
269 | " 148 | \n",
270 | " 72 | \n",
271 | " 35 | \n",
272 | " 0 | \n",
273 | " 33.6 | \n",
274 | " 0.627 | \n",
275 | " 50 | \n",
276 | " 1 | \n",
277 | "
\n",
278 | " \n",
279 | " | 1 | \n",
280 | " 1 | \n",
281 | " 85 | \n",
282 | " 66 | \n",
283 | " 29 | \n",
284 | " 0 | \n",
285 | " 26.6 | \n",
286 | " 0.351 | \n",
287 | " 31 | \n",
288 | " 0 | \n",
289 | "
\n",
290 | " \n",
291 | " | 2 | \n",
292 | " 8 | \n",
293 | " 183 | \n",
294 | " 64 | \n",
295 | " 0 | \n",
296 | " 0 | \n",
297 | " 23.3 | \n",
298 | " 0.672 | \n",
299 | " 32 | \n",
300 | " 1 | \n",
301 | "
\n",
302 | " \n",
303 | " | 3 | \n",
304 | " 1 | \n",
305 | " 89 | \n",
306 | " 66 | \n",
307 | " 23 | \n",
308 | " 94 | \n",
309 | " 28.1 | \n",
310 | " 0.167 | \n",
311 | " 21 | \n",
312 | " 0 | \n",
313 | "
\n",
314 | " \n",
315 | " | 4 | \n",
316 | " 0 | \n",
317 | " 137 | \n",
318 | " 40 | \n",
319 | " 35 | \n",
320 | " 168 | \n",
321 | " 43.1 | \n",
322 | " 2.288 | \n",
323 | " 33 | \n",
324 | " 1 | \n",
325 | "
\n",
326 | " \n",
327 | "
\n",
328 | "
"
329 | ],
330 | "text/plain": [
331 | " Pregnancies Glucose BloodPressure SkinThickness Insulin BMI \\\n",
332 | "0 6 148 72 35 0 33.6 \n",
333 | "1 1 85 66 29 0 26.6 \n",
334 | "2 8 183 64 0 0 23.3 \n",
335 | "3 1 89 66 23 94 28.1 \n",
336 | "4 0 137 40 35 168 43.1 \n",
337 | "\n",
338 | " DiabetesPedigreeFunction Age Outcome \n",
339 | "0 0.627 50 1 \n",
340 | "1 0.351 31 0 \n",
341 | "2 0.672 32 1 \n",
342 | "3 0.167 21 0 \n",
343 | "4 2.288 33 1 "
344 | ]
345 | },
346 | "execution_count": 10,
347 | "metadata": {},
348 | "output_type": "execute_result"
349 | }
350 | ],
351 | "source": [
352 | "cols = [\"Pregnancies\" ,\"Glucose\" ,\"BloodPressure\" ,\"SkinThickness\" ,\"Insulin\" ,\"BMI\" ,\"DiabetesPedigreeFunction\" ,\"Age\" ,\"Outcome\"]\n",
353 | "url = \"https://gist.githubusercontent.com/ktisha/c21e73a1bd1700294ef790c56c8aec1f/raw/819b69b5736821ccee93d05b51de0510bea00294/pima-indians-diabetes.csv\"\n",
354 | "\n",
355 | "diabetes_data = pd.read_csv(url, skiprows=9, header=None, names=cols)\n",
356 | "diabetes_data.head()"
357 | ]
358 | },
359 | {
360 | "cell_type": "code",
361 | "execution_count": 11,
362 | "metadata": {
363 | "ExecuteTime": {
364 | "end_time": "2020-04-11T22:38:11.999427Z",
365 | "start_time": "2020-04-11T22:38:11.989369Z"
366 | }
367 | },
368 | "outputs": [
369 | {
370 | "data": {
371 | "text/plain": [
372 | "(768, 9)"
373 | ]
374 | },
375 | "execution_count": 11,
376 | "metadata": {},
377 | "output_type": "execute_result"
378 | }
379 | ],
380 | "source": [
381 | "diabetes_data.shape"
382 | ]
383 | },
384 | {
385 | "cell_type": "code",
386 | "execution_count": 12,
387 | "metadata": {
388 | "ExecuteTime": {
389 | "end_time": "2020-04-11T22:38:12.130899Z",
390 | "start_time": "2020-04-11T22:38:12.003158Z"
391 | }
392 | },
393 | "outputs": [],
394 | "source": [
395 | "X = diabetes_data[cols[:-1]].values\n",
396 | "y = diabetes_data[cols[-1]].values"
397 | ]
398 | },
399 | {
400 | "cell_type": "code",
401 | "execution_count": 13,
402 | "metadata": {
403 | "ExecuteTime": {
404 | "end_time": "2020-04-11T22:38:12.285074Z",
405 | "start_time": "2020-04-11T22:38:12.134911Z"
406 | }
407 | },
408 | "outputs": [],
409 | "source": [
410 | "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, stratify=y, random_state=42)"
411 | ]
412 | },
413 | {
414 | "cell_type": "code",
415 | "execution_count": 14,
416 | "metadata": {
417 | "ExecuteTime": {
418 | "end_time": "2020-04-11T22:38:12.441193Z",
419 | "start_time": "2020-04-11T22:38:12.293223Z"
420 | }
421 | },
422 | "outputs": [],
423 | "source": [
424 | "nb = NaiveBayes()\n",
425 | "nb.fit(X_train, y_train.ravel())\n",
426 | "y_pred = nb.predict(X_test)"
427 | ]
428 | },
429 | {
430 | "cell_type": "code",
431 | "execution_count": 15,
432 | "metadata": {
433 | "ExecuteTime": {
434 | "end_time": "2020-04-11T22:38:12.614652Z",
435 | "start_time": "2020-04-11T22:38:12.449128Z"
436 | }
437 | },
438 | "outputs": [
439 | {
440 | "name": "stdout",
441 | "output_type": "stream",
442 | "text": [
443 | "Naive Bayes accuracy: 0.7532467532467533\n"
444 | ]
445 | }
446 | ],
447 | "source": [
448 | "print(f\"Naive Bayes accuracy: {accuracy(y_test, y_pred)}\")"
449 | ]
450 | },
451 | {
452 | "cell_type": "code",
453 | "execution_count": 16,
454 | "metadata": {
455 | "ExecuteTime": {
456 | "end_time": "2020-04-11T22:38:12.746000Z",
457 | "start_time": "2020-04-11T22:38:12.617873Z"
458 | }
459 | },
460 | "outputs": [],
461 | "source": [
462 | "from sklearn.metrics import precision_score, recall_score, f1_score"
463 | ]
464 | },
465 | {
466 | "cell_type": "code",
467 | "execution_count": 17,
468 | "metadata": {
469 | "ExecuteTime": {
470 | "end_time": "2020-04-11T22:38:13.191309Z",
471 | "start_time": "2020-04-11T22:38:12.750193Z"
472 | }
473 | },
474 | "outputs": [
475 | {
476 | "name": "stdout",
477 | "output_type": "stream",
478 | "text": [
479 | "Precision: 0.6428571428571429\n",
480 | "Recall: 0.6666666666666666\n",
481 | "F1-Score: 0.6545454545454545\n"
482 | ]
483 | }
484 | ],
485 | "source": [
486 | "print(f\"Precision: {precision_score(y_test, y_pred)}\")\n",
487 | "print(f\"Recall: {recall_score(y_test, y_pred)}\")\n",
488 | "print(f\"F1-Score: {f1_score(y_test, y_pred)}\")"
489 | ]
490 | }
491 | ],
492 | "metadata": {
493 | "kernelspec": {
494 | "display_name": "Python 3",
495 | "language": "python",
496 | "name": "python3"
497 | },
498 | "language_info": {
499 | "codemirror_mode": {
500 | "name": "ipython",
501 | "version": 3
502 | },
503 | "file_extension": ".py",
504 | "mimetype": "text/x-python",
505 | "name": "python",
506 | "nbconvert_exporter": "python",
507 | "pygments_lexer": "ipython3",
508 | "version": "3.7.6"
509 | },
510 | "toc": {
511 | "base_numbering": 1,
512 | "nav_menu": {},
513 | "number_sections": true,
514 | "sideBar": true,
515 | "skip_h1_title": false,
516 | "title_cell": "Table of Contents",
517 | "title_sidebar": "Contents",
518 | "toc_cell": false,
519 | "toc_position": {},
520 | "toc_section_display": true,
521 | "toc_window_display": false
522 | },
523 | "varInspector": {
524 | "cols": {
525 | "lenName": 16,
526 | "lenType": 16,
527 | "lenVar": 40
528 | },
529 | "kernels_config": {
530 | "python": {
531 | "delete_cmd_postfix": "",
532 | "delete_cmd_prefix": "del ",
533 | "library": "var_list.py",
534 | "varRefreshCmd": "print(var_dic_list())"
535 | },
536 | "r": {
537 | "delete_cmd_postfix": ") ",
538 | "delete_cmd_prefix": "rm(",
539 | "library": "var_list.r",
540 | "varRefreshCmd": "cat(var_dic_list()) "
541 | }
542 | },
543 | "types_to_exclude": [
544 | "module",
545 | "function",
546 | "builtin_function_or_method",
547 | "instance",
548 | "_Feature"
549 | ],
550 | "window_display": false
551 | }
552 | },
553 | "nbformat": 4,
554 | "nbformat_minor": 4
555 | }
556 |
--------------------------------------------------------------------------------
/datasets/diabetes_data.csv:
--------------------------------------------------------------------------------
1 | Pregnancies,Glucose,BloodPressure,SkinThickness,Insulin,BMI,DiabetesPedigreeFunction,Age,Outcome
2 | 6,148,72,35,0,33.6,0.627,50,1
3 | 1,85,66,29,0,26.6,0.35100000000000003,31,0
4 | 8,183,64,0,0,23.3,0.672,32,1
5 | 1,89,66,23,94,28.1,0.16699999999999998,21,0
6 | 0,137,40,35,168,43.1,2.2880000000000003,33,1
7 | 5,116,74,0,0,25.6,0.201,30,0
8 | 3,78,50,32,88,31.0,0.248,26,1
9 | 10,115,0,0,0,35.3,0.134,29,0
10 | 2,197,70,45,543,30.5,0.158,53,1
11 | 8,125,96,0,0,0.0,0.23199999999999998,54,1
12 | 4,110,92,0,0,37.6,0.191,30,0
13 | 10,168,74,0,0,38.0,0.537,34,1
14 | 10,139,80,0,0,27.1,1.4409999999999998,57,0
15 | 1,189,60,23,846,30.1,0.39799999999999996,59,1
16 | 5,166,72,19,175,25.8,0.5870000000000001,51,1
17 | 7,100,0,0,0,30.0,0.484,32,1
18 | 0,118,84,47,230,45.8,0.551,31,1
19 | 7,107,74,0,0,29.6,0.254,31,1
20 | 1,103,30,38,83,43.3,0.183,33,0
21 | 1,115,70,30,96,34.6,0.529,32,1
22 | 3,126,88,41,235,39.3,0.7040000000000001,27,0
23 | 8,99,84,0,0,35.4,0.38799999999999996,50,0
24 | 7,196,90,0,0,39.8,0.451,41,1
25 | 9,119,80,35,0,29.0,0.263,29,1
26 | 11,143,94,33,146,36.6,0.254,51,1
27 | 10,125,70,26,115,31.1,0.205,41,1
28 | 7,147,76,0,0,39.4,0.257,43,1
29 | 1,97,66,15,140,23.2,0.48700000000000004,22,0
30 | 13,145,82,19,110,22.2,0.245,57,0
31 | 5,117,92,0,0,34.1,0.337,38,0
32 | 5,109,75,26,0,36.0,0.546,60,0
33 | 3,158,76,36,245,31.6,0.851,28,1
34 | 3,88,58,11,54,24.8,0.267,22,0
35 | 6,92,92,0,0,19.9,0.188,28,0
36 | 10,122,78,31,0,27.6,0.512,45,0
37 | 4,103,60,33,192,24.0,0.966,33,0
38 | 11,138,76,0,0,33.2,0.42,35,0
39 | 9,102,76,37,0,32.9,0.665,46,1
40 | 2,90,68,42,0,38.2,0.503,27,1
41 | 4,111,72,47,207,37.1,1.39,56,1
42 | 3,180,64,25,70,34.0,0.271,26,0
43 | 7,133,84,0,0,40.2,0.696,37,0
44 | 7,106,92,18,0,22.7,0.235,48,0
45 | 9,171,110,24,240,45.4,0.721,54,1
46 | 7,159,64,0,0,27.4,0.294,40,0
47 | 0,180,66,39,0,42.0,1.893,25,1
48 | 1,146,56,0,0,29.7,0.564,29,0
49 | 2,71,70,27,0,28.0,0.586,22,0
50 | 7,103,66,32,0,39.1,0.344,31,1
51 | 7,105,0,0,0,0.0,0.305,24,0
52 | 1,103,80,11,82,19.4,0.491,22,0
53 | 1,101,50,15,36,24.2,0.526,26,0
54 | 5,88,66,21,23,24.4,0.342,30,0
55 | 8,176,90,34,300,33.7,0.467,58,1
56 | 7,150,66,42,342,34.7,0.718,42,0
57 | 1,73,50,10,0,23.0,0.248,21,0
58 | 7,187,68,39,304,37.7,0.254,41,1
59 | 0,100,88,60,110,46.8,0.9620000000000001,31,0
60 | 0,146,82,0,0,40.5,1.781,44,0
61 | 0,105,64,41,142,41.5,0.17300000000000001,22,0
62 | 2,84,0,0,0,0.0,0.304,21,0
63 | 8,133,72,0,0,32.9,0.27,39,1
64 | 5,44,62,0,0,25.0,0.5870000000000001,36,0
65 | 2,141,58,34,128,25.4,0.6990000000000001,24,0
66 | 7,114,66,0,0,32.8,0.258,42,1
67 | 5,99,74,27,0,29.0,0.203,32,0
68 | 0,109,88,30,0,32.5,0.855,38,1
69 | 2,109,92,0,0,42.7,0.845,54,0
70 | 1,95,66,13,38,19.6,0.33399999999999996,25,0
71 | 4,146,85,27,100,28.9,0.18899999999999997,27,0
72 | 2,100,66,20,90,32.9,0.867,28,1
73 | 5,139,64,35,140,28.6,0.41100000000000003,26,0
74 | 13,126,90,0,0,43.4,0.583,42,1
75 | 4,129,86,20,270,35.1,0.231,23,0
76 | 1,79,75,30,0,32.0,0.396,22,0
77 | 1,0,48,20,0,24.7,0.14,22,0
78 | 7,62,78,0,0,32.6,0.391,41,0
79 | 5,95,72,33,0,37.7,0.37,27,0
80 | 0,131,0,0,0,43.2,0.27,26,1
81 | 2,112,66,22,0,25.0,0.307,24,0
82 | 3,113,44,13,0,22.4,0.14,22,0
83 | 2,74,0,0,0,0.0,0.102,22,0
84 | 7,83,78,26,71,29.3,0.767,36,0
85 | 0,101,65,28,0,24.6,0.237,22,0
86 | 5,137,108,0,0,48.8,0.22699999999999998,37,1
87 | 2,110,74,29,125,32.4,0.698,27,0
88 | 13,106,72,54,0,36.6,0.17800000000000002,45,0
89 | 2,100,68,25,71,38.5,0.324,26,0
90 | 15,136,70,32,110,37.1,0.153,43,1
91 | 1,107,68,19,0,26.5,0.165,24,0
92 | 1,80,55,0,0,19.1,0.258,21,0
93 | 4,123,80,15,176,32.0,0.44299999999999995,34,0
94 | 7,81,78,40,48,46.7,0.261,42,0
95 | 4,134,72,0,0,23.8,0.27699999999999997,60,1
96 | 2,142,82,18,64,24.7,0.7609999999999999,21,0
97 | 6,144,72,27,228,33.9,0.255,40,0
98 | 2,92,62,28,0,31.6,0.13,24,0
99 | 1,71,48,18,76,20.4,0.32299999999999995,22,0
100 | 6,93,50,30,64,28.7,0.35600000000000004,23,0
101 | 1,122,90,51,220,49.7,0.325,31,1
102 | 1,163,72,0,0,39.0,1.222,33,1
103 | 1,151,60,0,0,26.1,0.179,22,0
104 | 0,125,96,0,0,22.5,0.262,21,0
105 | 1,81,72,18,40,26.6,0.28300000000000003,24,0
106 | 2,85,65,0,0,39.6,0.93,27,0
107 | 1,126,56,29,152,28.7,0.8009999999999999,21,0
108 | 1,96,122,0,0,22.4,0.207,27,0
109 | 4,144,58,28,140,29.5,0.287,37,0
110 | 3,83,58,31,18,34.3,0.336,25,0
111 | 0,95,85,25,36,37.4,0.247,24,1
112 | 3,171,72,33,135,33.3,0.19899999999999998,24,1
113 | 8,155,62,26,495,34.0,0.5429999999999999,46,1
114 | 1,89,76,34,37,31.2,0.192,23,0
115 | 4,76,62,0,0,34.0,0.391,25,0
116 | 7,160,54,32,175,30.5,0.588,39,1
117 | 4,146,92,0,0,31.2,0.539,61,1
118 | 5,124,74,0,0,34.0,0.22,38,1
119 | 5,78,48,0,0,33.7,0.654,25,0
120 | 4,97,60,23,0,28.2,0.44299999999999995,22,0
121 | 4,99,76,15,51,23.2,0.223,21,0
122 | 0,162,76,56,100,53.2,0.759,25,1
123 | 6,111,64,39,0,34.2,0.26,24,0
124 | 2,107,74,30,100,33.6,0.40399999999999997,23,0
125 | 5,132,80,0,0,26.8,0.18600000000000003,69,0
126 | 0,113,76,0,0,33.3,0.278,23,1
127 | 1,88,30,42,99,55.0,0.496,26,1
128 | 3,120,70,30,135,42.9,0.452,30,0
129 | 1,118,58,36,94,33.3,0.261,23,0
130 | 1,117,88,24,145,34.5,0.40299999999999997,40,1
131 | 0,105,84,0,0,27.9,0.741,62,1
132 | 4,173,70,14,168,29.7,0.361,33,1
133 | 9,122,56,0,0,33.3,1.114,33,1
134 | 3,170,64,37,225,34.5,0.35600000000000004,30,1
135 | 8,84,74,31,0,38.3,0.457,39,0
136 | 2,96,68,13,49,21.1,0.647,26,0
137 | 2,125,60,20,140,33.8,0.08800000000000001,31,0
138 | 0,100,70,26,50,30.8,0.597,21,0
139 | 0,93,60,25,92,28.7,0.532,22,0
140 | 0,129,80,0,0,31.2,0.703,29,0
141 | 5,105,72,29,325,36.9,0.159,28,0
142 | 3,128,78,0,0,21.1,0.268,55,0
143 | 5,106,82,30,0,39.5,0.28600000000000003,38,0
144 | 2,108,52,26,63,32.5,0.318,22,0
145 | 10,108,66,0,0,32.4,0.272,42,1
146 | 4,154,62,31,284,32.8,0.237,23,0
147 | 0,102,75,23,0,0.0,0.5720000000000001,21,0
148 | 9,57,80,37,0,32.8,0.096,41,0
149 | 2,106,64,35,119,30.5,1.4,34,0
150 | 5,147,78,0,0,33.7,0.218,65,0
151 | 2,90,70,17,0,27.3,0.085,22,0
152 | 1,136,74,50,204,37.4,0.39899999999999997,24,0
153 | 4,114,65,0,0,21.9,0.43200000000000005,37,0
154 | 9,156,86,28,155,34.3,1.189,42,1
155 | 1,153,82,42,485,40.6,0.687,23,0
156 | 8,188,78,0,0,47.9,0.13699999999999998,43,1
157 | 7,152,88,44,0,50.0,0.337,36,1
158 | 2,99,52,15,94,24.6,0.637,21,0
159 | 1,109,56,21,135,25.2,0.833,23,0
160 | 2,88,74,19,53,29.0,0.22899999999999998,22,0
161 | 17,163,72,41,114,40.9,0.8170000000000001,47,1
162 | 4,151,90,38,0,29.7,0.294,36,0
163 | 7,102,74,40,105,37.2,0.204,45,0
164 | 0,114,80,34,285,44.2,0.16699999999999998,27,0
165 | 2,100,64,23,0,29.7,0.368,21,0
166 | 0,131,88,0,0,31.6,0.743,32,1
167 | 6,104,74,18,156,29.9,0.722,41,1
168 | 3,148,66,25,0,32.5,0.256,22,0
169 | 4,120,68,0,0,29.6,0.7090000000000001,34,0
170 | 4,110,66,0,0,31.9,0.47100000000000003,29,0
171 | 3,111,90,12,78,28.4,0.495,29,0
172 | 6,102,82,0,0,30.8,0.18,36,1
173 | 6,134,70,23,130,35.4,0.542,29,1
174 | 2,87,0,23,0,28.9,0.773,25,0
175 | 1,79,60,42,48,43.5,0.6779999999999999,23,0
176 | 2,75,64,24,55,29.7,0.37,33,0
177 | 8,179,72,42,130,32.7,0.7190000000000001,36,1
178 | 6,85,78,0,0,31.2,0.382,42,0
179 | 0,129,110,46,130,67.1,0.319,26,1
180 | 5,143,78,0,0,45.0,0.19,47,0
181 | 5,130,82,0,0,39.1,0.956,37,1
182 | 6,87,80,0,0,23.2,0.084,32,0
183 | 0,119,64,18,92,34.9,0.725,23,0
184 | 1,0,74,20,23,27.7,0.299,21,0
185 | 5,73,60,0,0,26.8,0.268,27,0
186 | 4,141,74,0,0,27.6,0.244,40,0
187 | 7,194,68,28,0,35.9,0.745,41,1
188 | 8,181,68,36,495,30.1,0.615,60,1
189 | 1,128,98,41,58,32.0,1.321,33,1
190 | 8,109,76,39,114,27.9,0.64,31,1
191 | 5,139,80,35,160,31.6,0.361,25,1
192 | 3,111,62,0,0,22.6,0.142,21,0
193 | 9,123,70,44,94,33.1,0.374,40,0
194 | 7,159,66,0,0,30.4,0.38299999999999995,36,1
195 | 11,135,0,0,0,52.3,0.578,40,1
196 | 8,85,55,20,0,24.4,0.136,42,0
197 | 5,158,84,41,210,39.4,0.395,29,1
198 | 1,105,58,0,0,24.3,0.187,21,0
199 | 3,107,62,13,48,22.9,0.6779999999999999,23,1
200 | 4,109,64,44,99,34.8,0.905,26,1
201 | 4,148,60,27,318,30.9,0.15,29,1
202 | 0,113,80,16,0,31.0,0.8740000000000001,21,0
203 | 1,138,82,0,0,40.1,0.23600000000000002,28,0
204 | 0,108,68,20,0,27.3,0.787,32,0
205 | 2,99,70,16,44,20.4,0.235,27,0
206 | 6,103,72,32,190,37.7,0.324,55,0
207 | 5,111,72,28,0,23.9,0.40700000000000003,27,0
208 | 8,196,76,29,280,37.5,0.605,57,1
209 | 5,162,104,0,0,37.7,0.151,52,1
210 | 1,96,64,27,87,33.2,0.289,21,0
211 | 7,184,84,33,0,35.5,0.355,41,1
212 | 2,81,60,22,0,27.7,0.29,25,0
213 | 0,147,85,54,0,42.8,0.375,24,0
214 | 7,179,95,31,0,34.2,0.16399999999999998,60,0
215 | 0,140,65,26,130,42.6,0.431,24,1
216 | 9,112,82,32,175,34.2,0.26,36,1
217 | 12,151,70,40,271,41.8,0.742,38,1
218 | 5,109,62,41,129,35.8,0.514,25,1
219 | 6,125,68,30,120,30.0,0.46399999999999997,32,0
220 | 5,85,74,22,0,29.0,1.224,32,1
221 | 5,112,66,0,0,37.8,0.261,41,1
222 | 0,177,60,29,478,34.6,1.072,21,1
223 | 2,158,90,0,0,31.6,0.805,66,1
224 | 7,119,0,0,0,25.2,0.209,37,0
225 | 7,142,60,33,190,28.8,0.687,61,0
226 | 1,100,66,15,56,23.6,0.6659999999999999,26,0
227 | 1,87,78,27,32,34.6,0.10099999999999999,22,0
228 | 0,101,76,0,0,35.7,0.198,26,0
229 | 3,162,52,38,0,37.2,0.652,24,1
230 | 4,197,70,39,744,36.7,2.329,31,0
231 | 0,117,80,31,53,45.2,0.08900000000000001,24,0
232 | 4,142,86,0,0,44.0,0.645,22,1
233 | 6,134,80,37,370,46.2,0.23800000000000002,46,1
234 | 1,79,80,25,37,25.4,0.583,22,0
235 | 4,122,68,0,0,35.0,0.39399999999999996,29,0
236 | 3,74,68,28,45,29.7,0.293,23,0
237 | 4,171,72,0,0,43.6,0.479,26,1
238 | 7,181,84,21,192,35.9,0.586,51,1
239 | 0,179,90,27,0,44.1,0.6859999999999999,23,1
240 | 9,164,84,21,0,30.8,0.831,32,1
241 | 0,104,76,0,0,18.4,0.5820000000000001,27,0
242 | 1,91,64,24,0,29.2,0.192,21,0
243 | 4,91,70,32,88,33.1,0.446,22,0
244 | 3,139,54,0,0,25.6,0.402,22,1
245 | 6,119,50,22,176,27.1,1.318,33,1
246 | 2,146,76,35,194,38.2,0.32899999999999996,29,0
247 | 9,184,85,15,0,30.0,1.213,49,1
248 | 10,122,68,0,0,31.2,0.258,41,0
249 | 0,165,90,33,680,52.3,0.42700000000000005,23,0
250 | 9,124,70,33,402,35.4,0.282,34,0
251 | 1,111,86,19,0,30.1,0.14300000000000002,23,0
252 | 9,106,52,0,0,31.2,0.38,42,0
253 | 2,129,84,0,0,28.0,0.284,27,0
254 | 2,90,80,14,55,24.4,0.249,24,0
255 | 0,86,68,32,0,35.8,0.23800000000000002,25,0
256 | 12,92,62,7,258,27.6,0.9259999999999999,44,1
257 | 1,113,64,35,0,33.6,0.5429999999999999,21,1
258 | 3,111,56,39,0,30.1,0.557,30,0
259 | 2,114,68,22,0,28.7,0.092,25,0
260 | 1,193,50,16,375,25.9,0.655,24,0
261 | 11,155,76,28,150,33.3,1.3530000000000002,51,1
262 | 3,191,68,15,130,30.9,0.299,34,0
263 | 3,141,0,0,0,30.0,0.7609999999999999,27,1
264 | 4,95,70,32,0,32.1,0.612,24,0
265 | 3,142,80,15,0,32.4,0.2,63,0
266 | 4,123,62,0,0,32.0,0.226,35,1
267 | 5,96,74,18,67,33.6,0.997,43,0
268 | 0,138,0,0,0,36.3,0.9329999999999999,25,1
269 | 2,128,64,42,0,40.0,1.101,24,0
270 | 0,102,52,0,0,25.1,0.078,21,0
271 | 2,146,0,0,0,27.5,0.24,28,1
272 | 10,101,86,37,0,45.6,1.136,38,1
273 | 2,108,62,32,56,25.2,0.128,21,0
274 | 3,122,78,0,0,23.0,0.254,40,0
275 | 1,71,78,50,45,33.2,0.42200000000000004,21,0
276 | 13,106,70,0,0,34.2,0.251,52,0
277 | 2,100,70,52,57,40.5,0.677,25,0
278 | 7,106,60,24,0,26.5,0.29600000000000004,29,1
279 | 0,104,64,23,116,27.8,0.45399999999999996,23,0
280 | 5,114,74,0,0,24.9,0.7440000000000001,57,0
281 | 2,108,62,10,278,25.3,0.8809999999999999,22,0
282 | 0,146,70,0,0,37.9,0.33399999999999996,28,1
283 | 10,129,76,28,122,35.9,0.28,39,0
284 | 7,133,88,15,155,32.4,0.262,37,0
285 | 7,161,86,0,0,30.4,0.165,47,1
286 | 2,108,80,0,0,27.0,0.259,52,1
287 | 7,136,74,26,135,26.0,0.647,51,0
288 | 5,155,84,44,545,38.7,0.619,34,0
289 | 1,119,86,39,220,45.6,0.8079999999999999,29,1
290 | 4,96,56,17,49,20.8,0.34,26,0
291 | 5,108,72,43,75,36.1,0.263,33,0
292 | 0,78,88,29,40,36.9,0.434,21,0
293 | 0,107,62,30,74,36.6,0.757,25,1
294 | 2,128,78,37,182,43.3,1.224,31,1
295 | 1,128,48,45,194,40.5,0.613,24,1
296 | 0,161,50,0,0,21.9,0.254,65,0
297 | 6,151,62,31,120,35.5,0.6920000000000001,28,0
298 | 2,146,70,38,360,28.0,0.337,29,1
299 | 0,126,84,29,215,30.7,0.52,24,0
300 | 14,100,78,25,184,36.6,0.41200000000000003,46,1
301 | 8,112,72,0,0,23.6,0.84,58,0
302 | 0,167,0,0,0,32.3,0.8390000000000001,30,1
303 | 2,144,58,33,135,31.6,0.42200000000000004,25,1
304 | 5,77,82,41,42,35.8,0.156,35,0
305 | 5,115,98,0,0,52.9,0.209,28,1
306 | 3,150,76,0,0,21.0,0.207,37,0
307 | 2,120,76,37,105,39.7,0.215,29,0
308 | 10,161,68,23,132,25.5,0.326,47,1
309 | 0,137,68,14,148,24.8,0.14300000000000002,21,0
310 | 0,128,68,19,180,30.5,1.391,25,1
311 | 2,124,68,28,205,32.9,0.875,30,1
312 | 6,80,66,30,0,26.2,0.313,41,0
313 | 0,106,70,37,148,39.4,0.605,22,0
314 | 2,155,74,17,96,26.6,0.433,27,1
315 | 3,113,50,10,85,29.5,0.626,25,0
316 | 7,109,80,31,0,35.9,1.127,43,1
317 | 2,112,68,22,94,34.1,0.315,26,0
318 | 3,99,80,11,64,19.3,0.284,30,0
319 | 3,182,74,0,0,30.5,0.345,29,1
320 | 3,115,66,39,140,38.1,0.15,28,0
321 | 6,194,78,0,0,23.5,0.129,59,1
322 | 4,129,60,12,231,27.5,0.527,31,0
323 | 3,112,74,30,0,31.6,0.19699999999999998,25,1
324 | 0,124,70,20,0,27.4,0.254,36,1
325 | 13,152,90,33,29,26.8,0.731,43,1
326 | 2,112,75,32,0,35.7,0.14800000000000002,21,0
327 | 1,157,72,21,168,25.6,0.12300000000000001,24,0
328 | 1,122,64,32,156,35.1,0.6920000000000001,30,1
329 | 10,179,70,0,0,35.1,0.2,37,0
330 | 2,102,86,36,120,45.5,0.127,23,1
331 | 6,105,70,32,68,30.8,0.122,37,0
332 | 8,118,72,19,0,23.1,1.476,46,0
333 | 2,87,58,16,52,32.7,0.166,25,0
334 | 1,180,0,0,0,43.3,0.282,41,1
335 | 12,106,80,0,0,23.6,0.13699999999999998,44,0
336 | 1,95,60,18,58,23.9,0.26,22,0
337 | 0,165,76,43,255,47.9,0.259,26,0
338 | 0,117,0,0,0,33.8,0.932,44,0
339 | 5,115,76,0,0,31.2,0.34299999999999997,44,1
340 | 9,152,78,34,171,34.2,0.893,33,1
341 | 7,178,84,0,0,39.9,0.331,41,1
342 | 1,130,70,13,105,25.9,0.47200000000000003,22,0
343 | 1,95,74,21,73,25.9,0.6729999999999999,36,0
344 | 1,0,68,35,0,32.0,0.389,22,0
345 | 5,122,86,0,0,34.7,0.29,33,0
346 | 8,95,72,0,0,36.8,0.485,57,0
347 | 8,126,88,36,108,38.5,0.349,49,0
348 | 1,139,46,19,83,28.7,0.654,22,0
349 | 3,116,0,0,0,23.5,0.187,23,0
350 | 3,99,62,19,74,21.8,0.27899999999999997,26,0
351 | 5,0,80,32,0,41.0,0.34600000000000003,37,1
352 | 4,92,80,0,0,42.2,0.237,29,0
353 | 4,137,84,0,0,31.2,0.252,30,0
354 | 3,61,82,28,0,34.4,0.243,46,0
355 | 1,90,62,12,43,27.2,0.58,24,0
356 | 3,90,78,0,0,42.7,0.5589999999999999,21,0
357 | 9,165,88,0,0,30.4,0.302,49,1
358 | 1,125,50,40,167,33.3,0.9620000000000001,28,1
359 | 13,129,0,30,0,39.9,0.569,44,1
360 | 12,88,74,40,54,35.3,0.37799999999999995,48,0
361 | 1,196,76,36,249,36.5,0.875,29,1
362 | 5,189,64,33,325,31.2,0.583,29,1
363 | 5,158,70,0,0,29.8,0.207,63,0
364 | 5,103,108,37,0,39.2,0.305,65,0
365 | 4,146,78,0,0,38.5,0.52,67,1
366 | 4,147,74,25,293,34.9,0.385,30,0
367 | 5,99,54,28,83,34.0,0.499,30,0
368 | 6,124,72,0,0,27.6,0.368,29,1
369 | 0,101,64,17,0,21.0,0.252,21,0
370 | 3,81,86,16,66,27.5,0.306,22,0
371 | 1,133,102,28,140,32.8,0.23399999999999999,45,1
372 | 3,173,82,48,465,38.4,2.137,25,1
373 | 0,118,64,23,89,0.0,1.7309999999999999,21,0
374 | 0,84,64,22,66,35.8,0.545,21,0
375 | 2,105,58,40,94,34.9,0.225,25,0
376 | 2,122,52,43,158,36.2,0.816,28,0
377 | 12,140,82,43,325,39.2,0.528,58,1
378 | 0,98,82,15,84,25.2,0.299,22,0
379 | 1,87,60,37,75,37.2,0.509,22,0
380 | 4,156,75,0,0,48.3,0.23800000000000002,32,1
381 | 0,93,100,39,72,43.4,1.021,35,0
382 | 1,107,72,30,82,30.8,0.821,24,0
383 | 0,105,68,22,0,20.0,0.23600000000000002,22,0
384 | 1,109,60,8,182,25.4,0.9470000000000001,21,0
385 | 1,90,62,18,59,25.1,1.268,25,0
386 | 1,125,70,24,110,24.3,0.221,25,0
387 | 1,119,54,13,50,22.3,0.205,24,0
388 | 5,116,74,29,0,32.3,0.66,35,1
389 | 8,105,100,36,0,43.3,0.239,45,1
390 | 5,144,82,26,285,32.0,0.452,58,1
391 | 3,100,68,23,81,31.6,0.9490000000000001,28,0
392 | 1,100,66,29,196,32.0,0.444,42,0
393 | 5,166,76,0,0,45.7,0.34,27,1
394 | 1,131,64,14,415,23.7,0.389,21,0
395 | 4,116,72,12,87,22.1,0.46299999999999997,37,0
396 | 4,158,78,0,0,32.9,0.8029999999999999,31,1
397 | 2,127,58,24,275,27.7,1.6,25,0
398 | 3,96,56,34,115,24.7,0.9440000000000001,39,0
399 | 0,131,66,40,0,34.3,0.196,22,1
400 | 3,82,70,0,0,21.1,0.389,25,0
401 | 3,193,70,31,0,34.9,0.24100000000000002,25,1
402 | 4,95,64,0,0,32.0,0.161,31,1
403 | 6,137,61,0,0,24.2,0.151,55,0
404 | 5,136,84,41,88,35.0,0.28600000000000003,35,1
405 | 9,72,78,25,0,31.6,0.28,38,0
406 | 5,168,64,0,0,32.9,0.135,41,1
407 | 2,123,48,32,165,42.1,0.52,26,0
408 | 4,115,72,0,0,28.9,0.376,46,1
409 | 0,101,62,0,0,21.9,0.336,25,0
410 | 8,197,74,0,0,25.9,1.1909999999999998,39,1
411 | 1,172,68,49,579,42.4,0.7020000000000001,28,1
412 | 6,102,90,39,0,35.7,0.674,28,0
413 | 1,112,72,30,176,34.4,0.528,25,0
414 | 1,143,84,23,310,42.4,1.0759999999999998,22,0
415 | 1,143,74,22,61,26.2,0.256,21,0
416 | 0,138,60,35,167,34.6,0.534,21,1
417 | 3,173,84,33,474,35.7,0.258,22,1
418 | 1,97,68,21,0,27.2,1.095,22,0
419 | 4,144,82,32,0,38.5,0.5539999999999999,37,1
420 | 1,83,68,0,0,18.2,0.624,27,0
421 | 3,129,64,29,115,26.4,0.21899999999999997,28,1
422 | 1,119,88,41,170,45.3,0.507,26,0
423 | 2,94,68,18,76,26.0,0.561,21,0
424 | 0,102,64,46,78,40.6,0.496,21,0
425 | 2,115,64,22,0,30.8,0.42100000000000004,21,0
426 | 8,151,78,32,210,42.9,0.516,36,1
427 | 4,184,78,39,277,37.0,0.264,31,1
428 | 0,94,0,0,0,0.0,0.256,25,0
429 | 1,181,64,30,180,34.1,0.32799999999999996,38,1
430 | 0,135,94,46,145,40.6,0.284,26,0
431 | 1,95,82,25,180,35.0,0.233,43,1
432 | 2,99,0,0,0,22.2,0.10800000000000001,23,0
433 | 3,89,74,16,85,30.4,0.551,38,0
434 | 1,80,74,11,60,30.0,0.527,22,0
435 | 2,139,75,0,0,25.6,0.16699999999999998,29,0
436 | 1,90,68,8,0,24.5,1.138,36,0
437 | 0,141,0,0,0,42.4,0.205,29,1
438 | 12,140,85,33,0,37.4,0.244,41,0
439 | 5,147,75,0,0,29.9,0.434,28,0
440 | 1,97,70,15,0,18.2,0.147,21,0
441 | 6,107,88,0,0,36.8,0.727,31,0
442 | 0,189,104,25,0,34.3,0.435,41,1
443 | 2,83,66,23,50,32.2,0.49700000000000005,22,0
444 | 4,117,64,27,120,33.2,0.23,24,0
445 | 8,108,70,0,0,30.5,0.955,33,1
446 | 4,117,62,12,0,29.7,0.38,30,1
447 | 0,180,78,63,14,59.4,2.42,25,1
448 | 1,100,72,12,70,25.3,0.6579999999999999,28,0
449 | 0,95,80,45,92,36.5,0.33,26,0
450 | 0,104,64,37,64,33.6,0.51,22,1
451 | 0,120,74,18,63,30.5,0.285,26,0
452 | 1,82,64,13,95,21.2,0.415,23,0
453 | 2,134,70,0,0,28.9,0.542,23,1
454 | 0,91,68,32,210,39.9,0.381,25,0
455 | 2,119,0,0,0,19.6,0.8320000000000001,72,0
456 | 2,100,54,28,105,37.8,0.498,24,0
457 | 14,175,62,30,0,33.6,0.212,38,1
458 | 1,135,54,0,0,26.7,0.687,62,0
459 | 5,86,68,28,71,30.2,0.364,24,0
460 | 10,148,84,48,237,37.6,1.001,51,1
461 | 9,134,74,33,60,25.9,0.46,81,0
462 | 9,120,72,22,56,20.8,0.733,48,0
463 | 1,71,62,0,0,21.8,0.41600000000000004,26,0
464 | 8,74,70,40,49,35.3,0.705,39,0
465 | 5,88,78,30,0,27.6,0.258,37,0
466 | 10,115,98,0,0,24.0,1.022,34,0
467 | 0,124,56,13,105,21.8,0.452,21,0
468 | 0,74,52,10,36,27.8,0.26899999999999996,22,0
469 | 0,97,64,36,100,36.8,0.6,25,0
470 | 8,120,0,0,0,30.0,0.183,38,1
471 | 6,154,78,41,140,46.1,0.5710000000000001,27,0
472 | 1,144,82,40,0,41.3,0.607,28,0
473 | 0,137,70,38,0,33.2,0.17,22,0
474 | 0,119,66,27,0,38.8,0.259,22,0
475 | 7,136,90,0,0,29.9,0.21,50,0
476 | 4,114,64,0,0,28.9,0.126,24,0
477 | 0,137,84,27,0,27.3,0.231,59,0
478 | 2,105,80,45,191,33.7,0.711,29,1
479 | 7,114,76,17,110,23.8,0.466,31,0
480 | 8,126,74,38,75,25.9,0.162,39,0
481 | 4,132,86,31,0,28.0,0.419,63,0
482 | 3,158,70,30,328,35.5,0.344,35,1
483 | 0,123,88,37,0,35.2,0.19699999999999998,29,0
484 | 4,85,58,22,49,27.8,0.306,28,0
485 | 0,84,82,31,125,38.2,0.233,23,0
486 | 0,145,0,0,0,44.2,0.63,31,1
487 | 0,135,68,42,250,42.3,0.365,24,1
488 | 1,139,62,41,480,40.7,0.536,21,0
489 | 0,173,78,32,265,46.5,1.159,58,0
490 | 4,99,72,17,0,25.6,0.294,28,0
491 | 8,194,80,0,0,26.1,0.551,67,0
492 | 2,83,65,28,66,36.8,0.629,24,0
493 | 2,89,90,30,0,33.5,0.292,42,0
494 | 4,99,68,38,0,32.8,0.145,33,0
495 | 4,125,70,18,122,28.9,1.1440000000000001,45,1
496 | 3,80,0,0,0,0.0,0.174,22,0
497 | 6,166,74,0,0,26.6,0.304,66,0
498 | 5,110,68,0,0,26.0,0.292,30,0
499 | 2,81,72,15,76,30.1,0.547,25,0
500 | 7,195,70,33,145,25.1,0.163,55,1
501 | 6,154,74,32,193,29.3,0.8390000000000001,39,0
502 | 2,117,90,19,71,25.2,0.313,21,0
503 | 3,84,72,32,0,37.2,0.267,28,0
504 | 6,0,68,41,0,39.0,0.727,41,1
505 | 7,94,64,25,79,33.3,0.738,41,0
506 | 3,96,78,39,0,37.3,0.23800000000000002,40,0
507 | 10,75,82,0,0,33.3,0.263,38,0
508 | 0,180,90,26,90,36.5,0.314,35,1
509 | 1,130,60,23,170,28.6,0.6920000000000001,21,0
510 | 2,84,50,23,76,30.4,0.968,21,0
511 | 8,120,78,0,0,25.0,0.409,64,0
512 | 12,84,72,31,0,29.7,0.297,46,1
513 | 0,139,62,17,210,22.1,0.207,21,0
514 | 9,91,68,0,0,24.2,0.2,58,0
515 | 2,91,62,0,0,27.3,0.525,22,0
516 | 3,99,54,19,86,25.6,0.154,24,0
517 | 3,163,70,18,105,31.6,0.268,28,1
518 | 9,145,88,34,165,30.3,0.7709999999999999,53,1
519 | 7,125,86,0,0,37.6,0.304,51,0
520 | 13,76,60,0,0,32.8,0.18,41,0
521 | 6,129,90,7,326,19.6,0.5820000000000001,60,0
522 | 2,68,70,32,66,25.0,0.187,25,0
523 | 3,124,80,33,130,33.2,0.305,26,0
524 | 6,114,0,0,0,0.0,0.18899999999999997,26,0
525 | 9,130,70,0,0,34.2,0.652,45,1
526 | 3,125,58,0,0,31.6,0.151,24,0
527 | 3,87,60,18,0,21.8,0.444,21,0
528 | 1,97,64,19,82,18.2,0.299,21,0
529 | 3,116,74,15,105,26.3,0.107,24,0
530 | 0,117,66,31,188,30.8,0.493,22,0
531 | 0,111,65,0,0,24.6,0.66,31,0
532 | 2,122,60,18,106,29.8,0.7170000000000001,22,0
533 | 0,107,76,0,0,45.3,0.6859999999999999,24,0
534 | 1,86,66,52,65,41.3,0.917,29,0
535 | 6,91,0,0,0,29.8,0.501,31,0
536 | 1,77,56,30,56,33.3,1.251,24,0
537 | 4,132,0,0,0,32.9,0.302,23,1
538 | 0,105,90,0,0,29.6,0.19699999999999998,46,0
539 | 0,57,60,0,0,21.7,0.735,67,0
540 | 0,127,80,37,210,36.3,0.804,23,0
541 | 3,129,92,49,155,36.4,0.968,32,1
542 | 8,100,74,40,215,39.4,0.6609999999999999,43,1
543 | 3,128,72,25,190,32.4,0.5489999999999999,27,1
544 | 10,90,85,32,0,34.9,0.825,56,1
545 | 4,84,90,23,56,39.5,0.159,25,0
546 | 1,88,78,29,76,32.0,0.365,29,0
547 | 8,186,90,35,225,34.5,0.423,37,1
548 | 5,187,76,27,207,43.6,1.034,53,1
549 | 4,131,68,21,166,33.1,0.16,28,0
550 | 1,164,82,43,67,32.8,0.341,50,0
551 | 4,189,110,31,0,28.5,0.68,37,0
552 | 1,116,70,28,0,27.4,0.204,21,0
553 | 3,84,68,30,106,31.9,0.591,25,0
554 | 6,114,88,0,0,27.8,0.247,66,0
555 | 1,88,62,24,44,29.9,0.42200000000000004,23,0
556 | 1,84,64,23,115,36.9,0.47100000000000003,28,0
557 | 7,124,70,33,215,25.5,0.161,37,0
558 | 1,97,70,40,0,38.1,0.218,30,0
559 | 8,110,76,0,0,27.8,0.237,58,0
560 | 11,103,68,40,0,46.2,0.126,42,0
561 | 11,85,74,0,0,30.1,0.3,35,0
562 | 6,125,76,0,0,33.8,0.121,54,1
563 | 0,198,66,32,274,41.3,0.502,28,1
564 | 1,87,68,34,77,37.6,0.401,24,0
565 | 6,99,60,19,54,26.9,0.49700000000000005,32,0
566 | 0,91,80,0,0,32.4,0.601,27,0
567 | 2,95,54,14,88,26.1,0.748,22,0
568 | 1,99,72,30,18,38.6,0.41200000000000003,21,0
569 | 6,92,62,32,126,32.0,0.085,46,0
570 | 4,154,72,29,126,31.3,0.33799999999999997,37,0
571 | 0,121,66,30,165,34.3,0.203,33,1
572 | 3,78,70,0,0,32.5,0.27,39,0
573 | 2,130,96,0,0,22.6,0.268,21,0
574 | 3,111,58,31,44,29.5,0.43,22,0
575 | 2,98,60,17,120,34.7,0.198,22,0
576 | 1,143,86,30,330,30.1,0.892,23,0
577 | 1,119,44,47,63,35.5,0.28,25,0
578 | 6,108,44,20,130,24.0,0.813,35,0
579 | 2,118,80,0,0,42.9,0.693,21,1
580 | 10,133,68,0,0,27.0,0.245,36,0
581 | 2,197,70,99,0,34.7,0.575,62,1
582 | 0,151,90,46,0,42.1,0.371,21,1
583 | 6,109,60,27,0,25.0,0.20600000000000002,27,0
584 | 12,121,78,17,0,26.5,0.259,62,0
585 | 8,100,76,0,0,38.7,0.19,42,0
586 | 8,124,76,24,600,28.7,0.687,52,1
587 | 1,93,56,11,0,22.5,0.41700000000000004,22,0
588 | 8,143,66,0,0,34.9,0.129,41,1
589 | 6,103,66,0,0,24.3,0.249,29,0
590 | 3,176,86,27,156,33.3,1.1540000000000001,52,1
591 | 0,73,0,0,0,21.1,0.342,25,0
592 | 11,111,84,40,0,46.8,0.925,45,1
593 | 2,112,78,50,140,39.4,0.175,24,0
594 | 3,132,80,0,0,34.4,0.402,44,1
595 | 2,82,52,22,115,28.5,1.699,25,0
596 | 6,123,72,45,230,33.6,0.733,34,0
597 | 0,188,82,14,185,32.0,0.682,22,1
598 | 0,67,76,0,0,45.3,0.19399999999999998,46,0
599 | 1,89,24,19,25,27.8,0.5589999999999999,21,0
600 | 1,173,74,0,0,36.8,0.08800000000000001,38,1
601 | 1,109,38,18,120,23.1,0.40700000000000003,26,0
602 | 1,108,88,19,0,27.1,0.4,24,0
603 | 6,96,0,0,0,23.7,0.19,28,0
604 | 1,124,74,36,0,27.8,0.1,30,0
605 | 7,150,78,29,126,35.2,0.6920000000000001,54,1
606 | 4,183,0,0,0,28.4,0.212,36,1
607 | 1,124,60,32,0,35.8,0.514,21,0
608 | 1,181,78,42,293,40.0,1.258,22,1
609 | 1,92,62,25,41,19.5,0.48200000000000004,25,0
610 | 0,152,82,39,272,41.5,0.27,27,0
611 | 1,111,62,13,182,24.0,0.138,23,0
612 | 3,106,54,21,158,30.9,0.292,24,0
613 | 3,174,58,22,194,32.9,0.593,36,1
614 | 7,168,88,42,321,38.2,0.787,40,1
615 | 6,105,80,28,0,32.5,0.878,26,0
616 | 11,138,74,26,144,36.1,0.557,50,1
617 | 3,106,72,0,0,25.8,0.207,27,0
618 | 6,117,96,0,0,28.7,0.157,30,0
619 | 2,68,62,13,15,20.1,0.257,23,0
620 | 9,112,82,24,0,28.2,1.2819999999999998,50,1
621 | 0,119,0,0,0,32.4,0.141,24,1
622 | 2,112,86,42,160,38.4,0.24600000000000002,28,0
623 | 2,92,76,20,0,24.2,1.6980000000000002,28,0
624 | 6,183,94,0,0,40.8,1.4609999999999999,45,0
625 | 0,94,70,27,115,43.5,0.34700000000000003,21,0
626 | 2,108,64,0,0,30.8,0.158,21,0
627 | 4,90,88,47,54,37.7,0.36200000000000004,29,0
628 | 0,125,68,0,0,24.7,0.20600000000000002,21,0
629 | 0,132,78,0,0,32.4,0.39299999999999996,21,0
630 | 5,128,80,0,0,34.6,0.14400000000000002,45,0
631 | 4,94,65,22,0,24.7,0.14800000000000002,21,0
632 | 7,114,64,0,0,27.4,0.732,34,1
633 | 0,102,78,40,90,34.5,0.23800000000000002,24,0
634 | 2,111,60,0,0,26.2,0.34299999999999997,23,0
635 | 1,128,82,17,183,27.5,0.115,22,0
636 | 10,92,62,0,0,25.9,0.16699999999999998,31,0
637 | 13,104,72,0,0,31.2,0.465,38,1
638 | 5,104,74,0,0,28.8,0.153,48,0
639 | 2,94,76,18,66,31.6,0.649,23,0
640 | 7,97,76,32,91,40.9,0.871,32,1
641 | 1,100,74,12,46,19.5,0.149,28,0
642 | 0,102,86,17,105,29.3,0.695,27,0
643 | 4,128,70,0,0,34.3,0.303,24,0
644 | 6,147,80,0,0,29.5,0.17800000000000002,50,1
645 | 4,90,0,0,0,28.0,0.61,31,0
646 | 3,103,72,30,152,27.6,0.73,27,0
647 | 2,157,74,35,440,39.4,0.134,30,0
648 | 1,167,74,17,144,23.4,0.447,33,1
649 | 0,179,50,36,159,37.8,0.455,22,1
650 | 11,136,84,35,130,28.3,0.26,42,1
651 | 0,107,60,25,0,26.4,0.133,23,0
652 | 1,91,54,25,100,25.2,0.23399999999999999,23,0
653 | 1,117,60,23,106,33.8,0.466,27,0
654 | 5,123,74,40,77,34.1,0.26899999999999996,28,0
655 | 2,120,54,0,0,26.8,0.455,27,0
656 | 1,106,70,28,135,34.2,0.142,22,0
657 | 2,155,52,27,540,38.7,0.24,25,1
658 | 2,101,58,35,90,21.8,0.155,22,0
659 | 1,120,80,48,200,38.9,1.162,41,0
660 | 11,127,106,0,0,39.0,0.19,51,0
661 | 3,80,82,31,70,34.2,1.2919999999999998,27,1
662 | 10,162,84,0,0,27.7,0.182,54,0
663 | 1,199,76,43,0,42.9,1.3940000000000001,22,1
664 | 8,167,106,46,231,37.6,0.165,43,1
665 | 9,145,80,46,130,37.9,0.637,40,1
666 | 6,115,60,39,0,33.7,0.245,40,1
667 | 1,112,80,45,132,34.8,0.217,24,0
668 | 4,145,82,18,0,32.5,0.235,70,1
669 | 10,111,70,27,0,27.5,0.141,40,1
670 | 6,98,58,33,190,34.0,0.43,43,0
671 | 9,154,78,30,100,30.9,0.16399999999999998,45,0
672 | 6,165,68,26,168,33.6,0.631,49,0
673 | 1,99,58,10,0,25.4,0.551,21,0
674 | 10,68,106,23,49,35.5,0.285,47,0
675 | 3,123,100,35,240,57.3,0.88,22,0
676 | 8,91,82,0,0,35.6,0.5870000000000001,68,0
677 | 6,195,70,0,0,30.9,0.32799999999999996,31,1
678 | 9,156,86,0,0,24.8,0.23,53,1
679 | 0,93,60,0,0,35.3,0.263,25,0
680 | 3,121,52,0,0,36.0,0.127,25,1
681 | 2,101,58,17,265,24.2,0.614,23,0
682 | 2,56,56,28,45,24.2,0.332,22,0
683 | 0,162,76,36,0,49.6,0.364,26,1
684 | 0,95,64,39,105,44.6,0.366,22,0
685 | 4,125,80,0,0,32.3,0.536,27,1
686 | 5,136,82,0,0,0.0,0.64,69,0
687 | 2,129,74,26,205,33.2,0.591,25,0
688 | 3,130,64,0,0,23.1,0.314,22,0
689 | 1,107,50,19,0,28.3,0.18100000000000002,29,0
690 | 1,140,74,26,180,24.1,0.828,23,0
691 | 1,144,82,46,180,46.1,0.335,46,1
692 | 8,107,80,0,0,24.6,0.856,34,0
693 | 13,158,114,0,0,42.3,0.257,44,1
694 | 2,121,70,32,95,39.1,0.8859999999999999,23,0
695 | 7,129,68,49,125,38.5,0.439,43,1
696 | 2,90,60,0,0,23.5,0.191,25,0
697 | 7,142,90,24,480,30.4,0.128,43,1
698 | 3,169,74,19,125,29.9,0.268,31,1
699 | 0,99,0,0,0,25.0,0.253,22,0
700 | 4,127,88,11,155,34.5,0.598,28,0
701 | 4,118,70,0,0,44.5,0.904,26,0
702 | 2,122,76,27,200,35.9,0.483,26,0
703 | 6,125,78,31,0,27.6,0.565,49,1
704 | 1,168,88,29,0,35.0,0.905,52,1
705 | 2,129,0,0,0,38.5,0.304,41,0
706 | 4,110,76,20,100,28.4,0.11800000000000001,27,0
707 | 6,80,80,36,0,39.8,0.177,28,0
708 | 10,115,0,0,0,0.0,0.261,30,1
709 | 2,127,46,21,335,34.4,0.17600000000000002,22,0
710 | 9,164,78,0,0,32.8,0.14800000000000002,45,1
711 | 2,93,64,32,160,38.0,0.674,23,1
712 | 3,158,64,13,387,31.2,0.295,24,0
713 | 5,126,78,27,22,29.6,0.439,40,0
714 | 10,129,62,36,0,41.2,0.441,38,1
715 | 0,134,58,20,291,26.4,0.35200000000000004,21,0
716 | 3,102,74,0,0,29.5,0.121,32,0
717 | 7,187,50,33,392,33.9,0.826,34,1
718 | 3,173,78,39,185,33.8,0.97,31,1
719 | 10,94,72,18,0,23.1,0.595,56,0
720 | 1,108,60,46,178,35.5,0.415,24,0
721 | 5,97,76,27,0,35.6,0.37799999999999995,52,1
722 | 4,83,86,19,0,29.3,0.317,34,0
723 | 1,114,66,36,200,38.1,0.289,21,0
724 | 1,149,68,29,127,29.3,0.349,42,1
725 | 5,117,86,30,105,39.1,0.251,42,0
726 | 1,111,94,0,0,32.8,0.265,45,0
727 | 4,112,78,40,0,39.4,0.23600000000000002,38,0
728 | 1,116,78,29,180,36.1,0.496,25,0
729 | 0,141,84,26,0,32.4,0.433,22,0
730 | 2,175,88,0,0,22.9,0.326,22,0
731 | 2,92,52,0,0,30.1,0.141,22,0
732 | 3,130,78,23,79,28.4,0.32299999999999995,34,1
733 | 8,120,86,0,0,28.4,0.259,22,1
734 | 2,174,88,37,120,44.5,0.6459999999999999,24,1
735 | 2,106,56,27,165,29.0,0.426,22,0
736 | 2,105,75,0,0,23.3,0.56,53,0
737 | 4,95,60,32,0,35.4,0.284,28,0
738 | 0,126,86,27,120,27.4,0.515,21,0
739 | 8,65,72,23,0,32.0,0.6,42,0
740 | 2,99,60,17,160,36.6,0.45299999999999996,21,0
741 | 1,102,74,0,0,39.5,0.293,42,1
742 | 11,120,80,37,150,42.3,0.785,48,1
743 | 3,102,44,20,94,30.8,0.4,26,0
744 | 1,109,58,18,116,28.5,0.21899999999999997,22,0
745 | 9,140,94,0,0,32.7,0.7340000000000001,45,1
746 | 13,153,88,37,140,40.6,1.1740000000000002,39,0
747 | 12,100,84,33,105,30.0,0.488,46,0
748 | 1,147,94,41,0,49.3,0.358,27,1
749 | 1,81,74,41,57,46.3,1.0959999999999999,32,0
750 | 3,187,70,22,200,36.4,0.408,36,1
751 | 6,162,62,0,0,24.3,0.17800000000000002,50,1
752 | 4,136,70,0,0,31.2,1.182,22,1
753 | 1,121,78,39,74,39.0,0.261,28,0
754 | 3,108,62,24,0,26.0,0.223,25,0
755 | 0,181,88,44,510,43.3,0.222,26,1
756 | 8,154,78,32,0,32.4,0.44299999999999995,45,1
757 | 1,128,88,39,110,36.5,1.057,37,1
758 | 7,137,90,41,0,32.0,0.391,39,0
759 | 0,123,72,0,0,36.3,0.258,52,1
760 | 1,106,76,0,0,37.5,0.19699999999999998,26,0
761 | 6,190,92,0,0,35.5,0.278,66,1
762 | 2,88,58,26,16,28.4,0.7659999999999999,22,0
763 | 9,170,74,31,0,44.0,0.40299999999999997,43,1
764 | 9,89,62,0,0,22.5,0.142,33,0
765 | 10,101,76,48,180,32.9,0.171,63,0
766 | 2,122,70,27,0,36.8,0.34,27,0
767 | 5,121,72,23,112,26.2,0.245,30,0
768 | 1,126,60,0,0,30.1,0.349,47,1
769 | 1,93,70,31,0,30.4,0.315,23,0
770 |
--------------------------------------------------------------------------------
/Principal Component Analysis/dimensionality reduction.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "toc": true
7 | },
8 | "source": [
9 | "Table of Contents
\n",
10 | ""
11 | ]
12 | },
13 | {
14 | "cell_type": "code",
15 | "execution_count": 1,
16 | "metadata": {
17 | "ExecuteTime": {
18 | "end_time": "2020-04-17T16:53:43.976333Z",
19 | "start_time": "2020-04-17T16:53:40.941030Z"
20 | }
21 | },
22 | "outputs": [],
23 | "source": [
24 | "import numpy as np\n",
25 | "import matplotlib.pyplot as plt\n",
26 | "from sklearn.datasets import load_iris\n",
27 | "import pandas as pd\n",
28 | "from sklearn.model_selection import train_test_split\n",
29 | "from sklearn.linear_model import LogisticRegression\n",
30 | "from sklearn.metrics import accuracy_score"
31 | ]
32 | },
33 | {
34 | "cell_type": "code",
35 | "execution_count": 2,
36 | "metadata": {
37 | "ExecuteTime": {
38 | "end_time": "2020-04-17T16:53:43.992027Z",
39 | "start_time": "2020-04-17T16:53:43.981690Z"
40 | }
41 | },
42 | "outputs": [],
43 | "source": [
44 | "import warnings\n",
45 | "warnings.filterwarnings(\"ignore\")"
46 | ]
47 | },
48 | {
49 | "cell_type": "markdown",
50 | "metadata": {},
51 | "source": [
52 | "# Dimensionality reduction Using PCA"
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "execution_count": 3,
58 | "metadata": {
59 | "ExecuteTime": {
60 | "end_time": "2020-04-17T16:53:44.209748Z",
61 | "start_time": "2020-04-17T16:53:43.997649Z"
62 | }
63 | },
64 | "outputs": [],
65 | "source": [
66 | "class PCA:\n",
67 | " \n",
68 | " def __init__(self, n_component, solver=\"svd\"):\n",
69 | " self.n_component = n_component\n",
70 | " self.solver=solver\n",
71 | " self.components = None\n",
72 | " self.mean = None\n",
73 | " \n",
74 | " \n",
75 | " def fit(self, X):\n",
76 | " self.mean = X.mean(axis=0)\n",
77 | " X = X - self.mean\n",
78 | " \n",
79 | " # expects row=feature, column=sample \n",
80 | " # cov = np.cov(X.T)\n",
81 | " cov = (X - X.mean(axis=0)).T.dot(X - X.mean(axis=0)) / (X.shape[0] - 1)\n",
82 | " \n",
83 | " \n",
84 | " if self.solver == \"eig\":\n",
85 | " # eigenvalue[i] -> eigenvector[:, i]\n",
86 | " eigenvalues, eigenvectors = np.linalg.eig(cov)\n",
87 | " \n",
88 | " eigenvectors = eigenvectors.T\n",
89 | " \n",
90 | " idxs = np.argsort(eigenvalues)[::-1]\n",
91 | " eigenvalues = eigenvalues[idxs]\n",
92 | " eigenvectors = eigenvectors[idxs]\n",
93 | " \n",
94 | " self.components = eigenvectors[0:self.n_component]\n",
95 | " \n",
96 | " \n",
97 | " else: \n",
98 | " # SVD\n",
99 | " _, S, Vt = np.linalg.svd(X)\n",
100 | " idxs = np.argsort(S)[::-1]\n",
101 | " \n",
102 | " S = S[idxs]\n",
103 | " Vt = Vt[idxs]\n",
104 | " \n",
105 | " self.components = Vt[0:self.n_component]\n",
106 | " \n",
107 | " \n",
108 | " def transform(self, X):\n",
109 | " X = X - self.mean\n",
110 | " return np.dot(X, self.components.T)\n",
111 | " \n",
112 | " def fit_transform(self, X):\n",
113 | " self.fit(X)\n",
114 | " return self.transform(X)"
115 | ]
116 | },
117 | {
118 | "cell_type": "markdown",
119 | "metadata": {},
120 | "source": [
121 | "# Feature Extraction on Diabetes dataset"
122 | ]
123 | },
124 | {
125 | "cell_type": "code",
126 | "execution_count": 4,
127 | "metadata": {
128 | "ExecuteTime": {
129 | "end_time": "2020-04-17T16:53:44.419215Z",
130 | "start_time": "2020-04-17T16:53:44.218687Z"
131 | }
132 | },
133 | "outputs": [
134 | {
135 | "data": {
136 | "text/html": [
137 | "\n",
138 | "\n",
151 | "
\n",
152 | " \n",
153 | " \n",
154 | " | \n",
155 | " Pregnancies | \n",
156 | " Glucose | \n",
157 | " BloodPressure | \n",
158 | " SkinThickness | \n",
159 | " Insulin | \n",
160 | " BMI | \n",
161 | " DiabetesPedigreeFunction | \n",
162 | " Age | \n",
163 | " Outcome | \n",
164 | "
\n",
165 | " \n",
166 | " \n",
167 | " \n",
168 | " | 0 | \n",
169 | " 6 | \n",
170 | " 148 | \n",
171 | " 72 | \n",
172 | " 35 | \n",
173 | " 0 | \n",
174 | " 33.6 | \n",
175 | " 0.627 | \n",
176 | " 50 | \n",
177 | " 1 | \n",
178 | "
\n",
179 | " \n",
180 | " | 1 | \n",
181 | " 1 | \n",
182 | " 85 | \n",
183 | " 66 | \n",
184 | " 29 | \n",
185 | " 0 | \n",
186 | " 26.6 | \n",
187 | " 0.351 | \n",
188 | " 31 | \n",
189 | " 0 | \n",
190 | "
\n",
191 | " \n",
192 | " | 2 | \n",
193 | " 8 | \n",
194 | " 183 | \n",
195 | " 64 | \n",
196 | " 0 | \n",
197 | " 0 | \n",
198 | " 23.3 | \n",
199 | " 0.672 | \n",
200 | " 32 | \n",
201 | " 1 | \n",
202 | "
\n",
203 | " \n",
204 | " | 3 | \n",
205 | " 1 | \n",
206 | " 89 | \n",
207 | " 66 | \n",
208 | " 23 | \n",
209 | " 94 | \n",
210 | " 28.1 | \n",
211 | " 0.167 | \n",
212 | " 21 | \n",
213 | " 0 | \n",
214 | "
\n",
215 | " \n",
216 | " | 4 | \n",
217 | " 0 | \n",
218 | " 137 | \n",
219 | " 40 | \n",
220 | " 35 | \n",
221 | " 168 | \n",
222 | " 43.1 | \n",
223 | " 2.288 | \n",
224 | " 33 | \n",
225 | " 1 | \n",
226 | "
\n",
227 | " \n",
228 | "
\n",
229 | "
"
230 | ],
231 | "text/plain": [
232 | " Pregnancies Glucose BloodPressure SkinThickness Insulin BMI \\\n",
233 | "0 6 148 72 35 0 33.6 \n",
234 | "1 1 85 66 29 0 26.6 \n",
235 | "2 8 183 64 0 0 23.3 \n",
236 | "3 1 89 66 23 94 28.1 \n",
237 | "4 0 137 40 35 168 43.1 \n",
238 | "\n",
239 | " DiabetesPedigreeFunction Age Outcome \n",
240 | "0 0.627 50 1 \n",
241 | "1 0.351 31 0 \n",
242 | "2 0.672 32 1 \n",
243 | "3 0.167 21 0 \n",
244 | "4 2.288 33 1 "
245 | ]
246 | },
247 | "execution_count": 4,
248 | "metadata": {},
249 | "output_type": "execute_result"
250 | }
251 | ],
252 | "source": [
253 | "diabetes_data = pd.read_csv(r'../datasets/diabetes_data.csv')\n",
254 | "diabetes_data.head()"
255 | ]
256 | },
257 | {
258 | "cell_type": "code",
259 | "execution_count": 5,
260 | "metadata": {
261 | "ExecuteTime": {
262 | "end_time": "2020-04-17T16:53:44.499226Z",
263 | "start_time": "2020-04-17T16:53:44.428118Z"
264 | }
265 | },
266 | "outputs": [],
267 | "source": [
268 | "X = diabetes_data[diabetes_data.columns[:-1]].values\n",
269 | "y = diabetes_data[diabetes_data.columns[-1]].values"
270 | ]
271 | },
272 | {
273 | "cell_type": "markdown",
274 | "metadata": {
275 | "ExecuteTime": {
276 | "end_time": "2020-04-17T16:43:53.350520Z",
277 | "start_time": "2020-04-17T16:43:53.342122Z"
278 | }
279 | },
280 | "source": [
281 | "## Accuracy Before applying PCA"
282 | ]
283 | },
284 | {
285 | "cell_type": "code",
286 | "execution_count": 6,
287 | "metadata": {
288 | "ExecuteTime": {
289 | "end_time": "2020-04-17T16:53:44.652486Z",
290 | "start_time": "2020-04-17T16:53:44.507580Z"
291 | }
292 | },
293 | "outputs": [],
294 | "source": [
295 | "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)"
296 | ]
297 | },
298 | {
299 | "cell_type": "code",
300 | "execution_count": 7,
301 | "metadata": {
302 | "ExecuteTime": {
303 | "end_time": "2020-04-17T16:53:44.948070Z",
304 | "start_time": "2020-04-17T16:53:44.666777Z"
305 | }
306 | },
307 | "outputs": [
308 | {
309 | "name": "stdout",
310 | "output_type": "stream",
311 | "text": [
312 | "Before feature extraction\n",
313 | "Number of features of X: 8\n",
314 | "Accuracy: 0.7142857142857143\n"
315 | ]
316 | }
317 | ],
318 | "source": [
319 | "# using Logistic Regression\n",
320 | "\n",
321 | "lr = LogisticRegression()\n",
322 | "lr.fit(X_train, y_train)\n",
323 | "y_pred = lr.predict(X_test)\n",
324 | "print(\"Before feature extraction\")\n",
325 | "print(f\"Number of features of X: {X_train.shape[1]}\")\n",
326 | "print(f\"Accuracy: {accuracy_score(y_test, y_pred)}\")"
327 | ]
328 | },
329 | {
330 | "cell_type": "markdown",
331 | "metadata": {},
332 | "source": [
333 | "## Accuracy After applying PCA"
334 | ]
335 | },
336 | {
337 | "cell_type": "code",
338 | "execution_count": 8,
339 | "metadata": {
340 | "ExecuteTime": {
341 | "end_time": "2020-04-17T16:53:45.049918Z",
342 | "start_time": "2020-04-17T16:53:44.960489Z"
343 | }
344 | },
345 | "outputs": [],
346 | "source": [
347 | "# Transforming Dataset\n",
348 | "\n",
349 | "pca = PCA(n_component=6)\n",
350 | "X_transformed = pca.fit_transform(X)\n",
351 | "X_train, X_test, y_train, y_test = train_test_split(X_transformed, y, test_size=0.2, stratify=y, random_state=42)"
352 | ]
353 | },
354 | {
355 | "cell_type": "code",
356 | "execution_count": 9,
357 | "metadata": {
358 | "ExecuteTime": {
359 | "end_time": "2020-04-17T16:53:45.162775Z",
360 | "start_time": "2020-04-17T16:53:45.049918Z"
361 | }
362 | },
363 | "outputs": [
364 | {
365 | "name": "stdout",
366 | "output_type": "stream",
367 | "text": [
368 | "After feature extraction\n",
369 | "Number of features of X: 6\n",
370 | "Accuracy: 0.7337662337662337\n"
371 | ]
372 | }
373 | ],
374 | "source": [
375 | "lr = LogisticRegression()\n",
376 | "lr.fit(X_train, y_train)\n",
377 | "y_pred = lr.predict(X_test)\n",
378 | "print(\"After feature extraction\")\n",
379 | "print(f\"Number of features of X: {X_train.shape[1]}\")\n",
380 | "print(f\"Accuracy: {accuracy_score(y_test, y_pred)}\")"
381 | ]
382 | },
383 | {
384 | "cell_type": "markdown",
385 | "metadata": {
386 | "ExecuteTime": {
387 | "end_time": "2020-04-17T16:53:17.733258Z",
388 | "start_time": "2020-04-17T16:53:17.726273Z"
389 | }
390 | },
391 | "source": [
392 | "# On Mnist Dataset\n",
393 | "\n",
394 | "Reducing number of features for visualization"
395 | ]
396 | },
397 | {
398 | "cell_type": "code",
399 | "execution_count": 10,
400 | "metadata": {
401 | "ExecuteTime": {
402 | "end_time": "2020-04-17T16:53:45.271370Z",
403 | "start_time": "2020-04-17T16:53:45.165615Z"
404 | }
405 | },
406 | "outputs": [],
407 | "source": [
408 | "data = load_iris()\n",
409 | "X = data.data\n",
410 | "y = data.target"
411 | ]
412 | },
413 | {
414 | "cell_type": "code",
415 | "execution_count": 11,
416 | "metadata": {
417 | "ExecuteTime": {
418 | "end_time": "2020-04-17T16:53:45.397396Z",
419 | "start_time": "2020-04-17T16:53:45.276300Z"
420 | }
421 | },
422 | "outputs": [],
423 | "source": [
424 | "pca = PCA(n_component=2)\n",
425 | "X_projected = pca.fit_transform(X)"
426 | ]
427 | },
428 | {
429 | "cell_type": "code",
430 | "execution_count": 12,
431 | "metadata": {
432 | "ExecuteTime": {
433 | "end_time": "2020-04-17T16:53:45.527547Z",
434 | "start_time": "2020-04-17T16:53:45.404998Z"
435 | }
436 | },
437 | "outputs": [
438 | {
439 | "name": "stdout",
440 | "output_type": "stream",
441 | "text": [
442 | "Shape of X: (150, 4)\n",
443 | "Shape of transformed X: (150, 2)\n"
444 | ]
445 | }
446 | ],
447 | "source": [
448 | "print(f\"Shape of X: {X.shape}\")\n",
449 | "print(f\"Shape of transformed X: {X_projected.shape}\")"
450 | ]
451 | },
452 | {
453 | "cell_type": "code",
454 | "execution_count": 13,
455 | "metadata": {
456 | "ExecuteTime": {
457 | "end_time": "2020-04-17T16:53:45.655688Z",
458 | "start_time": "2020-04-17T16:53:45.537553Z"
459 | }
460 | },
461 | "outputs": [],
462 | "source": [
463 | "x1 = X_projected[:, 0]\n",
464 | "x2 = X_projected[:, 1]"
465 | ]
466 | },
467 | {
468 | "cell_type": "code",
469 | "execution_count": 14,
470 | "metadata": {
471 | "ExecuteTime": {
472 | "end_time": "2020-04-17T16:53:46.104685Z",
473 | "start_time": "2020-04-17T16:53:45.665223Z"
474 | }
475 | },
476 | "outputs": [
477 | {
478 | "data": {
479 | "text/plain": [
480 | "(150, 3)"
481 | ]
482 | },
483 | "execution_count": 14,
484 | "metadata": {},
485 | "output_type": "execute_result"
486 | }
487 | ],
488 | "source": [
489 | "X_trans = np.c_[x1, x2, y]\n",
490 | "X_trans.shape"
491 | ]
492 | },
493 | {
494 | "cell_type": "code",
495 | "execution_count": 15,
496 | "metadata": {
497 | "ExecuteTime": {
498 | "end_time": "2020-04-17T16:53:47.087110Z",
499 | "start_time": "2020-04-17T16:53:46.115345Z"
500 | }
501 | },
502 | "outputs": [
503 | {
504 | "data": {
505 | "image/png": "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2kT14s59Jl+2bFlYbGhpacFiCexWrysKRVF6HMEeWvXggw/y61//uu3z0qVLKSoqYvny5VxxxRXk5OTwyCOPALBv3z7GjRvHfffdx+WXX87BgweZN28e48ePZ8KECW1d2PPmzeP5558H4P333+eqq65i4sSJTJkyhZqaGhoaGpg/fz4TJkxg0qRJrF+//hy7Tpw4waxZs8jJyWHq1KmUlZW12bdgwQI+97nPMXfu3IB+d1BHocQwOsFO6YxQDK264447WLPm7CyTP//5zwwcOJCPP/6YTZs2sWXLFjZv3szGjY5r7Nq1i7lz5/Lhhx9y/PhxDh8+zPbt29m2bRvz589vd+6mpiZmz57No48+ytatW1m3bh19+vThscceAxzyIX/84x+56667zhEJfOSRR5g0aRJlZWX8z//8TzunsHnzZl5++WX+8Ic/+P17u4iooxCR34mITUS2e/heRGSFiOwRkTIRuTzcNirRR0nJRqzWW5kx42E2bLiehIQndIKd0kYohlZNmjQJm83GkSNH2Lp1K/369aOsrIzXXnuNSZMmcfnll/PRRx/x8ccfAzBixAimTp0KwEUXXcQnn3zC/fffz6uvvkp6enq7c+/atYtBgwZxxRVXAJCeno7FYuGtt95izpw5gENccMSIEezevbvdse77XH/99VRVVXH69GkAZs6cSZ8+ffz+nd2J9IpiFXCTl+//AxjjfC0AfhMGm5QoxvW0WF6eQnLyL7Hbb2DnzqM0Nw/RCXYKABUVB0lLy263LS0tm4qKgwGd9wtf+ALPP/88a9as4Y477sAYw0MPPdQmNb5nzx7uvvtuAFJTU9uO69evH1u3bmXatGk89thj3HPPPe3Oa4xBRM65ni86fJ3t4zqXuw2BElFHYYzZCJzwssstwLPOAUzvAeeLyKDwWKdEI66nxebmGuLjx2OxpBMfn8W+fUeCcjNQYp9QDa264447+NOf/sTzzz/PF77wBW688UZ+97vfUeuUND98+DA2m+2c444fP47dbuf222/nBz/4AR988EG778eOHcuRI0d4//33AaipqaGlpYW8vDxWr14NwO7duzlw4ACXXHJJu2Pd99mwYQMDBgw4Z8USDKK96mkI4P6Xf8i57dOOO4rIAhyrDoYPHx4W45TwU1FxkMzMbFJShtHYWI7FkoPFkkZ9/RmdYKcAjqFVhYUrgMWk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\n",
506 | "text/plain": [
507 | ""
508 | ]
509 | },
510 | "metadata": {
511 | "needs_background": "light"
512 | },
513 | "output_type": "display_data"
514 | }
515 | ],
516 | "source": [
517 | "colors = [\"red\", \"blue\", \"green\"]\n",
518 | "for i in range(3):\n",
519 | " plt.scatter(X_trans[X_trans[:, 2] == i][:, 0], X_trans[X_trans[:, 2] == i][:, 1], c=colors[i], \n",
520 | " edgecolors=\"k\", alpha=0.7, label=data.target_names[i])\n",
521 | "\n",
522 | "plt.xlabel(\"Principal Component 1\")\n",
523 | "plt.ylabel(\"Principal Component 2\")\n",
524 | "plt.legend()\n",
525 | "plt.show()"
526 | ]
527 | }
528 | ],
529 | "metadata": {
530 | "kernelspec": {
531 | "display_name": "Python 3",
532 | "language": "python",
533 | "name": "python3"
534 | },
535 | "language_info": {
536 | "codemirror_mode": {
537 | "name": "ipython",
538 | "version": 3
539 | },
540 | "file_extension": ".py",
541 | "mimetype": "text/x-python",
542 | "name": "python",
543 | "nbconvert_exporter": "python",
544 | "pygments_lexer": "ipython3",
545 | "version": "3.7.6"
546 | },
547 | "toc": {
548 | "base_numbering": 1,
549 | "nav_menu": {},
550 | "number_sections": true,
551 | "sideBar": true,
552 | "skip_h1_title": false,
553 | "title_cell": "Table of Contents",
554 | "title_sidebar": "Contents",
555 | "toc_cell": true,
556 | "toc_position": {},
557 | "toc_section_display": true,
558 | "toc_window_display": false
559 | },
560 | "varInspector": {
561 | "cols": {
562 | "lenName": 16,
563 | "lenType": 16,
564 | "lenVar": 40
565 | },
566 | "kernels_config": {
567 | "python": {
568 | "delete_cmd_postfix": "",
569 | "delete_cmd_prefix": "del ",
570 | "library": "var_list.py",
571 | "varRefreshCmd": "print(var_dic_list())"
572 | },
573 | "r": {
574 | "delete_cmd_postfix": ") ",
575 | "delete_cmd_prefix": "rm(",
576 | "library": "var_list.r",
577 | "varRefreshCmd": "cat(var_dic_list()) "
578 | }
579 | },
580 | "types_to_exclude": [
581 | "module",
582 | "function",
583 | "builtin_function_or_method",
584 | "instance",
585 | "_Feature"
586 | ],
587 | "window_display": false
588 | }
589 | },
590 | "nbformat": 4,
591 | "nbformat_minor": 4
592 | }
593 |
--------------------------------------------------------------------------------
/K-Nearest Neigbors/KNN_weighted_classification.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {
7 | "ExecuteTime": {
8 | "end_time": "2020-02-16T23:07:58.179814Z",
9 | "start_time": "2020-02-16T23:07:56.458785Z"
10 | }
11 | },
12 | "outputs": [],
13 | "source": [
14 | "import pandas as pd\n",
15 | "import numpy as np\n",
16 | "import matplotlib.pyplot as plt\n",
17 | "from sklearn.model_selection import StratifiedShuffleSplit\n",
18 | "import operator"
19 | ]
20 | },
21 | {
22 | "cell_type": "code",
23 | "execution_count": 2,
24 | "metadata": {
25 | "ExecuteTime": {
26 | "end_time": "2020-02-16T23:07:58.195684Z",
27 | "start_time": "2020-02-16T23:07:58.185150Z"
28 | }
29 | },
30 | "outputs": [],
31 | "source": [
32 | "def getDataset(loc):\n",
33 | " columns = ['sepal_length', 'sepal_width','petal_length','petal_width', 'class']\n",
34 | " data = pd.read_csv(loc, header=None, names=columns)\n",
35 | " return data"
36 | ]
37 | },
38 | {
39 | "cell_type": "code",
40 | "execution_count": 3,
41 | "metadata": {
42 | "ExecuteTime": {
43 | "end_time": "2020-02-16T23:07:58.447880Z",
44 | "start_time": "2020-02-16T23:07:58.201359Z"
45 | }
46 | },
47 | "outputs": [],
48 | "source": [
49 | "def splitDataset(dataset, ratio):\n",
50 | " split = StratifiedShuffleSplit(n_splits=1, test_size=ratio, random_state=42)\n",
51 | " \n",
52 | " for train_index, test_index in split.split(dataset, dataset['class']):\n",
53 | " train_data = dataset.loc[train_index]\n",
54 | " test_data = dataset.loc[test_index]\n",
55 | " \n",
56 | " \n",
57 | " return train_data, test_data"
58 | ]
59 | },
60 | {
61 | "cell_type": "code",
62 | "execution_count": 4,
63 | "metadata": {
64 | "ExecuteTime": {
65 | "end_time": "2020-02-16T23:07:58.630056Z",
66 | "start_time": "2020-02-16T23:07:58.450499Z"
67 | }
68 | },
69 | "outputs": [],
70 | "source": [
71 | "def euclideanDistance(instance1, instance2):\n",
72 | " instance1 = np.array(instance1)\n",
73 | " instance2 = np.array(instance2)\n",
74 | " distance = np.sum(np.power(instance1 - instance2, 2))\n",
75 | " return np.sqrt(distance)"
76 | ]
77 | },
78 | {
79 | "cell_type": "code",
80 | "execution_count": 5,
81 | "metadata": {
82 | "ExecuteTime": {
83 | "end_time": "2020-02-16T23:07:58.768916Z",
84 | "start_time": "2020-02-16T23:07:58.632827Z"
85 | }
86 | },
87 | "outputs": [],
88 | "source": [
89 | "# using pandas indexing methods\n",
90 | "\n",
91 | "def getKNeighbors(training_set, test_instance, k):\n",
92 | " distances = []\n",
93 | " classes = training_set['class'].unique()\n",
94 | " for row in range(len(training_set)):\n",
95 | " dist = euclideanDistance(training_set.iloc[row].values[:-1], test_instance[:-1])\n",
96 | " \n",
97 | " distances.append((training_set.iloc[row]['class'], dist))\n",
98 | "\n",
99 | " distances = sorted(distances, key=operator.itemgetter(1))[:k]\n",
100 | " inv_class_freq = {x:0 for x in classes}\n",
101 | " \n",
102 | " for cls, dist in distances:\n",
103 | " inv_class_freq[cls] += (1 / dist)\n",
104 | "\n",
105 | " return inv_class_freq"
106 | ]
107 | },
108 | {
109 | "cell_type": "code",
110 | "execution_count": 6,
111 | "metadata": {
112 | "ExecuteTime": {
113 | "end_time": "2020-02-16T23:07:58.941440Z",
114 | "start_time": "2020-02-16T23:07:58.771905Z"
115 | }
116 | },
117 | "outputs": [],
118 | "source": [
119 | "# faster cause turning the data into a list of lists\n",
120 | "# as the dataset is smaller in size\n",
121 | "\n",
122 | "def getKNeighbors(training_set, test_instance, k):\n",
123 | " distances = []\n",
124 | " classes = training_set['class'].unique()\n",
125 | " \n",
126 | " training_set = training_set.values\n",
127 | " \n",
128 | " for row in range(len(training_set)):\n",
129 | " dist = euclideanDistance(training_set[row][:-1], test_instance[:-1])\n",
130 | " \n",
131 | " distances.append((training_set[row][-1], dist))\n",
132 | " distances = sorted(distances, key=operator.itemgetter(1))[:k]\n",
133 | " inv_class_freq = {x:0 for x in classes}\n",
134 | " \n",
135 | " for cls, dist in distances:\n",
136 | " inv_class_freq[cls] += (1 / dist)\n",
137 | "\n",
138 | " return inv_class_freq"
139 | ]
140 | },
141 | {
142 | "cell_type": "code",
143 | "execution_count": 7,
144 | "metadata": {
145 | "ExecuteTime": {
146 | "end_time": "2020-02-16T23:07:59.117381Z",
147 | "start_time": "2020-02-16T23:07:58.951616Z"
148 | }
149 | },
150 | "outputs": [],
151 | "source": [
152 | "def getResponse(inv_freq):\n",
153 | " predicted_class = max(inv_freq, key=inv_freq.get)\n",
154 | " return predicted_class"
155 | ]
156 | },
157 | {
158 | "cell_type": "code",
159 | "execution_count": 8,
160 | "metadata": {
161 | "ExecuteTime": {
162 | "end_time": "2020-02-16T23:07:59.266774Z",
163 | "start_time": "2020-02-16T23:07:59.123520Z"
164 | }
165 | },
166 | "outputs": [],
167 | "source": [
168 | "def getAccuracy(testSet, predictions):\n",
169 | " correct = 0\n",
170 | " for x in range(len(testSet)):\n",
171 | " if testSet.iloc[x]['class'] == predictions[x]:\n",
172 | " correct += 1\n",
173 | " return (correct/len(testSet)) * 100.0"
174 | ]
175 | },
176 | {
177 | "cell_type": "code",
178 | "execution_count": 9,
179 | "metadata": {
180 | "ExecuteTime": {
181 | "end_time": "2020-02-16T23:08:05.002270Z",
182 | "start_time": "2020-02-16T23:07:59.271965Z"
183 | }
184 | },
185 | "outputs": [],
186 | "source": [
187 | "if __name__ == '__main__':\n",
188 | " # get data\n",
189 | " data = getDataset(r'../datasets/iris_data.csv')\n",
190 | " \n",
191 | " # split data into stratified subsets\n",
192 | " ratio = 0.2\n",
193 | " trainingSet, testSet = splitDataset(data, ratio)\n",
194 | "\n",
195 | " trainingSet = trainingSet.reset_index(drop=True)\n",
196 | " testSet = testSet.reset_index(drop=True)\n",
197 | " accuracy_scores = []\n",
198 | " # generate predictions\n",
199 | " for k in range(1, 31):\n",
200 | " predictions = []\n",
201 | " for row in range(len(testSet)):\n",
202 | " inv_freq = getKNeighbors(trainingSet, testSet.iloc[row].values, k)\n",
203 | " result = getResponse(inv_freq)\n",
204 | " predictions.append(result)\n",
205 | "\n",
206 | " accuracy = getAccuracy(testSet, predictions)\n",
207 | " accuracy_scores.append(accuracy)\n",
208 | "# print(f'k: {k}, Accuracy: {round(accuracy,3)}%')"
209 | ]
210 | },
211 | {
212 | "cell_type": "code",
213 | "execution_count": 10,
214 | "metadata": {
215 | "ExecuteTime": {
216 | "end_time": "2020-02-16T23:08:05.817093Z",
217 | "start_time": "2020-02-16T23:08:05.006180Z"
218 | }
219 | },
220 | "outputs": [
221 | {
222 | "data": {
223 | "text/plain": [
224 | ""
225 | ]
226 | },
227 | "execution_count": 10,
228 | "metadata": {},
229 | "output_type": "execute_result"
230 | },
231 | {
232 | "data": {
233 | "image/png": "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f+1rX6tHPOIROnXqlF7+8pdLkr7whS/oKU95ik6dOqVHP/rR+qd/+id98IMf1NOe9rT5n/vxH/9xveUtb5EkXXnllfqFX/gFPf7xj9c73/lO/dZv/Za+5Vu+RadOndIzn/lMra6uSpLuuece3XDDDTp16pROnTqlj3zkI/q5n/s53XTTTfPr/uzP/qxe//rXH/rvyzGEAAAA2JNbbrtLP/3uT2ttY7qSfNfpNf30uz8tSbr+mssOft1bbtH3fd/36cEPfrDa7bY+8YlP6J577tEtt9yiv/3bv9XS0pJ6vZ4k6TnPeY5e/vKX64YbbtD6+romk4m++tWv7nr9hYUFffjDH5YkRVGkF77whZKkV7ziFXrTm96kn/iJn9BP/uRP6ju/8zv1nve8R+PxWP1+X5deeqme8Yxn6CUveYkmk4ne/va36+/+7u8O/PdMEMABAACwJ7/yvs/Nw3dibWOsX3nf5w4VwG+++Wa99KUvlSQ961nP0s0336zJZKIf/uEf1tLSkiSp3W7r3Llzuuuuu3TDDTdImgbrvfjBH/zB+a9vv/12veIVr9Dp06fV7/d13XXXSZI+8IEP6Hd/93clSdVqVSdOnNCJEycUhqFuu+023XPPPbrmmmsUhuGB/54JAjgAAAD25O7Ta/t6fS+iKNIHPvAB3X777TLGaDweyxijZz7zmfc53s9au+01arWaJpPJ/PcXnsndbDbnv37+85+vW265RadOndJb3vIWffCDH9x1fD/6oz+qt7zlLfra176mF7zgBfv8222PGnAAAADsyaUnF/f1+l784R/+oZ773Ofqy1/+sr70pS/pq1/9qh70oAep3W7rzW9+87xGu9fr6fjx47r88st1yy23SJKGw6FWV1f1jd/4jfrsZz+r4XCoM2fO6P3vf/+O73fu3Dk94AEP0MbGht72trfNX3/yk5+s3/zN35Q03ax59uxZSdINN9yg9773vfrYxz42Xy0/LAI4AAAA9uRl112txXr1vNcW61W97LqrD3zNm2++eV5SknjmM5+pu+++W09/+tN17bXX6lGPepR+9Vd/VZL01re+Va9//ev1yEc+Uo973OP0ta99TQ984AN144036pGPfKSe85zn6Jprrtnx/V796lfrW7/1W/U93/M9eshDHjJ//aabbtJf/uVf6hGPeIQe85jH6DOf+YwkKQgCffd3f7du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\n",
234 | "text/plain": [
235 | ""
236 | ]
237 | },
238 | "metadata": {
239 | "needs_background": "light"
240 | },
241 | "output_type": "display_data"
242 | }
243 | ],
244 | "source": [
245 | "plt.figure(figsize=(12, 10))\n",
246 | "plt.plot(list(range(1, 31)), accuracy_scores)\n",
247 | "plt.scatter(list(range(1, 31)), accuracy_scores, label=\"Accuracy\")\n",
248 | "plt.title('K vs Accuracy')\n",
249 | "plt.xticks(ticks=range(1, 31))\n",
250 | "plt.xlabel('K')\n",
251 | "plt.ylabel('Accuracy', rotation=0)\n",
252 | "plt.legend()"
253 | ]
254 | }
255 | ],
256 | "metadata": {
257 | "kernelspec": {
258 | "display_name": "Python 3",
259 | "language": "python",
260 | "name": "python3"
261 | },
262 | "language_info": {
263 | "codemirror_mode": {
264 | "name": "ipython",
265 | "version": 3
266 | },
267 | "file_extension": ".py",
268 | "mimetype": "text/x-python",
269 | "name": "python",
270 | "nbconvert_exporter": "python",
271 | "pygments_lexer": "ipython3",
272 | "version": "3.7.6"
273 | },
274 | "toc": {
275 | "base_numbering": 1,
276 | "nav_menu": {},
277 | "number_sections": true,
278 | "sideBar": true,
279 | "skip_h1_title": false,
280 | "title_cell": "Table of Contents",
281 | "title_sidebar": "Contents",
282 | "toc_cell": false,
283 | "toc_position": {},
284 | "toc_section_display": true,
285 | "toc_window_display": false
286 | },
287 | "varInspector": {
288 | "cols": {
289 | "lenName": 16,
290 | "lenType": 16,
291 | "lenVar": 40
292 | },
293 | "kernels_config": {
294 | "python": {
295 | "delete_cmd_postfix": "",
296 | "delete_cmd_prefix": "del ",
297 | "library": "var_list.py",
298 | "varRefreshCmd": "print(var_dic_list())"
299 | },
300 | "r": {
301 | "delete_cmd_postfix": ") ",
302 | "delete_cmd_prefix": "rm(",
303 | "library": "var_list.r",
304 | "varRefreshCmd": "cat(var_dic_list()) "
305 | }
306 | },
307 | "types_to_exclude": [
308 | "module",
309 | "function",
310 | "builtin_function_or_method",
311 | "instance",
312 | "_Feature"
313 | ],
314 | "window_display": false
315 | }
316 | },
317 | "nbformat": 4,
318 | "nbformat_minor": 2
319 | }
320 |
--------------------------------------------------------------------------------