mojmelo 0.1.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. mojmelo-0.1.5/LICENSE +37 -0
  2. mojmelo-0.1.5/PKG-INFO +318 -0
  3. mojmelo-0.1.5/README.md +302 -0
  4. mojmelo-0.1.5/_mojmelo/__init__.py +0 -0
  5. mojmelo-0.1.5/_mojmelo/mojmelo/DBSCAN.mojo +81 -0
  6. mojmelo-0.1.5/_mojmelo/mojmelo/DecisionTree.mojo +376 -0
  7. mojmelo-0.1.5/_mojmelo/mojmelo/GBDT.mojo +251 -0
  8. mojmelo-0.1.5/_mojmelo/mojmelo/HDBSCAN.mojo +141 -0
  9. mojmelo-0.1.5/_mojmelo/mojmelo/KMeans.mojo +289 -0
  10. mojmelo-0.1.5/_mojmelo/mojmelo/KNN.mojo +127 -0
  11. mojmelo-0.1.5/_mojmelo/mojmelo/LinearRegression.mojo +182 -0
  12. mojmelo-0.1.5/_mojmelo/mojmelo/LogisticRegression.mojo +220 -0
  13. mojmelo-0.1.5/_mojmelo/mojmelo/NaiveBayes.mojo +200 -0
  14. mojmelo-0.1.5/_mojmelo/mojmelo/PCA.mojo +129 -0
  15. mojmelo-0.1.5/_mojmelo/mojmelo/PolynomialRegression.mojo +219 -0
  16. mojmelo-0.1.5/_mojmelo/mojmelo/RandomForest.mojo +216 -0
  17. mojmelo-0.1.5/_mojmelo/mojmelo/SVM.mojo +455 -0
  18. mojmelo-0.1.5/_mojmelo/mojmelo/__init__.mojo +0 -0
  19. mojmelo-0.1.5/_mojmelo/mojmelo/preprocessing.mojo +332 -0
  20. mojmelo-0.1.5/_mojmelo/mojmelo/utils/BDecisionTree.mojo +199 -0
  21. mojmelo-0.1.5/_mojmelo/mojmelo/utils/KDTree.mojo +632 -0
  22. mojmelo-0.1.5/_mojmelo/mojmelo/utils/Matrix.mojo +1782 -0
  23. mojmelo-0.1.5/_mojmelo/mojmelo/utils/__init__.mojo +0 -0
  24. mojmelo-0.1.5/_mojmelo/mojmelo/utils/algorithm/__init__.mojo +29 -0
  25. mojmelo-0.1.5/_mojmelo/mojmelo/utils/algorithm/backend/__init__.mojo +12 -0
  26. mojmelo-0.1.5/_mojmelo/mojmelo/utils/algorithm/backend/cpu/__init__.mojo +25 -0
  27. mojmelo-0.1.5/_mojmelo/mojmelo/utils/algorithm/backend/cpu/parallelize.mojo +351 -0
  28. mojmelo-0.1.5/_mojmelo/mojmelo/utils/algorithm/backend/cpu/reduction.mojo +497 -0
  29. mojmelo-0.1.5/_mojmelo/mojmelo/utils/algorithm/backend/cpu/runtime/__init__.mojo +12 -0
  30. mojmelo-0.1.5/_mojmelo/mojmelo/utils/algorithm/backend/cpu/runtime/tracing.mojo +718 -0
  31. mojmelo-0.1.5/_mojmelo/mojmelo/utils/algorithm/functional.mojo +20 -0
  32. mojmelo-0.1.5/_mojmelo/mojmelo/utils/algorithm/reduction.mojo +1333 -0
  33. mojmelo-0.1.5/_mojmelo/mojmelo/utils/hdbscan/KDTreeBoruvka.mojo +253 -0
  34. mojmelo-0.1.5/_mojmelo/mojmelo/utils/hdbscan/__init__.mojo +1 -0
  35. mojmelo-0.1.5/_mojmelo/mojmelo/utils/hdbscan/hdbscan_boruvka.mojo +362 -0
  36. mojmelo-0.1.5/_mojmelo/mojmelo/utils/hdbscan/hdbscan_linkage.mojo +181 -0
  37. mojmelo-0.1.5/_mojmelo/mojmelo/utils/hdbscan/hdbscan_tree.mojo +884 -0
  38. mojmelo-0.1.5/_mojmelo/mojmelo/utils/libsvm/__init__.mojo +0 -0
  39. mojmelo-0.1.5/_mojmelo/mojmelo/utils/libsvm/svm.mojo +2782 -0
  40. mojmelo-0.1.5/_mojmelo/mojmelo/utils/libsvm/svm_model.mojo +22 -0
  41. mojmelo-0.1.5/_mojmelo/mojmelo/utils/libsvm/svm_node.mojo +4 -0
  42. mojmelo-0.1.5/_mojmelo/mojmelo/utils/libsvm/svm_parameter.mojo +33 -0
  43. mojmelo-0.1.5/_mojmelo/mojmelo/utils/libsvm/svm_problem.mojo +12 -0
  44. mojmelo-0.1.5/_mojmelo/mojmelo/utils/mojmelo_matmul/__init__.mojo +0 -0
  45. mojmelo-0.1.5/_mojmelo/mojmelo/utils/mojmelo_matmul/matmul.mojo +385 -0
  46. mojmelo-0.1.5/_mojmelo/mojmelo/utils/mojmelo_matmul/params.mojo +4 -0
  47. mojmelo-0.1.5/_mojmelo/mojmelo/utils/sort.mojo +329 -0
  48. mojmelo-0.1.5/_mojmelo/mojmelo/utils/svd.mojo +224 -0
  49. mojmelo-0.1.5/_mojmelo/mojmelo/utils/utils.mojo +426 -0
  50. mojmelo-0.1.5/_mojmelo/setup.mojo +202 -0
  51. mojmelo-0.1.5/_mojmelo/setup.py +31 -0
  52. mojmelo-0.1.5/mojmelo.egg-info/PKG-INFO +318 -0
  53. mojmelo-0.1.5/mojmelo.egg-info/SOURCES.txt +57 -0
  54. mojmelo-0.1.5/mojmelo.egg-info/dependency_links.txt +1 -0
  55. mojmelo-0.1.5/mojmelo.egg-info/entry_points.txt +2 -0
  56. mojmelo-0.1.5/mojmelo.egg-info/requires.txt +1 -0
  57. mojmelo-0.1.5/mojmelo.egg-info/top_level.txt +1 -0
  58. mojmelo-0.1.5/pyproject.toml +38 -0
  59. mojmelo-0.1.5/setup.cfg +4 -0
mojmelo-0.1.5/LICENSE ADDED
@@ -0,0 +1,37 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2024, Tiyagora Yetalit
4
+
5
+ All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms,
8
+ with or without modification, are permitted provided
9
+ that the following conditions are met:
10
+
11
+ 1. Redistributions of source code must retain the above
12
+ copyright notice, this list of conditions, and the
13
+ following disclaimer.
14
+
15
+ 2. Redistributions in binary form must reproduce the above
16
+ copyright notice, this list of conditions, and the
17
+ following disclaimer in the documentation and/or other
18
+ materials provided with the distribution.
19
+
20
+ 3. Neither the name of the copyright holder nor the names
21
+ of its contributors may be used to endorse or promote
22
+ products derived from this software without specific
23
+ prior written permission.
24
+
25
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
26
+ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
27
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
30
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
32
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
36
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
37
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
mojmelo-0.1.5/PKG-INFO ADDED
@@ -0,0 +1,318 @@
1
+ Metadata-Version: 2.4
2
+ Name: mojmelo
3
+ Version: 0.1.5
4
+ Summary: Machine Learning algorithms in pure Mojo.
5
+ License-Expression: BSD-3-Clause
6
+ Project-URL: Homepage, https://github.com/yetalit/Mojmelo
7
+ Project-URL: Issues, https://github.com/yetalit/Mojmelo/issues
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: POSIX :: Linux
10
+ Classifier: Operating System :: MacOS
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: mojo-compiler>=1.0.0
15
+ Dynamic: license-file
16
+
17
+ <a id="readme-top"></a>
18
+
19
+ [![Issues][issues-shield]][issues-url]
20
+ [![BSD-3-Clause License][license-shield]][license-url]
21
+ ![CodeQL](https://github.com/yetalit/Mojmelo/workflows/CodeQL/badge.svg)
22
+
23
+ <br />
24
+ <div align="center">
25
+ <a href="https://github.com/yetalit/mojmelo">
26
+ <img src="./images/logo-min.jpg" alt="Logo" width="256" height="256">
27
+ </a>
28
+ <h3 align="center">Mojmelo</h3>
29
+ <p align="center">
30
+ <a href="https://github.com/yetalit/mojmelo/issues/new?labels=bug&template=bug-report---.md">Report Bug</a>
31
+ ·
32
+ <a href="https://github.com/yetalit/mojmelo/issues/new?labels=enhancement&template=feature-request---.md">Request Feature</a>
33
+ </p>
34
+ </div>
35
+
36
+ ## About The Project
37
+
38
+ The name `Mojmelo` is derived from the "Mojo Machine Learning" expression. It includes the implementation of Machine Learning algorithms from scratch in pure Mojo.
39
+ Here is the list of the algorithms:
40
+ * Linear Regression
41
+ * Polynomial Regression
42
+ * Logistic Regression
43
+ * KNN
44
+ * KMeans
45
+ * HDBSCAN
46
+ * DBSCAN
47
+ * SVM
48
+ * Naive Bayes
49
+ 1. GaussianNB
50
+ 2. MultinomialNB
51
+ * Decision Tree (Regression/Classification)
52
+ * Random Forest (Regression/Classification)
53
+ * GBDT (Regression/Classification)
54
+ * PCA
55
+
56
+ Preprocessing:
57
+ * normalize
58
+ * MinMaxScaler
59
+ * StandardScaler
60
+ * KFold
61
+ * GridSearchCV
62
+ * LabelEncoder
63
+
64
+ **Documentation:** https://yetalit.github.io/Mojmelo/docs/_index.html
65
+
66
+ ## Getting Started
67
+
68
+ If you are not familiar with Mojo projects, you can get started here: https://mojolang.org/docs/manual/get-started/
69
+
70
+ ### Prerequisites
71
+
72
+ * mojo-compiler 1.0.0 or later
73
+
74
+ Optionally, bellow Python packages can be installed for a better usability and to run tests:
75
+ 1. Numpy
76
+ 2. Pandas
77
+ 3. Scikit-learn
78
+ 4. Matplotlib
79
+
80
+ ### Installation
81
+
82
+ There are three ways to install mojmelo: Using Pixi CLI, PyPI CLI and through the source code.
83
+
84
+ Additionally, completing the setup process (discussed later) is recommended.
85
+
86
+ #### Pixi CLI
87
+
88
+ Make sure you have the Modular community channel (https://repo.prefix.dev/modular-community) in your `pixi.toml` file in the channels section, then add mojmelo this way:
89
+ ```
90
+ pixi add mojmelo
91
+ ```
92
+
93
+ To start the setup process, run the following command from the `main folder` of your project:
94
+ ```
95
+ bash ./.pixi/envs/default/etc/conda/test-files/mojmelo/0/tests/setup.sh
96
+ ```
97
+
98
+ Note: If CPU cache details are available by the OS, benchmarking parts of the setup will be skipped. Otherwise, please try not to run other tasks on your pc during the process for better results.
99
+
100
+ #### PyPI CLI
101
+
102
+ Using the command below, the PyPI package containing the source code will be installed from the github repository:
103
+ ```
104
+ pip install "git+https://github.com/yetalit/Mojmelo.git#subdirectory=pypi"
105
+ ```
106
+
107
+ Then start the setup process this way:
108
+ ```
109
+ mojmelo-setup
110
+ ```
111
+
112
+ Note: If CPU cache details are available by the OS, benchmarking parts of the setup will be skipped. Otherwise, please try not to run other tasks on your pc during the process for better results.
113
+
114
+ #### Source Code
115
+
116
+ Mojmelo can also be installed through the source code. This way, you will have the source code in your project.
117
+
118
+ First, Download `mojmelo` folder and `setup.mojo` file. To start the setup process, run these commands from where `mojmelo` folder and `setup.mojo` file are stored:
119
+ ```
120
+ mojo build setup.mojo -o setup &&
121
+ ./setup &&
122
+ ./setup 1 &&
123
+ ./setup 2 &&
124
+ ./setup 3 &&
125
+ ./setup 4 &&
126
+ ./setup 5 &&
127
+ ./setup 6 &&
128
+ ./setup 7 &&
129
+ ./setup 8 &&
130
+ ./setup 9 &&
131
+ rm -f ./setup
132
+ ```
133
+
134
+ Note: If CPU cache details are available by the OS, benchmarking parts of the setup will be skipped. Otherwise, please try not to run other tasks on your pc during the process for better results.
135
+
136
+ ## Usage
137
+
138
+ Importing models is straightforward:
139
+ ```mojo
140
+ from mojmelo.LinearRegression import LinearRegression
141
+ ```
142
+ You may also want to use the utility codes written for this project:
143
+ ```mojo
144
+ from mojmelo.utils.Matrix import Matrix
145
+ from mojmelo.utils.utils import *
146
+ ```
147
+ Here is an example code demonstrating a common training process:
148
+ ```mojo
149
+ from mojmelo.KNN import KNN
150
+ from mojmelo.utils.Matrix import Matrix
151
+ from mojmelo.preprocessing import train_test_split, GridSearchCV, LabelEncoder
152
+ from mojmelo.utils.utils import accuracy_score
153
+ from std.python import Python
154
+ import std.os as os
155
+
156
+ def main() raises:
157
+ # Load the Iris dataset from scikit-learn using the Python interoperability API.
158
+ var iris = Python.import_module("sklearn.datasets").load_iris()
159
+
160
+ # Create a LabelEncoder instance.
161
+ # This converts class labels into integer values that the model can work with.
162
+ var le = LabelEncoder()
163
+
164
+ # Convert the NumPy feature array into a native Matrix.
165
+ var X = Matrix.from_numpy(iris.data)
166
+ # Encode the target labels into integer values.
167
+ var y = le.fit_transform(iris.target)
168
+
169
+ # Define the hyperparameter values to test.
170
+ # Here we evaluate KNN with k = 3, 5, and 7.
171
+ var params = Dict[String, List[String]]()
172
+ params["k"] = ["3", "5", "7"]
173
+ # Find the best hyperparameters using grid search.
174
+ # - accuracy_score is the evaluation metric.
175
+ # - n_jobs=-1 uses all available CPU cores.
176
+ #
177
+ # GridSearchCV returns the best hyperparameters and their score. [0] contains the best parameters.
178
+ var best_params = GridSearchCV[KNN](
179
+ X,
180
+ y,
181
+ params,
182
+ accuracy_score,
183
+ cv=4,
184
+ n_jobs=-1,
185
+ )[0].copy()
186
+ print("Tuned parameters:", best_params)
187
+
188
+ # Split the dataset into training and testing sets.
189
+ var X_train, X_test, y_train, y_test = train_test_split(
190
+ X,
191
+ y,
192
+ test_size=0.2,
193
+ random_state=1234,
194
+ )
195
+
196
+ # Create a KNN model using the best hyperparameters found above.
197
+ var knn = KNN(best_params)
198
+ # Train the model using the training data.
199
+ knn.fit(X_train, y_train)
200
+ # Save the trained model to disk.
201
+ knn.save("knn")
202
+
203
+ # Load the saved model back from disk.
204
+ knn = KNN.load("knn")
205
+ # Predict the labels for the test samples.
206
+ var y_pred = knn.predict(X_test)
207
+ # Compare the predictions with the expected labels.
208
+ print("KNN classification accuracy:", accuracy_score(y_test, y_pred))
209
+
210
+ # Remove the saved model file created by this example.
211
+ os.remove("knn.mjml")
212
+ ```
213
+ More examples are available in [`tests`](https://github.com/yetalit/Mojmelo/blob/main/tests) folder.
214
+
215
+ ## Benchmarks (AMD Zen 4)
216
+
217
+ [`KMeans`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/kmeans_bench.mojo)
218
+
219
+ | Model | Fit Time (s) | ARI vs sklearn | ARI vs truth |
220
+ |----------------|-----------------|----------------|--------------|
221
+ | sklearn KMeans | 0.2764 ± 0.0010 | - | 0.9390 |
222
+ | mojmelo KMeans | 0.1713 ± 0.0029 | 0.8822 | 0.9390 |
223
+
224
+ [`HDBSCAN`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/hdbs_bench.mojo) (algorithm='boruvka_kdtree')
225
+
226
+ | Model | Fit Time (s) | ARI vs sklearn | ARI vs fast_hdbscan | ARI vs truth |
227
+ |------------------|-----------------|----------------|---------------------|--------------|
228
+ | skl-contrib HDBS | 1.1945 ± 0.0067 | - | - | 0.9988 |
229
+ | fast hdbscan | 0.2412 ± 0.0014 | - | - | 0.9989 |
230
+ | mojmelo HDBS | 0.1765 ± 0.0032 | 0.9923 | 0.9989 | 0.9933 |
231
+
232
+ [`DBSCAN`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/dbs_bench.mojo) (algorithm='kd_tree')
233
+
234
+ | Model | Fit Time (s) | ARI vs sklearn | ARI vs truth |
235
+ |-------------|-----------------|----------------|--------------|
236
+ | sklearn DBS | 1.0625 ± 0.0020 | - | 0.8605 |
237
+ | mojmelo DBS | 0.4817 ± 0.0035 | 1.0000 | 0.8605 |
238
+
239
+ [`KNN`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/knn_bench.mojo) (algorithm='kd_tree')
240
+
241
+ | Model | Fit Time (s) | Predict Time (s) | Accuracy |
242
+ |-------------|-----------------|------------------|----------|
243
+ | sklearn KNN | 0.0353 ± 0.0005 | 1.7600 ± 0.0063 | 0.8543 |
244
+ | mojmelo KNN | 0.0149 ± 0.0006 | 0.2126 ± 0.0040 | 0.8347 |
245
+
246
+ [`SVM`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/svm_bench.mojo)
247
+
248
+ | Model | Fit Time (s) | Predict Time (s) | Accuracy |
249
+ |-------------|-----------------|------------------|----------|
250
+ | sklearn SVM | 1.2857 ± 0.0020 | 0.3720 ± 0.0008 | 0.9750 |
251
+ | mojmelo SVM | 0.8618 ± 0.0091 | 0.0600 ± 0.0002 | 0.9750 |
252
+
253
+ [`DecisionTreeClassifier`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/dtc_bench.mojo)
254
+
255
+ | Model | Fit Time (s) | Predict Time (s) | Accuracy |
256
+ |-------------|-----------------|------------------|----------|
257
+ | sklearn DTC | 0.8498 ± 0.0033 | 0.0004 ± 0.0000 | 0.9667 |
258
+ | mojmelo DTC | 0.0810 ± 0.0057 | 0.0001 ± 0.0000 | 0.9668 |
259
+
260
+ [`DecisionTreeRegressor`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/dtr_bench.mojo)
261
+
262
+ | Model | Fit Time (s) | Predict Time (s) | MSE |
263
+ |-------------|-----------------|------------------|-----------|
264
+ | sklearn DTR | 0.6466 ± 0.0006 | 0.0005 ± 0.0000 | 8247.9358 |
265
+ | mojmelo DTR | 0.0795 ± 0.0049 | 0.0003 ± 0.0000 | 8192.1982 |
266
+
267
+ [`RandomForestClassifier`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/rfc_bench.mojo)
268
+
269
+ | Model | Fit Time (s) | Predict Time (s) | Accuracy |
270
+ |-------------|-----------------|------------------|----------|
271
+ | sklearn RFC | 0.4401 ± 0.0078 | 0.0139 ± 0.0002 | 0.9163 |
272
+ | mojmelo RFC | 0.4064 ± 0.0036 | 0.0044 ± 0.0001 | 0.9144 |
273
+
274
+ [`RandomForestRegressor`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/rfr_bench.mojo)
275
+
276
+ | Model | Fit Time (s) | Predict Time (s) | MSE |
277
+ |-------------|-----------------|------------------|-----------|
278
+ | sklearn RFR | 2.0257 ± 0.0050 | 0.0134 ± 0.0004 | 8454.5517 |
279
+ | mojmelo RFR | 1.2247 ± 0.0094 | 0.0067 ± 0.0002 | 9155.6895 |
280
+
281
+ [`PCA`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/pca_bench.mojo) (svd_solver='full')
282
+
283
+ | Model | Fit Time (s) | Transform Time (s) | Explained Var |
284
+ |-------------|-----------------|--------------------|---------------|
285
+ | sklearn PCA | 0.2359 ± 0.0081 | 0.0088 ± 0.0019 | 0.5375 |
286
+ | mojmelo PCA | 0.0515 ± 0.0027 | 0.0103 ± 0.0001 | 0.5375 |
287
+
288
+ ## Contributing
289
+
290
+ Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
291
+
292
+ Contributions can be done to the project in these 3 ways:
293
+ 1. Applying improvements to the code and opening a Pull Request
294
+ 2. Reporting a bug
295
+ 3. Suggesting new features
296
+
297
+ <!-- ACKNOWLEDGMENTS -->
298
+ ## Acknowledgments
299
+
300
+ * Mojo usage and distribution are licensed under the [Modular Community License](https://www.modular.com/legal/community).
301
+
302
+ * <a href='https://www.csie.ntu.edu.tw/~cjlin/libsvm/'>Libsvm</a>, A Library for Support Vector Machines by Chih-Chung Chang and Chih-Jen Lin licensed under the BSD-3-Clause license.
303
+
304
+ * `HDBSCAN` implementation is partially based on <a href='https://hdbscan.readthedocs.io/en/latest/'>hdbscan</a> by Leland McInnes, John Healy and Steve Astels licensed under the BSD-3-Clause license and <a href='https://fast-hdbscan.readthedocs.io/en/latest/'>Fast Multicore HDBSCAN</a> by Tutte Institute for Mathematics and Computing licensed under the BSD-2-Clause license.
305
+
306
+ * `matmul` implementation is based on <a href='https://github.com/YichengDWu/matmul.mojo'>matmul.mojo</a> by Ethan Wu (YichengDWu) licensed under the Apache-2.0 license.
307
+
308
+ * `argmin`, `argmax` and `argsort` implementations and `utils.algorithm` submodule are based on codes from <a href='https://github.com/modular/modular'>Modular</a> licensed under the Apache License v2.0 with LLVM Exceptions.
309
+
310
+ * <a href='https://arxiv.org/abs/physics/0408067'>KDTREE2</a>, a kd-tree implementation in Fortran 95 and C++ by Matthew B. Kennel.
311
+
312
+ * Initially drew inspiration from Patrick Loeber's <a href='https://github.com/patrickloeber/MLfromscratch/'>MLfromscratch</a>.
313
+
314
+
315
+ [issues-shield]: https://img.shields.io/github/issues/yetalit/mojmelo
316
+ [issues-url]: https://github.com/yetalit/mojmelo/issues
317
+ [license-shield]: https://img.shields.io/badge/license-BSD%203--Clause-blue
318
+ [license-url]: https://github.com/yetalit/Mojmelo/blob/main/LICENSE
@@ -0,0 +1,302 @@
1
+ <a id="readme-top"></a>
2
+
3
+ [![Issues][issues-shield]][issues-url]
4
+ [![BSD-3-Clause License][license-shield]][license-url]
5
+ ![CodeQL](https://github.com/yetalit/Mojmelo/workflows/CodeQL/badge.svg)
6
+
7
+ <br />
8
+ <div align="center">
9
+ <a href="https://github.com/yetalit/mojmelo">
10
+ <img src="./images/logo-min.jpg" alt="Logo" width="256" height="256">
11
+ </a>
12
+ <h3 align="center">Mojmelo</h3>
13
+ <p align="center">
14
+ <a href="https://github.com/yetalit/mojmelo/issues/new?labels=bug&template=bug-report---.md">Report Bug</a>
15
+ ·
16
+ <a href="https://github.com/yetalit/mojmelo/issues/new?labels=enhancement&template=feature-request---.md">Request Feature</a>
17
+ </p>
18
+ </div>
19
+
20
+ ## About The Project
21
+
22
+ The name `Mojmelo` is derived from the "Mojo Machine Learning" expression. It includes the implementation of Machine Learning algorithms from scratch in pure Mojo.
23
+ Here is the list of the algorithms:
24
+ * Linear Regression
25
+ * Polynomial Regression
26
+ * Logistic Regression
27
+ * KNN
28
+ * KMeans
29
+ * HDBSCAN
30
+ * DBSCAN
31
+ * SVM
32
+ * Naive Bayes
33
+ 1. GaussianNB
34
+ 2. MultinomialNB
35
+ * Decision Tree (Regression/Classification)
36
+ * Random Forest (Regression/Classification)
37
+ * GBDT (Regression/Classification)
38
+ * PCA
39
+
40
+ Preprocessing:
41
+ * normalize
42
+ * MinMaxScaler
43
+ * StandardScaler
44
+ * KFold
45
+ * GridSearchCV
46
+ * LabelEncoder
47
+
48
+ **Documentation:** https://yetalit.github.io/Mojmelo/docs/_index.html
49
+
50
+ ## Getting Started
51
+
52
+ If you are not familiar with Mojo projects, you can get started here: https://mojolang.org/docs/manual/get-started/
53
+
54
+ ### Prerequisites
55
+
56
+ * mojo-compiler 1.0.0 or later
57
+
58
+ Optionally, bellow Python packages can be installed for a better usability and to run tests:
59
+ 1. Numpy
60
+ 2. Pandas
61
+ 3. Scikit-learn
62
+ 4. Matplotlib
63
+
64
+ ### Installation
65
+
66
+ There are three ways to install mojmelo: Using Pixi CLI, PyPI CLI and through the source code.
67
+
68
+ Additionally, completing the setup process (discussed later) is recommended.
69
+
70
+ #### Pixi CLI
71
+
72
+ Make sure you have the Modular community channel (https://repo.prefix.dev/modular-community) in your `pixi.toml` file in the channels section, then add mojmelo this way:
73
+ ```
74
+ pixi add mojmelo
75
+ ```
76
+
77
+ To start the setup process, run the following command from the `main folder` of your project:
78
+ ```
79
+ bash ./.pixi/envs/default/etc/conda/test-files/mojmelo/0/tests/setup.sh
80
+ ```
81
+
82
+ Note: If CPU cache details are available by the OS, benchmarking parts of the setup will be skipped. Otherwise, please try not to run other tasks on your pc during the process for better results.
83
+
84
+ #### PyPI CLI
85
+
86
+ Using the command below, the PyPI package containing the source code will be installed from the github repository:
87
+ ```
88
+ pip install "git+https://github.com/yetalit/Mojmelo.git#subdirectory=pypi"
89
+ ```
90
+
91
+ Then start the setup process this way:
92
+ ```
93
+ mojmelo-setup
94
+ ```
95
+
96
+ Note: If CPU cache details are available by the OS, benchmarking parts of the setup will be skipped. Otherwise, please try not to run other tasks on your pc during the process for better results.
97
+
98
+ #### Source Code
99
+
100
+ Mojmelo can also be installed through the source code. This way, you will have the source code in your project.
101
+
102
+ First, Download `mojmelo` folder and `setup.mojo` file. To start the setup process, run these commands from where `mojmelo` folder and `setup.mojo` file are stored:
103
+ ```
104
+ mojo build setup.mojo -o setup &&
105
+ ./setup &&
106
+ ./setup 1 &&
107
+ ./setup 2 &&
108
+ ./setup 3 &&
109
+ ./setup 4 &&
110
+ ./setup 5 &&
111
+ ./setup 6 &&
112
+ ./setup 7 &&
113
+ ./setup 8 &&
114
+ ./setup 9 &&
115
+ rm -f ./setup
116
+ ```
117
+
118
+ Note: If CPU cache details are available by the OS, benchmarking parts of the setup will be skipped. Otherwise, please try not to run other tasks on your pc during the process for better results.
119
+
120
+ ## Usage
121
+
122
+ Importing models is straightforward:
123
+ ```mojo
124
+ from mojmelo.LinearRegression import LinearRegression
125
+ ```
126
+ You may also want to use the utility codes written for this project:
127
+ ```mojo
128
+ from mojmelo.utils.Matrix import Matrix
129
+ from mojmelo.utils.utils import *
130
+ ```
131
+ Here is an example code demonstrating a common training process:
132
+ ```mojo
133
+ from mojmelo.KNN import KNN
134
+ from mojmelo.utils.Matrix import Matrix
135
+ from mojmelo.preprocessing import train_test_split, GridSearchCV, LabelEncoder
136
+ from mojmelo.utils.utils import accuracy_score
137
+ from std.python import Python
138
+ import std.os as os
139
+
140
+ def main() raises:
141
+ # Load the Iris dataset from scikit-learn using the Python interoperability API.
142
+ var iris = Python.import_module("sklearn.datasets").load_iris()
143
+
144
+ # Create a LabelEncoder instance.
145
+ # This converts class labels into integer values that the model can work with.
146
+ var le = LabelEncoder()
147
+
148
+ # Convert the NumPy feature array into a native Matrix.
149
+ var X = Matrix.from_numpy(iris.data)
150
+ # Encode the target labels into integer values.
151
+ var y = le.fit_transform(iris.target)
152
+
153
+ # Define the hyperparameter values to test.
154
+ # Here we evaluate KNN with k = 3, 5, and 7.
155
+ var params = Dict[String, List[String]]()
156
+ params["k"] = ["3", "5", "7"]
157
+ # Find the best hyperparameters using grid search.
158
+ # - accuracy_score is the evaluation metric.
159
+ # - n_jobs=-1 uses all available CPU cores.
160
+ #
161
+ # GridSearchCV returns the best hyperparameters and their score. [0] contains the best parameters.
162
+ var best_params = GridSearchCV[KNN](
163
+ X,
164
+ y,
165
+ params,
166
+ accuracy_score,
167
+ cv=4,
168
+ n_jobs=-1,
169
+ )[0].copy()
170
+ print("Tuned parameters:", best_params)
171
+
172
+ # Split the dataset into training and testing sets.
173
+ var X_train, X_test, y_train, y_test = train_test_split(
174
+ X,
175
+ y,
176
+ test_size=0.2,
177
+ random_state=1234,
178
+ )
179
+
180
+ # Create a KNN model using the best hyperparameters found above.
181
+ var knn = KNN(best_params)
182
+ # Train the model using the training data.
183
+ knn.fit(X_train, y_train)
184
+ # Save the trained model to disk.
185
+ knn.save("knn")
186
+
187
+ # Load the saved model back from disk.
188
+ knn = KNN.load("knn")
189
+ # Predict the labels for the test samples.
190
+ var y_pred = knn.predict(X_test)
191
+ # Compare the predictions with the expected labels.
192
+ print("KNN classification accuracy:", accuracy_score(y_test, y_pred))
193
+
194
+ # Remove the saved model file created by this example.
195
+ os.remove("knn.mjml")
196
+ ```
197
+ More examples are available in [`tests`](https://github.com/yetalit/Mojmelo/blob/main/tests) folder.
198
+
199
+ ## Benchmarks (AMD Zen 4)
200
+
201
+ [`KMeans`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/kmeans_bench.mojo)
202
+
203
+ | Model | Fit Time (s) | ARI vs sklearn | ARI vs truth |
204
+ |----------------|-----------------|----------------|--------------|
205
+ | sklearn KMeans | 0.2764 ± 0.0010 | - | 0.9390 |
206
+ | mojmelo KMeans | 0.1713 ± 0.0029 | 0.8822 | 0.9390 |
207
+
208
+ [`HDBSCAN`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/hdbs_bench.mojo) (algorithm='boruvka_kdtree')
209
+
210
+ | Model | Fit Time (s) | ARI vs sklearn | ARI vs fast_hdbscan | ARI vs truth |
211
+ |------------------|-----------------|----------------|---------------------|--------------|
212
+ | skl-contrib HDBS | 1.1945 ± 0.0067 | - | - | 0.9988 |
213
+ | fast hdbscan | 0.2412 ± 0.0014 | - | - | 0.9989 |
214
+ | mojmelo HDBS | 0.1765 ± 0.0032 | 0.9923 | 0.9989 | 0.9933 |
215
+
216
+ [`DBSCAN`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/dbs_bench.mojo) (algorithm='kd_tree')
217
+
218
+ | Model | Fit Time (s) | ARI vs sklearn | ARI vs truth |
219
+ |-------------|-----------------|----------------|--------------|
220
+ | sklearn DBS | 1.0625 ± 0.0020 | - | 0.8605 |
221
+ | mojmelo DBS | 0.4817 ± 0.0035 | 1.0000 | 0.8605 |
222
+
223
+ [`KNN`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/knn_bench.mojo) (algorithm='kd_tree')
224
+
225
+ | Model | Fit Time (s) | Predict Time (s) | Accuracy |
226
+ |-------------|-----------------|------------------|----------|
227
+ | sklearn KNN | 0.0353 ± 0.0005 | 1.7600 ± 0.0063 | 0.8543 |
228
+ | mojmelo KNN | 0.0149 ± 0.0006 | 0.2126 ± 0.0040 | 0.8347 |
229
+
230
+ [`SVM`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/svm_bench.mojo)
231
+
232
+ | Model | Fit Time (s) | Predict Time (s) | Accuracy |
233
+ |-------------|-----------------|------------------|----------|
234
+ | sklearn SVM | 1.2857 ± 0.0020 | 0.3720 ± 0.0008 | 0.9750 |
235
+ | mojmelo SVM | 0.8618 ± 0.0091 | 0.0600 ± 0.0002 | 0.9750 |
236
+
237
+ [`DecisionTreeClassifier`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/dtc_bench.mojo)
238
+
239
+ | Model | Fit Time (s) | Predict Time (s) | Accuracy |
240
+ |-------------|-----------------|------------------|----------|
241
+ | sklearn DTC | 0.8498 ± 0.0033 | 0.0004 ± 0.0000 | 0.9667 |
242
+ | mojmelo DTC | 0.0810 ± 0.0057 | 0.0001 ± 0.0000 | 0.9668 |
243
+
244
+ [`DecisionTreeRegressor`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/dtr_bench.mojo)
245
+
246
+ | Model | Fit Time (s) | Predict Time (s) | MSE |
247
+ |-------------|-----------------|------------------|-----------|
248
+ | sklearn DTR | 0.6466 ± 0.0006 | 0.0005 ± 0.0000 | 8247.9358 |
249
+ | mojmelo DTR | 0.0795 ± 0.0049 | 0.0003 ± 0.0000 | 8192.1982 |
250
+
251
+ [`RandomForestClassifier`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/rfc_bench.mojo)
252
+
253
+ | Model | Fit Time (s) | Predict Time (s) | Accuracy |
254
+ |-------------|-----------------|------------------|----------|
255
+ | sklearn RFC | 0.4401 ± 0.0078 | 0.0139 ± 0.0002 | 0.9163 |
256
+ | mojmelo RFC | 0.4064 ± 0.0036 | 0.0044 ± 0.0001 | 0.9144 |
257
+
258
+ [`RandomForestRegressor`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/rfr_bench.mojo)
259
+
260
+ | Model | Fit Time (s) | Predict Time (s) | MSE |
261
+ |-------------|-----------------|------------------|-----------|
262
+ | sklearn RFR | 2.0257 ± 0.0050 | 0.0134 ± 0.0004 | 8454.5517 |
263
+ | mojmelo RFR | 1.2247 ± 0.0094 | 0.0067 ± 0.0002 | 9155.6895 |
264
+
265
+ [`PCA`](https://github.com/yetalit/Mojmelo/blob/main/benchmarks/pca_bench.mojo) (svd_solver='full')
266
+
267
+ | Model | Fit Time (s) | Transform Time (s) | Explained Var |
268
+ |-------------|-----------------|--------------------|---------------|
269
+ | sklearn PCA | 0.2359 ± 0.0081 | 0.0088 ± 0.0019 | 0.5375 |
270
+ | mojmelo PCA | 0.0515 ± 0.0027 | 0.0103 ± 0.0001 | 0.5375 |
271
+
272
+ ## Contributing
273
+
274
+ Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
275
+
276
+ Contributions can be done to the project in these 3 ways:
277
+ 1. Applying improvements to the code and opening a Pull Request
278
+ 2. Reporting a bug
279
+ 3. Suggesting new features
280
+
281
+ <!-- ACKNOWLEDGMENTS -->
282
+ ## Acknowledgments
283
+
284
+ * Mojo usage and distribution are licensed under the [Modular Community License](https://www.modular.com/legal/community).
285
+
286
+ * <a href='https://www.csie.ntu.edu.tw/~cjlin/libsvm/'>Libsvm</a>, A Library for Support Vector Machines by Chih-Chung Chang and Chih-Jen Lin licensed under the BSD-3-Clause license.
287
+
288
+ * `HDBSCAN` implementation is partially based on <a href='https://hdbscan.readthedocs.io/en/latest/'>hdbscan</a> by Leland McInnes, John Healy and Steve Astels licensed under the BSD-3-Clause license and <a href='https://fast-hdbscan.readthedocs.io/en/latest/'>Fast Multicore HDBSCAN</a> by Tutte Institute for Mathematics and Computing licensed under the BSD-2-Clause license.
289
+
290
+ * `matmul` implementation is based on <a href='https://github.com/YichengDWu/matmul.mojo'>matmul.mojo</a> by Ethan Wu (YichengDWu) licensed under the Apache-2.0 license.
291
+
292
+ * `argmin`, `argmax` and `argsort` implementations and `utils.algorithm` submodule are based on codes from <a href='https://github.com/modular/modular'>Modular</a> licensed under the Apache License v2.0 with LLVM Exceptions.
293
+
294
+ * <a href='https://arxiv.org/abs/physics/0408067'>KDTREE2</a>, a kd-tree implementation in Fortran 95 and C++ by Matthew B. Kennel.
295
+
296
+ * Initially drew inspiration from Patrick Loeber's <a href='https://github.com/patrickloeber/MLfromscratch/'>MLfromscratch</a>.
297
+
298
+
299
+ [issues-shield]: https://img.shields.io/github/issues/yetalit/mojmelo
300
+ [issues-url]: https://github.com/yetalit/mojmelo/issues
301
+ [license-shield]: https://img.shields.io/badge/license-BSD%203--Clause-blue
302
+ [license-url]: https://github.com/yetalit/Mojmelo/blob/main/LICENSE
File without changes