knnopt 1.0.2__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.
- knnopt-1.0.2/LICENSE +21 -0
- knnopt-1.0.2/MANIFEST.in +7 -0
- knnopt-1.0.2/PKG-INFO +629 -0
- knnopt-1.0.2/README.md +603 -0
- knnopt-1.0.2/knnopt/__init__.py +0 -0
- knnopt-1.0.2/knnopt/cli_predict.py +104 -0
- knnopt-1.0.2/knnopt/cli_train.py +64 -0
- knnopt-1.0.2/knnopt/cli_validate.py +203 -0
- knnopt-1.0.2/knnopt/knnopt.py +461 -0
- knnopt-1.0.2/knnopt/utils/__init__.py +0 -0
- knnopt-1.0.2/knnopt/utils/combine_csv.py +50 -0
- knnopt-1.0.2/knnopt/utils/csv_diff.py +121 -0
- knnopt-1.0.2/knnopt/utils/data_processing.py +179 -0
- knnopt-1.0.2/knnopt/utils/get_dataset_cls.py +80 -0
- knnopt-1.0.2/knnopt/utils/get_dataset_reg.py +88 -0
- knnopt-1.0.2/knnopt/utils/knnopt_example.py +160 -0
- knnopt-1.0.2/knnopt/utils/pearson_coeffs.py +66 -0
- knnopt-1.0.2/knnopt/utils/split_csv.py +75 -0
- knnopt-1.0.2/knnopt/utils/split_csv_by_row.py +59 -0
- knnopt-1.0.2/knnopt/utils/train_validate_split.py +45 -0
- knnopt-1.0.2/knnopt.egg-info/PKG-INFO +629 -0
- knnopt-1.0.2/knnopt.egg-info/SOURCES.txt +26 -0
- knnopt-1.0.2/knnopt.egg-info/dependency_links.txt +1 -0
- knnopt-1.0.2/knnopt.egg-info/entry_points.txt +14 -0
- knnopt-1.0.2/knnopt.egg-info/requires.txt +6 -0
- knnopt-1.0.2/knnopt.egg-info/top_level.txt +1 -0
- knnopt-1.0.2/setup.cfg +4 -0
- knnopt-1.0.2/setup.py +43 -0
knnopt-1.0.2/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jianbo Huang (黄建波: jianbo.huang22@gmail.com)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
knnopt-1.0.2/MANIFEST.in
ADDED
knnopt-1.0.2/PKG-INFO
ADDED
|
@@ -0,0 +1,629 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: knnopt
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: Optimized KNN Regressor/Classifier with NLopt weight optimization and CSV file process utilities
|
|
5
|
+
Author: Jianbo Huang
|
|
6
|
+
Author-email: jianbo.huang22@gmail.com
|
|
7
|
+
License: MIT
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: numpy
|
|
12
|
+
Requires-Dist: pandas
|
|
13
|
+
Requires-Dist: scikit-learn
|
|
14
|
+
Requires-Dist: tabulate
|
|
15
|
+
Requires-Dist: joblib
|
|
16
|
+
Requires-Dist: nlopt
|
|
17
|
+
Dynamic: author
|
|
18
|
+
Dynamic: author-email
|
|
19
|
+
Dynamic: description
|
|
20
|
+
Dynamic: description-content-type
|
|
21
|
+
Dynamic: license
|
|
22
|
+
Dynamic: license-file
|
|
23
|
+
Dynamic: requires-dist
|
|
24
|
+
Dynamic: requires-python
|
|
25
|
+
Dynamic: summary
|
|
26
|
+
|
|
27
|
+
# knnopt
|
|
28
|
+
|
|
29
|
+
**Optimized KNN Regressor/Classifier with NLopt weight optimization**
|
|
30
|
+
|
|
31
|
+
`knnopt` is a Python package that extends the standard K-Nearest Neighbors (KNN) algorithm by automatically optimizing **feature-target weights**
|
|
32
|
+
using the [NLopt](https://nlopt.readthedocs.io/en/latest/) library.
|
|
33
|
+
This allows KNN models to adapt feature importance for each target variable, improving accuracy and robustness.
|
|
34
|
+
Test and validation cases show that it has better accuracy than other commonly-used machine-learning
|
|
35
|
+
models for most of the test cases, while on other cases, its accuracy has similar level
|
|
36
|
+
with other models. Our validation cases show that, it does not have over-fitting issues. Test and
|
|
37
|
+
validation accuracy is consistent across different cases, and performs well for cases
|
|
38
|
+
with big sample records such as 10000 records, as well as cases with small number of records
|
|
39
|
+
around 100.
|
|
40
|
+
|
|
41
|
+
This package also contain a number of utilities for handling CSV data file. They are designed to help
|
|
42
|
+
with general data science and machine learning tasks.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 🚀 Features
|
|
47
|
+
|
|
48
|
+
- **Supports Regression and Classification**
|
|
49
|
+
- **Automatic Feature Weight Optimization** per target using NLopt
|
|
50
|
+
- **Scales Features** with `MinMaxScaler` for consistent distance metrics
|
|
51
|
+
- **Saves Models and Scalers** for later prediction
|
|
52
|
+
- **Performance Tracking** via `performance.csv`
|
|
53
|
+
- **Customizable KNN Parameters** (`n_neighbors`, `weights`, `metric`)
|
|
54
|
+
- **Choice of NLopt Optimizers** (e.g., `LN_COBYLA`, `LD_MMA`, etc.)
|
|
55
|
+
- **CSV utilities** a set of utilities for handling CSV data, useful for data analysis and machine learning tasks
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 🛠 Technology Overview
|
|
60
|
+
|
|
61
|
+
This model is implemented as a Python class KnnOpt. It consists of methods for loading training data,
|
|
62
|
+
scale dataset, optimization objective function, optimization model, feature-target correlation,
|
|
63
|
+
train model, performance metrics calculation, targets prediction with new, untrained feature records,
|
|
64
|
+
model validation with untrained dataset which contains both features and targets columns.
|
|
65
|
+
|
|
66
|
+
Apart from the class implementation, this package also contains three CLI utility files for model training,
|
|
67
|
+
prediction and validation, and a set of utilities for CSV file handling and training data preperation.
|
|
68
|
+
The knnopt-model-related utilities are:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
cli_predict.py cli_train.py cli_validate.py
|
|
72
|
+
```
|
|
73
|
+
These utilities allow us to train, validate KnnOpt model, and use the trained model for targets
|
|
74
|
+
prediction using commands run on terminals. This approach simplifies the usage of machine-learning
|
|
75
|
+
models, especially helpful for researchers/engineers who do not have much experiences in
|
|
76
|
+
data science and computer languages.
|
|
77
|
+
|
|
78
|
+
This package also includes utilites for preparing CSV data files prior to train a model.
|
|
79
|
+
They can be used for any data analysis and machine-learning jobs involving CSV data. The utility files are:
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
```combine_csv.py csv_diff.py data_processing.py get_dataset_cls.py
|
|
83
|
+
get_dataset.py pearson_coeffs.py split_csv_by_row.py split_csv.py
|
|
84
|
+
train_validate_split.py
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## KnnOpt Model creation
|
|
88
|
+
|
|
89
|
+
The syntax to create a KnnOpt model is:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
model = KnnOpt(
|
|
93
|
+
features=['f0','f1','f2'...], # feature-column names list
|
|
94
|
+
targets=['t0','t1','t2'...], # target-column names list
|
|
95
|
+
model_type='reg', # cls
|
|
96
|
+
n_neighbors=5, #any suitable int >= 1, 3 to 7 are suitable choices
|
|
97
|
+
weights='distance', #uniform
|
|
98
|
+
metric='euclidean', #manhattan
|
|
99
|
+
optimizer='LN_COBYLA' #LN_BOBYQA, GN_DIRECT
|
|
100
|
+
)
|
|
101
|
+
```
|
|
102
|
+
The most influential parameter is: n_neighbors. The weights, metric and optimizer default values are suitable for majority cases.
|
|
103
|
+
|
|
104
|
+
## Train KnnOpt Model
|
|
105
|
+
|
|
106
|
+
Once KnnOpt model instance is created, the next step is to train the model. The syntax is:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
model.train(csv_path, test_size=0.3)
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
where csv_path is the absolute path to the training data file, test_size is fraction of data used for model testing.
|
|
113
|
+
Note that:
|
|
114
|
+
|
|
115
|
+
- All the model-related data files, results files, weights, pipeline file will be saved in the same directory as the training data file.
|
|
116
|
+
- test_size has a substantial effect on model accuracy. A value range of [0.2, 0.35] is a suitable choice.
|
|
117
|
+
- The train method will automatically call data pre-processing method to scale the data
|
|
118
|
+
- All data columns in the training data file needs to contain numerical data only
|
|
119
|
+
- If your CSV data file contain categorical data, and/or missing data, you can use the data_processing utility to pre-process the data file first.
|
|
120
|
+
- The test accuracy or test error metrics are the real measurement of model accuracy. High train accuracy does not mean the model
|
|
121
|
+
is accurate, because the target values for evaluation are used in training the model.
|
|
122
|
+
- In evaluating the test accuracy/error, the target values are not used for model training, so it is a real representation of the
|
|
123
|
+
model performance.
|
|
124
|
+
- During training, the weights of feature(i) to target(j), W(i,j) is optimized in such a way that the test error becomes minimized.
|
|
125
|
+
The optimization procedure is automatically called, and the final weights array W is used to fit the model.
|
|
126
|
+
- The feature-target weight can be seen as the importance factor of a feature influencing a target, therefore, optimized weights will
|
|
127
|
+
help KNN model to find the best match between a new record and the neighbouring records, thus increase prediction accuracy.
|
|
128
|
+
- The training process will create and store 4 files in the case directory:
|
|
129
|
+
```
|
|
130
|
+
knn_models.pkl scaler.pkl weights.npy performance.csv
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Workflow of the model training process
|
|
134
|
+
|
|
135
|
+
1. Load CSV containing features and targets.
|
|
136
|
+
1. Scale Features using MinMaxScaler.
|
|
137
|
+
1. Split Data into train/test sets.
|
|
138
|
+
1. Optimize Feature Weights for each target using NLopt:
|
|
139
|
+
1. Minimizes RMSE for regression. Maximizes accuracy/F1 for classification.
|
|
140
|
+
1. Train KNN Models with optimized weights.
|
|
141
|
+
1. Save Outputs in case directory:
|
|
142
|
+
- **scaler.pkl** — feature scaler
|
|
143
|
+
- **weights.npy** — optimized weights
|
|
144
|
+
- **knn_models.pkl** — trained KNN model
|
|
145
|
+
- **performance.csv** — metrics for each target
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
## Validate KnnOpt Model
|
|
149
|
+
|
|
150
|
+
The test accuracy is a good indication of machine-learning model performance, but it does not ensure the prediction will
|
|
151
|
+
have the same accuracy due to potential parameter overfitting issue. To check whether a KnnOpt model is overfitted, a validation method is created.
|
|
152
|
+
The idea is that we keep a fraction of the sample data which contains both features and targets out of the train-test loop, therefore it is
|
|
153
|
+
true representation of model prediction except that we know the true targets. To validate KnnOpt model against a given dataset, the procedure is:
|
|
154
|
+
|
|
155
|
+
- Split the whole data into training data and validation data, using Scikit-learn train-test split function. You can control the fraction of the data
|
|
156
|
+
to be used for validation and randomly mix up the data for a fair validation.
|
|
157
|
+
- The remaining data train data can then be fed into a KnnOpt model for training.
|
|
158
|
+
- This process can be done by using this packages utility code: **train_validate_split.py**
|
|
159
|
+
- The process will create two files in the case directory, while the original data file is unchanged:
|
|
160
|
+
```
|
|
161
|
+
train_data.csv validation_input.csv
|
|
162
|
+
```
|
|
163
|
+
- To validate the trained model, you can either use the validation utility in cli_validate.py or use the class method
|
|
164
|
+
model.validate(input_csv), where input_csv is the filename which contains validation input data. The file must already be in the
|
|
165
|
+
case directory
|
|
166
|
+
|
|
167
|
+
## KnnOpt class methods
|
|
168
|
+
|
|
169
|
+
The KnnOpt class contains the following methods:
|
|
170
|
+
|
|
171
|
+
- **load_train_data**: load training dataset in given CSV file. The data file contains features columns, targets columns, and can contain
|
|
172
|
+
other columns not used for training/prediction. It also scale the data using Scikit-lean MinMaxScaler() function
|
|
173
|
+
- **data_split**: split the loaded data into train and test parts
|
|
174
|
+
- **objective**: objective function to minimise the test error
|
|
175
|
+
- **optimize_model**: Procedure to get the optimized weights
|
|
176
|
+
- **correlation**: helper method to get correlation coefficients of all features with respect to targets[t_idx]
|
|
177
|
+
- **finalize_regressor**: calculate and save the performance metrics for regressor
|
|
178
|
+
- **finalize_classifier**: calculate and save the performance metrics for classifier
|
|
179
|
+
- **train**: scale training data, train the model, optimize weights, save model file, scalar file and weights file in case directory
|
|
180
|
+
- **predict**: use the trained model to predict targets based on unseen features data
|
|
181
|
+
- **validate**: use untrained input file which contains both features and targets and the trained model to predict
|
|
182
|
+
targets, find the difference between true values and predicted values, output the relative errors, prediction
|
|
183
|
+
accuracy to case directory. This is an effective tool to check whether the model overfits the training data.
|
|
184
|
+
|
|
185
|
+
## Utilities
|
|
186
|
+
|
|
187
|
+
1. Train KnnOpt model **cli_train.py**: CLI command to train a KnnOpt model.
|
|
188
|
+
|
|
189
|
+
- Usage example for regressor
|
|
190
|
+
|
|
191
|
+
Under a terminal, type the following command:
|
|
192
|
+
```
|
|
193
|
+
cd ~/knnOptModel/knnopt/examples/metal_strength
|
|
194
|
+
knn-train train_data.csv -f f0,f1,f2,f3,f4 -t target1,target2,target3,target4 -n 7 --test-size 0.2
|
|
195
|
+
```
|
|
196
|
+
You can also put the command in a train.sh file, make it executable, go to the directory, then under terminal window,
|
|
197
|
+
type:
|
|
198
|
+
```
|
|
199
|
+
train.sh
|
|
200
|
+
```
|
|
201
|
+
Note that model_type default is 'reg', therefore for regression application, the --model-type option is not needed.
|
|
202
|
+
|
|
203
|
+
- Usage example for classifier
|
|
204
|
+
|
|
205
|
+
Under a terminal type the following command:
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
knnopt-train train_data.csv -f f0,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11 \
|
|
209
|
+
-t medical_event --model-type cls -n 7 --test-size 0.25
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Note that the
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
--model-type cls
|
|
216
|
+
```
|
|
217
|
+
is needed, as classifier is not the default model type. Put the command in a train.sh file is a better choice for reuse
|
|
218
|
+
and for keeping record.
|
|
219
|
+
|
|
220
|
+
2. Validate KnnOpt model **cli_validate.py**: CLI command to validate a trained KnnOpt model.
|
|
221
|
+
- Usage example for regressor: the bash file validate.sh for command is as follows
|
|
222
|
+
|
|
223
|
+
```
|
|
224
|
+
knnopt-validate reg ./ validate_input.csv
|
|
225
|
+
```
|
|
226
|
+
where ./ is the directory containing the validation input file. You can use absolute path name
|
|
227
|
+
and any filename (must be with extension .csv) for the validation input file.
|
|
228
|
+
|
|
229
|
+
- Usage example for classifier: the bash file validate.sh for command is as follows
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
knnopt-validate cls ./ validate_input.csv
|
|
233
|
+
```
|
|
234
|
+
where ./ is the directory containing the validation input file. You can use absolute path name
|
|
235
|
+
and any filename (must be with extension .csv) for the validation input file.
|
|
236
|
+
|
|
237
|
+
3. KnnOpt model prediction **cli_predict.py**: CLI command to predict the targets of giving features data, by using a trained KnnOpt model.
|
|
238
|
+
- Usage example for regressor: the bash file predict.sh for command is as follows
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
```
|
|
242
|
+
knnopt-predict reg input.csv
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
where reg is the model_type, input.csv is input data path
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
- Usage example for classifier: the bash file predict.sh for command is as follows
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
```
|
|
252
|
+
knnopt-predict cls input.csv
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
where cls is the model_type, input.csv is input data path
|
|
256
|
+
|
|
257
|
+
4. combine-csv **utils/combine_csv.py**: combine two CSV files the same number of rows but
|
|
258
|
+
different column names.
|
|
259
|
+
|
|
260
|
+
- Usage:
|
|
261
|
+
```
|
|
262
|
+
combine-csv file1.csv file2.csv
|
|
263
|
+
```
|
|
264
|
+
- Both files must contain a header and have the same number of rows
|
|
265
|
+
- Combined CSV data will be saved as combined_csv.csv, and in the same directory as file1.csv
|
|
266
|
+
- Duplicated column names in file2.csv will be ignored
|
|
267
|
+
- This utility is useful to combine feature data and target data, if they are originally not in the same file
|
|
268
|
+
- It is useful for any data analytics, not specific to KnnOpt model
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
5. csv-diff **utile/csv_diff.py**: find data difference between two CSV files.
|
|
272
|
+
|
|
273
|
+
- Usage example:
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
csv-diff file1 file2 --columns f1,f2,f3,f4 --eps 1.0e-4
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
where file1 and file2 are the paths of the two CSV files, columns is a string containing comma-separated column names to find the differences with.
|
|
280
|
+
The two files may contain other columns, but names in **--columns** must be exist in both files. Both files must have the same number of rows.
|
|
281
|
+
eps is a small number to prevent division-by-zero. The cell-wise absolute difference is normalized by the mean of the associated column.
|
|
282
|
+
If **--columns** is missing, all columns will be compared.
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
6. data-process **utile/data_processing.py**: CSV preprocessing utility: auto missing data handling, categorical/boolean to numeric, float rounding
|
|
286
|
+
|
|
287
|
+
- Usage example:
|
|
288
|
+
|
|
289
|
+
```
|
|
290
|
+
data-process input_csv -s skip-columns -e extra-category -m missing-value
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
where input_csv is the file path to the csv file to be processed. All processed data will be written in the same directory as the input_csv.
|
|
294
|
+
skip-columns is a string of comma-separated names, those columns will not be handled. The utility will automatically identify category data columns,
|
|
295
|
+
However, if some data columns seemingly numerical such as postcodes, but actually category, you can use the -e option to define them.
|
|
296
|
+
The -s option missing-value is for defining missing value cells in the dataset, such as NA, N/A, nan, or empty string, default is empty string("").
|
|
297
|
+
Processed data will be saved into file processed.csv.
|
|
298
|
+
|
|
299
|
+
7. dataset-cls **utile/get_dataset_cls.py**: get CSV data from Scikit-learn classification datasets and save as CSV files.
|
|
300
|
+
|
|
301
|
+
- Usage example:
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
dataset-cls dataset_name -c case_directory -s -r records -n noise
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
where: dataset_name includes iris, wine, breast_cancer, synthetic. -s means the data rows are randomly shuffled for model training.
|
|
308
|
+
case_directory default to current working directory. records(default 500) and noise(default 0.1) are only for synthetic
|
|
309
|
+
dataset.
|
|
310
|
+
|
|
311
|
+
- Output data file: output data will be saved as full_data.csv, in case_directory
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
8. dataset-reg **utile/get_dataset_reg.py**: get CSV data from Scikit-learn regression datasets and save as CSV files.
|
|
316
|
+
|
|
317
|
+
- Usage example:
|
|
318
|
+
|
|
319
|
+
```
|
|
320
|
+
dataset-reg dataset_name -c case_directory -f nfeatures -s -r records -n noise
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
where: dataset_name includes wine, california_housing, synthetic. -s means the data rows are randomly shuffled for model training.
|
|
324
|
+
case_directory default to current working directory. nfeatures(default 10), records(default 1000) and noise(default 0.1) are only for synthetic
|
|
325
|
+
dataset.
|
|
326
|
+
|
|
327
|
+
- Output data file: output data will be saved as full_data.csv, in case_directory
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
9. correlation **utile/pearson_coeffs.py**: calculates correlation coefficients of each feature column to a target column.
|
|
331
|
+
|
|
332
|
+
- Usage example:
|
|
333
|
+
|
|
334
|
+
```
|
|
335
|
+
correlation csv_path targets -s skip_columns
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
where: csv_path is the data file to be handled, targets is a comma-separated string containing the target names. skip_columns
|
|
339
|
+
is a comma-separated string containing names of columns in the data file to be skipped for correlation.
|
|
340
|
+
|
|
341
|
+
- Output data file: output data files are: correlation_coefficients.csv and normalized_coefficients.csv. They will be saved in the same directory as csv_path file.
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
10. split-csv **utile/split_csv.py**: split a CSV file into two CSV files based on specified columns.
|
|
345
|
+
|
|
346
|
+
- Usage example:
|
|
347
|
+
```
|
|
348
|
+
split-csv csv_path file1_name file2_name file2_columns -c common_columns
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
where:
|
|
352
|
+
- **csv_path** : path to the input CSV file
|
|
353
|
+
- **file1_name**: name of the first output CSV file
|
|
354
|
+
- **file2_name**: name of the second output CSV file
|
|
355
|
+
- **file2_columns** : comma-separated string containing column names for file2.csv
|
|
356
|
+
- **common_columns**: Optional comma-separated list of columns to include in both files
|
|
357
|
+
|
|
358
|
+
This utility is useful for spliting a file into feature file and target file.
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
11. split-csv-rows **utile/split_csv_by_row.py**: split a CSV file into two files by randomly selecting rows.
|
|
362
|
+
|
|
363
|
+
- Usage example:
|
|
364
|
+
```
|
|
365
|
+
split-csv-rows csv_path file1_name file2_name -r file2_ratio
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
where:
|
|
369
|
+
- **csv_path** : path to the input CSV file
|
|
370
|
+
- **file1_name**: name of the first output CSV file
|
|
371
|
+
- **file2_name**: name of the second output CSV file
|
|
372
|
+
- **file2_ratio**: ratio of rows to put into file2.csv (0 < ratio < 1, default 0.1)
|
|
373
|
+
|
|
374
|
+
This utility is useful for spliting a file into train file and validation file.
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
12. train-validate-split **utile/train_validate_split.py**: split a CSV file into train file and validate file.
|
|
378
|
+
|
|
379
|
+
- Usage example:
|
|
380
|
+
```
|
|
381
|
+
train-validate-split csv_path -r validate_size
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
where:
|
|
385
|
+
- **csv_path** : path to the input CSV file
|
|
386
|
+
|
|
387
|
+
- **validate_size**: fraction of data for validation (0 < ratio < 1, default 0.1)
|
|
388
|
+
|
|
389
|
+
- The splitted data will be saved into train_data.csv and validation_input.csv, stored in the same
|
|
390
|
+
directory as the csv_path.
|
|
391
|
+
|
|
392
|
+
This utility is useful for spliting a file into train file and validation file.
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
## Examples
|
|
396
|
+
|
|
397
|
+
A number of examples are provided in the examples/ folder. There are two types of examples:
|
|
398
|
+
1. Examples using datasets provided by scikit-learn, for create and run those examples, do:
|
|
399
|
+
```
|
|
400
|
+
cd knnOptModel/knnopt/examples
|
|
401
|
+
python3 knnopt_validate.py
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
There are 7 cases in this category: 4 classification cases: breast_cancer, wine, iris, synthetic_classification and 3
|
|
405
|
+
regression cases: diabetes, california_housing, synthetic_regression
|
|
406
|
+
|
|
407
|
+
2. Datasets provided by this package
|
|
408
|
+
|
|
409
|
+
The package includes 5 additional test and validation cases: 3 regression cases: metal_strength, heat_tr_coef, matprop,
|
|
410
|
+
2 classification cases: medical_event, claim_predict.
|
|
411
|
+
|
|
412
|
+
To run those cases, cd to the a case, then type ./run.sh. You may change the parameters in the run.sh file
|
|
413
|
+
to see the effect of each parameter.
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
## Installation
|
|
418
|
+
|
|
419
|
+
To install this package, you can download or clone the source package. Assuming the package is stored
|
|
420
|
+
in the $HOME directory, then under terminal, do:
|
|
421
|
+
|
|
422
|
+
```
|
|
423
|
+
cd ~/knnOptModel
|
|
424
|
+
pip install .
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
📜 License
|
|
429
|
+
This project is licensed under the MIT License — see the LICENSE file for details.
|
|
430
|
+
|
|
431
|
+
🤝 Contributing
|
|
432
|
+
Pull requests are welcome!
|
|
433
|
+
If you have suggestions for optimizers, metrics, or additional features, feel free to open an issue.
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
## 📊 KnnOpt accuracy comparison with other models
|
|
437
|
+
|
|
438
|
+
### Case name: diabetes regression
|
|
439
|
+
This case uses sklearn diabetes dataset. All models use test_size: 0.25, random_state: 42
|
|
440
|
+
|
|
441
|
+
-----------------------------------------
|
|
442
|
+
| Model name | Target Name| Test Rel MAE% |Validate Rel MAE% | Model parameters|
|
|
443
|
+
|------------|---------|----------|----------------|----------------|
|
|
444
|
+
| KnnOpt | target |23.67% | 25.52% |n_neighbours=5, weights: distance, metric: euclidean, optimizer: LN_COBYLA|
|
|
445
|
+
| XGBoost | target |26.36% | 26.03% |n_estimators=300,learning_rate=0.05,max_depth=6,subsample=0.8,colsample_bytree=0.8|
|
|
446
|
+
| SVR | target |24.50% | 27.50% |C=200, gamma=0.05,epsilon=0.01,Kernel=RBF|
|
|
447
|
+
| RandomForest| target |25.07% | 24.38% |n_estimators=300,max_depth=6,min_samples_split=2,min_samples_leaf=1|
|
|
448
|
+
| MLP | target |23.96% | 27.46% |hidden_layer_sizes: [50, 30, 20], activation: relu, solver: adam, alpha: 0.0001, learning_rate: constant, max_iter: 600|
|
|
449
|
+
| Knn | target |26.25% | 27.15% |n_neighbours=5, weights: distance, metric: euclidean|
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
### Case name: california_housing regression
|
|
454
|
+
It uses sklearn california_housing dataset. All models use test_size: 0.25, random_state: 42
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
-----------------------------------------
|
|
458
|
+
| Model name | Target Name| Test Rel MAE% |Validate Rel MAE | Model parameters|
|
|
459
|
+
|------------|---------|----------|----------------|----------------|
|
|
460
|
+
| KnnOpt | target |13.82% | 13.57% |n_neighbours=5, weights: distance, metric: euclidean, optimizer: LN_COBYLA|
|
|
461
|
+
| XGBoost | target |15.42% | 15.05% |n_estimators=300,learning_rate=0.05,max_depth=6,subsample=0.8,colsample_bytree=0.8|
|
|
462
|
+
| SVR | target |23.69% | 24.37% |C=200, gamma=0.05,epsilon=0.01,Kernel=RBF|
|
|
463
|
+
| RandomForest| target |22.38% | 22.24% |n_estimators=300,max_depth=6,min_samples_split=2,min_samples_leaf=1|
|
|
464
|
+
| MLP | target |20.64% | 20.69% |hidden_layer_sizes: [50, 30, 20], activation: relu, solver: adam, alpha: 0.0001, learning_rate: constant, max_iter: 600|
|
|
465
|
+
| Knn | target |21.93% | 22.40% |n_neighbours=5, weights: distance, metric: euclidean|
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
### Case name: heat_tr_coef regression
|
|
470
|
+
|
|
471
|
+
The dataset comes from CFD simulation of heat transfer coefficients of two-dimensional rectangular objects
|
|
472
|
+
of different dimensions and flow configs. The purpose here is to use the dataset to validate different models.
|
|
473
|
+
All models use test_size: 0.3, random_state: 42
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
-----------------------------------------
|
|
477
|
+
| Model name | Target Name| Test Rel MAE% |Validate Rel MAE | Model parameters|
|
|
478
|
+
|------------|---------|----------|----------------|----------------|
|
|
479
|
+
| KnnOpt | hcoef |7.18% | 8.22% |n_neighbours=5, weights: distance, metric: euclidean, optimizer: LN_COBYLA|
|
|
480
|
+
| XGBoost | hcoef |9.24% | 8.11% |n_estimators=300,learning_rate=0.05,max_depth=6,subsample=0.8,colsample_bytree=0.8|
|
|
481
|
+
| SVR | hcoef |5.61% | 7.28% |C=200, gamma=0.05,epsilon=0.01,Kernel=RBF|
|
|
482
|
+
| RandomForest| hcoef |10.81% | 8.21% |n_estimators=300,max_depth=6,min_samples_split=2,min_samples_leaf=1|
|
|
483
|
+
| MLP | hcoef |33.38% | 32.46% |hidden_layer_sizes: [50, 30, 20], activation: relu, solver: adam, alpha: 0.0001, learning_rate: constant, max_iter: 600|
|
|
484
|
+
| Knn | hcoef |14.76% | 10.81% |n_neighbours=5, weights: distance, metric: euclidean|
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
### Case name: metal_strength regression
|
|
489
|
+
|
|
490
|
+
The dataset correlates metal strength properties with different operational treatment conditions.
|
|
491
|
+
There are 4 targets in this case. The physics background of the dataset is obsecured, but the data relationships are kept for model
|
|
492
|
+
validations. All models use test_size: 0.2, random_state: 42
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
-----------------------------------------
|
|
496
|
+
| Model name | Target Name| Test Rel MAE% |Validate Rel MAE | Model parameters|
|
|
497
|
+
|------------|---------|----------|----------------|----------------|
|
|
498
|
+
| KnnOpt |t1,t2,t3,t4 |6.57.2.02,5.10,8.63% |6.51,2.28,11.31,12.08% |n_neighbours=3, weights: distance, metric: euclidean, optimizer: LN_COBYLA|
|
|
499
|
+
| XGBoost | t1,t2,t3,t4 |7.84,2.09,6.2,8.19% | 7.99,1.87,11.11,12.42% |n_estimators=300,learning_rate=0.05,max_depth=6,subsample=0.8,colsample_bytree=0.8|
|
|
500
|
+
| SVR | t1,t2,t3,t4 |18.96,2.65,11.23,15.02% |20.96,3.29,15.23,16.91% |C=200, gamma=0.05,epsilon=0.01,Kernel=RBF|
|
|
501
|
+
| RandomForest| t1,t2,t3,t4 |6.84,1.99,5.70,8.18% |6.82,2.09,8.62,11.68% |n_estimators=300,max_depth=6,min_samples_split=2,min_samples_leaf=1|
|
|
502
|
+
| MLP | t1,t2,t3,t4 |17.74,14.24,26.39,28.59% |18.81,7.43,31.58,18.72% |hidden_layer_sizes: [50, 30, 20], activation: relu, solver: adam, alpha: 0.0001, learning_rate: constant, max_iter: 600|
|
|
503
|
+
| Knn | t1,t2,t3,t4 |10.14,2.13,8.71,11.10% | 8.51,2.80,12.05,10.93% |n_neighbours=5, weights: distance, metric: euclidean|
|
|
504
|
+
|
|
505
|
+
### Case name: synthetic regression
|
|
506
|
+
|
|
507
|
+
The dataset is generated using sklearn make_regression function with some post transformation. All models use test_size: 0.3,
|
|
508
|
+
random_state: 42, total 1000 records are generated, of which 10% is used for validation and 90% for train/test, and 30% of the remaining data is for test.
|
|
509
|
+
The target is of normal distribution with mean=10, std=1, noise level 10%.
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
-----------------------------------------
|
|
513
|
+
| Model name | Target Name| Test Rel MAE% |Validate Rel MAE | Model parameters|
|
|
514
|
+
|------------|---------|----------|----------------|----------------|
|
|
515
|
+
| KnnOpt |target |2.58% |2.75% |n_neighbours=3, weights: distance, metric: euclidean, optimizer: LN_COBYLA|
|
|
516
|
+
| XGBoost | target |2.13% | 2.11% |n_estimators=300,learning_rate=0.05,max_depth=6,subsample=0.8,colsample_bytree=0.8|
|
|
517
|
+
| SVR | target |0.05% |0.06% |C=200, gamma=0.05,epsilon=0.01,Kernel=RBF|
|
|
518
|
+
| RandomForest| target |3.53% |3.46% |n_estimators=300,max_depth=6,min_samples_split=2,min_samples_leaf=1|
|
|
519
|
+
| MLP |target |0.31% |0.29% |hidden_layer_sizes: [50, 30, 20], activation: relu, solver: adam, alpha: 0.0001, learning_rate: constant, max_iter: 600|
|
|
520
|
+
| Knn | target |3.76 | 3.92% |n_neighbours=3, weights: distance, metric: euclidean|
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
### Case name: product quality reqression
|
|
524
|
+
|
|
525
|
+
This case correlates the product quality parameters with its raw material composition. All models use test_size=0.3.
|
|
526
|
+
4 product characteristics are chosen for comparing the model prediction capabilities: size, strength, component6, react_rate1
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
-----------------------------------------
|
|
530
|
+
| Model name | Target Name| Test Rel MAE% |Validate Rel MAE | Model parameters|
|
|
531
|
+
|------------|---------|----------|----------------|----------------|
|
|
532
|
+
| KnnOpt | size, strength, component6, react_rate1|1.87,0.57,2.81,2.47% |3.49,0.67,1.88,3.18% |n_neighbours=3, weights: distance, metric: euclidean, optimizer: LN_COBYLA|
|
|
533
|
+
| XGBoost | size, strength, component6, react_rate1|5.07,3.51,3.57,3.15% | 5.93,2.43,2.59,3.31% |n_estimators=300,learning_rate=0.05,max_depth=6,subsample=0.8,colsample_bytree=0.8|
|
|
534
|
+
| SVR | size, strength, component6, react_rate1 |3.65,0.75,3.68,3.15% |3.12,0.79,2.86,3.15% |C=200, gamma=0.05,epsilon=0.01,Kernel=RBF|
|
|
535
|
+
| RandomForest|size, strength, component6, react_rate1 |4.96,3.48,3.36,2.65% |7.04,4.31,2.55,3.28% |n_estimators=200,max_depth=6,min_samples_split=2,min_samples_leaf=1|
|
|
536
|
+
| MLP |size, strength, component6, react_rate1|8.12,6.33,11.87,6.52% |5.22,8.61,11.62,7.57% |hidden_layer_sizes: [100], activation: relu, solver: adam, alpha: 0.0001, learning_rate: constant, max_iter: 600|
|
|
537
|
+
| Knn | size, strength, component6, react_rate1|2.29,0.68,3.57,3.39% |3.59,0.69,2.05,3.29% |n_neighbours=3, weights: distance, metric: euclidean|
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
### Case name: breast_cancer classfication
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
This case uses sklearn breast_cancer dataset. All models use test_size=0.3, random_state: 42
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
-----------------------------------------
|
|
547
|
+
| Model name | Target Name| Test Accuracy% |Validate Accuracy| Model parameters|
|
|
548
|
+
|------------|---------|----------|----------------|----------------|
|
|
549
|
+
| KnnOpt | target|98.72% |100% |n_neighbours=5, weights: distance, metric: euclidean, optimizer: LN_COBYLA|
|
|
550
|
+
| XGBoost | target|97.44% | 100% |n_estimators=300,learning_rate=0.05,max_depth=6,subsample=0.8,colsample_bytree=0.8|
|
|
551
|
+
| SVC | target |98.72% |98.25% |C=200, gamma=0.05,epsilon=0.01,Kernel=RBF|
|
|
552
|
+
| RandomForest|target |95.12% |96.49% |n_estimators=200,max_depth=6,min_samples_split=2,min_samples_leaf=1|
|
|
553
|
+
| MLP |target|98.37% |98.25% |hidden_layer_sizes: [100], activation: relu, solver: adam, alpha: 0.0001, learning_rate: constant, max_iter: 600|
|
|
554
|
+
| Knn | target|96.75% |94.74% |n_neighbours=3, weights: distance, metric: euclidean|
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
### Case name: iris classification
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
This case uses sklearn iris dataset. All models use test_size=0.3, random_state: 42
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
-----------------------------------------
|
|
565
|
+
| Model name | Target Name| Test Accuracy% |Validate Accuracy| Model parameters|
|
|
566
|
+
|------------|---------|----------|----------------|----------------|
|
|
567
|
+
| KnnOpt | target|100% |100% |n_neighbours=5, weights: distance, metric: euclidean, optimizer: LN_COBYLA|
|
|
568
|
+
| XGBoost | target|97.50% | 100% |n_estimators=300,learning_rate=0.05,max_depth=6,subsample=0.8,colsample_bytree=0.8|
|
|
569
|
+
| SVC | target |96.97% |100% |C=200, gamma=0.05,epsilon=0.01,Kernel=RBF|
|
|
570
|
+
| RandomForest|target |84.85% |100% |n_estimators=200,max_depth=6,min_samples_split=2,min_samples_leaf=1|
|
|
571
|
+
| MLP |target|96.97% |93.33% |hidden_layer_sizes: [100], activation: relu, solver: adam, alpha: 0.0001, learning_rate: constant, max_iter: 600|
|
|
572
|
+
| Knn | target|87.88% |100% |n_neighbours=3, weights: distance, metric: euclidean|
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
### Case name: wine classification
|
|
578
|
+
|
|
579
|
+
This case uses sklearn wine dataset. All models use test_size=0.3, random_state: 42
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
-----------------------------------------
|
|
583
|
+
| Model name | Target Name| Test Accuracy% |Validate Accuracy| Model parameters|
|
|
584
|
+
|------------|---------|----------|----------------|----------------|
|
|
585
|
+
| KnnOpt | target|100% |100% |n_neighbours=4, weights: distance, metric: euclidean, optimizer: LN_COBYLA|
|
|
586
|
+
| XGBoost | target|97.92% | 100% |n_estimators=300,learning_rate=0.05,max_depth=6,subsample=0.8,colsample_bytree=0.8|
|
|
587
|
+
| SVC | target |87.18% |100% |C=200, gamma=0.05,epsilon=0.01,Kernel=RBF|
|
|
588
|
+
| RandomForest|target |97.44% |100% |n_estimators=200,max_depth=6,min_samples_split=2,min_samples_leaf=1|
|
|
589
|
+
| MLP |target|92.31% |100% |hidden_layer_sizes: [100], activation: relu, solver: adam, alpha: 0.0001, learning_rate: constant, max_iter: 600|
|
|
590
|
+
| Knn | target|89.74% |94.44% |n_neighbours=4, weights: distance, metric: euclidean|
|
|
591
|
+
|
|
592
|
+
|
|
593
|
+
### Case name: synthetic_classification
|
|
594
|
+
|
|
595
|
+
It uses sklearn make_classification to generate the dtaset. 1000 records are generated,
|
|
596
|
+
of which 900 is for train/test the model, and 100 for validate the model. There are 10 features and 1 target in this case.
|
|
597
|
+
All models use test_size=0.2, random_state: 42
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
-----------------------------------------
|
|
601
|
+
| Model name | Target Name| Test Accuracy% |Validate Accuracy| Model parameters|
|
|
602
|
+
|------------|---------|----------|----------------|----------------|
|
|
603
|
+
| KnnOpt | target|92.22% |85% |n_neighbours=7, weights: distance, metric: euclidean, optimizer: LN_COBYLA|
|
|
604
|
+
| XGBoost | target|93.33% | 84% |n_estimators=300,learning_rate=0.05,max_depth=6,subsample=0.8,colsample_bytree=0.8|
|
|
605
|
+
| SVC | target |88.89% |81% |C=200, gamma=0.05,epsilon=0.01,Kernel=RBF|
|
|
606
|
+
| RandomForest|target |92.78% |85% |n_estimators=200,max_depth=6,min_samples_split=2,min_samples_leaf=1|
|
|
607
|
+
| MLP |target|88.89% |81% |hidden_layer_sizes: [100], activation: relu, solver: adam, alpha: 0.0001, learning_rate: constant, max_iter: 600|
|
|
608
|
+
| Knn | target|83.33% |80% |n_neighbours=4, weights: distance, metric: euclidean|
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
## Concluding remarks
|
|
613
|
+
|
|
614
|
+
- KnnOpt model consistently shows stable and mostly better accuracy compare to other models both reegression and classification cases.
|
|
615
|
+
- The consistently good performance is because KnnOpt introduces a weights-based importance
|
|
616
|
+
factor to measure a feature with regard to a target. The weights matrix is then optimized to minimize the
|
|
617
|
+
RMAE error for unseen dataset in the training process. If the unseen dataset covers a wide range of
|
|
618
|
+
potential new data in prediction, it is then able to give good accuracy
|
|
619
|
+
- The accuracy of the model depends on how close of a new data record is from the train/test data. If a data
|
|
620
|
+
record is too far away from the dataset used to train/test the model, the prediction accuracy will drop.
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
|