240 lines
8.7 KiB
Python
240 lines
8.7 KiB
Python
|
# Iris_AllClassifiers.py
|
||
|
# The code demonstrates the process of training 27 Classifier models on the Iris dataset, exports them to ONNX format, and making predictions using the ONNX model.
|
||
|
# It also evaluates the accuracy of both the original and the ONNX models.
|
||
|
# Copyright 2023, MetaQuotes Ltd.
|
||
|
# https://www.mql5.com
|
||
|
|
||
|
# import necessary libraries
|
||
|
from sklearn import datasets
|
||
|
from sklearn.metrics import accuracy_score
|
||
|
from skl2onnx import convert_sklearn
|
||
|
from skl2onnx.common.data_types import FloatTensorType
|
||
|
import onnxruntime as ort
|
||
|
import numpy as np
|
||
|
import matplotlib.pyplot as plt
|
||
|
from sys import argv
|
||
|
|
||
|
# define the path for saving the model
|
||
|
data_path = argv[0]
|
||
|
last_index = data_path.rfind("\\") + 1
|
||
|
data_path = data_path[0:last_index]
|
||
|
|
||
|
# load the Iris dataset
|
||
|
iris = datasets.load_iris()
|
||
|
X = iris.data
|
||
|
y = iris.target
|
||
|
|
||
|
# create and train each classifier model
|
||
|
from sklearn.svm import SVC
|
||
|
svc_model = SVC()
|
||
|
svc_model.fit(X, y)
|
||
|
|
||
|
from sklearn.ensemble import RandomForestClassifier
|
||
|
random_forest_model = RandomForestClassifier(random_state=42)
|
||
|
random_forest_model.fit(X, y)
|
||
|
|
||
|
from sklearn.ensemble import GradientBoostingClassifier
|
||
|
gradient_boosting_model = GradientBoostingClassifier(random_state=42)
|
||
|
gradient_boosting_model.fit(X, y)
|
||
|
|
||
|
from sklearn.ensemble import AdaBoostClassifier
|
||
|
adaboost_model = AdaBoostClassifier(random_state=42)
|
||
|
adaboost_model.fit(X, y)
|
||
|
|
||
|
from sklearn.ensemble import BaggingClassifier
|
||
|
bagging_model = BaggingClassifier(random_state=42)
|
||
|
bagging_model.fit(X, y)
|
||
|
|
||
|
from sklearn.neighbors import KNeighborsClassifier
|
||
|
knn_model = KNeighborsClassifier()
|
||
|
knn_model.fit(X, y)
|
||
|
|
||
|
from sklearn.neighbors import RadiusNeighborsClassifier
|
||
|
radius_neighbors_model = RadiusNeighborsClassifier(radius=1.0)
|
||
|
radius_neighbors_model.fit(X, y)
|
||
|
|
||
|
from sklearn.tree import DecisionTreeClassifier
|
||
|
decision_tree_model = DecisionTreeClassifier(random_state=42)
|
||
|
decision_tree_model.fit(X, y)
|
||
|
|
||
|
from sklearn.linear_model import LogisticRegression
|
||
|
logistic_regression_model = LogisticRegression(max_iter=1000, random_state=42)
|
||
|
logistic_regression_model.fit(X, y)
|
||
|
|
||
|
from sklearn.linear_model import RidgeClassifier
|
||
|
ridge_classifier_model = RidgeClassifier(random_state=42)
|
||
|
ridge_classifier_model.fit(X, y)
|
||
|
|
||
|
from sklearn.linear_model import PassiveAggressiveClassifier
|
||
|
passive_aggressive_model = PassiveAggressiveClassifier(max_iter=1000, random_state=42)
|
||
|
passive_aggressive_model.fit(X, y)
|
||
|
|
||
|
from sklearn.linear_model import Perceptron
|
||
|
perceptron_model = Perceptron(max_iter=1000, random_state=42)
|
||
|
perceptron_model.fit(X, y)
|
||
|
|
||
|
from sklearn.linear_model import SGDClassifier
|
||
|
sgd_model = SGDClassifier(max_iter=1000, random_state=42)
|
||
|
sgd_model.fit(X, y)
|
||
|
|
||
|
from sklearn.naive_bayes import GaussianNB
|
||
|
gaussian_nb_model = GaussianNB()
|
||
|
gaussian_nb_model.fit(X, y)
|
||
|
|
||
|
from sklearn.naive_bayes import MultinomialNB
|
||
|
multinomial_nb_model = MultinomialNB()
|
||
|
multinomial_nb_model.fit(X, y)
|
||
|
|
||
|
from sklearn.naive_bayes import ComplementNB
|
||
|
complement_nb_model = ComplementNB()
|
||
|
complement_nb_model.fit(X, y)
|
||
|
|
||
|
from sklearn.naive_bayes import BernoulliNB
|
||
|
bernoulli_nb_model = BernoulliNB()
|
||
|
bernoulli_nb_model.fit(X, y)
|
||
|
|
||
|
from sklearn.naive_bayes import CategoricalNB
|
||
|
categorical_nb_model = CategoricalNB()
|
||
|
categorical_nb_model.fit(X, y)
|
||
|
|
||
|
from sklearn.tree import ExtraTreeClassifier
|
||
|
extra_tree_model = ExtraTreeClassifier(random_state=42)
|
||
|
extra_tree_model.fit(X, y)
|
||
|
|
||
|
from sklearn.ensemble import ExtraTreesClassifier
|
||
|
extra_trees_model = ExtraTreesClassifier(random_state=42)
|
||
|
extra_trees_model.fit(X, y)
|
||
|
|
||
|
from sklearn.svm import LinearSVC # Import LinearSVC
|
||
|
linear_svc_model = LinearSVC(random_state=42)
|
||
|
linear_svc_model.fit(X, y)
|
||
|
|
||
|
from sklearn.svm import NuSVC
|
||
|
nu_svc_model = NuSVC()
|
||
|
nu_svc_model.fit(X, y)
|
||
|
|
||
|
from sklearn.linear_model import LogisticRegressionCV
|
||
|
logistic_regression_cv_model = LogisticRegressionCV(cv=5, max_iter=1000, random_state=42)
|
||
|
logistic_regression_cv_model.fit(X, y)
|
||
|
|
||
|
from sklearn.neural_network import MLPClassifier
|
||
|
mlp_model = MLPClassifier(max_iter=1000, random_state=42)
|
||
|
mlp_model.fit(X, y)
|
||
|
|
||
|
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
|
||
|
lda_model = LinearDiscriminantAnalysis()
|
||
|
lda_model.fit(X, y)
|
||
|
|
||
|
from sklearn.experimental import enable_hist_gradient_boosting
|
||
|
from sklearn.ensemble import HistGradientBoostingClassifier
|
||
|
hist_gradient_boosting_model = HistGradientBoostingClassifier(random_state=42)
|
||
|
hist_gradient_boosting_model.fit(X, y)
|
||
|
|
||
|
from sklearn.linear_model import RidgeClassifierCV
|
||
|
ridge_classifier_cv_model = RidgeClassifierCV()
|
||
|
ridge_classifier_cv_model.fit(X, y)
|
||
|
|
||
|
# define a dictionary to store results
|
||
|
results = {}
|
||
|
|
||
|
# loop through the models
|
||
|
for model_name, classifier_model in [
|
||
|
('SVC Classifier', svc_model),
|
||
|
('Random Forest Classifier', random_forest_model),
|
||
|
('Gradient Boosting Classifier', gradient_boosting_model),
|
||
|
('AdaBoost Classifier', adaboost_model),
|
||
|
('Bagging Classifier', bagging_model),
|
||
|
('K-NN Classifier', knn_model),
|
||
|
('Radius Neighbors Classifier', radius_neighbors_model),
|
||
|
('Decision Tree Classifier', decision_tree_model),
|
||
|
('Logistic Regression Classifier', logistic_regression_model),
|
||
|
('Ridge Classifier', ridge_classifier_model),
|
||
|
('Ridge ClassifierCV', ridge_classifier_cv_model),
|
||
|
('Passive-Aggressive Classifier', passive_aggressive_model),
|
||
|
('Perceptron Classifier', perceptron_model),
|
||
|
('SGD Classifier', sgd_model),
|
||
|
('Gaussian Naive Bayes Classifier', gaussian_nb_model),
|
||
|
('Multinomial Naive Bayes Classifier', multinomial_nb_model),
|
||
|
('Complement Naive Bayes Classifier', complement_nb_model),
|
||
|
('Bernoulli Naive Bayes Classifier', bernoulli_nb_model),
|
||
|
('Categorical Naive Bayes Classifier', categorical_nb_model),
|
||
|
('Extra Tree Classifier', extra_tree_model),
|
||
|
('Extra Trees Classifier', extra_trees_model),
|
||
|
('LinearSVC Classifier', linear_svc_model),
|
||
|
('NuSVC Classifier', nu_svc_model),
|
||
|
('Logistic RegressionCV Classifier', logistic_regression_cv_model),
|
||
|
('MLP Classifier', mlp_model),
|
||
|
('Linear Discriminant Analysis Classifier', lda_model),
|
||
|
('Hist Gradient Boosting Classifier', hist_gradient_boosting_model)
|
||
|
]:
|
||
|
# predict classes for the entire dataset
|
||
|
y_pred = classifier_model.predict(X)
|
||
|
|
||
|
# evaluate the model's accuracy
|
||
|
accuracy = accuracy_score(y, y_pred)
|
||
|
|
||
|
# define the input data type
|
||
|
initial_type = [('float_input', FloatTensorType([None, X.shape[1]]))]
|
||
|
|
||
|
# export the model to ONNX format with float data type
|
||
|
onnx_model = convert_sklearn(classifier_model, initial_types=initial_type, target_opset=12)
|
||
|
|
||
|
# save the model to a file
|
||
|
onnx_filename = data_path + f"{model_name.lower().replace(' ', '_')}_iris.onnx"
|
||
|
with open(onnx_filename, "wb") as f:
|
||
|
f.write(onnx_model.SerializeToString())
|
||
|
|
||
|
# load the ONNX model and make predictions
|
||
|
onnx_session = ort.InferenceSession(onnx_filename)
|
||
|
input_name = onnx_session.get_inputs()[0].name
|
||
|
output_name = onnx_session.get_outputs()[0].name
|
||
|
|
||
|
# convert data to floating-point format (float32)
|
||
|
X_float32 = X.astype(np.float32)
|
||
|
|
||
|
# predict classes for the entire dataset using ONNX
|
||
|
y_pred_onnx = onnx_session.run([output_name], {input_name: X_float32})[0]
|
||
|
|
||
|
# evaluate the accuracy of the ONNX model
|
||
|
accuracy_onnx = accuracy_score(y, y_pred_onnx)
|
||
|
|
||
|
# store results
|
||
|
results[model_name] = {
|
||
|
'accuracy': accuracy,
|
||
|
'accuracy_onnx': accuracy_onnx
|
||
|
}
|
||
|
|
||
|
#print the accuracy of the original model and the ONNX model
|
||
|
print(f"{model_name} - Original Accuracy: {accuracy}, ONNX Accuracy: {accuracy_onnx}")
|
||
|
|
||
|
# sort the models based on accuracy
|
||
|
sorted_results = dict(sorted(results.items(), key=lambda item: item[1]['accuracy'], reverse=True))
|
||
|
|
||
|
# print the sorted results
|
||
|
print("Sorted Results:")
|
||
|
for model_name, metrics in sorted_results.items():
|
||
|
print(f"{model_name} - Original Accuracy: {metrics['accuracy']:.4f}, ONNX Accuracy: {metrics['accuracy_onnx']:.4f}")
|
||
|
|
||
|
# create comparison plots for sorted results
|
||
|
fig, ax = plt.subplots(figsize=(12, 8))
|
||
|
|
||
|
model_names = list(sorted_results.keys())
|
||
|
accuracies = [sorted_results[model_name]['accuracy'] for model_name in model_names]
|
||
|
accuracies_onnx = [sorted_results[model_name]['accuracy_onnx'] for model_name in model_names]
|
||
|
|
||
|
bar_width = 0.35
|
||
|
index = range(len(model_names))
|
||
|
|
||
|
bar1 = plt.bar(index, accuracies, bar_width, label='Model Accuracy')
|
||
|
bar2 = plt.bar([i + bar_width for i in index], accuracies_onnx, bar_width, label='ONNX Accuracy')
|
||
|
|
||
|
plt.xlabel('Models')
|
||
|
plt.ylabel('Accuracy')
|
||
|
plt.title('Comparison of Model and ONNX Accuracy (Sorted)')
|
||
|
plt.xticks([i + bar_width / 2 for i in index], model_names, rotation=90, ha='center')
|
||
|
plt.legend()
|
||
|
|
||
|
plt.tight_layout()
|
||
|
plt.show()
|
||
|
|